如果是这样,以下程序的输出将是什么。
#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 ** 但是如何?
如果是这样,以下程序的输出将是什么。
#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 ** 但是如何?
++i
具有 value -2
,它不为零,因此在布尔上下文中为“真”,短路条件停在那里j
并k
保留其原始值。布尔值“true”转换为 value 的整数,1
赋值给m
。
优先级决定了操作数和运算符的分组;它不决定评估的顺序。||
和&&
强制从左到右的评估;++i
首先被评估。如果结果不为 0(例如在本例中),则++j && ++k
根本不计算。
那是因为逻辑运算符会进行短路评估。
一旦知道结果,就不再进行评估。
在您的情况下, as++i
评估为true
并且后跟一个 or,甚至不再评估子表达式。
“优先级”发生的情况是:要计算||
(最低“优先级”)的结果,编译器需要首先计算左边的结果。在您的情况下,true
由于整个表达式的结果是已知的,因此不需要更多的计算。
如果需要评估右侧,++
则将在||
.
其他人已经解释了为什么'||'之后的部分 不评估。但是,我想强调导致这种行为的标准的一个非常重要的部分。'||' 逻辑运算符充当序列点,无论同一表达式中的其他运算符如何,都需要从左到右的评估顺序。
引用标准ISO/IEC 9899 (6.5.13/14, pg 88)
不像按位 | 运算符,|| 运算符保证从左到右的评估;在计算第一个操作数之后有一个序列点。如果第一个操作数比较不等于 0,则不计算第二个操作数。
换句话说,表达式“a + b * c”与“a || b && c”不同,前者被视为一个没有序列点的表达式,而后者是一个有序列点的表达式。顾名思义,序列点强制评估序列。一旦对完整表达式的结果求值(例如,当|| 的LHS 求值为'1'),就可以停止对表达式的进一步求值。因此,您看到的顺序。