运算符优先级和评估顺序

shi*_*iva 6 c++ operators operator-precedence output

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

1
2 1 1
Run Code Online (Sandbox Code Playgroud)

如果||被评为第一,然后这个输出是好的,但是这个文章说,&&比一个更高的优先级||,因此必须首先评估.如果是这种情况那么根据我的输出应该是:

1
1 2 2
Run Code Online (Sandbox Code Playgroud)

++y && ++z将评估为true,因此++x将不进行评估.

son*_*yao 7

&&优先级高于||,因此必须首先进行评估.

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

请注意,关联性operator||是从左到右,因此++x将首先进行评估,并且(++y && ++z)由于短路评估(除了过载operator||)而不会进行评估.


mol*_*ilo 7

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

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

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


   or
   /\
++x  and       [++x || (++y && ++z)]
     / \
  ++y ++z
Run Code Online (Sandbox Code Playgroud)

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

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

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


Fit*_*rcy 5

让我们把多余的parantheses放在:

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

然后很容易看出,只有在0 (++y && ++z )才会被评估.++x所以你可以看到,无论运算符优先级如何,短的循环性质||意味着只有左侧是0才能评估右侧.

(如果右手侧evaluted,然后记下++z被评估,如果++y不为0)

  • 这并没有真正解决这个问题 - 评估顺序不是由优先级决定的**. (2认同)