C语言陷阱与技巧第1节,C语言函数中的局部变量作用范围是整个函数吗?
发表于: 2019-03-22 16:52:29 | 已被阅读: 37 | 分类于: C语言
在开发C语言程序的过程中,若是能为变量取一个合适的名字,即使不写额外的注释也能让整个程序段一目了然。不过遗憾的是,有时候好用的名字会被其他变量占用,这时为变量取名就是一件头疼的事了。
我常常在同事的代码里看到诸如 size1, size2, size3 的变量名,令人眼花缭乱。
局部变量的作用域,是整个函数吗?
总体来说,C语言中的变量可根据作用域的不同分为全局变量和局部变量。一般来说,定义在函数中的变量被称为局部变量,非 static 局部变量存在于函数的栈帧中,函数的栈帧在其执行完毕后会被系统回收,此时局部变量自动释放,因此局部变量只在函数中有效。这一点相信即使C语言初学者,也是明白的。
void fun()
{
printf("something\n");
int i = 3;
printf("i=%d\n", i);
}
定义变量 i 可以在若干行语句之后,甚至像下面的C语言代码这样,在 if 语句块中定义变量 size 也是合法的,请看:
int main()
{
int i = 3, j;
j = i++;
if(j > 3){
int size = 30;
}
return 0;
}
现在在上面的C语言 main() 函数返回前添加一行 size ++;,即:
# gcc tmp.c
tmp.c: In function ‘main’:
tmp.c:8:2: error: ‘size’ undeclared (first use in this function)
size ++;
^
不知道会不会有朋友认为:编译失败是因为 if 语句没有执行,所以 int size = 30; 也没有执行,因此 size 没有声明。
既然局部变量作用域不是整个函数,那它的作用域是什么呢?
相信读者已经知道,C语言代码中具有人类语言意义的 main、if、while 等词只是为了便于程序员使用,计算机并不能识别这些单词,因此若想执行C语言程序,需要通过
以上分析基于 gcc version 4.8.4。
现在就清楚了,
事实上,在C语言程序开发中,可以只使用“{}”做局部处理,例如下面这段代码:
#include <stdio.h>
int main()
{
int size = 12;
{
int size = 8;
size ++;
printf("inside size: %d\n", size);
}
printf("outside size: %d\n", size);
return 0;
}
# gcc t.c
# ./a.out
inside size: 9
outside size: 12
显然,函数内部的 "{}" 包裹的C语言代码段并没有影响到外面的 size,这下就不用怕变量名被占用了。
函数内部子{}代码块运行完毕之后,变量内存会被释放吗?
这个问题的答案其实上面已经解释了,变量即使是函数内部子{}代码块里的局部变量,它也是存储在函数的栈帧内的,而栈帧只有在整个函数运行完毕后才会被系统回收,所以函数内部子{}代码块里的局部变量占用的内存也在函数执行完毕之后才会被释放。
int main()
{
char size[2*1024*1024] = {};
{
}
while(1);
return 0;
}
编译并执行这段C语言代码,然后使用 top 命令查看程序所占资源如下:
然后,在函数的子 {} 代码块
int main()
{
{
char size[2*1024*1024] = {};
}
while(1);
return 0;
}
编译并执行这段C语言代码,然后使用 top 命令查看程序所占资源如下:
已经一目了然了。
小结
C语言函数中的局部变量的作用范围有时并不是整个函数,利用这一点可以在一定程度上解决变量名被占用的问题。不过应该注意,函数内部子{}代码块里的局部变量占用的内存也在函数执行完毕之后才会被释放。