首先看看:
#include <stdio.h>
static int v1 = 0;
int fun()
{
static int v2 = 0;
++v2 && ++v1;
printf("%in", v2);
return v2;
}
int main()
{
++v1;
printf("%in", fun());
printf("%in", 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("%in", v2);
}
int main()
{
++v1;
printf("%in", fun());
printf("%in", v1);
}
输出:
1
2
2
问题是为什么?谢谢。
main()
递增v1
,因此其值为1
。
当你调用fun()
时,它会递增v2
和v1
,所以v2
是1
,v1
是2
。
然后它打印v2
,所以它打印1
。这是输出的第一行。
然后它返回v2
,所以它返回1
。
然后main()
打印返回值,因此打印1
。这是输出的第二行。
然后main()
打印v1
,所以它打印2
。这是输出的第三行。
您不会调用fun()
两次,因此代码段中的任何内容都不取决于是否保留该值。为了看到变量被保留,您必须再次调用该函数。如果您添加另一个
printf("%dn", fun());
最后,它将打印两次2
,因为v2
的值将被保留和递增。
第二个代码段会产生未定义的行为,因为声明为返回int
的函数不返回任何内容。它只是意外地返回了你所期望的 -2
是printf()
的返回值,因为它返回它打印的字符数(1
后跟换行符),并且它被留在用于函数返回值的位置。更改要执行的操作
printf("|%d|"n", v2);
我希望你会得到不同的结果。
带有 return 语句的第一个代码块是正确的行为。 程序的流程是这样的:
- 编译器从 main() 开始
- v1 = v1 + 1; 因此 v1 = 1
- 你在打印语句中调用 fun() -->程序控制转到 fun():
- v2 已初始化 v1 和 v2
- 递增,v2 = 1 ; v1 = 2; (如果 && 语句中的第一个值结果为 0,这部分实际上很棘手)
- 将 1 打印到控制台
- 向调用函数返回值 iof v2,即 1;在本例中为 main()
- 控制又回到了主要;由于您正在打印函数的返回值,因此它打印 1
- 最后一条语句打印 v1 的值为 2。
因此输出为
1
1
2
在第二个代码块中,您可能只是很幸运。函数签名说它返回一个 int,而你什么都不返回。这会导致不稳定/未定义的行为。不幸的是,C作为一种语言并没有强制程序员这样做。
有关由于eax 寄存器而导致的这种未定义行为的原因的更多详细信息,请参阅: 函数返回值而不返回语句