作者VictorTom (鬼翼&娃娃魚)
看板C_and_CPP
標題Re: [問題] 若ptr為整數型態指標 ptr+1 = = ptr ++ ?
時間Sun Jun 14 23:56:54 2009
※ 引述《Dsigma (不要想啦)》之銘言:
: → Dsigma:我知道L value的意思 但還是對於實作不是清楚 @@'' 謝謝 06/14 23:27
: → Dsigma:可是 請問左邊(ptr1+1)現在就是一個記憶體位置 不是嗎? 06/14 23:30
: 推 VictorTom:它是一個address, 但不是(也沒辦法是)一個L-value:) 06/14 23:32
小弟我試著回文一下好了, 只是我也只知道個大概....
所以還是老樣子, 小弟直接貼一些例子來做說明吧....
int a = 10;
int b = 20;
a = b;
上面這樣的code, 把記憶體與值拿進來看可能像下面這樣....
變數: 實際位址: 值:
a 0x00100000 10
b 0x00100004 20
那在 a = b; 的時候, 獨眼龍也知道a是10, b是20....
可是如果compiler產生個機械碼是做到 10 = 20....
這樣顯然不符合我們程式碼的需求, 也沒有什麼意義....
所以實際上, 我們需要的機械碼是要能夠做到:
把 20 這個值, 寫到 a 實際的位址 0x00100000 裡去....
所以雖然a, b同樣是int, 但是在 = (assign) 左右的時候....
=左邊需要的是L-value, =右邊需要的是R-value....
也就是, =左邊需要一個目的地位址, 而右邊是要一個值....
(這裡的位址與值也不是pointer/變數值那種東西, fu不夠請再看下面)
如果寫到這邊您懂了, 大概就明白為什麼運算式沒有L-value....
為什麼pointer不行也應該懂了; 如果還不懂, 那再來個例子吧....
int *a = NULL;
int *b = NULL;
a = b;
指標變數: 實際位址: 值(指到位址):
a 0x00100000 0x00000000
b 0x00100004 0x00000000
....以下略....因為其實跟int的時候根本就一樣....
a+1 = b;
上面這樣的程式碼, 在int時不行, 在int*時也一樣不行....
因為 = 右邊的b, 我們知道現在它拿R-value是 0x00000000 ....
=左邊你寫成a+1, 它就只能拿R-value, 即 0x00000004 了....
因為現在 0x00000004 不過是一個中間產物, 沒有實際位址....
所以自然也沒有L-value; 跟是不是pointer沒有關係....
相對的, *(a+1) = b; 這樣的程式碼就變成合法的了....
(我知道這個例子會讀寫非法記憶體位址, 現在只討論語法^^||)
a+1會算出 0x00000004, 然後把b的值(0x00000000)寫到 0x00000004 去....
(然後就會遇到memory access violation, 好啦人家只是不想寫太多嘛Q_Q~)
至於那種什麼a++=b;還是++a=b;這種小弟覺得很噁心的寫法....
精華區裡面有一篇也有講L-value的有提到, 想搞清楚可以去爬爬:)
==
至於 a = b = c = d; 這種好像L一下又R一下的, 等其他大大補充吧....
以上, 還是那句老話, 有錯漏的還請板上先進不吝指教....<(_ _)>
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 58.41.17.189
※ 編輯: VictorTom 來自: 58.41.17.189 (06/15 00:04)
推 Dsigma:我懂你了 好樣的 好文 哈~ 謝謝你 06/15 00:41
→ Dsigma:a+1本身是一個記憶體位址 但他本身沒有辦法"取"記憶體位址 06/15 00:42
推 zlw:a=b=c=d; 也是半知半解,猜看看:=運算子是由右至左結合性的 06/15 01:27
→ zlw:二元運算子,每次把右邊的運算元取出右值給左邊的運算元。類似 06/15 01:28
→ zlw:*dereference運算子 (如 ****ptr)。故先做 c=d 的運算,使c的 06/15 01:29
→ zlw:值跟d一樣。接著做b=c的運算,最後做a=b的運算,故abcd都變d值 06/15 01:30
推 zlw:修正,剛測試過,假設d=4;則 c=d 跟 c=4 這兩個運算都是使c變 06/15 01:34
→ softwind:有asm code 可以看嗎? 有得看最清楚了 06/15 01:35
→ zlw:成4後,再傳回一個rvalue的值,故接下來是做 b=4 的運算才對。 06/15 01:35
→ VictorTom:科科~~所以其實是 a = (b = (c = d)); 這樣子對吧:) 06/15 01:53
→ VictorTom:每一個()都留下了一個R-value就是了....@_@" 06/15 01:53
推 zlw:我猜錯了,本來以為c=4這樣的運算跟c+4一樣,運算完傳回rvalue 06/15 01:59
→ zlw:可是用C++跑這 int x = ++(a=5, b=6); x的值變成7,也就是說 06/15 01:59
→ zlw:b=6是傳回左值,根據C++的,運算子規定,如果最右邊運算式是左 06/15 01:59
→ zlw:值就傳回左值,而++運算子只能搭配左值服用,故b=6傳回左值 06/15 02:00
→ VictorTom:Orz 暈~~看來還是早點睡, 明天來等大大們的解釋好了XD 06/15 02:07