关于以下代码:
#include <stdio.h>
int lastval(void)
{
`static int k = 0;
return k++;
}
int main(void)
{
int i = 0;
printf("I previously said %d\n", lastval());
i++;
i++;
i++;
i++;
i++;
printf("I previously said %d\n", lastval());
i++;
i++;
i++;
printf("I previously said %d\n", lastval());
i++;
i++;
i++;
printf("I previously said %d", lastval());
i++;
i++;
i++;
return 0;
}
任何人都可以向我解释静态如何保持其价值?我虽然这是因为函数的堆栈框架在返回后没有被销毁所以我编写了这个代码在gdb下运行它并且我在每行之后进行回溯只有main的堆栈框架出现(它甚至没有列出lastval当我做坐在printf电话上的回溯,但无论如何)。
它的k实际如何存储?我知道这不像普通变量,因为第一个k ++返回1而不是0,并且它不像全局,因为我无法访问main中的k,例如,那么......发生了什么?
`在本地k上,K ++ //始终返回0
`在全局k = 0,k ++ //返回0,1,2
`在静态k上,k ++ //返回1,2,3
任何人都可以帮助我理解这两个问题吗?
答案 0 :(得分:5)
函数内部的静态定义就像在符号范围之外的函数之外的静态定义(在程序中可以引用它)。它与堆栈帧无关... k不在堆栈中,它位于“静态”/global/.data内存中。
我知道这不像普通变量,因为第一个k ++返回1而不是0
不,它返回0,但k的值则为1.
在静态k上,k ++ //返回1,2,3
不,这不正确......它返回0,1,2 ......
并且它不像全局,因为我无法在main中访问k,例如
这就是名称范围的工作原理;它与k的存储方式无关。
答案 1 :(得分:1)
不要太苛刻,但 C上的任何引用都会解释这一点。
函数中变量使用的 static 关键字允许值在函数调用中保持不变。它像全局一样存储,但您只能在定义它的函数范围内按名称访问它。
标准C库中static
变量的一些典型用法出现在rand(3)
和strtok(3)
的实现中。通常不鼓励使用它们,因为它可能导致不是 reentrant 的函数,因此在使用多个线程时会造成严重破坏。 POSIX定义了strtok_r
函数,以便在需要重入时使用。
答案 2 :(得分:1)
变量k
在函数lastval
中定义,因此其范围仅在此函数中。但由于您使用static
关键字定义它,因此其生命周期等于程序的生命周期。 / p>
因此,根据static的定义,此变量k
将仅初始化一次并保留其最后一个值,这就是您的案例中发生的事情。初始化的静态变量将进入.data
部分memory.so k
将获得.data
内存。
答案 3 :(得分:1)
静态变量存储为全局变量,但范围除外。您的程序在我的计算机上输出0 1 2 3,因此请仔细检查它。
答案 4 :(得分:0)
在程序开始执行main之前,静态变量在全局内存空间(不在堆栈框架中)中实例化。
C, 该变量在程序开始执行main之前初始化。
C ++, 当程序第一次遇到这一行时,该变量被初始化。
执行“lastval()”函数时,将不再执行“static int k = 0”。