7

我无法理解这个程序的输出:

#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

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

1
1 2 2

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

4

5 回答 5

8

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

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

那么很容易看出,只有在为 0 时才会(++y && ++z )被评估。所以你可以看到,无论运算符优先级如何,短路性质意味着只有在左侧为 0 时才评估右侧。++x||

(如果右手边被求值,那么请注意,只有在不为 0++z时才会被求值。)++y

于 2016-08-24T14:31:11.347 回答
8

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

否。运算符优先级仅确定在解析表达式时运算符将如何更紧密地绑定到其参数(就像括号一样),它不会影响评估顺序。在这种情况下,它只是意味着++x || ++y && ++z将被解析为(++x) || (++y && ++z),而不是(++x || ++y) && (++z)

请注意, 的关联性operator||是从左到右的,因此++x首先会被评估,并且(++y && ++z)不会因为短路评估而被评估(除了重载operator||)。

于 2016-08-24T14:33:33.883 回答
5

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

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

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


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

优先级规则确定在 C++ 中选择后一种树,因为中间操作数 ,++y与 分组&&,而不是与分组||

这些运算符的“短路”意味着评估必须从最左边的叶子开始(每个运算符必须首先评估其左腿,然后如果需要,再评估其右腿)。
因此,++x首先评估,如果为零,则||仅继续其右腿,而事实并非如此。++x

(从精彩而艺术的图表中可以看出,无论和的相对优先级如何,都++x必须先评估。)&&||

于 2016-08-24T15:23:26.407 回答
1

这个表达

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

相当于表达式

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

而不是这样

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

如果逻辑 OR 表达式的第一个操作数被评估为真(如您的示例中所示),则第二个操作数( ++y && ++z )不被评估。

于 2016-08-24T14:32:51.717 回答
0

( ++x || (++y && ++z )) - 可以看作是布尔值 - 只有 ++x 被评估。它的 int 值为 2,布尔值为 1(真)。

于 2016-08-24T15:06:42.997 回答