请解释每种情况下的工作情况。
为什么两种情况都有相同的输出?
案例I:
int main (void)
{
int i = 5;
if(i == ++i) //plz explain here How values are checked
printf("Equal");
else
printf("Not Equal");
return 0;
}
//Output: Equal;
案例II:
int main (void)
{
int i = 5;
if(++i == i) //plz explain here How values are checked
printf("Equal");
else
printf("Not Equal");
return 0;
}
//Output: Equal;
答案 0 :(得分:10)
这些程序都不是有效的;如果没有序列点,则不允许读取和更新相同的变量。因此,这些程序中的任何一个都会执行未定义的行为,因此它们可能碰巧在编译器和机器上返回相同的答案并不意味着什么。
答案 1 :(得分:0)
它是相同的,因为这是C.正如另一个答案所说,这个操作的结果是未定义的,因为你违反了C规则 - 这意味着在切换编译器时你不能保证相同的答案(尽管所有编译器都可以实现)类似,这并不能保证)。事实上C允许你用脚射击自己并不意味着这样做是好习惯。
现在,它为什么有用?
猜想#1:
i
可以存储在寄存器中,比如说r1
,并且编译器可能正在将这整个比较编译成一个单独的CMP指令,具有自动增量寻址模式。假设它是CMP ++r1, r1
或CMP r1, ++r1
,那么根据实际的CPU,两者都可能返回真正的比较。
猜想#2:
编译器可能正在将比较编译为:
inc r1 // increment r1
CMP r1, r1 // compare with itself
猜想#3:
编译器可能正在优化以始终将简单的变量访问权限放在右侧。允许这样做是因为==
运算符中的执行顺序是未定义的,编译器可以根据需要重新排列。