我在Windows 7上的Code :: Blocks 10.05中执行了以下代码。
int a=0,b=0,c;
c=a++&&b++;
printf("\na=%d\nb=%d\nc=%d\n\n",a,b,c);
我获得的输出如下,
a=1
b=0
c=0
由于短路评估,这非常有意义。
表达式a++
是后增量,0
返回逻辑和(&&
)。因此,b++
和0 && 0
都不评估部分0 && 1
0
评估为++
。
但这引起了我的怀疑。运算符的优先级值清楚地表明&&
优先于a++
。所以我的理解是这样的,&&
和b ++都被评估,然后a++
只检查表达式a++
的结果来做出决定。但这并没有发生,只有&&
在这里被评估。
这种行为的原因是什么?作为序列点的&&
是否与此行为有关?如果是这样,为什么我们说++
的优先级低于TARGET API
?
答案 0 :(得分:34)
您对优先级和评估顺序感到困惑。
优先顺序定义了运算符的分组方式,即
c = a++ && b++;
相当于:
c = ((a++) && (b++));
评估顺序定义了如何评估表达式,&&
的短路意味着a++
首先被评估,如果它是零,则结束;如果它不为零,则评估b++
。
另一个例子:
c = (a++) + (b++);
在a++
之前评估b++
?答案是我们不知道。大多数运营商没有定义评估顺序。 &&
是为数不多的定义运营商之一。 (其余为||
,,
和?:
)
答案 1 :(得分:4)
这里有两个概念 - 优先顺序和评估顺序。只有在评估表达式(或子表达式)时,优先顺序才会产生影响。
通常,评估顺序未按顺序排列。给定运算符,可以按任何顺序评估其操作数。可以按任何顺序评估函数的参数。
来自C ++标准:
1.9程序执行
15除非另有说明,否则对单个算子的操作数和个别表达式的子表达式的评估是不合理的。
和
8.3.6默认参数
每次调用函数时都会计算默认参数。函数参数的评估顺序未指定。
对于逻辑AND运算符&&
,C ++ 11标准说:
5.14逻辑AND运算符
1
&&
运算符组从左到右。操作数都在上下文中转换为类型bool
(第4条)。如果两个操作数分别为true
和true
,则结果为false
。与&
不同,&&
保证从左到右评估:如果第一个操作数为false
,则不评估第二个操作数。
为逻辑OR运算符||
指定了类似的异常。
由于b++
操作符导致表达式短路,因此&&
未被评估,因此在这种特殊情况下,运算符的优先顺序没有意义。