运算符优先级和求值顺序[重复]

问题描述 投票:0回答:5

我无法理解该程序的输出:

#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;
}

输出:

1
2 1 1

如果首先评估

||
,则此输出没问题,但是 this 文章说
&&
的优先级高于
||
,因此必须首先评估它。如果是这种情况,那么根据我的输出应该是:

1
1 2 2

因为

++y && ++z
会评估为
true
,因此
++x
不会被评估。

c++ operators operator-precedence logical-or logical-and
5个回答
9
投票

让我们把多余的括号放入:

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

然后很容易看出,如果

(++y && ++z )
为 0,则++x
被评估。因此,您可以看到,无论运算符优先级如何,
||
的短路性质意味着右侧仅是评估左侧是否为 0。

(如果评估右侧,请注意,如果

++z
不为 0,则++y
被评估。)


9
投票

&&
的优先级高于
||
,因此必须首先对其进行评估。

不。 运算符优先级仅决定在解析表达式时运算符如何更紧密地(就像通过括号)与其参数绑定,它不影响计算顺序。在这种情况下,它只是意味着

++x || ++y && ++z
将被解析为
(++x) || (++y && ++z)
,而不是
(++x || ++y) && (++z)

请注意,

operator||
的结合性是从左到右的,因此
++x
将首先被评估,而
(++y && ++z)
由于短路评估而不会被评估(除了重载的
operator||
) ).


7
投票

“优先级”影响分组,而不是顺序,并且意味着如果操作数“属于”哪个运算符可能存在任何歧义,则具有较高优先级的运算符将首先获得它。

由于涉及两个二元运算符,因此有两种方法可以读取表达式。
作为树,这些将是:

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


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

优先级规则决定在 C++ 中选择后一棵树,因为中间操作数

++y
&&
分组,而不是与
||
分组。

这些运算符的“短路”意味着评估必须从最左边的叶子开始(每个运算符必须首先评估其左腿,如果需要,然后评估右腿)。
因此,首先评估

++x
,如果
||
为零(事实并非如此),则
++x
仅继续其右腿。

(从精彩又艺术的图可以看出,无论

++x
&&
的相对优先级如何,都必须首先评估
||
。)


1
投票

这个表情

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

相当于表达式

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

而不是这样

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

如果逻辑 OR 表达式的第一个操作数被评估为 true(如您的示例中所示),则不会评估第二个操作数

( ++y && ++z )


0
投票

( ++x || (++y && ++z )) - 可以视为布尔值 - 仅评估 ++x。它的int值为2,布尔值为1(true)。

© www.soinside.com 2019 - 2024. All rights reserved.