2016-09-14 116 views
3

好吧,所以我一直在學習左值和右值 - 有人可以精通C/C++告訴我,如果我的思想是正確的?C++左值和右值

考慮代碼:

int i = 3; 
int j = i; 

在這裏,我們有兩個左值ij,當i被分配到j因爲i一個副本存儲在j它成爲一個隱含的右值。然而,如果代碼看起來像:

int i = 3; 
int j = &i; 

既能j&i是左值,因爲它們在內存物理地址?我理解的方式是右值是臨時數據,而左值具有物理/可參考內存地址。

對此的任何澄清將是偉大的!

+3

我推薦[Strachey(1967)](http://www.itu.dk/courses/BPRD/E2009/fundamental-1967.pdf),第2部分。 – molbdnilo

+0

謝謝@molbdnilo - 我會檢查該參考現在 – Alex

回答

1

在這裏,我們有兩個左值ij

沒錯

i分配給j它成爲一個隱含的右值,因爲i一個副本存儲在j

不是,i仍然是一個左值,但它被轉換爲右值以讀取其值。這被稱爲左值到右值的轉換。 j仍然是一個左翼。

j&i是否都是左值,因爲它們都是內存中的物理地址?

j是一個左值,但是&i是一個右值;特別是類型int*的價值。

+0

有趣 - 感謝對'&i'變成'int *'這一事實的解釋。 – Alex

4

變量i永不停止作爲左值。如果你可以將address-of運算符應用於某些事物(就像你在第二個例子中那樣),那麼它就是一個左值。

此外,在第二示例&i指針i,並具有類型int*。在j的聲明和要用其初始化的值之間存在類型不匹配。

最後,雖然i本身是一個左值表達式&i左值,因爲你不能應用地址的運營商給它(即你不能做&&i)。

+0

,這是非常有意義的 - 謝謝:) – Alex

3

作爲左值右值是表達式的屬性。通常,構成一個非const限定的標識符的所有表達式是修改左值

int i = 5; 
i; // the expression "i" is an lvalue and is modifiable 

const int j = 3; 
j; // the expression "j" is still an lvalue, but not modifiable 

左值表達式(除非合格與const)可通過任何分配時,或++運營--進行改性。您也可以在這樣的表達式上應用&「address-of」運算符。

一些運算符,如一元運算符*,數組下標運算符[].->運算符也產生左值。這意味着您可以說,例如,*p = 3a[i] = 5b.c++&c->d

另一方面,不是左值的表達式是右值(它們是臨時值,不能被修改)。如果您編寫類似3 = 57++的東西,編譯器會抱怨37子表達式不是左值。

+0

「他們是暫時的,不能修改」,這不一定是真實的。像'std :: string {} =「hi」'是完全有效的。 – TartanLlama