ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从零开始的敲代码生活--C语言篇(函数)

从零开始的敲代码生活--C语言篇(函数) C语言函数完整整理一、函数核心作用模块化拆分代码减少重复冗余代码提高复用性降低代码耦合逻辑分层清晰便于阅读、修改、调试实现功能封装对外只暴露接口隐藏内部实现细节二、函数完整语法1. 函数定义实现返回值类型 函数名(形参列表) { 函数体功能代码; return 返回值; // void函数可省略return }各部分说明返回值类型int/char/float/double/结构体/指针函数运算结束返回对应数据void无返回值函数仅执行操作无需return补充非void函数必须写return否则返回随机垃圾值函数名 遵循标识符规则字母、数字、下划线不能数字开头推荐动宾命名get_max() print_arr()见名知意形参列表 格式类型1 变量1, 类型2 变量2 无参数写void标准规范fun(void)空括号fun()老式写法不推荐函数体 大括号不可省略内部是实现逻辑returnreturn 数值/变量;终止当前函数把值返回给调用处return;仅结束void函数无返回数据2. 函数调用格式函数名(实参列表);int max(int a,int b){ return ab?a:b; } int main(){ int res max(10,20); // 接收返回值 max(5,8); // 不接收返回值直接丢弃结果 return 0; }调用规则实参与形参个数、顺序、数据类型必须一一匹配实参可以是常量、变量、表达式函数不调用则不执行调用一次执行一次3. 函数声明作用若函数定义写在main之后编译器识别不到函数报隐式声明警告需提前声明语法声明只写头无函数体返回值类型 函数名(形参类型列表); // 示例 int max(int a, int b); void print_str(char str[]);使用场景单个.c文件内函数定义在主函数下方多文件工程函数写在其他.c在头文件.h统一声明外部文件#include即可调用。三、函数调用底层流程保护现场调用时将下一条指令地址、局部寄存器压入栈分配形参栈空间将实参拷贝给形参值传递执行函数内部代码恢复现场函数结束弹出栈中保存的地址回到调用位置继续执行释放函数栈内所有局部变量局部变量生命周期结束。补充函数栈空间有限递归过深会栈溢出程序崩溃四、函数传参三大核心方式1. 值传递普通变量传参规则实参拷贝一份副本给形参形参修改不影响外部实参void change(int n){ n 100; // 仅修改副本main里num不变 } int main(){ int num 10; change(num); printf(%d,num); // 输出10 }适用场景仅读取数据不需要修改外部变量2. 地址传递一级指针传参实参传递变量地址形参用指针接收通过*修改原变量内存外部实参同步变化void change(int *n){ *n 100; // 直接修改main中num的内存 } int main(){ int num 10; change(num); printf(%d,num); // 输出100 }适用场景函数内需要修改外部普通变量函数返回多个结果传递数组数组名本质首地址3. 二级指针传参实参传递指针变量的地址形参类型**接收可在函数内修改外部指针本身的指向void set_str(char **p){ *p hello c; // 修改外部指针pstr的指向 } int main(){ char *pstr test; set_str(pstr); }典型用途操作指针数组、动态分配内存返回堆地址五、数组作为函数参数1. 一维整形数组传参两种等价形参写法数组形参会退化指针函数内sizeof(数组名)仅得8字节指针大小必须手动传长度// 写法1 void print(int arr[], int len); // 写法2推荐直观体现指针本质 void print(int *arr, int len);2. 一维字符数组字符串传参字符串自带\0结束符无需传长度int mystrlen(char str[]); int mystrlen(char *str);3. 二维数组传参行数可省略列绝对不能省略二维数组名是数组指针int (*)[列]void show(int arr[][4], int row); void show(int (*arr)[4], int row);二维字符数组同理void print_strs(char str[][100], int line);六、递归函数定义函数直接/间接调用自身用递归代替循环完成重复逻辑必备条件递归出口终止条件必须存在结束分支否则无限递归栈溢出每次递归向出口靠近优缺点优点代码简洁树、阶乘、斐波那契等场景逻辑直观缺点频繁栈保护/恢复运行效率低于循环深度过大会栈溢出// 递归求阶乘 int fact(int n){ if(n 1) return 1; // 递归出口 return n * fact(n-1); }七、特殊函数拓展笔记补充1. 指针函数返回指针的函数返回值为类型*禁止返回局部栈变量地址函数结束栈销毁野指针。 合法返回值全局变量、static静态变量、字符串常量、堆malloc地址、传入的参数地址char *get_str(){ static char buf[20] hello; // static生命周期全局合法 return buf; }2. 函数指针指向函数的指针存储函数入口地址多用于回调函数解耦代码。 语法返回值(*指针名)(形参列表)int add(int a,int b){return ab;} int (*pfun)(int,int) add; // 定义并赋值 int res p(3,5); // 通过指针调用函数3. main主函数程序入口系统自动调用标准规范写法int main(void){ return 0; // 0代表程序正常退出 }八、变量作用域函数搭配补充局部变量函数内/形参 作用域仅限当前{}栈存储函数结束自动销毁默认随机值static局部静态变量 生命周期全局程序运行全程仅第一次调用初始化保留上次值全局变量 所有函数均可访问数据区存储默认初始0多文件用extern声明九、高频易错点函数声明和定义返回值、形参类型必须完全一致否则编译报错值传递无法修改外部变量改值必须传地址数组作参数退化为指针不能用sizeof求数组长度递归必须写出口否则栈溢出崩溃指针函数不能返回局部栈数组/变量地址void函数内return后不能加数值二维数组传参列数不可省略函数实参求值顺序自右向左
返回列表