對左值與右值的一些個人思考


今天重溫C語言的指針,看的書是《C和指針》,關於左值和右值以及指針表達式的內容看得甚是迷惑與煎熬,怎么會這么難理解,指針表達式又是作為左值又一會作為右值,而且二者有着不一樣的含義,為什么當年學習C語言的時候沒有遇到這些頭疼的問題呢?這就是沒有學好C的原因吧。

功夫不負有心人,認真思考,對比總結,竟有些頭緒,記錄下來吧。以免以后又忘了沒有參考。


先談談左值與右值的定義吧。

左值就是那些能夠出現在賦值符號左邊的東西;因此,右值就是那些可以出現在賦值符號右邊的東西。

舉個例子:

a = b + 25;

a是一個左值,因為它標識了一個可以存儲結果值的地點;b + 25是一個右值,因為它指定了一個值。

它們可以互換嗎?也就是 b + 25 = a;

原先用作左值的a,此時也可以用作右值,因為每個位置包含一個值。然后 b + 25不能作為左值,因為它並未標識一個特定的位置。因此,這條賦值語句是錯誤的。

注意,當計算機計算b+25時,它的結果必然保存於機器的某個地方。但是,程序員並沒有辦法預測該結果會存儲於什么地方,也無法保證這個表達式的值下次還會存儲於那個地方。其結果是,這個表達式不是一個左值。基於同樣的道理,字面值(常數)也都不是左值。


看了上面的總結,是不是有這樣的感覺,變量可以作為左值,而表達式不能作為左值?

這是一種錯覺,事實情況下並非如此,下面就專門總結這種情況。

第一個例子:

int a[30]; ... a[b+10] = 0; 

[]是下表引用操作符,所以左邊實際上是一個表達式,但它卻是一個合法的左值,因為它標識了一個特定的位置,這個數組的某個特定的位置。

第二個例子:

int a, *p;
...
p = &a;
*p = 20;

第一條賦值語句自然不必多說,指向整型變量的指針變量指定了一個特定的位置存放變量a的地址,p可以作為左值;

第二個賦值語句是需要重點分析的:

理解這個表達式作為左值之前,先了解一下*這個操作符。

*這是一個間接訪問的操作符。

通過一個指針訪問它所指向的地址的過程稱為間接訪問(indirection)或解引用指針(dereferencing the pointer)。

是不是有點難以理解?

下面直接給出上面的*p作為左值所表達的意義:*p作為左值代表的是指針變量p所指向的地址。

或者說,指針p的值是內存中某個特定位置的地址,*操作符使機器指向那個位置。當它作為左值使用時,這個表達式指定需要進行修改的位置。當它作為右值時,它就是提取當前存儲於這個位置的值。

還不是太明白?那。。。

舉個實際的例子:

//下面是這些變量的聲明
int a = 112, b = -1;
float c = 3.14;
int *d = &a;
float *e = &c;

d的值是a的位置(&a),假設為100;

當我們對d使用間接訪問操作符時,它表示訪問內存位置100並察看那里的值。

因此,*d的右值是112;而它的左值表示它指向的那個位置本身,因此是100本身。

我想舉了這個實際的例子,大家已經明白了,左值與右值的含義了,不過還是免不了要憤怒。。。(真jr難理解,真jr麻煩!)哎,只能用熟能生巧來安慰自己了。


對於指針表達式,我下篇博文專門介紹一些有深度的內容,可謂是撲朔迷離,但是如果想深入掌握這門語言,還是要下功夫去研究。

本文參考《C和指針》這本書,但是里面畫圖的做法,我是真的接受不了,讓我徒增迷惑。

給出我的csdn博客地址:https://blog.csdn.net/Reborn_Lee

里面有我的更多博文。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM