C++ 为什么if(x=+;+;x=+;+;y)起作用,而if(x+;+;&+;y)不起作用?

C++ 为什么if(x=+;+;x=+;+;y)起作用,而if(x+;+;&+;y)不起作用?,c++,operators,C++,Operators,当我执行此程序时: #include<iostream> using namespace std; int main(){ int x=5,y=9; if(++x=y++){ cout<<"Works "<<x; } else{ cout<<"No"; } return 0; } #包括 使用名称空间std; int main(){ int x=5,y=9; 如果(

当我执行此程序时:

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

    if(++x=y++){
        cout<<"Works "<<x;
    }
    else{
        cout<<"No";
    }
    return 0;
}
#包括
使用名称空间std;
int main(){
int x=5,y=9;
如果(++x=y++){

不能,因为
x++
不是左值

更具体地说,
x++
递增
x
,然后返回一个初始值为
x
的临时对象。临时对象不能(撇开可疑合法性不谈)在赋值的左侧使用,因此它不是左值

++x
递增
x
并返回对
x
的引用(及其新值)。然后,如果选择,可以直接分配给它,因此它是左值


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

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


第二种情况是有意义的;x正在被返回,您可以做任何事情。第一种情况毫无意义;x++不是一个值。事实上,一旦您返回该值,x就不再是该值。

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

该值是一个非常临时的值,与所有其他临时值一样,它不是“左值”,也就是说,它不是可以赋值的对象

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

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


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

根据运算符优先级添加一些括号,以了解发生了什么:

(++x) = (y++)
这将递增x,递增y,并将y-1(递增之前的y值)赋给x(y++计算为y,因为这里是后递增)

这里的语句无效,因为x++没有左值


参见:

< P>正如大家所解释的,x++< /Cord>的值是一个临时的包含“代码> x/CODE”的旧值,并且临时赋值不能被分配给它。编译器因此拒绝代码,而不符合C++的语法。 您遇到的问题是第一个示例也是错误的。虽然
++x
在语法上是一个左值,但如果您将它放在赋值运算符的左侧,您将同时递增
x
并赋值给
x
,并且不清楚您的意思是什么。C++89和C都有序列点的概念s、 如果在没有插入序列点的情况下修改同一变量两次,则程序的行为不会被定义(任何情况都可能发生,包括用
return
或segfault替换整个函数)


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

@BoBTFish因此,
++x
是左值吗?奇怪的是,用于比较的运算符是
=
而不是
=
。因此很难理解您试图实现的目标。That说,这是一个有趣的问题,
++x
是一个左值,但是如果你给它赋值,你会调用未定义的行为(在C和C++89语言中,两个修改没有插入序列点),因为(x++和++y)不属于同一类型,您需要==进行比较。您应该删除
if
s,因为它们会让每个人都感到困惑。我是否遗漏了什么?第一个示例怎么不是UB?@MartinBonner如果是例如
++x=x++
则是UB。但现在OP使用了两个不同的变量,所以没问题。为什么?T这是x的增量,这是x的赋值。这是两个修改,没有中间的序列点(或者C++11以后的等价术语)@MartinBonner这里是一个关于正常的问题。递增运算符的优先级比赋值高很多,因此将首先执行。前缀递增运算符返回对递增的
x
的引用,此引用通常可以用作赋值的左侧。不,这绝对是错误的。o运算符优先级定义正在操作的对象(例如
a/b+c
意味着
/
的操作数是
a
b
,而不是
b+c
),而不是副作用的顺序。我必须在回答中查找措辞并引用相关部分。
(++x) = (y++)
(x++)=(y++)