如果是,那么以下程序的输出是什么。
#include<stdio.h>
int main()
{
int i=-3, j=2, k=0, m;
m = ++i || ++j && ++k;
printf("%d, %d, %d, %d\n", i, j, k, m);
return 0;
}
在gcc下输出是** -2 2 0 1 **但是怎么样?
答案 0 :(得分:3)
++i
的值为-2
,它不为零,因此在布尔上下文中为“true”,短的cirtuited条件在那里j
和{{1}停止保留原始值。布尔值“true”转换为值k
的整数,该值被赋值给1
。
答案 1 :(得分:2)
优先级确定操作数和运算符的分组;它不确定评估顺序。 ||
和&&
强制从左到右评估;首先评估++i
。如果结果不为0(例如在这种情况下),则根本不评估++j && ++k
。
答案 2 :(得分:1)
这是因为逻辑运算符进行短路评估。
一旦知道结果,就不再进行评估。
在您的情况下,当++i
评估为true
并且后面跟着一个或者时,甚至不再评估子表达式。
“优先级”会发生什么:计算||
(最低“优先级”)的结果,编译器需要先计算左边的结果。在你的情况下,产生true
所以不再需要计算,因为整个表达式的结果是已知的。
如果需要评估右侧,++
将在||
之前进行评估。
答案 3 :(得分:0)
其他人已经解释过为什么“||”之后的部分没有评估。但是,我想强调标准的一个非常重要的部分,导致这种行为。 '||'逻辑运算符充当序列点,无论同一表达式中的其他运算符如何,都需要从左到右的求值顺序。
引自标准ISO/IEC 9899(6.5.13 / 14,第88页)
与按位|不同运算符,||运营商保证 从左到右的评价;之后有一个序列点 评估第一个操作数。如果第一个操作数比较不相等 为0,不评估第二个操作数。
换句话说,表达“a + b * c”与“a || b&amp; c”不同,前者被视为一个没有序列点的表达式,而后者是带有序列点的表达式。顾名思义,序列点强制评估序列。一旦评估完全表达的结果(例如,当||的LHS评估为'1'时),可以停止进一步的表达评估。因此,您看到的顺序。