补充
- 递归调用的补充:无限制的递归调用不会产生死循环,而是在栈区空间中,被调函数“入栈(保护现场)”产生的返回值地址占满整个栈区空间,程序直接崩溃。
- 数组作为参数传递,传递的是数组的首元素地址。字符串数组的末尾存在‘\0’,因此字符串数组作为函数参数时,不需要元素个数作为函数参数,而是“找“字符串末尾的'\0'。
- 二维数组作为函数参数时,可以将二维数组看作时一维数组的数组,而数组的地址是数组首元素的地址,即二维数组是数组指针的数组。
标识符发作用域和可见性
- 作用域:标识符被定义的区域
- 可见性:标识符能够被访问的范围
作用域
- 作用域分为局部作用域和全局作用域
- 局部作用域定义局部变量,从定义位置开始生效,该作用域末尾结束,局部变量存储在栈区,当局部变量未初始化是,其输出结果随机。
- 全局作用域定义全局变量,从定义位置开始生效,程序文件末尾结束。全局变量存储在全局区(静态区),当全局变量未初始化时,输出结果默认为0.
- 尽量使用参数传参,全局变量与调用该全局变量的参数高度绑定,耦合性较高。
可见性
- 标识符必须先定义再使用
- 同一作用域内不得定义同名标识符
- 在没有包含关系的不同作用域中定义的同名标识符不受影响
- 在两个或两个以上具有包含关系的作用域中定义的同名标识符,外层标识符在内层不可见
变量的生存期
标量的生存期是指变量存在的周期。变量的生存期分为静态生存期和动态生存期。
静态生存期
静态生存期在程序开始运行前分配内存空间,程序运行结束后内存空间销毁。常用于存放全局变量。
动态生存期
动态生存期是作用域内定义开始,到函数运行结束。
- static:static函数修饰局部变量,用于修改变量的生存期,将其修改为静态生存期。局部作用域内函数运行结束后,内存空间不收回,直至程序运行结束后,内存空间销毁。当static修饰全局变量时,表示该变量仅在本程序文件可用,其它程序文件不可用。
- auto:系统自动分配内存空间,用完销毁。与之相对的是堆区内存空间,需要用户手动申请内存空间,手动销毁内存空间。
- register:修饰变量,表示用户建议CPU将该变量分配至寄存器中,以提高读写效率,但具体分配区域,取决于编译器。当运算过多过大时,系统可能会在CPU的寄存器中分配内存空间,以提高运算效率,被称作编译优先。register定义变量后,不得对变量取地址;
内部函数与外部函数
Linux系统可将多个C语言文件一同编译,编译命令如下:
gcc main.c func.c
表示将main.c文件和func.c文件一起进行编译。
- 函数调用的本质是CPU的指令跳转。
- extern修饰标识符,说明是对全局变量的声明
预处理命令
预处理命令用于改进编译环境,以提高编译效率。
Linux可对C语言文件只做预处理,不运行,命令如下:
gcc -E main.c -omain.i
表示将main.c文件只做预处理,不运行,并将其输出为main.i
预处理命令包含宏定义、文件包含以及条件编译。
宏定义
宏定义分为带参宏和不带参宏,为了区分其它标识符,通常宏命全部大写。不带参宏常用于为条件编译做准备,带参宏相较于函数调用效率更高,不需要加载函数入口和“保护现场”,但如果多次使用带参宏,则程序的复用性降低。
文件包含
文件包含是按照文件地址,对文件内容进行替换。
在Linux系统中,文件包含有’< >和‘" "‘两种使用方式,在使用时,有如下区别:
- 对于绝对路径,两者使用没有区别
- 对于相对路径,前者访问/user/include文件中,后者访问C文件同级目录
条件编译
如果变量符合某个条件,就执行某段程序,否则跳过。防止多次对同一个头文件多次引用。
编程规范如下
#ifndef _MAIN
#if _MAIN
......
#endif
标签:文件,函数,作用域,20250117,生存期,关于,数组,标识符,定义 From: https://blog.csdn.net/2501_90172633/article/details/145213504