Re: [問題] 對陣列名稱取址

看板C_and_CPP作者 (河海不擇細水長流)時間9年前 (2015/05/13 03:15), 9年前編輯推噓1(1016)
留言17則, 7人參與, 最新討論串3/5 (看更多)
※ 引述《Hazukashiine (恥ずかしい ね...(>///<))》之銘言: : b 跟 &b 的地址不一樣,簡單地說, &b 的地址並不存在,而且對編譯器來說是非法的。 : 因為當你在寫單獨一個 b 的時候, b 已經被隱式轉換成指標型態,而且這是被強制的。 : 在且 b 是一個右值(r-value),意思是你不能對此作取址的動作。 : 根據 ISO 文件 §4.2.1 Standard Conversions: Array-to-pointer conversion : An lvalue or rvalue of type "array of N T" or "array of unknown bound of T" : can be converted to an rvalue of type "pointer to T." The result is a pointer : to the first element of the array. : 接下來的第三個也是一樣, : 陣列名稱有佔空間嗎?結果呼之欲出,當然不佔。因為陣列名稱(b)是右值,並不佔空間。 : 可是你一定會很好奇不佔空間的話你的程式要如何知道陣列在哪? : 這件事很妙,站在C語言的角度並不佔空間,但是實作上辦不到,所以當然要佔空間。 : 只是這個變數不是你的程式可以 access 的,它被編譯器巧妙地包裝了。 不用爭論了,反正下面三件事情結果都是一樣的: #include <stdio.h> int main() { int a[5]; printf("&a[0]\t%p\n", &a[0]); printf("a\t%p\n", a); printf("&a\t%p\n", &a); return 0; } 執行結果: &a[0] 0018FF48 a 0018FF48 &a 0018FF48 反組譯奉上: .text:004011E8 push ebp .text:004011E9 mov ebp, esp .text:004011EB add esp, 0FFFFFFECh .text:004011EE lea eax, [ebp-14h] ; 是這樣 .text:004011F1 push eax ; &a[0] .text:004011F2 push offset aA0P ; "&a[0]\t%p\n" .text:004011F7 call 00403DA8 ; 前往 printf .text:004011FC add esp, 8 .text:004011FF lea edx, [ebp-14h] ; 一樣 .text:00401202 push edx ; a .text:00401203 push offset aAP ; "a\t%p\n" .text:00401208 call 00403DA8 ; 前往 printf .text:0040120D add esp, 8 .text:00401210 lea ecx, [ebp-14h] ; 還是一樣 .text:00401213 push ecx ; &a .text:00401214 push offset aAP_0 ; "&a\t%p\n" .text:00401219 call 00403DA8 ; 前往 printf .text:0040121E add esp, 8 .text:00401221 xor eax, eax .text:00401223 mov esp, ebp .text:00401225 pop ebp .text:00401226 retn 由於 a is an array of 5 int, 又 sizeof(int) = 4, 故 sizeof(a) = 5 * 4 = 20 跟ASM中的[ebp-0x14]符合, add esp, 0FFFFFFECh 又 相當於 sub esp, 0x14 反正這個 array 會放在 stack, 會擔心找不到位址嗎? 編譯器都安排好一切了, 結案。 題外話我後來用MSVC CL沒有其他參數下編譯後, &a[0]的部分反組譯結果是 .text:00401010 mov eax, 4 ; sizeof(int) = 4 .text:00401015 imul ecx, eax, 0 ; 0 elements .text:00401018 lea edx, [ebp+ecx-18h] 有趣的是這樣比較貼近原始的意義, 是透過陣列元素型態的大小(4)和數量(0)來算所需的偏移量(ecx)。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.192.56.215 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1431458144.A.862.html ※ 編輯: TobyH4cker (123.192.56.215), 05/13/2015 03:37:32 ※ 編輯: TobyH4cker (123.192.56.215), 05/13/2015 03:55:30 ※ 編輯: TobyH4cker (123.192.56.215), 05/13/2015 03:58:55

05/13 07:55, , 1F
array 不一定會放在 stack, 其實用組語解釋真的有點風險阿
05/13 07:55, 1F

05/13 07:56, , 2F
為甚麼人家 python 都不需要用組語 xD
05/13 07:56, 2F

05/13 08:11, , 3F
樓上????
05/13 08:11, 3F

05/13 09:49, , 4F
是的我是以原發問者的例子來解釋而已
05/13 09:49, 4F

05/13 09:52, , 5F
C的好玩之處就是可以直接想像在CPU會怎麼運算
05/13 09:52, 5F

05/13 11:20, , 6F
用組語解釋其實是「編譯器」怎麼算 XD
05/13 11:20, 6F

05/13 11:20, , 7F
不過這個求證方法至少有90分 讚
05/13 11:20, 7F

05/13 13:33, , 8F
其實每次有這個問題的討論串,我都很想問,int a[5];
05/13 13:33, 8F

05/13 13:34, , 9F
到底什麼時候會用到 &a?? ?_?
05/13 13:34, 9F

05/13 14:06, , 10F
不小心戳到的時候?
05/13 14:06, 10F

05/13 14:15, , 11F
通常就是用二維陣列的時候
05/13 14:15, 11F

05/13 14:18, , 12F
大概只有「特別指出避免被誤以為a是int的時候」吧
05/13 14:18, 12F

05/13 14:49, , 13F
可是用array本來就要有只有a時是什麼意義的觀念
05/13 14:49, 13F

05/13 15:03, , 14F
wenyonba: 當你有個指標的陣列, 每個元素想指向陣列時
05/13 15:03, 14F

05/13 15:04, , 15F
傳統的例子就是一堆字串要排序.
05/13 15:04, 15F

05/13 15:05, , 16F
實際上應該還是有很多特殊的情境需要.
05/13 15:05, 16F

05/13 15:08, , 17F
陣列原則上也是 object 的一種, 這部分好像也沒道理要不一樣
05/13 15:08, 17F
文章代碼(AID): #1LKb5WXY (C_and_CPP)
文章代碼(AID): #1LKb5WXY (C_and_CPP)