简体   繁体   English

运算符优先级和评估顺序

[英]Operator precedence and evaluation order

I can't understand output of this program: 我无法理解这个程序的输出:

#include<iostream>
using namespace std;
int main()
{
    int x = 1 , y = 1, z = 1;
    cout << ( ++x || ++y && ++z ) << endl; //outputs 1;
    cout << x << " " << y << " " << z ;  //x = 2 , y = 1 , z = 1;
    return 0;
}

Output: 输出:

1
2 1 1

If || 如果|| is evaluated first then this output is fine, however this article says that && has a higher precedence than || 首先计算那么这个输出是好的,但是这个文章说, &&比一个更高的优先级|| , and thus it must be evaluated first. ,因此必须首先评估。 If this is the case then according to me output should be: 如果是这种情况那么根据我的输出应该是:

1
1 2 2

as ++y && ++z would evaluate to true and thus ++x won't be evaluated. 因为++y && ++z将评估为true ,因此不会评估++x

&& has a higher precedence than || &&的优先级高于|| , and thus it must be evaluated first. ,因此必须首先评估。

No. Operator precedence only determines that how the operators will be bound tighter (as if by parentheses) to its arguments when parsing an expression, it doesn't influence evaluation order. 否。 运算符优先级仅确定运算符在解析表达式时如何更严格地(如通过括号)绑定到其参数,它不会影响评估顺序。 In this case, it just means ++x || ++y && ++z 在这种情况下,它只意味着++x || ++y && ++z ++x || ++y && ++z will be parsed as (++x) || (++y && ++z) ++x || ++y && ++z将被解析为(++x) || (++y && ++z) (++x) || (++y && ++z) , rather than (++x || ++y) && (++z) . (++x) || (++y && ++z) ,而不是(++x || ++y) && (++z)

Note that the associativity of operator|| 注意operator||的关联性operator|| is left-to-right, so ++x will be evaluated at first, and (++y && ++z) won't be evaluated because of short-circuit evaluation (other than overloaded operator|| ). 从左到右,所以首先评估++x ,并且由于短路评估(除了重载operator|| ),不会评估(++y && ++z) )。

Let's put the excess parantheses in: 让我们把多余的parantheses放在:

( ++x || (++y && ++z ))

Then it's easy to see that (++y && ++z ) will only be evaluated if ++x is 0. So you can see that irrespective of operator precedence, the short-circutting nature of || 然后很容易看出(++y && ++z ) 只有++x为0时才会被评估。所以你可以看到,无论运算符优先级如何, ||的短循环特性 means that the right hand side is only evaluated if the left hand side is 0. 表示仅在左侧为0时评估右侧。

(If the right hand side is evaluted, then note that ++z will only be evaluated if ++y is not 0.) (如果评估了右侧,请注意, 只有++y不为0时才会评估++z

"Precedence" affects grouping, not order, and means that if there could be any ambiguity regarding which operator an operand "belongs to", the operator with the higher precedence gets first dibs on it. “优先级”影响分组,而不是顺序,并且意味着如果操作数“属于”哪个运算符可能存在任何歧义,则具有较高优先级的运算符将获得第一个dib。

Since there are two binary operators involved, there are two ways you can read the expression. 由于涉及两个二元运算符,因此有两种方法可以读取表达式。
As trees, these would be: 作为树木,这些将是:

    and
    /\
   or ++z       [(++x || ++y) && ++z]
  / \
++x ++y 


   or
   /\
++x  and       [++x || (++y && ++z)]
     / \
  ++y ++z

The precedence rules determine that the latter tree is chosen in C++, since the middle operand, ++y , is grouped with && , not with || 优先规则确定后一个树是在C ++中选择的,因为中间操作数++y&&组合,而不是与|| .

The "short-circuiting" of these operators means that evaluation must start at the leftmost leaf (each operator must first evaluate its left leg, then its right if it needs to). 这些运算符的“短路”意味着评估必须从最左边的叶子开始(每个操作员必须首先评估其左腿,然后如果需要则评估其右侧)。
Thus, ++x is evaluated first, and || 因此,首先评估++x|| only continues with its right leg if ++x is zero, which it isn't. 如果++x为零,则仅继续其右腿,而不是。

(As can be seen from the wonderful and artistic diagrams, ++x must be evaluated first regardless of the relative precedence of && and || .) (从精彩和艺术图表中可以看出,无论&&||的相对优先级如何,都必须首先评估++x 。)

( ++x || (++y && ++z )) - can be seen as boolean values - only ++x is evaluated. (++ x ||(++ y && ++ z)) - 可以看作是布尔值 - 只评估++ x。 Its int value is 2 and the boolean value is 1 (true). 其int值为2,布尔值为1(true)。

This expression 这个表达

 ++x || ++y && ++z

is equivalent to expression 等同于表达

++x || ( ++y && ++z )

and not like this 而不是这样

 ( ++x || ++y ) && ++z

If the first operand of the logical OR expression is evaluated to true (as in your example) then the second operand that is ( ++y && ++z ) is not evaluated. 如果逻辑OR表达式的第一个操作数被计算为true(如在您的示例中),则不计算第二个操作数( ++y && ++z )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM