解释一下这个C程序的工作原理
请解释每种情况下的工作情况。
为什么两种情况的输出相同?
情况一:
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;
情况二:
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;
Please explain working in each case.
Why both cases have same output?
Case 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;
Case 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;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这些程序都无效;如果中间没有序列点,则不允许读取和更新同一变量。因此,这些程序将执行的操作都是未定义的行为,因此它们可能碰巧在您的编译器和机器上返回相同的答案这一事实并不意味着任何事情。
Neither of those programs is valid; you are not allowed to read and update the same variable without a sequence point in between. Thus, it is undefined behavior what either of those programs will do, and so the fact that they may happen to return the same answer on your compiler and machine doesn't mean anything.
它是相等的,因为这是 C。正如另一个答案所说,这个操作的结果是未定义的,因为你违反了 C 规则——这意味着你不能保证在切换编译器时得到相同的答案(尽管所有编译器可能实现相似,这并不构成保证)。 C 允许你搬起石头砸自己的脚,但这并不意味着这样做是好的做法。
现在,为什么它有效?
猜想#1:
i
可能存储在寄存器中,例如r1
,并且编译器可以使用自动增量寻址模式将整个比较编译成单个 CMP 指令。假设它是CMP ++r1, r1
或CMP r1, ++r1
,那么根据实际的 CPU,两者都可能返回 true 比较。猜想#2:
编译器可能会将比较编译为:
猜想#3:
编译器可能正在优化以始终将简单的变量访问放在右侧。允许这样做是因为
==
运算符中的执行顺序未定义,并且编译器可以根据需要重新排列内容。It is equal because this is C. As the other answer says, the result of this operation is undefined because you violate C rules -- which means that you cannot guarantee the same answer when switching compilers (although all compilers may be implemented similar, which doesn't make it a guarantee). The fact that C allows you to shoot yourself in the foot does not mean that it is good practice to do so.
Now, why does it work?
Conjecture #1:
i
may be stored in a register, sayr1
, and the compiler may be compiling this entire comparison into one single CMP instruction, with an autoincrement addressing mode. Say it isCMP ++r1, r1
orCMP r1, ++r1
, then depending on the actual CPU, both may return a true compare.Conjecture #2:
The compiler may be compiling the compare into:
Conjecture #3:
The compiler may be optimizing to always put a simple variable access to the right hand side. It is allowed to do that because the order of execution in a
==
operator is undefined and the compiler can rearrange things as it likes.