Re: [問題] 關於二維陣列的pass by ref
※ 引述《Arim (Arim5566)》之銘言:
: 各位版友好
: 在傳遞二維陣列給foo的時候:
: void foo(char str[][11]){
: }
: int main(){
: char str[11][11];
: foo(str)
: }
: 請問為什麼在foo的參數列上面
: 要用str[][11]
: 為什麼不需要指定第一個[]的upper bound 而只要去指定第二個[]的upper bound(也就是
: 指定[11])
: 謝謝各位版友的指教
提外話,這問題和 pass by reference 沒有關係。
void foo(char str[][11]){
}
這段碼最後會被 compiler 翻譯成
void foo(char (*str)[11]) {
}
str 本質上是一個指標,所以在這裡 str 取得的還是一個 address 而已,
並不是整個 array. 所有的 str[i][j] 運算都是基於這個 address 做偏移處理。
一些基本假設先確立
(1) 陣列分配必為連續且線性 < 連續是必然,線性就不確定 >
(2) CHAR_BITS = 8 < 說明方便假設, depends on compiler / machine >
(3) 陣列管理為 Major in Row < C 語言是 如此沒錯, Fortran 是 Major in Column >
(4) sizeof( void *) = 4 < 說明方便假設, depends on compiler / machine >
(5) sizeof(int) = 4
(6) 橫排為列,直排為行 < 統一用語,避免困惑 >
------------------------------
首先了解 int arr[2][3] 在記憶體配置連續的,可能這樣。
Variable Address
arr[0][0] 0x80000000
arr[0][1] 0x80000004
arr[0][2] 0x80000008
arr[1][0] 0x8000000c
arr[1][1] 0x80000010
arr[1][2] 0x80000014
首先 str[0][0] 這是此陣列第一個元素,也是開頭位址,
這個位址我稱 base address of array ,陣列之基底位址,
< 恕我在高階程式語言的書籍裡,找不到合適的稱呼,引用其他書籍的稱呼 >
代表整個 arr 之位置,也常以 str[0][0] 此位址示之,只差在型態有所不同,
但代表的數值都是 0x80000000 。
對 int arr[2][3] 而言,在底層下當要定址到 arr[1][2] 時,它的做法是
< arr[H][W] arr[R][C] >
< H 列 W 行 第 R 列, 第 C 行 >
(1) 先去找 arr 之基底位址在哪 : 0x80000000
(2) 先定位到 arr[R][0], 由於一列有 W 個元素,所以 R 列有 R*W 個元素
現在是 int arr[2][3],W=3 , 所以先定位到 arr[1][0] 時,得到位置是
(W)
arr[1][0] = 0x80000000 + 3 * 1 * sizeof(int) = 0x80000000 + 3*4 = 0x8000000c
(3) 再從剛剛的 arr[R][0],偏移 C ,得到 arr[R][C]。
arr[1][2] = 0x8000000c + 2 * sizeof(int) = 0x8000000c + 8 = 0x80000014
--------------------------------------
實際上 2,3 步驟是合併的,只是說明方便才拆開來。
從上面整個計算裡,可以得到一個結論 :
int Base[H][W]; // 宣告
Base[i][j] = 0; // *(Base + i*W + j) = 0;
有看到了嗎?計算上從頭到尾沒有用到 H, 只有用到 W;
再換三維的看看。
int Base[X][Y][Z]; // 宣告
Base[i][j][k] = 0; // *(Base + i*Y*Z + j*Z + k) = 0;
一樣的,三維在計算上只用到 Y, Z , 而沒用到 X。
對所有多維 array 之定址而言,這種公式是可遞推出來的,
有興趣也可想想在 4, 5 維的時候該怎麼遞推。
但無論如何遞推,只有最高維度之常數用不到,其他的都用得到。
這也是為何書上告知多維陣列初始化時,只有最高維度可不指定,
因為這裡 compiler 會幫忙算。
扣除掉最高維度之常數,其他維度之常數在計算上都用得到,
所以必須指定。
--------
敘述可能有點亂,但原理就是如此,不清楚的話可再稍畫一下圖
( 就簡單的面積計算而已 ) ,應可清楚很多。
一點意見,希望可解決疑惑。
另有誤請不吝指正,感激不盡。
--
「自從我學了 C# , 人都變聰明 , 考試都考一百分」
「自從我學了 VB , 皮膚都變好 , 人也變漂亮了 」
「自從我學了 Java , 明顯變壯 , 個子也變高了 」
「自從我學了 C++ , 內分泌失調 , 頭都禿了... 」
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.76.161
推
08/05 22:45, , 1F
08/05 22:45, 1F
→
08/05 22:45, , 2F
08/05 22:45, 2F
→
08/05 22:47, , 3F
08/05 22:47, 3F
→
08/05 22:48, , 4F
08/05 22:48, 4F
→
08/05 22:48, , 5F
08/05 22:48, 5F
→
08/05 22:49, , 6F
08/05 22:49, 6F
推
08/05 22:51, , 7F
08/05 22:51, 7F
→
08/05 22:52, , 8F
08/05 22:52, 8F
→
08/05 22:53, , 9F
08/05 22:53, 9F
→
08/05 22:53, , 10F
08/05 22:53, 10F
→
08/05 22:53, , 11F
08/05 22:53, 11F
推
08/05 22:55, , 12F
08/05 22:55, 12F
→
08/05 23:16, , 13F
08/05 23:16, 13F
→
08/05 23:29, , 14F
08/05 23:29, 14F
→
08/05 23:29, , 15F
08/05 23:29, 15F
→
08/05 23:37, , 16F
08/05 23:37, 16F
→
08/05 23:45, , 17F
08/05 23:45, 17F
→
08/05 23:48, , 18F
08/05 23:48, 18F
→
08/06 00:02, , 19F
08/06 00:02, 19F
推
08/06 06:15, , 20F
08/06 06:15, 20F
推
08/06 19:49, , 21F
08/06 19:49, 21F
推
05/29 01:02, , 22F
05/29 01:02, 22F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章