2017-01-12 142 views
-4

當我執行這個程序:爲什麼if(++ x = ++ y)有效,if(x ++ = ++ y)不起作用?

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

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

它正常工作,輸出是:工作9

,但如果我執行:

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

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

它指出: 在函數「廉政main()': 6:11:error:賦值爲左操作數所需的左值如果(x ++ = y ++){

+0

@BoBTFish所以'++ x'是一個左值?很奇怪 – edc65

+0

用於比較的運算符是'=='而不是'='。所以很難說清你正在努力完成什麼。也就是說,這是一個有趣的問題 – edc65

+1

'++ x'是一個左值,但如果賦值給它,則會調用未定義的行爲(兩個修改,C和C++ 89語言中沒有插入序列點)。 –

回答

4

因爲x++不是左翼。

更具體地,增量x++x,然後返回一個臨時x原始值。一個臨時對象不能在一個任務的左側使用(拋開可疑的合法性),所以它不是左值。

++x增量x並返回對x(及其新值)的引用。你可以直接分配給它,如果你選擇,所以它是一個左值。

但是,您實際上可能意圖比較兩個表達式是否相等,而不是進行分配。在這種情況下,您需要使用==而不是=

0

x ++返回x,然後增加x。另一方面,++ x遞增x,然後返回它。

第二種情況是有意義的; x正在退回,你可以做任何事情。第一種情況根本沒有意義; x ++不是一個值。事實上,一旦你回到價值,x不再是價值。

2

您必須記住,後綴增量運算符在增量之前返回舊的值。

此值是一個非常臨時的值,並且與所有其他臨時值不同,它不是「左值」,即它不是可分配的值。

前綴增量運算符執行其增量操作,然後返回對新值的引用。對於++x,它返回對x的引用。它一個「左值」。

當然是相同的減法(--)運算符。

互聯網上有很多來源可以幫助你理解「左值」和「右值」(臨時值)之間的差異。

+0

我錯過了什麼嗎?第一個例子不是UB? –

+0

@MartinBonner如果它是例如'++ x = x ++'那麼是的,它會是UB。但是現在OP正在使用兩個不同的變量,所以沒關係。 –

+0

??爲什麼?有x的增量,並且有x的賦值。這是兩個修改,沒有中間順序點(或者C++ 11以後的等價術語)。 –

0

根據運算符優先級添加一些括號,看看是怎麼回事:

(++x) = (y++) 

這增加x的,增加Y和Y-1(增量前Y的前值)分配給X(Y ++求值到y,因爲這是後期增量)

(x++)=(y++) 

這裏是不是一個有效的聲明,因爲x ++沒有左值。

參見:Why is ++i considered an l-value, but i++ is not?

1

至於其他人已經解釋的,x++的值是包含的x舊值一個臨時的,和臨時不能分配給。因此編譯器拒絕將代碼與C++的語法不一致。

您遇到的問題是第一個的例子也是錯的。儘管++x在語法上是一個左值,但如果將它放在賦值運算符的左側,那麼您將增加x分配給x,但目前尚不清楚您要實現的目標。 C++ 89和C具有序列點的概念,如果您在沒有插入序列點的情況下修改同一個變量兩次 - 程序的行爲未定義(任何事情都可能發生 - 包括用return代替整個函數,或段錯誤)。

C++ 11引入了我不熟悉的不同術語,但在這種情況下的效果是相同的 - 第一個示例是未定義的行爲。

相關問題