2010年1月20日 星期三

Why is Row Irrelevant in 2-Dimensional Arrays?

在傳入 2-dimensional array 到某個 function 裡面, 我們可以省略 row 的 subscript, 但是 column 的 subscript 確不可以省略.

ex:
void funtion(int array[][5]);

從 reference 查到的原因是因為, C 必須知道有多少 column, 所以他才可以正確的找到每個row的起點在哪.

我們來看看可以作為存取 2-dimensional 資料的宣告方式.



1. int ptr[2][5]; /* array 是一個二維陣列*/

2維陣列, C 可以依據 column 大小去找到下個 row 的起點.

2. int (*ptr)[5]; /* array is a pointer which point to array[5] of int */

如同一, 如果 *(ptr + 1) 存在, C 也可以依據 column 大小去找到下個 row 的起點.

3. int *ptr[5] /* array[5] of pointer to int */

這個就比較有趣, ptr 其實是一個大小為5的陣列, 陣列內每個元素都指向 int *, 所以每個 row 的 length 可以不一樣, 但是 (ptr+1)並不會讓 C 找不到下個 row 的起點, 他其實只是找到 ptr 陣列的下個 element.

以上內容不確定正確, 如果有哪裡有問題, 希望大家一起來討論. XD


References:
http://www.java-samples.com/showtutorial.php?tutorialid=538
http://www.velocityreviews.com/forums/t666081-passing-a-two-dimensional-array-to-function.html
http://c-codin.blogspot.com/2008/05/pointermulti-dimensional-arrays-pointer.html

11 則留言:

  1. 麻煩哪位大德~ 可以幫我改一下 read more 嗎? XD
    實在找不到哪裡可以設這個東西 T_T

    回覆刪除
  2. 問了阿~ 叫不出來~ 囧rz

    回覆刪除
  3. 我發現像:
    function(int array[][5]) {
    array[1][0]=0xFF;
    }
    function中的那行會被compile成:
    mov eax+5,0FFh

    所以column dimension是compiler需要的(為了產生assembly code中的那個+5),array本身還是以int*傳進function

    因此同理三維陣列array[2][3][4]的第二三個dimension也不能省略:
    function(int array[][3][4])

    當然如果要處理的array大小不固定,還是可以用int*來傳資料:
    function(int* pArray) {
    *(pArray + 5) = 0xFF;
    }
    只是這時候offset(+5 in this case)要自己加進去囉

    回覆刪除
  4. 感覺指標真是有趣阿 :D

    回覆刪除
  5. 想請問一下, 函示如下

    void function(char (*ptr)[5])
    {
    printf("(*ptr+1)[3]:%c\n", (*ptr+1)[3]); // note 1
    printf("(*(ptr+1))[3]):%c\n", (*(ptr+1))[3]); // note 2
    }

    note 1:
    (*ptr+1)[3] 指的是 ptr[0][4],
    我的想法是, *ptr 指的是陣列第一個元素, 而 +1 讓他指向陣列第二個元素,
    然後 [3] 會以第二個元素為目前陣列的起點, 然後往後找4個元素 (0,1,2,3), 所以會取出這一行陣列第五個元素 ptr[0][4].

    note 2:
    (*(ptr+1))[3], 就是 ptr 會跳一個 row, 然後取出下個 row 的第四個元素. ptr[1][3].

    感覺怕怕的, 不曉得這樣的想法是不是正確的.

    回覆刪除
  6. 實驗結果,讓我更同意這樣的想法。但是,code寫成這樣,怎麼這麼難~

    回覆刪除
  7. 最近這幾篇好文又燃起我的熱情,所以在這邊又來碎碎念一下。
    在我看來,這種參數傳遞方式定義得很鬆散,callie根本無法得知傳進來的參數到底何不合法(至少要確認size是對的)以免reference超過當初記憶體配製的範圍。
    還是這種宣告方式有何特殊使用時機?

    回覆刪除
  8. nj好有心還用AXvx+畫圖。。。可惜最近精神有點不繼不然我實在很想發篇git的文章跟參與討論阿orz

    回覆刪除