【问题标题】:Operator precedence and evaluation order运算符优先级和评估顺序
【发布时间】:2016-12-31 18:07:36
【问题描述】:

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

#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 文章说&amp;&amp; 的优先级高于||,因此必须先评估它。如果是这种情况,那么根据我的输出应该是:

1
1 2 2

因为++y &amp;&amp; ++z 将评估为true,因此不会评估++x

【问题讨论】:

标签: c++ operators operator-precedence logical-or logical-and


【解决方案1】:

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

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

那么很容易看出(++y &amp;&amp; ++z )++x 为0 时才被评估。所以你可以看到,不管运算符优先级如何,|| 的短路性质意味着仅当左侧为 0 时才计算右侧。

(如果右侧已评估,则请注意,++z++y 不为 0 时评估。)

【讨论】:

  • 这并没有真正解决问题 - 评估顺序由优先级决定。
  • @OliverCharlesworth:是的,我认为你是对的。我已经修改了这个答案。
【解决方案2】:

这个表达式

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

等价于表达式

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

不是这样的

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

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

【讨论】:

    【解决方案3】:

    &amp;&amp; 的优先级高于||,因此必须先评估。

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

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

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

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

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

        (从精彩绝伦的图表中可以看出,++x无论&amp;&amp;||的相对优先级如何,都必须先求值。)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-04-14
          • 1970-01-01
          • 2011-07-24
          • 2018-03-28
          • 2011-05-11
          • 1970-01-01
          • 2019-06-05
          • 1970-01-01
          相关资源
          最近更新 更多