嵌入式学习day8(C基础函数)

一丶函数

  定义:

           一个可以完成特定功能的代码模块 函数可以实现代码的复用

  三要素:

             功能,参数,返回值

  格式:

              存储类型 数据类型 函数名(参数列表) // 参数 形参

                {

                  函数体; // 功能

                  return 返回值; // 返回值

                 }
            注意:(
1)  没有参数:参数列表可以省略,也可以用 void
                       (2)  没有返回值:数据类型为 void,函数内部没有return语句
                       (3)  有返回值:要根据返回值的数据类型定义函数的数据类型
                       (4)  定义子函数时可以直接定义在主函数的上面,如果定义在主函数下面需要提前声明函数,声明函数:
数据类型 函数名(参数列表); // 形参

            形参和实参的区别:
                        形参是函数定义时,定义的形参变量。是形式上存在的参数,只有在电泳函数时才会开辟内存空间。
                        实参是调用函数时,实际传递的值。实际存在的值。
                        
形参的个数要和实参的个数一一对应(数据类型也要对应)

  特点:

         函数不调用不执行, 函数调用多次就会执行多次

函数的传参:

        1.值传递:

                   单向传递(实参--->形参)修改形参 实参不会发生变化

#include<stdio.h>
int fun(int a,int b)
{
    int sum;
    sum = a + b;
    return sum;
}
int main(int argc, char const *argv[])
{
    int a = 10;
    int b =20;
    int sum = fun(a,b); //a,b传参给函数后,a,b的值并不会发生改变
    printf("%d\n",sum);
    return 0;
}

2.地址传递:

                 双向传递,在函数中修改形参,实参会一起改变(把变量的地址传递过去,通过地址对原内容修改)

#include<stdio.h>
void fun(int *p1,int*p2)
{
    int c =*p1;                  
    *p1 = *p2;
    *p2 = c;                  //交换ab的值
}
int main(int argc, char const *argv[])
{
    int a =1,b=2;             //a = 1,b=2
    fun(&a,&b);               //将a,b的地址传给fun函数,函数中形参改变后,实参也会改变
    printf("%d %d\n",a,b);    //a = 2 , a = 1
    return 0;
}

3.数组传递

                和地址传递一样,参数中如果存在数组的定义,也会认为是指针 (本质也会认为是地址传递,传递的是数组的首地址(一维数组))
#include <stdio.h>
void *fun(char *p)
{
    for (int a = 0; a < 5; a++,p++)
        printf("%c", *p);
}
int main(int argc, char const *argv[])
{
    char buf[32] = "hello";
    char *p = fun(buf);
    return 0;
}

二丶开辟堆区空间

为什么存在动态内存开辟

          在技术方面,普通的空间申请,都是在全局或者栈区,全局一般不太建议大量使用,而栈空间有限,那么如果一个应 用需要大量的内存空间的时候,需要通过申请堆空间来支持基本业务。
          在应用方面,程序员很难一次预估好自己总共需要花费多大的空间。想想之前我们定义的所有数组,因为其语法约束,我们必须得明确"指出"空间大小.但是如果用动态内存申请(malloc)因为malloc是函数,而函数就可以传参,也就意味着,我们可以通过具体的情况,对需要的内存大小进行动态计算,进而在传参申请,提供了很大的灵活性。
          
需要手动开辟空间,手动释放、如果只开辟不释放,所用的空间会越来越少

开辟空间

                #include <stdlib.h>

                void *malloc(size_t size);
                功能:在堆区开辟空间
                参数:size:开辟空间的大小(单位:字节)
                返回值:成功:返回开辟空间的首地址
                              失败:NULL // 为什么出现开辟失败,它没有足够大的空间了

释放空间

                #include <stdlib.h>
                void free(void *ptr);
                功能:释放堆区空间
                参数:ptr:堆区空间的首地址
                返回值:无
 

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
    // 你可以这么开辟 malloc(40);
    // 也可以这么开辟 malloc(size(int)*10);
    int *p = (int *)malloc(sizeof(int)*10);
    if (NULL == p)
    {
        printf("开辟失败!\n");
        return -1;
    }
    printf("开辟成功!\n");
    // 在此去书写一些功能
    for (int i = 0; i < 9; i++)
    {
        scanf("%d", &p[i]);
    }
    for (int i = 0; i < 9; i++)
    {
        printf("%d\n", p[i]);
    }
    // 空间使用完成之后,记得释放
    free(p);
    p=NULL;
    return 0;
}
注意:

           1. 手动开辟堆区空间,要注意内存泄漏 ,当指针指向开辟堆区的空间之后,又对指针重新赋值,则没有指针指向开辟堆区空间,就会造成内存泄露
            2. 使用完堆区空间之后及时释放空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值