int a;
int b;
1) a = 5;
2) b = a + 1;//這句話是對的
而3) a + 1 = 10;//這句話就是錯的呢?
關於左值右值的要點:
1) 變數可以作為左值也可以作為右值
有人會說,3)中的變數a不是可以作為左值嗎?為什麼是錯的。看看第二點。
2) 在進行表示式求值時,請注意每個操作符需要的運算元是左值還是右值,且操作符的操作結果是左值還是右值
什麼意思?a + 1 = 10中,等號左邊a+1是個表示式,其操作是加法,標準規定:加法操作的兩個運算元都要是右值,也就是說a其實取的是右值,而不是左值。2)句中的
a也是右值。1)句中a才是左值。那麼左值和右值到底有什麼不同呢?
3) 左值是位置(位址),右值是乙個值(位置裡面的內容)
以1)句為例,因為a在等號左邊單獨出現,沒有參與任何的操作符,所以它是個左值,因為是左值,它表示的是乙個位置,即a的位址,a=5,就是將值5放進a的位址。
再看看3),a雖然也在等號的左邊,但不能僅僅因為a出現在等號的哪一邊而確定它是左值還是右值,在3)中a參與了加號操作符,而加號操作符需要的兩個運算元都是右值,
所以a就算是出現在等號左邊,它取的也是右值,即a的內容5, 那麼a + 1 = 10是錯的就顯而易見了。再看2), a參與了加號操作,取的是右值,為5,b則是左值,是位置,
所以2)的意思是將6存入b這個位置作為內容。
4)在使用右值的地方可以使用左值,但在需要左值的地方不能使用右值
3)句除了上面說的出錯的原因外,還有這個要點的原因。怎麼理解? a+1是乙個加法操作,其結果是乙個右值。右值是不能出現在等號左邊作為左值的。所以3)句出錯的
原因其實有兩點。
那如何理解左值可以用在使用右值的地方呢?
看看例子
int c = 5;
int *p = &c;
int d;
4) d = *p + 1;
5) *p = 9;
看到4)和5)的特點嗎?*p既出現在了等號的左邊,也出現在了等號的右邊。根據規定:間接訪問操作符*的運算元是右值,而操作的結果是左值,也就是說*p這個表示式
的結果其實是左值,但它出現在了等號兩邊,而且都沒有錯。那麼如何理解4)和5)呢?
先看4), 因為*操作符的運算元是右值,所以p取的是右值,即內容,也就是c的位址,來看看*p,有人會說既然p取的是內容,也就是c的位址,那*p是不是就是取的c這個
位址裡面的內容5呢?不是的。我們可以把*p想象成,從p裡面丟擲了乙個箭頭,直指向c這個位址,注意*p的結果是個左值,左值是位置,即c的位址,但是在4)中*p的結果 參與了加法操作,所以它又神奇的變成了右值,既然是右值,那當然是c這個位址的內容5了。
那麼5)句呢?p作為*操作符的運算元,取的是右值,即c的位址,*p操作丟擲箭頭,指向c,其結果是左值,左值是位置,即c的位址,所以將9存入c這個位置。
說了這麼多,感覺有點亂啊,不知道大家看明白沒?
再來看看下面的例子:
int a = 2;
int *p = &a;
int b;
6) *p + 1 = 12; //錯的
儘管*p的結果是左值,加法運算元需要右值,但是左值可以出現在使用右值的地方,這沒有錯,但加法操作的結果是右值,而等號左邊只能是左值,所以錯了。
7) b = *(p + 1);
這句話在語法上沒錯,但執行中可能出錯。因為p參與了加法操作,所以取右值,即a 的位址,然後改位址加1(注意因為a是整型,所以此處加1其實加的是4個位元組), 也就
是指向了a後面的位址,然後進行*操作,即向a後面的那個位址丟擲箭頭,其結果是乙個左值,又因為左值可以出現在使用右值的地方,神奇變成右值,所以*(p+1)的結果
是去a後面的位址的內容,但該內容未知,因此語法是沒錯,執行時可能出錯。
8) *(p + 1) = 12;
同樣是語法沒錯,執行時可能非法,因為它修改了a後面的位址的內容,這是非法修改,可能引發打錯。
左值與右值
本文摘自 http jiang5005.spaces.live.com blog cns 619f3de8ab99988e 111.entry?action post wa wsignin1.0 8月20日 c 中的左值和右值 1.概念 變數和文字常量都有儲存區,並且有相關的型別,區別在於變數是可定...
左值與右值
左值就是那些能夠出現在賦值符號左邊的東西。右值就是那些可以出現賦值符號右邊的東西。例如 a b 25 a就是乙個左值,因為它標識了乙個可以儲存結果值的地點,b 25是個右值,因為它指定了乙個值。但是它們可以互換嗎?b 25 a 原先用作左值的a此時也可以當作右值,因為每個位置都 包含乙個值。然而,b...
左值與右值
對左值和右值的乙個最常見的誤解是 等號左邊的就是左值,等號右邊的就是右值。左值和右值都是針對表示式而言的,左值是指表示式結束後依然存在的持久物件,右值是指表示式結束時就不再存在的臨時物件。乙個區分左值與右值的便捷方法是 看能不能對表示式取位址,如果能,則為左值,否則為右值。下面給出一些例子來進行說明...