【问题标题】:why static local variable doesn't preserve it's value in this case?为什么在这种情况下静态局部变量不保留它的值?
【发布时间】:2021-08-23 07:51:24
【问题描述】:

先看看:

#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

问题是为什么?谢谢。

【问题讨论】:

  • 您只调用该函数一次。你怎么知道它是否在调用之间保留了价值?
  • 如果你删除 return v2; 你有未定义的行为,因为函数被声明为返回一些东西。
  • 我明白了,该函数是未定义的“种类”,但它仍然返回一个值,即变量 v2 的值,并且该变量在第一个 ++v2 中静态保留其值,而当有一个变量没有保持其值的返回语句时,对于您的第一条评论,该变量在函数中被调用两次,它是自身和外部。
  • 变量的值为1++v2之后。为什么你认为它没有保留它?

标签: c scope static global-variables local


【解决方案1】:

main() 递增v1,因此其值为1

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

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

然后它返回v2,所以它返回1

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

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

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

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

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

您的第二个代码 sn-p 产生未定义的行为,因为声明为返回 int 的函数不返回任何内容。它只是意外地返回了你所期望的——2printf() 的返回值,因为它返回它打印的字符数(1 后跟换行符),并且它留在了使用的位置为函数的返回值。改变功能做

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

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

【讨论】:

  • 是的,就像你说的那样 Barmar,当函数调用时没有返回,t 打印出 printf 函数中有多少元素 2 感谢您伸出援手并提供良好的解释
【解决方案2】:

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

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

所以输出是

1
1
2

在第二个代码块中,您可能刚刚走运。函数签名说它返回一个 int 而你什么也不返回。这会导致不稳定/未定义的行为。不幸的是,C 作为一种语言并没有强制程序员这样做。

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

【讨论】:

  • 是的,只是不小心打印了 2,这是 printf() 函数 1 和馈线 \n 中有多少元素,感谢您的参考。
猜你喜欢
  • 2013-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
  • 2017-05-15
相关资源
最近更新 更多