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

作者: Hazukashiine (私は幸せです)   2015-05-12 21:42:16
※ 引述《lalaboom (lalaboom)》之銘言:
: 標題: [問題] 對陣列名稱取址
: 時間: Tue May 12 19:54:31 2015
: 
: 之前我的認知陣列名稱是一個常數指標,非指標常數喔,
:  
: 1. 請問這個敘述對嗎?
:  
: 現在有陣列 int b[2]; int a[2][3];
:  
: 2. 請問為什麼 b 跟 &b 兩個address會一樣呢?
: 我可以理解 a, a[0], &a[0][0] 這3個一樣,
: 但是type不同,還是說這個認知也是錯的XD
:  
: 3. 陣列在記憶體裏面除了宣告出來的連續空間,
: 陣列名稱是否會有另外像宣告指標一樣有一個變數空間嗎?
:  
: 關於2之前好像有看到說&b = b 是定義好的 (compiler ? )
這些問題好像有許多的初學者都很困惑,
雖然明天我要考可怕的偏微分段考已經自顧不暇了,不過還是想回答一下。(笑
站在C語言本身的角度,陣列本身不是一個指標,它就是一個單單純純的陣列。
站在機器的角度,陣列佔據了記憶體一段連續的空閒,並且有個變數記錄了它的位置。
但是這個變數不是程式設計師可以直接獲得的,它需要進行轉換才能獲得。
先說說第二個好了:
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 的,它被編譯器巧妙地包裝了。
這樣很矛盾嗎?
其實,不。
因為程式語言本身定義的是語法結構,並不是實作的內容。
因此一個程式語言可以有很多種編譯器,像是 GCC C Compiler, MSVC etc.
如有錯誤歡迎指正。
( ̄▽ ̄#)=﹏﹏ 飄走=
作者: Feis (永遠睡不著 @@)   2015-05-12 21:54:00
&b 存在且合法. b 不佔空間的話, 試解釋 sizeof(b)b 是個陣列. 但是不占空間嗎? 蠻有趣的
作者: CaptainH (Cannon)   2015-05-12 22:53:00
b 是 lvalue
作者: AstralBrain   2015-05-12 22:57:00
b[2]不是陣列, b[2]是陣列的第3個elementb 是 lvalue (這很重要) http://ideone.com/mKCvI2
作者: CaptainH (Cannon)   2015-05-12 22:58:00
那你怎麼解釋An lvalue or rvalue of type "array of NT"這個東西?
作者: Feis (永遠睡不著 @@)   2015-05-12 23:15:00
放在 stack 中? 這也蠻有趣的
作者: CaptainH (Cannon)   2015-05-12 23:15:00
修正後仍是錯,b[]不是正確的語法,更別說他代表什麼了
作者: Feis (永遠睡不著 @@)   2015-05-12 23:17:00
推一下右值的定義. 蠻有趣的對了. 忘了問 4.2.1 的那節是 ISO C 哪個版本?我建議你可以去 C 標準找一下 rvalue (如果你在說 C 的話)所以你的 compiler 印不出 &b ?此外你可以想想 struct 變數~ 比對一下跟 array 的差別還有你的 sizeof 的說明不是已經說了 b 是 array type ?如果 b 不是 array type, 那 sizeof(b) 到底是甚麼.. 頭痛b 會被轉成 &b[0] 喔~ 所以是 int * 而不是 int(*)[2]恩.. 我們看的是同一篇嗎 XDDDDD我需要一點時間理解. 晚安 : )是阿. 那不就是 &b 嗎 xD但是你說的不是 b 在程式碼中會被轉 int (*)[2] 嗎?我說的是 b 會轉為 int * 不是 &b 阿 QQ用編輯文章好難回阿 xD 原文 &b 的 address 應該不是 &&b 的意思. 或者我以為他不是 xD
作者: bibo9901 (function(){})()   2015-05-13 00:00:00
你是跟葉孤紅一樣有人專門寫一本錯誤的書給你看嗎 XD既然 b 是一個 rvalue 那你怎麼能用 address-of 呢?
作者: Feis (永遠睡不著 @@)   2015-05-13 00:06:00
提醒一下... standard conversion 是 C++ 的...
作者: bibo9901 (function(){})()   2015-05-13 00:10:00
我說的是 address-of "&" 不是 sizeof如果 b 不佔空間的 rvalue, 那你寫下 &b 就是非法的
作者: Feis (永遠睡不著 @@)   2015-05-13 00:12:00
其實我不知道 rvalue 不占空間這樣的說法到底該怎麼解釋 xD我是覺得 rvalue 很玄阿~ 大家晚安~
作者: bibo9901 (function(){})()   2015-05-13 00:14:00
的確很怪, 但暫且假設如他所說的那樣, 對 b 取址更怪
作者: Feis (永遠睡不著 @@)   2015-05-13 00:25:00
對轉換有興趣請參閱 C89 標準 3.2.2.1
作者: yvb   2015-05-13 14:57:00
94行說 "使用C++來檢視C?"但 35行 "ISO 文件 §4.2.1" 似乎引自 C++ ??另外, 原原PO問 "為什麼 b 跟 &b 兩個address會一樣"然後 30行那邊回 "b 跟 &b 的地址不一樣" ...感覺答非所問? 還是 "地址不一樣" 似乎不是唯一解??上面 F大的 3.2.2.1 其實是指 6.3.2.1 ?
作者: Feis (永遠睡不著 @@)   2015-05-13 17:20:00
yvb: 好像是版本差異 XD 那是 C89 Draft
作者: yvb   2015-05-13 17:57:00
soga... C89 3.2.2.1 => C90 6.2.2.1 => C99~C11 6.3.2.1c89 要 google ansi.c.txt 才找得到 :P (好像沒 pdf 的?)

Links booklink

Contact Us: admin [ a t ] ucptt.com