【问题标题】:Postfix and prefix increment that causes an error导致错误的后缀和前缀增量
【发布时间】:2017-12-12 03:19:30
【问题描述】:

为什么该代码由于错误而无法编译:

#include <iostream>

using namespace std;

int main()
{
    int i = 0; 
    cout << ++(i++) << " " << i << endl;
    return 0;
}

虽然该代码确实可以编译:

#include <iostream>

using namespace std;

int main()
{
    int i = 0; 
    cout << (++i)++ << " " << i << endl;
    return 0;
}

我不明白。从我的角度来看,编译第一个块是非常合理的。表达式 ++(i++) 只是表示取 i,递增并输出,然后再次递增。

我不是在询问 int 溢出中的未定义行为。在撰写问题时,我根本不知道 r 和 l 值,我也不关心为什么 ++i 被认为是 l 值,但 i++ 不是。

【问题讨论】:

  • @user0042,我查了答案,但并没有让我失望。我没有询问整数溢出,我的代码中没有未定义的行为,只有一个错误。
  • @EugeneSh.,你读过我的问题吗?它与您提出的复制品完全不同。
  • @Yaroslav 这是确切的问题。 Post 和 pre-increment 运算符需要 lvalue 作为操作数。在您的问题中,第一个不是lvalue,但第二个是。
  • @EugeneSh.,好的。现在你给我一个答案。但是,当我问这个问题时,我应该怎么知道答案呢?事实证明,您提出的与我重复的问题的答案有助于回答我的问题。

标签: c++ increment postfix-notation prefix-notation


【解决方案1】:

这是因为后自增和前自增运算符返回不同类型的值。后增量的结果是一个所谓的“右值”,意味着它不能被修改。但是预增量需要一个可修改的值来增加它!

另一方面,前置增量的结果是一个左值,这意味着它可以被后置增量安全地修改。

上述规则的原因是后增量需要返回对象的值,就像应用增量之前一样。顺便说一句,这就是为什么在一般情况下,在用于非内置对象时,后增量被认为比前增量更昂贵。

【讨论】:

  • 好的。它澄清了一切。非常感谢您的关注。
【解决方案2】:

简而言之,区别在于,在 C++ 中,您可以使用任意偶数个加号(仅受编译器限制)作为前缀递增运算符,如下所示

++++++++++++++++i;

后自增运算符只有两个优点

i++;

后缀递增运算符返回一个值(C++ 标准,5.2.6 递增和递减)

1 后缀++表达式的值是它的值 操作数。 [注:得到的值是原值的副本 ——尾注]

而前缀自增运算符在自增后返回其操作数(C++标准,5.3.2自增和自减)

1 ...结果是更新后的操作数;它是一个左值...

与 C 中的 C++ 不同,您也可以使用前缀自增运算符仅对对象应用两个加号。:) 因此,C 编译器会为这样的表达式发出错误

++++++++++++++++i;

【讨论】:

    【解决方案3】:

    当您使用 clang 编译它时,您会收到说明一切的错误消息。

    <source>:8:13: error: expression is not assignable
    cout << ++(i++) << " " << i << endl;
    

    也许从 ++ 运算符开始是好的。实际上它是i = i + 1 的简写。现在,如果我们查看后缀版本 i++,它在标准中表示它返回原始值的副本,并且 side efect 它增加原始值。 所以从 (i++) 你得到右值并试图分配给它,我们知道你不能分配给右值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-08
      • 2012-10-03
      • 2014-08-11
      • 2011-03-12
      • 1970-01-01
      • 2017-08-04
      • 1970-01-01
      相关资源
      最近更新 更多