【问题标题】:C++ "operator+=" and "operator++" priority questionC++ "operator+=" 和 "operator++" 优先问题
【发布时间】:2020-04-13 16:23:10
【问题描述】:
int a = 1;
a += ++a;
cout << a << endl; // 4
int a = 1;
a += a++;
cout << a << endl; // 3

为什么这两个例子有不同的行为?

【问题讨论】:

  • ++a 表示变量将在所有其他事物之前增加一。但是a++ 意味着当一切都完成后,你的变量会增加。在这种情况下,第一步将是a+a,这两个值都是1,等于2。然后a 将增加到3
  • 请注意,您的示例仅具有自 C++17(及更高版本)以来定义明确的行为。 C++17 之前的第二个示例具有未定义的行为,C++11 之前的第一个示例也是如此,请参阅Undefined behavior and sequence points

标签: c++


【解决方案1】:

a++++a 做不同的事情。

a++a 增加 1 并返回之前的值。

++aa 增加 1 并返回新值。

【讨论】:

    【解决方案2】:

    a++ 返回a 的值增量之前。 ++a 在增量之后返回a 的值。 这就是它们不同的原因。

    【讨论】:

      【解决方案3】:

      这里的区别不是三个运算符的优先级。它遵循this chart,其中a++ > ++a > a+=

      而是两个增量运算符的工作方式。当您使用++a时,您首先递增然后返回该值(新值)。而使用a++ 将首先使用旧值然后递增。 Also see here for related.

      【讨论】:

        【解决方案4】:
        a += ++a;
        

        替换为如下编译器:

        a = a + 1;// a = 1 + 1
        a = a + a;// a = 2 + 2 
        

        第二个例子

        a += a++;
        

        解决如下:

        a = a + a;// a = 1 + 1
        a = a + 1;// a = 2 + 1
        

        以下是操作规则: https://en.cppreference.com/w/cpp/atomic/atomic/operator_arith2 https://en.cppreference.com/w/cpp/language/operator_precedence

        【讨论】:

        • 错误的解释和错误的链接,但如果你跟着它,它在Notes下就有正确的链接
        • 虽然这在理论上可以回答问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。
        • 改进了答案
        • 还是错了。您需要阅读的链接是en.cppreference.com/w/cpp/language/eval_order
        • 我认为这个问题是以描述性的方式回答的。提到的链接是导致正确行为的参考。链接或答案有什么问题?所以,我可以改进。我写答案背后的想法是不要用勺子喂每一件事。人们应该了解解决问题的实际方法,然后代码会自动改进。你说什么?
        【解决方案5】:

        与:

        a += a++;
        

        将 a 的前一个值相加,然后将 a 加 1

        与:

        a += ++a;
        

        你把已经加 1 的值加起来

        【讨论】:

          【解决方案6】:

          警告:您正在查看的作业有未定义的行为。见Why are these constructs using pre and post-increment undefined behavior? 问题Undefined behavior and sequence points 中的this answer 也解决了C++17 如何解决这些问题。

          您的编译器可能会以下列方式处理操作,解释不同之处:

          预增操作: 以下几行:

          a=2;
          a+=++a;
          

          也是等价的:

          a=2;
          tmp=++a;    
          a+=tmp;
          

          读作:

          1. 2赋值给变量a
          2. 预增量a (++a) 赋予a3 并将其分配给tmp(使其变为3
          3. a(当前为3)的值增加tmp(当前为3)的值给我们6

          后自增操作: 以下几行:

          a=2;
          a+=a++;
          

          也是等价的:

          a=2;
          tmp=a++;    
          a+=tmp;
          

          读作:

          1. 2赋值给变量a
          2. 后递增aa++)首先返回a的原始值(即2)并将其分配给tmp(使其变为2),然后将a递增为3 的值
          3. a(当前为3)的值增加tmp(当前为2)的值给我们5

          【讨论】:

          • 欢迎来自任何 C++ 大师的任何 cmets。我是来学习的
          • 查看@walnut 对原始问题的评论:在 17 和 11 之前,这些是未定义的表达式,实际上没有任何意义。在那之后,你的“等效”位有点好,但谈论排序会更正确,例如,+= 现在必须等待而不是从左边的 a 读取,直到 ++ 完成写入右边的 a .
          猜你喜欢
          • 2020-01-12
          • 2021-06-08
          • 2012-01-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多