【问题标题】:why does if(++x=++y) works and if(x++=++y) does not work?为什么 if(++x=++y) 有效而 if(x++=++y) 无效?
【发布时间】:2017-01-12 07:49:42
【问题描述】:

当我执行这个程序时:

#include<iostream>
using namespace std;
int main(){
    int x=5,y=9;

    if(++x=y++){
        cout<<"Works "<<x;
    }
    else{
        cout<<"No";
    }
    return 0;
}

它工作正常,输出是:Works 9

但如果我执行:

  #include<iostream>
using namespace std;
int main(){
    int x=5,y=9;

    if(x++=y++){
        cout<<"Works "<<x;
    }
    else{
        cout<<"No";
    }
    return 0;
}

它指出: 在函数'int main()'中: 6:11:错误:需要左值作为赋值的左操作数 如果(x++=y++){

【问题讨论】:

  • @BoBTFish 那么++x 是左值吗?奇怪
  • 比较运算符是==,而不是=。所以很难理解你想要完成什么。也就是说,这是一个有趣的问题
  • ++x 是一个左值,但如果你分配给它,你会调用未定义的行为(在 C 和 C++89 语言中没有插入序列点的两个修改。)
  • 因为(x++ 和++y) 不是同一类型,需要== 进行比较。
  • 你应该删除ifs,因为它们让每个人都感到困惑。

标签: c++ operators


【解决方案1】:

因为x++ 不是左值。

更具体地说,x++ 递增 x,然后返回一个 临时,其原始值为 x。不能在赋值的左侧使用临时对象(不考虑合法性的转换),因此它不是左值。

++x 递增x 并返回对x 的引用(及其新值)。如果你愿意,你可以直接分配给它,所以它是一个左值。

但是,您实际上可能是要比较两个表达式的相等性,而不是进行赋值。在这种情况下,您需要使用== 而不是=

【讨论】:

    【解决方案2】:

    您必须记住,后缀增量运算符在增量之前返回值。

    此值是一个非常临时的值,与所有其他临时值一样,它不是“左值”,即它不是可以分配的东西。

    前缀自增运算符执行自增操作,然后返回对新值的引用。对于++x,它返回对x 的引用。它一个“左值”。

    当然,减量 (--) 运算符也是如此。

    互联网上有许多资源可以帮助您了解“左值”和“右值”(临时值)之间的区别。

    【讨论】:

    • 我错过了什么吗?第一个例子怎么不是UB?
    • @MartinBonner 如果它是例如++x=x++ 那么是的,它将是 UB。但是现在 OP 使用了两个不同的变量,所以没关系。
    • ??为什么?有 x 的增量,有 x 的赋值。这是两个修改,没有中间序列点(或 C++11 以后的任何等效术语)。
    • @MartinBonner 这是一个关于普通operator precedence 的问题。增量运算符的优先级比赋值高得多,因此将首先完成。前缀自增运算符返回一个对自增后的x的引用,这个引用通常可以作为赋值的左边。
    • 不,这绝对错了。运算符优先级定义了正在操作的内容(例如,a / b + c 表示/ 的操作数是ab,而不是b+c),而不是副作用的顺序。我将不得不在我的回答中查找措辞并引用相关部分。
    【解决方案3】:

    x++ 返回 x,然后递增 x。另一方面,++x 增加 x,然后返回它。

    第二种情况是有道理的; x 被返回,你可以做任何事情。第一种情况根本没有意义; x++ 不是一个值。事实上,一旦你取回这个值,x 就不再是那个值了。

    【讨论】:

      【解决方案4】:

      正如其他人所解释的那样,x++ 的值是包含 x 旧值的临时值,不能分配临时值。编译器因此拒绝代码,因为它不符合 C++ 的语法。

      您遇到的问题是 first 示例也是错误的。虽然++x 在语法上是一个左值,但如果你把它放在赋值运算符的左边,你会同时增加x 分配给x,不清楚你是什么意味着发生。 C++89 和 C 有序列点的概念,如果你修改同一个变量两次而没有插入序列点 - 程序的行为没有定义(任何事情都可能发生 - 包括替换return 或段错误的整个函数)。

      C++11 引入了一个我不熟悉的不同术语,但在这种情况下的效果是相同的 - 您的第一个示例是未定义的行为。

      【讨论】:

        【解决方案5】:

        根据运算符优先级添加一些括号,看看是怎么回事:

        (++x) = (y++)
        

        这会增加 x,增加 y 并将 y-1(在增加之前 y 的前一个值)分配给 x(y++ 计算为 y,因为它在这里是一个后自增)

        (x++)=(y++)
        

        这不是一个有效的陈述,因为 x++ 没有左值。

        另请参阅:Why is ++i considered an l-value, but i++ is not?

        【讨论】:

          猜你喜欢
          • 2012-01-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-21
          • 1970-01-01
          • 2016-05-01
          相关资源
          最近更新 更多