C语言函数学习
一、函数核心作用
解耦程序,拆分重复代码,降低代码冗余
模块化开发,提升代码复用性、可读性与维护性
二、函数定义(完整实现)
语法格式
返回值类型 函数名(形参列表) { 函数体; }返回值
支持
int/char/float/double等基础类型、构造类型;void空类型:函数执行完毕无返回结果,可省略return或写return;;非
void函数必须用return返回对应类型值,否则返回随机垃圾值。
函数名遵循标识符命名规则,建议见名知意,多用动宾命名(
get_max_val、print_star)。形参列表格式:
数据类型 形参名, 数据类型 形参名...; 作用:函数执行依赖的外部条件,仅函数内部有效。
三、函数调用
基础语法
函数名(实参列表);
调用规则
实参个数、数据类型必须与形参匹配(兼容类型也可,如 char 传给 int);
实参与形参名称无强制关联,可相同可不同;
函数不调用则不执行,调用多少次就执行多少次;
函数调用整体是表达式,结果为函数返回值;
传参求值顺序:自右向左。
概念区分
主调函数:发起调用的函数(如
main);被调函数:被其他代码调用的自定义函数。
四、函数声明
作用场景
自定义函数写在
main之后,编译器报隐式声明警告,需提前声明;多文件工程,供其他
.c文件调用该函数。
声明语法
返回值类型 函数名(形参列表);(末尾分号不可少)
五、函数调用底层流程
保护现场:调用函数时,将下一条指令地址存入栈,记录返回位置;
执行被调函数内部逻辑;
恢复现场:函数执行完毕,取出栈中保存的地址,回到主调函数断点继续执行。
六、函数传参(值传递)
本质:实参向形参拷贝一份数据,实参、形参拥有完全独立的内存空间;
特性:被调函数内修改形参,不会影响主调函数原始变量;
图示逻辑:main 栈区变量和 fun 栈区变量分属两块内存,互不干扰。
七、递归函数
定义
函数直接 / 间接调用自身,本质等价循环。
必备要求
必须设置递归出口(终止条件),否则无限递归栈溢出;
优缺点
优点:代码简洁,适合阶乘、斐波那契、树形问题;
缺点:频繁入栈出栈,系统内存开销大于普通循环。
执行流程
递推:逐层调用自身,直到触发出口;
回溯:从出口逐层返回计算结果,合并得到最终值。
八、数组作为函数参数
定义格式
void print_array(int a[], int len){
逻辑;
}
核心特性
数组名传参本质传递数组首元素地址,不是完整拷贝数组;
形参写法
int a[]等价int *a,sizeof(a)结果为指针大小(64 位系统 8 字节),无法在函数内计算数组长度;必须额外传入数组长度
len;因为传递地址,函数内修改数组元素,会直接改变外部原数组;
外部数组的下标访问逻辑,在函数内完全通用。