2

我正在学习 CI 中的存储类有一个简单的代码

enter code here
int f1()
{
    static int i=0;
    i++;
    printf("%d",i);
}

int f2()
{
    printf("%d",i);
}

int main()
{
    f1();f2();f1();f2();
}

编译器给出错误,因为 f2() 中未声明“i”。正如我所想,内存静态变量分配在程序内存的数据部分中。因此该文件中的任何函数都应该能够访问它。

编译器如何知道函数中本地声明的变量仅绑定到该函数?编译器如何评估它?

4

3 回答 3

4

尽管static变量的生命周期与定义它的范围无关(与具有自动存储持续时间的变量不同):

{
    static int i=0;
    i++;
    ...
    {
        i++;  // <-- still well defined, even in nested scope
    }
}
i++;  // <-- undefined

它只能在这个范围内访问。编译器只是检查符号i之前是否已定义,并且它看到,该符号i尚未在该范围内定义(static int i=0;定义了一个可在本地访问的变量~编译器不关心它的生命周期)。

如果您需要在其范围之外访问它,则必须通过引用(其地址)将其传递出去或使其成为全局:

static int i = 0;
...
{
    i++;
}
...
i++;  // <-- accessing global variable
于 2013-09-24T11:36:31.257 回答
1

静态变量确实存储在数据部分中,但仅在声明它们的函数范围内。

您应该执行以下操作

static int i=0;
int f1()
{
    i++;
    printf("%d",i);
}

int f2()
{
    printf("%d",i);
}

现在两个函数都可以访问变量 i 。

于 2013-09-24T11:36:13.083 回答
1

永远记住范围是编译时而不是运行时。C 有一个扁平的内存结构。这意味着您可以从任何地方访问任何内容。您可以制作 i 的指针并可以访问它。但是,当变量的范围结束时,C 会说未定义的行为。这完全是一个编译器限制。您还可以看到链接 - C 中的范围是否仅与编译时相关,因为我们知道我们可以在运行时访问任何内存?更多细节。此外,这可能会有所帮助静态变量和全局变量都驻留在数据段中。不过,静态变量的范围有限。为什么?. 因此,是翻译单元向您抛出错误。

让我们通过例子来理解这一点。

#include "stdio.h"


int *ptr_i;

void func1()
{
  static int i = 0;

  ptr_i = &i;

  i++;
  printf("The static i=%d\r\n",i);

}

int main(int argc, char *argv[])
{

  func1();

  (*ptr_i)++;

  func1();


}

该程序的输出如下。静态 i=1 静态 i=3

正如您可能已经理解的那样,范围不是运行时。我能够通过指针访问 i 使用的内存位置。因此,您可以访问 C 中的任何内存,因为它是一个平面内存结构。在这个例子中,我使用指向 i 的指针访问了 i 的内存。注意,编译器永远不会抛出任何错误。因此,范围是编译时而不是运行时。

于 2013-09-24T12:09:39.563 回答