0

如果是这样,以下程序的输出将是什么。

#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 ** 但是如何?

4

4 回答 4

3

++i具有 value -2,它不为零,因此在布尔上下文中为“真”,短路条件停在那里jk保留其原始值。布尔值“true”转换为 value 的整数,1赋值给m

于 2013-01-18T16:50:09.540 回答
2

优先级决定了操作数和运算符的分组;它决定评估的顺序。||&&强制从左到右的评估;++i首先被评估。如果结果不为 0(例如在本例中),则++j && ++k根本不计算。

于 2013-01-18T17:03:57.220 回答
1

那是因为逻辑运算符会进行短路评估。

一旦知道结果,就不再进行评估。

在您的情况下, as++i评估为true并且后跟一个 or,甚至不再评估子表达式。

“优先级”发生的情况是:要计算||(最低“优先级”)的结果,编译器需要首先计算左边的结果。在您的情况下,true由于整个表达式的结果是已知的,因此不需要更多的计算。

如果需要评估右侧,++则将在||.

于 2013-01-18T16:51:35.280 回答
0

其他人已经解释了为什么'||'之后的部分 不评估。但是,我想强调导致这种行为的标准的一个非常重要的部分。'||' 逻辑运算符充当序列点,无论同一表达式中的其他运算符如何,都需要从左到右的评估顺序。

引用标准ISO/IEC 9899 (6.5.13/14, pg 88)

不像按位 | 运算符,|| 运算符保证从左到右的评估;在计算第一个操作数之后有一个序列点。如果第一个操作数比较不等于 0,则不计算第二个操作数。

换句话说,表达式“a + b * c”与“a || b && c”不同,前者被视为一个没有序列点的表达式,而后者是一个有序列点的表达式。顾名思义,序列点强制评估序列。一旦对完整表达式的结果求值(例如,当|| 的LHS 求值为'1'),就可以停止对表达式的进一步求值。因此,您看到的顺序。

于 2014-11-26T04:43:35.163 回答