-1

关于以下代码:

#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,所以.. 发生了什么?

`on a local k, K++ // 总是返回 0

`在全局 k = 0, k++ // 返回 0, 1, 2

`在静态 k, k++ // 返回 1, 2 ,3

谁能帮我理解这两个问题?

4

5 回答 5

5

函数内部的静态定义就像符号范围之外的函数外部的静态定义(在您的程序中您可以引用它)。它与堆栈帧无关...... k 不在堆栈上,它在“静态”/global/.data 内存中。

我知道这不像一个普通变量,因为第一个 k++ 返回 1 而不是 0

不,它返回 0,但 k 的值是 1。

在静态 k, k++ // 返回 1, 2 ,3

不,那不正确......它返回 0, 1, 2 ...

它不像一个全局的,因为我无法访问 main 例如里面的 k

这就是名称范围的工作原理;它与如何存储 k 无关。

于 2013-07-08T06:13:49.647 回答
1

不要刻薄,但任何关于 C 的参考都会解释这一点。

函数内变量上使用的static关键字允许该值在函数调用之间保持不变。它像全局一样存储,但您只能在定义它的函数范围内按名称访问它。

static标准 C 库中变量的一些典型用法出现在 和 的实现rand(3)strtok(3)。通常不鼓励使用它们,因为它会导致函数不可重入,从而在使用多个线程时造成严重破坏。POSIX 定义了一个strtok_r在需要重入时使用的函数。

于 2013-07-08T06:13:32.880 回答
1

变量k是在函数内部定义的,lastval所以它的作用域只在这个函数中。但是由于你用static关键字定义了它,它的生命周期就等于程序的生命周期。

所以根据静态的定义,这个变量k将只初始化一次,它将保留它的最后一个值,这就是你的情况。初始化的静态变量将进入内存.data部分。所以k将获得内存.data

于 2013-07-08T06:14:43.487 回答
1

存储为全局变量的静态变量,除了它们的作用域。您的程序在我的计算机上输出 0 1 2 3,因此请仔细检查。

于 2013-07-08T06:14:46.753 回答
0

在程序开始执行 main 之前,静态变量在全局内存空间(不在堆栈帧中)中实例化。

C,该变量在程序开始执行main之前被初始化。

C++,当程序第一次遇到这一行时,该变量被初始化。

当你执行“lastval()”函数时,那个“static int k = 0”将不再被执行。

于 2013-07-08T06:28:42.487 回答