C中函数内部的静态变量

Vad*_*klk 105 c static

什么会被打印出来?6 6或6 7?为什么?

void foo()
{
    static int x = 5;
    x++;
    printf("%d", x);
}

int main()
{
    foo();
    foo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

小智 161

这里有两个问题,生命周期和范围.

变量的范围是可以看到变量名称的位置.这里,x只在函数foo()中可见.

变量的生命周期是它存在的时间段.如果在没有关键字static的情况下定义x,则生命周期将从foo()的入口到foo()的返回; 因此每次通话都会重新初始化为5.

关键字static用于将变量的生命周期延长到程序的生命周期; 例如,初始化仅发生一次,然后变量保留其值 - 无论它是什么 - 将来所有对foo()的调用.

  • @devanl,是的,我们是. (15认同)
  • @LakshyaGoyal你的第二行是一个声明,而不是初始化。所以是的,你是正确的,每次“a”都为零(在第二行运行后立即)。当然,这可能会抵消使用静态变量的好处。 (3认同)
  • 如果我声明一个静态变量,然后像这样在单独的行上进行初始化,会发生什么:`static int a;``a = 0;` 在这种情况下,a 每次都会重置为 0。那是对的吗? (2认同)

Nit*_*rad 47

输出:6 7

原因:静态变量仅初始化一次(与自动变量不同),并且在运行时期间将绕过静态变量的进一步定义.如果没有手动初始化,则会自动初始化值0.所以,

void foo() {
    static int x = 5; // assigns value of 5 only once
    x++;
    printf("%d", x);
}

int main() {
    foo(); // x = 6
    foo(); // x = 7
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Cha*_*etz 9

6 7

编译器安排每次输入函数时都不会发生静态变量初始化


Ric*_*III 9

这与以下程序相同:

static int x = 5;

void foo()
{
    x++;
    printf("%d", x);
}

int main()
{
     foo();
     foo();
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

static关键字在该程序中所做的全部是它告诉编译器(基本上)'嘿,我在这里有一个变量,我不希望任何其他人访问,不要告诉其他人它存在'.

在一个方法中,static关键字告诉编译器与上面相同,但是,"不要告诉任何人这个函数在这个函数之外,它应该只能在这个函数内部访问".

我希望这有帮助

  • 嗯,它实际上并不相同.在X中仍然存在范围问题.在这个例子中,你可以用main中的`x`戳戳和futz; 它是全球性的.在原始示例中,`x`是foo的本地,只有在该块内部才可见,这是_generally_首选:如果foo存在以可预测和可见的方式维护`x`,那么让其他人戳它通常是危险的.另一个好处是保持它的范围`foo()`它还保持`foo()`可移植. (11认同)
  • 虽然您已经解决了由于声明变量的位置而导致的范围问题,但静态描述影响范围而不是生命周期似乎是不正确的. (3认同)
  • @ user2149140'不要告诉任何人这个函数存在于此函数之外,它应该只能在这个函数内部访问' (2认同)

Iva*_*van 6

输出:6,7

原因

的声明在x内部,foox=5初始化发生在foo!

这里我们需要明白的是

static int x = 5;
Run Code Online (Sandbox Code Playgroud)

不一样

static int x;
x = 5;
Run Code Online (Sandbox Code Playgroud)

其他答案在这里使用了重要的词,范围和生命周期,并指出范围x是从它在函数中声明的点到函数foo结束foo。例如,我通过将声明移到函数末尾来进行检查,这使得xx++;语句中未声明。

因此,static int x语句的(范围)部分实际上适用于您阅读它的地方,函数内部的某个地方,并且仅从那里开始,而不是函数内部的上方。

然而,x = 5声明(寿命)的部分是变量的初始化和将发生的OUTSIDE功能作为程序加载的一部分。变量x5程序加载时的值一起生成。

我在其中一条评论中读到了这一点:“此外,这并没有解决真正令人困惑的部分,即在后续调用中跳过初始化程序这一事实。 ”它在所有调用中都被跳过。变量的初始化在适当的函数代码之外。

无论 foo 是否被调用,理论上都会设置 5 的值,尽管如果您不在任何地方调用它,编译器可能会优化该函数。在调用 foo 之前,5 的值应该在变量中。

在 内部foo,该语句static int x = 5;根本不可能生成任何代码。

我发现x当我将一个函数foo放入我的程序时使用的地址,然后(正确地)猜测如果我再次运行该程序将使用相同的位置。部分屏幕捕获如下图的是x具有价值5,甚至在第一次调用之前foo

第一次调用 foo 之前的断点


Don*_*alo 5

只要程序运行,函数内的静态变量就具有生命周期.每次调用函数时都不会分配它,并在函数返回时取消分配.