学嵌入式和C语言编程 | 学习日记Day10:函数、函数的调用,值传递、递归、一维整型数组做函数参数
前言
今天学习 C 语言函数,函数是实现代码模块化最重要的工具。使用函数可以降低程序耦合度,减少重复代码,提高代码复用能力。在嵌入式项目开发中,我们会把传感器读取、外设驱动、数据处理全部封装成函数,方便调用与维护。本次学习内容包含函数定义、调用、声明、值传递、递归调用,以及数组作为函数参数的传参规则。
一、函数基础
函数优点:降低程序的耦合性(关联度),减少重复代码,让程序模块化,增强代码复用性。
1. 函数定义
格式:
c |
- 返回值:可以是 int、char 等基础数据类型,也可以是构造数据类型。用来返回函数最终运算结果。void空类型:函数执行完毕,不需要返回任何结果时使用 void 作为返回值。
- 函数名:标识符,遵守标识符命名规则,尽量见名知意。习惯以 “动词”+“宾语” 命名,例如get_max_val();获取最大值。
- 形参表:函数执行过程中需要用到的条件。
格式:数据类型 形参名, 数据类型 形参名, 数据类型 形参名 …
注意:当函数有明确返回值类型,必须写return;如果不写 return,系统返回内存里随机垃圾值。 |
2. 函数调用
格式:
c |
实参:传递给函数的实际条件,可以是常量、变量、表达式。
实参要求:
- 实参的个数和形参的个数必须一一对应。
- 实参和形参的数据类型要一致或者相互兼容。
概念区分:
- 主调函数:发起调用的函数
- 被调函数:被别人调用的函数
函数执行规则:
- 函数不被调用则不会执行,调用几次就执行几次。
- 实参和形参名字可以相同,也可以不同。
3. 函数的声明
出现场景:被调函数写在主调函数后面,编译器报implicit declaration隐式声明警告。
两种声明方式:
- 在主调函数前面进行函数声明:返回值类型 函数名(形参表);
- 多文件开发,其他文件想要调用本文件函数,也需要做函数声明。
4. 函数调用过程(栈空间工作机制)
- 保护现场:函数被调用时,把调用位置的下一条指令地址保存到栈空间,栈遵循先进后出。
- 恢复现场:被调函数执行结束,从栈取出保存的地址,CPU 回到调用处,继续执行后续代码。
二、函数的传参 —— 值传递
值传递:实参向形参做拷贝,实参、形参拥有各自独立内存空间。 |
值传递核心特点:
- 单向传递,只把实参拷贝给形参。
- 在被调函数内部修改形参,不会影响主调函数里面原来的实参变量。
项目 | 值传递说明 |
内存空间 | 实参、形参各自独立内存 |
数据流向 | 只能实参 → 形参,单向拷贝 |
修改效果 | 被调函数修改形参,主调函数变量不受影响 |
三、函数的递归调用
- 定义:函数直接或者间接调用自身。
- 本质:属于循环的一种实现方式。
- 重点规则:递归必须设置递归出口,没有出口就会变成死循环,造成栈溢出。
- 缺点:递归调用系统资源开销大于普通循环,消耗栈内存,嵌入式开发不建议深度递归。
简单递归示例逻辑,求累加:
Plain Text get_sum(5) → get_sum(4)+1 → get_sum(3)+1 → get_sum(2)+1 → get_sum(1)+1→return 1; |
四、一维数组作为函数参数
数组名本质是数组首元素的地址。 |
1. 传参书写格式
函数定义:
c |
函数调用:
c |
2. 数组做函数参数四条注意点
- 形参书写格式:int a[],方括号内常量可以写,也可以省略。
- 数组名传参,传递的不是全部数组拷贝,传递的是数组首元素地址,形参本质接收一个起始地址。
- 只传数组名无法得到数组长度,必须额外把数组长度 len 当做参数传入函数。
- 数组作为函数参数传递给被调函数后,函数内部的使用方法和外部的使用方法一样,除了sizeof(数组名);。
值传递 vs 数组传参对比
传参方式 | 传递内容 | 修改是否影响外部原始数据 |
普通变量值传递 | 变量值拷贝 | 不影响外部变量 |
数组名作为参数 | 数组首元素地址 | 函数内修改数组,外部数组同步改变 |
今日学习总结
- 函数三要素:返回值、函数名、形参列表;void 代表无返回值;有返回值的函数必须使用 return。
- 实参与形参个数、类型需要匹配;值传递是单向拷贝,修改形参不会改变主调函数变量。
- 函数写在调用之后,必须提前做函数声明,消除隐式声明警告。
- 函数调用依靠栈空间完成保护现场、恢复现场,栈遵循先进后出。
- 递归就是函数调用自己,一定要写递归出口,递归栈开销大,嵌入式尽量少用深度递归。
- 数组名做函数参数传递的是首元素地址,不是完整数组拷贝,必须额外传入数组长度;函数内部修改数组,外部原始数组会被同步修改。
- 工程实践:嵌入式开发中,传感器处理、外设驱动全部封装为函数,提升代码可读性、复用性。