Re: [問題] 若ptr為整數型態指標 ptr+1 = = ptr ++ ?

看板C_and_CPP (C/C++)作者 (鬼翼&娃娃魚)時間16年前 (2009/06/14 23:56), 編輯推噓4(4012)
留言16則, 4人參與, 最新討論串2/2 (看更多)
※ 引述《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)

06/15 00:41, , 1F
我懂你了 好樣的 好文 哈~ 謝謝你
06/15 00:41, 1F

06/15 00:42, , 2F
a+1本身是一個記憶體位址 但他本身沒有辦法"取"記憶體位址
06/15 00:42, 2F

06/15 01:27, , 3F
a=b=c=d; 也是半知半解,猜看看:=運算子是由右至左結合性的
06/15 01:27, 3F

06/15 01:28, , 4F
二元運算子,每次把右邊的運算元取出右值給左邊的運算元。類似
06/15 01:28, 4F

06/15 01:29, , 5F
*dereference運算子 (如 ****ptr)。故先做 c=d 的運算,使c的
06/15 01:29, 5F

06/15 01:30, , 6F
值跟d一樣。接著做b=c的運算,最後做a=b的運算,故abcd都變d值
06/15 01:30, 6F

06/15 01:34, , 7F
修正,剛測試過,假設d=4;則 c=d 跟 c=4 這兩個運算都是使c變
06/15 01:34, 7F

06/15 01:35, , 8F
有asm code 可以看嗎? 有得看最清楚了
06/15 01:35, 8F

06/15 01:35, , 9F
成4後,再傳回一個rvalue的值,故接下來是做 b=4 的運算才對。
06/15 01:35, 9F

06/15 01:53, , 10F
科科~~所以其實是 a = (b = (c = d)); 這樣子對吧:)
06/15 01:53, 10F

06/15 01:53, , 11F
每一個()都留下了一個R-value就是了....@_@"
06/15 01:53, 11F

06/15 01:59, , 12F
我猜錯了,本來以為c=4這樣的運算跟c+4一樣,運算完傳回rvalue
06/15 01:59, 12F

06/15 01:59, , 13F
可是用C++跑這 int x = ++(a=5, b=6); x的值變成7,也就是說
06/15 01:59, 13F

06/15 01:59, , 14F
b=6是傳回左值,根據C++的,運算子規定,如果最右邊運算式是左
06/15 01:59, 14F

06/15 02:00, , 15F
值就傳回左值,而++運算子只能搭配左值服用,故b=6傳回左值
06/15 02:00, 15F

06/15 02:07, , 16F
Orz 暈~~看來還是早點睡, 明天來等大大們的解釋好了XD
06/15 02:07, 16F
文章代碼(AID): #1ADHt7JX (C_and_CPP)
文章代碼(AID): #1ADHt7JX (C_and_CPP)