false
?
main()
{
int i=1;
if(i<=i++)
printf("false");
else
printf("true");
}
答案 0 :(得分:12)
这不是假的,你只需打印false
就可以了。
答案 1 :(得分:2)
比较运算符<=
未指定首先评估哪一方,i
或i++
,并且左侧末尾没有序列点操作数到比较函数(见http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Sequence-Points)。
如果首先评估左侧,则得到:
if (1 <= 1)
如果首先评估右侧,则得到:
if (2 <= 1)
这凸显了这个问题,但情况甚至更糟。
您编写了具有未定义行为的代码,这意味着“未定义”。在这种情况下,编译器可以执行 anything ,并且仍然符合标准。
例如,这些编译器(-O3
)遵循else分支:
虽然这些编译器(-O3
)遵循true
分支:
g++-4.7 (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04) 4.7.3
其他编译器可以做一些完全不同的事情。
答案 2 :(得分:1)
这是一个组合unspecified behavior,简单明了undefined behavior。因此,您无法预测此代码的结果,并且无法依赖结果。它没有说明,因为在这一行:
if(i<=i++)
我们不知道是先评估i
还是i++
。 draft C99 standard部分6.5
第3段表示:
运算符和操作数的分组由语法表示.74)除了稍后指定的(对于函数调用(),&amp;&amp;,||,?:和逗号运算符),子表达式的评估顺序和副作用发生的顺序都是未指定的。
上面提到的行也是未定义的行为,因为在sequence points之间我们只允许修改一次变量,如果我们修改它,我们只允许读取前一个值来确定要设置的新值。在这种情况下,我们正在阅读先前值,以确定i
和i++
。从草案标准部分6.5
第2段:
在上一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。此外,先前的值应该是只读的,以确定要存储的值。
答案 3 :(得分:-3)
要了解你的代码在做什么,我将重写,只会非常明确:
main()
{
int i=1;
if(i<=i) {
i++;
printf("false");
} else {
i++:
printf("true");
}
}
i++
表示在比较后增加i 。在if i的两个分支中都是递增的,所以它是等价的。