為什麼這篇指標與陣列的差別鄉民發文收入到精華區:因為在指標與陣列的差別這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者Hazukashiine (恥ずかしい ね...(>///<))看板C_and_CP...
: 標題: [問題] 對陣列名稱取址
: 時間: 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.
如有錯誤歡迎指正。
( ̄▽ ̄#)=﹏﹏ 飄走=
--
當教授在講臺上C++的時候,我的臉比佳佳還要沮喪...
講正經的... C++是一個被過度設計的程式語言,完全遭透了!
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.113.91.124
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1431438143.A.864.html
※ 編輯: Hazukashiine (140.113.91.124), 05/12/2015 21:49:51
&b 當然存在且合法。不存在的是 &b 的地址。
請您再仔細地看上文「&b 的地址(即&&b)並不存在,而且對編譯器來說是非法」
根據 ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007 WG14/N1256
§6.5.3.4
3. ... When applied to an operand that has array type,
the result is the total number of bytes in the array.
這項目特別被舉出來是為了避免 sizeof(b) 中的 b 被 implicitly convert.
所以說,sizeof(b) 仍然是 int b[2] 這個陣列的位元組大小。
b 是陣列名稱, b[] 才是是陣列,該陣列的型態是 int[2]。
b 不佔空間,只有 b[] 佔空間,但是實作上需要使用一個空間來儲存 b[2] 的地址。
而且這個空間也一樣是放在 stack 中,會隨函式的增長或消滅來生成與毀滅。
已修正,感謝提出錯誤。
這是邏輯謬誤,使用C++來檢視C?
在C語言中,不實際擁有在記憶體中一塊物理位置的稱之為右值。
b 是陣列名稱(並非陣列本身),當然在記憶體中不擁有物理位置。
不然大大覺得應該要如何準確地表示陣列?
陣列一語本來就不是正確的語法,最正確的用法是:
It has type `int[2]`.
L-values have storage addresses that are programmatically accessible to the
running program, meaning that they are variables or dereferenced references to
a certain memory location.
Does b have its own storage address? Only b[0] and b[1] does!
`b` has type `int[2]`, and `&b` has type `int(*)[2]`.
Type `int(*)[2]` will decay to `int*` while the array length is useless.
我承認我真的不知道 b 是不是 array type,
但是 b 肯定是 int[2],只是在程式碼中會被轉型成 int(*)[2]。
絕不是 int*
http://stackoverflow.com/questions/2893911/
address-of-an-array-address-of-being-ignored-be-gcc
int(*)[2] 會 decay 成 int* 當陣列長度無用的時候,
A pointer that points to an array of 50 ints has type int (*)[50] - that's
the type of &test.
是呀~所以 &b has type `int(*)[2]` not type `int*`.
喔喔喔~我錯亂惹~
整理一下:
b: int[2] -> int* (implicit conversion: array-to-pointer conversion)
&b: int(*)[2] (address-of operator)
搞不好真的不是,中文有時候會怪怪der.
XDDD
錯亂惹啦~先去準備偏微分啦!!!
這篇的重點是:
1. Implicit type conversion: array-to-pointer conversion
2. b has type int[2], and &b has type int(*)[], and &&b is invalid.
暈~
b 在 code 中被轉換的才是 rvalue,
在 sizeof operator 中不用被轉換,是 lvalue!!!
喔喔喔~是 Implicit type conversion
改了改了
眼殘XD
compiler 很聰明吧~
也許看到前方有&就不會作 implicit conversion 吧?阿災?
我翻遍標準文檔就還是覺得怪怪的
可能就真的不隱式轉換了吧~
※ 編輯: Hazukashiine (140.113.91.124), 05/13/2015 00:18:09