技术宅小伙:CPU眼里的静态、全局和临时变量

大家好,我是技术宅小伙,关注没有用的知识。众所周知,C语言简单容易上手,往往是编程的入门语言。是的,如果只考虑最简单的编程场景,C语言确实比较简单。例如,定义一个全局变量、静态变量、临时变量,这都不是问题。但如果具体到全局变量、静态变量、临时变量之间的区别,以及它们所在的存储位置是在初始化数据段还是在未初始化数据段时,这又岂是一句话能解释清楚的呢?也许,我们并不需要绞尽脑汁的为它百度、谷歌或者用chat GPT找到一个合理的解释,而是用CPU的视角实际走一下程序过程,就能开云见日了。

打开ComponentX Pro,定义一个全局变量a,再写一个简单的函数FUNK1,并在函数里面定义一个静态变量b。最后写一个内函数做一下函数调用。发现问题了吗?函数FUNK1对应的CPU指令里面,居然对静态变量b没有任何表示。尽管我们在函数FUNK1里面定义了一个静态变量b,但编译器也会视而不见,似乎这根把静态变量b定义在函数FUNK1外面是完全等价的。如果我们打印一下它们所在的内存地址的话,你可以清楚的看到,它们的内存地址是相互邻近的,之间正好是一个Int类型的四字结宽度。所以全局变量a和静态变量b应该存储在同一块数据区域。所以除了作用域对静态变量b有限制外,静态变量b跟全局变量a的很多属性都是相似的。甚至,如果我们知道全局变量币的内存地址0X404034,我们也可以通过指针绕过作用域的限制,像全局变量一样读写全局变量币。

好了,让我们再定义一个临时变量c,然后分别做一下变量b和c的加1运算,并分别打印出两个变量的值和内存地址。为了让效果更加明显,我们最后做一下低规调用。如你所见,临时变量c的值是固定的。由于每次函数调用,变量c都会被重新初始化为2,然后做加1运算,所以每次打印出来的临时变量c的值都是3。但临时变量c的内存地址却不是固定的,而是在不断的变化。随着函数的不断调用,临时变量c的地址值也在下降。这也再次证明,堆栈是向低端地址生长的。虽然临时变量c的值没有变化,但显然每个临时变量c都是不同的,它们分别保存在不同的内存地址上,每个临时变量c都属于不同的函数作用域。就像广东有一个人叫张三,上海也有一个人叫张三,但显然两个张三并不是同一个人。

此时你可以简单休息或回味一下刚才的内容。也可以考虑点赞、关注、分享该视频,支持阿布持续输出没有用的知识。

再看看静态变量b,每次输出静态变量b的内存地址都是相同的,所以函数FUNK1被调用了多少次,静态变量b就会进行多少次加以运算,因为他们都是在对同一个变量币操作,所以变量币的值就会随着函数的不断调用而不断增加。

最后我们再看看初始化数据和未初始化数据。先定义一个负了初值的全局变量和一个临时变量,然后再定义几个全局变量或者临时变量,要么不给他们负初值要么就负值为0,最后打印一下他们的地址。在当前的编译环境下,Int类型会占据4个字节。如果所有的变量都存储在同一个内存区域的话,它们的地址间隔应该都是4个字节。但显然,这些变量被分割在两个内存区域,其中变量a、b被安排在一个区域,也称初始化数据段。如上期的视频,CPU眼里的程序运行所说,操作系统或运行库会在程序运行的时候从二进制文件中加载它们的初始值。、所以,编译器会把它们的值预先存储在二进制文件中。剩下的变量c、d、e、f被安排在另一个区域,也称未初始化数据段。无论它们是否被初始化为0,还是根本就没有初始化,都会在运行的时候被操作系统的加载程序或运行库初始化为0。由于编译器会在二进制文件中标识出未初始化数据段的起始终止地址,所以这些重复的0并不需要保存在二进制文件中,这样一定程度上可以减少二进制文件的大小,从而节省硬盘或Flash的存储空间。

总结一下: 1.全局变量和静态变量的内存地址是固定的,但临时变量的内存地址往往不是固定的。 2.静态变量除了作用域跟全局变量有所差异外,其存储原则、生命周期跟全局变量类似。 3.无论是全局变量还是静态变量,如果它们没有被初始化或者被初始化为0,都会被安置在未初始化数据段。一定程度上,可以节省二进制文件的存储空间。

好了,关于全局变量、静态变量、临时变量,你有什么高见呢?欢迎大家留言讨论,我们会在公众号阿布编程中持续跟大家分享。

全局变量还是静态变量,如果它们没有被初始化或者被初始化为0,都会被安置在未初始化数据段。一定程度上,可以节省二进制文件的存储空间。

好了,关于全局变量、静态变量、临时变量,你有什么高见呢?欢迎大家留言讨论,我们会在公众号阿布编程中持续跟大家分享。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术宅小伙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值