最近在一次采访中,我遇到了这个问题“静态变量如何在函数调用中保持其先前的值”。想了半天,实在想不出有什么令人信服的答案。有人可以解释一下吗?试过谷歌,找不到我的信息。
7 回答
静态变量存储在存储所有全局变量的 .data 区域中。并且这些全局和静态变量被分配为 exec 操作的一部分(即创建一个新进程/分叉一个新进程)。
-----------------------
| Command Line Arg |
|---------------------|
| Stack |
| \/ | < Grow downward
|---------------------|
| /\ |
| Heap | < Grows Upward
|---------------------|
| .bss | (Uninitialized global variables)
|---------------------|
| .data | (initialized global/static variables)
|---------------------|
| .text |
-----------------------
上图中.data是存放所有在函数内部声明或声明为全局变量的静态变量的区域。希望这可以帮助。
简单来说,函数内部的静态变量类似于全局变量。编译器对变量的可见性和访问进行所有必要的检查。除此之外,它只是另一个全局变量。
因此,这样做是合法的:
int *test_static()
{
static int func_var = 1234;
printf("%d", func_var);
return &func_var; // return pointer to int
}
int main()
{
int *i = test_static(); // will print '1234' and point i to func_var
// we can't do "func_var = 99;" here, but...
*i = 99;
test_static(); // will print '99'
return 0;
}
我并不是建议我们应该练习这个!;)
引用 ISO C 标准,第 6.2.4 节第 2 段:
对象的生命周期是程序执行期间保证为其保留存储的部分。一个对象存在,有一个不变的地址,并在其整个生命周期中保留其最后存储的值。
第 3 段:
一个对象,其标识符被声明为[SNIP]并带有存储类说明符static,具有静态存储持续时间。它的生命周期是程序的整个执行过程,它的存储值只在程序启动之前初始化一次。
这就解释了为什么它需要保持其先前的值,而不是它是如何做到的(告诉实现如何做事,而不是他们必须做什么不是标准的工作)。
它是如何做到的?无论如何,实现选择让它这样做。你可以很容易地问为什么它不能保持以前的值。
但基本上它存储在函数启动之前分配的某个内存区域中,main
只要程序正在运行,它就不会被释放,并且除非程序本身这样做,否则它的内容不会被修改。
static
在这方面,在文件范围内定义的对象与在函数内使用关键字定义的对象之间没有区别;两个对象都具有静态存储持续时间,并且很可能存储在同一内存区域中。
静态变量(无论是否在函数内部)都在全局内存空间中。它们在程序开始时被初始化并在程序的长度内驻留。
C11 5.1.2 “所有具有静态存储持续时间的对象应在程序启动前初始化(设置为其初始值)。”
6.2.4.3 “......它的生命周期是程序的整个执行过程,它的存储值在程序启动之前只初始化一次。”
将函数作用域的静态变量视为仅对定义它们的函数的作用域可见的全局变量。
我给你一个参考,可以帮助你假设。
静态变量存在于正在执行的程序的整个生命周期中。当执行线程离开声明它的函数时,它不会停止存在。所以,它永远不会失去它的价值。