为什么静态局部变量在这种情况下不保留它的值?

why static local variable doesn't preserve it's value in this case?

先来看看:

#include <stdio.h>

static int v1 = 0;

int fun()
{
    static int v2 = 0;
    ++v2 && ++v1;
    printf("%i\n", v2);
    return v2;
}
int main()
{
    ++v1;
    printf("%i\n", fun());
    printf("%i\n", v1);
}

输出:

1
1
2

所以整个事情都是关于 C 中的全局静态和局部静态变量,所以静态变量的主要 属性 是它“保留它的值”这一事实,但在这里它不是,第一条输出符合预期: fun()v2 的值应该是 ++v2,即 1 但第二条不是,预期的是当它调用时main() 它的保留值将是 1 并且它会再次 ++v2 所以第二个输出预计是 2 。 当我们消除 return v2 时,程序会按预期工作。

#include <stdio.h>

static int v1 = 0;

int fun()
{
    static int v2 = 0;
    ++v2 && ++v1;
    printf("%i\n", v2);
}
int main()
{
    ++v1;
    printf("%i\n", fun());
    printf("%i\n", v1);
}

输出:

1
2
2

问题是为什么?谢谢。

main()递增v1,所以它的值为1.

当您调用 fun() 时,它会递增 v2v1,因此 v21v12.

然后它打印 v2,所以它打印 1。这是第一行输出。

然后它 returns v2, 所以它 returns 1.

然后 main() 打印 return 值,所以它打印 1。这是第二行输出。

然后 main() 打印 v1,所以它打印 2。这是第三行输出。

您没有调用 fun() 两次,因此您的代码段中的任何内容都取决于该值是否保留。为了看到变量被保留,您必须再次调用该函数。如果再添加一个

printf("%d\n", fun());

最后它会打印两次2,因为v2的值会被保留和递增。

你的第二个代码片段产生了未定义的行为,因为声明给 return 和 int 的函数没有 return 任何东西。它只是不小心 return 达到了您的预期——2printf() 的 return 值,因为它 return 是它打印的字符数( 1 后跟一个换行符),它被留在用于函数的 return 值的位置。改函数做

printf("|%d|"\n", v2);

我希望你会得到不同的结果。

带有 return 语句的第一个代码块是正确的行为。 程序的流程是这样的:

  1. 编译器从main()开始
  2. v1 = v1 + 1;因此 v1 = 1
  3. 您正在 print 语句中调用 fun() --> 程序控制转到 fun():
    1. v2 已初始化
    2. v1和v2递增,v2 = 1; v1 = 2; (如果 && 语句中的第一个值结果为 0,这部分实际上很棘手)
    3. 向控制台打印 1
    4. returns 调用函数的 v2 的值为 1 的值;在这种情况下 main()
  4. 控制权又回到了主线;由于您正在打印它打印的函数的 return 值 1
  5. 最后一条语句打印出 v1 的值为 2。

因此输出为

1
1
2

在第二个代码块中,您可能刚刚走运。函数签名说它 return 是一个 int 而你 return 什么都没有。这会导致 erratic/undefined 行为。不幸的是,C 作为一种语言并没有对程序员强制执行此操作。

有关由于 eax 寄存器 导致的这种未定义行为的原因的更多详细信息,请参阅:Function returns value without return statement