全局变量的作用域(C语言程序变量作用域的实现机制是什么)
本文目录
C语言程序变量作用域的实现机制是什么
没有标签。作用域和编译后程序的内存布局有关,全局变量,静态变量存放在数据段中,在整个程序的生命周期内一直存在,作用域是全局的;动态分配的变量存放在堆区,在释放之前也是全局的;局部变量在栈上分配,由编译器管理,前一个作用域内的变量在下一个作用域没已经被释放了,所以是局部的
C语言程序中有全局变量和局部变量,函数内部的局部变量作用范围是整个函数吗
谢邀。
在开发C语言程序的过程中,若是能为变量取一个合适的名字,即使不写额外的注释也能让整个程序段一目了然。不过遗憾的是,有时候好用的名字会被其他变量占用,这时为变量取名就是一件头疼的事了。
我常常在同事的代码里看到诸如 size1, size2, size3 的变量名,令人眼花缭乱。
局部变量的作用域,是整个函数吗?
总体来说,C语言中的变量可根据作用域的不同分为全局变量和局部变量。一般来说,定义在函数中的变量被称为局部变量,非 static 局部变量存在于函数的栈帧中,函数的栈帧在其执行完毕后会被系统回收,此时局部变量自动释放,因此局部变量只在函数中有效。这一点相信即使C语言初学者,也是明白的。
不过不知道读者有没有想过这个问题:C语言函数中的局部变量作用范围是整个函数吗?比如,在函数 fun() 中定义了变量 size,那 size 是否在 fun() 函数所属的整个代码段都可用呢?在回答这个问题之前,应明白,至少gcc version 4.8.4 已经不再限制C语言函数定义变量必须在代码段的开头了,也就是说下面这段C语言代码是合法的:
定义变量 i 可以在若干行语句之后,甚至像下面的C语言代码这样,在 if 语句块中定义变量 size 也是合法的,请看:
现在在上面的C语言 main() 函数返回前添加一行 size ++;,即:
编译并执行添加 size++; 之后的C语言代码,会发生什么呢?请看:
编译失败了,提示第 8 行的 size 没有声明!这就奇怪了,size 明明在上面的C语言代码第 6 行声明了啊?!这其实就解答了“C语言函数中的局部变量作用范围是整个函数吗?”这个问题,显然,局部变量 size 的作用范围就不是整个函数。
不知道会不会有朋友认为:编译失败是因为 if 语句没有执行,所以 int size = 30; 也没有执行,因此 size 没有声明。
既然局部变量作用域不是整个函数,那它的作用域是什么呢?
相信读者已经知道,C语言代码中具有人类语言意义的 main、if、while 等词只是为了便于程序员使用,计算机并不能识别这些单词,因此若想执行C语言程序,需要通过编译器将代码“翻译”成计算机认识的指令序列。
编译器在编译C语言代码过程中,也要处理变量的作用范围问题。应明白“全局”和“局部”是对相对概念,所以编译器首先需要定义一个“局部”的标准,将“{}”符号包围的代码视为一个“局部”就是一个不错的选择。
以上分析基于 gcc version 4.8.4。
现在就清楚了,局部变量的作用范围就是它所属的 “{}” 包围的代码块,而全局变量的作用范围则是多个 “{}” 包围的代码块。再来看上面的问题,main() 函数中第 6 行的 size 属于 if{} 代码块,而第 8 行的 size 属于 main{} 代码块,因此虽然它俩名字一模一样,但是编译器仍然会认为是不同的变量,编译就报错了。
事实上,在C语言程序开发中,可以只使用“{}”做局部处理,例如下面这段代码:
编译上面这段C语言代码并执行,结果如下:
显然,函数内部的 “{}” 包裹的C语言代码段并没有影响到外面的 size,这下就不用怕变量名被占用了。
函数内部子{}代码块运行完毕之后,变量内存会被释放吗?
这个问题的答案其实上面已经解释了,变量即使是函数内部子{}代码块里的局部变量,它也是存储在函数的栈帧内的,而栈帧只有在整个函数运行完毕后才会被系统回收,所以函数内部子{}代码块里的局部变量占用的内存也在函数执行完毕之后才会被释放。
可以做如下实验,首先在函数的子 {} 代码块外部定义一个很大的数组,相关C语言代码如下,请看:
编译并执行这段C语言代码,然后使用 top 命令查看程序所占资源如下:
编译并执行这段C语言代码,然后使用 top 命令查看程序所占资源如下:
已经一目了然了。
小结
C语言函数中的局部变量的作用范围有时并不是整个函数,利用这一点可以在一定程度上解决变量名被占用的问题。不过应该注意,函数内部子{}代码块里的局部变量占用的内存也在函数执行完毕之后才会被释放。
欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。
本文相关文章:

哪一个编程语言比较好?什么是pypl,以及tiobe-index的不同
2025年4月5日 03:30

java接口代码(不同编程语言的程序可不可以通过接口相互调用)
2025年4月1日 13:00

java接口代码(不同编程语言的程序可不可以通过接口相互调用)
2025年4月1日 13:00

c语言程序设计 谭浩强(谭浩强在程序员圈子里的口碑如何为什么)
2025年3月30日 13:50

widevine(HTC 手机 开机说 Android 正在升级 正在优化第1个应用程序 共36个)
2025年3月29日 22:40

stakeholder theory(英语语言文学硕士毕业论文答辩一般会问什么问题)
2025年3月29日 17:00

zencart下载(如何用xampp搭建本地环境并安装zencart程序)
2025年3月29日 15:20

在C语言中 z=x>y x: y; 这个表达式是什么意思啊,求解?if(i=a<ba:b;i>0;i--)啥意思
2025年3月29日 11:50

provision apk(摩托罗拉xt800可以删除的系统程序有哪些)
2025年3月29日 06:50

python实现socket编程(python功能强大,开发网络程序如何快速入门)
2025年3月23日 12:30

谭浩强c语言电子版(哪本书最适合初学电工电子比如初学C语言就用谭浩强C程序设计,单片机就郭天祥单片机)
2025年3月23日 06:30

谭浩强c语言电子版(哪本书最适合初学电工电子比如初学C语言就用谭浩强C程序设计,单片机就郭天祥单片机)
2025年3月23日 06:30

git 常用命令(使用git命令行的是什么样的感受是不是程序员对于命令行都有种“信仰”)
2025年3月21日 22:20
更多文章:

addeventlistener绑定事件(js 判断是否存有事件 addeventlistener)
2025年3月20日 18:10

数据库sql语句常见面试题(互联网公司在面试数据分析师工作时会被问什么样的问题)
2025年3月15日 02:30

android api 30(android API是什么)
2025年2月15日 18:30

equals和等号的区别(java==和equals的区别)
2025年4月3日 10:50

西门子组态软件wincc教程(如何安装西门子wincc组态软件要具体的)
2025年3月4日 12:00

日志分析系统(日志分析系统硬件配置啥配置求各位大牛解答一下)
2025年2月24日 18:40

boundless品牌(boundless voyage什么牌子)
2025年4月3日 13:30

免费下载动画模板(我想自己制作动画,要什么软件,在哪野可以下载)
2025年3月23日 03:30

filter python(python中的filter()函数怎么用特别是一个函数有多个输入参数时)
2025年2月25日 12:50

房产小程序后台有什么功能?有房产项目的小程序吗有没有必要定制一个
2025年2月18日 02:10