作用域
在先前的教程中,已经提到了全局变量这一概念。全局变量就是作用域之一。作用域决定了变量可访问性。在超出作用域的位置不能访问对应变量。
在 C
中,有三种地方可以声明变量:
在所有函数之外的全局变量
在函数或代码块内部的局部变量
在函数声明中的形式参数
全局变量
全局变量顾名思义,在程序中的任意地方均可访问。全局变量声明在所有函数之外。
在所有函数之外也可以声明全局常量。
1 |
|
很多时候全局变量只是为了在当前文件中传递信息或者别的用途,不想其他文件可以访问到这个变量,这时候可以使用
static
存储类。static
的全局变量的作用域会被限制在当前文件,即使在其他文件内使用extern
也访问不到。
局部变量
局部变量是声明在函数或代码块内的变量。其作用域局限在代码块内,只在代码块内可以使用,代码块外不可访问。
如果局部变量与全局变量重名,则优先使用局部变量。如果存在作用域嵌套,内层变量与外层同名,则在内存作用域优先使用内层变量
1 |
|
局部变量会被分配在栈上存储,会随着函数运行结束栈空间回收被一起回收。如果不想局部变量被回收可以使用
static
存储类。static
变量会被分配在静态存储区上,不会随着栈回收而被回收。
形式参数
函数的参数即形式参数,作用域为函数体内部,如果与全局变量同名会优先使用参数。
1 |
|
作用域相关的变量初始化
在声明变量时如果没有手动初始化,全局变量和静态变量会被编译器自动初始化为 0值
(数字类型为0,指针类型为NULL),局部变量则是随机值。
- 静态变量与全局变量
程序内存区域中有两个区段: data
和 bss
区段,用来存放全局变量和静态变量,其空间在程序运行结束后自动释放。其中 data
区段用于存放已初始化的全局变量和静态变量; bss
区段用于存放为初始化的全局变量和静态变量,并在程序运行前被自动清零。所以未初始化的全局变量和静态变量在程序执行之前已经为0。
- 局部变量
1 |
|
多次尝试时会发现,未初始化的局部变量的值似乎一直都是0。这是因为未初始化的局部变量会被直接指派到未经任何处理的原生栈空间上,其内容为内存内部的随机垃圾值。然而内存很大,可能大部分空间都为默认值0,所以会产生这种情况。但是正因为是垃圾值,其内容完全不可控,所以变量声明后一定要初始化。
- 形式参数
形参的值由传入值决定,在给函数传参时参数不够或类型不对会导致编译器报错,如果通过函数指针强行传入,缺少的参数会被初始化为随机值。
写在最后
作用域控制着变量的使用范围,管理好作用域,保证变量之间不会互相干扰。