fly*_*uzi 0 c evaluation operands
所以只是为了好玩,我有这个代码片段:
#include <stdio.h>
main()
{
int i;
int a;
i = 17;
//scanf("%d", &i);
a = (i+=5) * (i-=3);
printf("a is %d, i is %d\n", a, i);
}
Run Code Online (Sandbox Code Playgroud)
在C规范中,它表示操作数评估的顺序是未定义的,所以我期望看到22*19或19*14.但是,结果是19*19:
~ $ gcc a.c
~ $ ./a.out
a is 361, i is 19
Run Code Online (Sandbox Code Playgroud)
我想到了,我能想出的唯一解释是编译器对值进行了"延迟"评估(i+=5)
,它认为(i+=5)
价值只是i的值.同样的(i-=3)
.
但是,如果我取消注释scanf()
:
#include <stdio.h>
main()
{
int i;
int a;
i = 17;
scanf("%d", &i);
a = (i+=5) * (i-=3);
printf("a is %d, i is %d\n", a, i);
}
Run Code Online (Sandbox Code Playgroud)
现在我在提示时输入17:
~ $ gcc a.c
~ $ ./a.out
17
a is 418, i is 19
Run Code Online (Sandbox Code Playgroud)
为什么它表现出不同的行为?
这是未定义的行为.C标准表示不允许i
在两个序列点之间多次修改同一个对象(在本例中)(在这种情况下,语句之前和之后的分号).
未定义的行为意味着任何事情都会发生.它似乎可以正常工作.它可以给出错误的答案.它可能会使您的流程崩溃.它可以擦除你的硬盘.或者它甚至可以让您的CPU着火.根据语言标准,这些都是允许的行为.