2011-01-20 63 views
3

我在將多維數組傳遞給C中的函數時遇到了問題。在typedef中以及參數應該是什麼。將多維數組傳遞給函數C

目前,我的功能高清看起來是這樣的:

int foo(char *a, char b[][7], int first_dimension_of_array); 

我宣佈一個這樣的數組:

char multi_D_array[20][7]; 

當我嘗試這樣調用該函數:

foo(d, multi_D_array, 20); 

我得到警告,該函數的第二個參數來自不兼容的指針類型。我已經嘗試了許多我在網上看到的變體,但仍然無法正確顯示。另外,在使用GDB時,我發現只有2D數組的第一個數組被傳入。對於我所做錯誤的反饋將不勝感激。

+1

嘗試將指針傳遞給數組 – 2011-01-20 01:48:48

回答

5

大警告:我通常不會這樣處理多維數組。

我想這只是爲了檢查,但這:

#include <stdio.h> 

int foo(char b[][7]) 
{ 
    printf("%d\n", b[3][4]); 
    return 0; 
} 

int main(int argc, char** argv) 
{ 
    char multi_d_arr[20][7]; 
    multi_d_arr[3][4] = 42; 
    foo(multi_d_arr); 
    return 0; 
} 

編譯並運行不受任何問題,請使用gcc -Wall。老實說,我不確定第二個參數如何被認爲是不兼容的指針類型。工作正常。

但是,既然你問了,我將如何處理二維數組?更好的方法是使用指針,像這樣:

char** array2d = malloc((MAX_i+1)*sizeof(char*)); 
for (i = 0; i < (MAX_i+1); i++) 
{ 
    array2d[i] = malloc((MAX_j+1)*sizeof(char)); 
} 

現在,僅僅是明確的,你可以訪問的最大元素是array2d[MAX_i][MAX_j]

完成後不要忘記反轉過程:

for (i = 0; i < (MAX_i+1); i++) 
{ 
    free(array2d[i]); 
} 
free(array2d); 

現在,使用這種方法,下標符號仍然有效,所以array2d[x][y]還訪問權價值。從字面上看,array2d是一個指針數組,每個array2d[i]也是如此。

爲什麼這是一個更好的方法?那麼,如果你喜歡,你可以有可變大小的子數組。你所要做的就是改變for循環。這種技術經常用於字符串數組,特別是在應用程序的int main(int argc, char** argv)簽名中。 argv是一個可變長度字符串數組的數組。使用strlen()來確定它們的長度。

你能通過嗎?當然。你剛剛收到它的主,對於初學者,但你也可以寫你的函數簽名如下所示:

int foo(char** ar2d, const unsigned int size); 

,並稱之爲:

char** somearray; 
/* initialisation of the above */ 

foo(ar2d, thesizeofar2d); 

/* when done, free somearray appropriately */ 

只是要清楚,你包括尺寸參數的方法(如const unsigned int size)是非常好的做法,你應該堅持下去。

+0

對於你在答案中所做的工作+1 :) – 2011-01-20 02:31:09

+0

使用C99變長數組可以做得更好,並根據它的運行時大小聲明數組的類型。你的建議是真的**不好主意**。如果子數組更改大小,則必須*保留每行的大小(或者如果大小更改,則風險訪問外部未分配的子數組)。這意味着要分配一個結構長度和指針數據和更復雜的語法。如果每個子數組的大小相同,那麼只用一個malloc分配一塊內存會更高效,更易於閱讀並且不易出錯。 – kriss 2011-01-20 07:47:03

-2

底線是C/C++不能很好地處理多維數組。大多數情況下,使它成爲一個單維數組並自己進行行列尋址更容易。

0

那麼,它是不符合定義的。

char[20][7]是不一樣的char[][7]

剛剛擺脫的警告。

它不傳遞「只有2D數組的第一個數組」,它只傳遞一個指向數組的指針(指向第一個元素的指針或數組的開頭)。 您只能看到GDB中的前7個元素,因爲根據函數內部數組的類型,GDB只知道7個元素。

+1

它們是兼容的。數組`multi_D_array`在函數調用上下文中使用時,被轉換爲指向其第一個元素的指針,該元素的類型爲char(*)[7]`。參數`char [] [7]`正是這種類型。 – caf 2011-01-20 03:22:49

0

從C99開始,您可以使用可變長度的數組,並執行下面的操作。基本上,維數組提供的參數用於聲明數組大小。這很可能是現代編譯器的最佳方法。

#include <stdio.h> 

int foo(char *a, int fdim, char b[fdim][7]){ 

    printf("b[19][6] = %d\n", b[19][6]); 
    return 0; 
} 

int main(){ 
    char d[10]; 
    char multi_D_array[20][7]; 
    int x, y; 

    for (x = 0 ; x < 7 ; ++x){ 
     for (y=0 ; y < 20 ; ++y){ 
      multi_D_array[y][x] = y + x; 
     } 
    } 
    foo(d, 20, multi_D_array); 
} 

即使它也適用於C++,你也可能有意通過閱讀我的答案therethere(別人的肯定回答)爲更好地理解C數組中。

1

你在問題中給出的聲明和函數調用是完全正確的C,並且不會給gcc一個警告。

你確定你已經完全複製了有問題的代碼嗎?