【发布时间】:2019-03-15 19:23:20
【问题描述】:
免责声明:我不会这样编码,我只是想了解 c 语言的工作原理!!!
输出为 12。
这个表达式(a-- == 10 && a-- == 9) 从左到右求值,在a-- == 10 处a 仍为10,但在a-- == 9 处a 为9。
1) 关于后增量评估的时间是否有明确的规则?从这个例子来看,它似乎在 && 之前但在 == 之后进行评估。是不是因为 && 逻辑运算符使a-- == 10 成为一个完整的表达式,所以 a 在执行后更新?
2) 同样对于 c/c++,某些运算符(例如前缀递减)从右到左发生,因此 a == --a 首先将 a 递减为 9,然后比较 9 == 9。c/c++ 设计这个是否有原因大大地?我知道对于 Java,情况正好相反(从左到右计算)。
#include <stdio.h>
int main() {
int a = 10;
if (a-- == 10 && a-- == 9)
printf("1");
a = 10;
if (a == --a)
printf("2");
return 0;
}
【问题讨论】:
-
这不是逻辑与,而是按位。逻辑与是
&& -
递增和递减的副作用在序列点完成,而不是之前。
&&和||运算符提供序列点;&和|运算符没有。 -
不!这个问题对于未定义行为的问题不是“重复的”。没有任何 UB,因为 C 标准说
logical and运算符"guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand."。因此,a-- == 10的所有副作用在a-- == 9评估之前完成。这是喷气式飞机的另一种情况。 -
@Observe:两者都不是由编译器首先编译的。在现代编译器中,表达式被解析并转换为内部表示,这可能是某种丰富的数据结构。该数据结构由编译器中的各种代码转换,包括优化,其结果通常是不可预测的。然后将结果用于生成一些内部代码,然后将其用于生成汇编代码。假设表达式的可识别部分仍然存在,它的任何部分都可以在汇编代码中首先出现。
标签: c operator-precedence post-increment side-effects sequence-points