2013-10-25 88 views
1

按本https://stackoverflow.com/a/3912959/1814023我們可以宣佈它接受二維數組作爲二維數組和功能

void func(int array[ROWS][COLS]). 

而且按照這樣的功能,http://c-faq.com/aryptr/pass2dary.html他們說:「由於調用的函數並不爲數組分配空間,它不需要知道整體大小,因此可以省略行數NROWS,數組的寬度仍然很重要,所以列維數NCOLUMNS(對於三維或更多維數組, )必須保留

我試過這個,它的工作原理......請注意,我改變了列的大小。

#include <stdio.h> 
#define ROWS 4 
#define COLS 5 

void func1(int myArray[][25]) 
{ 
    int i, j; 

    for (i=0; i<ROWS; i++) 
    { 
     for (j=0; j<COLS; j++) 
     { 
      myArray[i][j] = i*j; 
      printf("%d\t",myArray[i][j]); 
     } 
     printf("\n"); 
    } 
} 

int main(void) 
{ 
    int x[ROWS][COLS] = {0}; 
    func1(x); 
    getch(); 
    return 0; 
} 

我的問題是,爲什麼在CFAQ鏈接(http://c-faq.com/aryptr/pass2dary.html)他們說: 「The width of the array is still important」?即使我提供了錯誤的列大小。 有人可以解釋一下嗎?

+0

這不應該編譯,真的。你正在試圖將一個int(*)[5]'(當然是衰減後)作爲int(*)[25]'傳遞。 – chris

+3

實際上很簡單。要索引第一行(第0行)中的元素,您只需要知道列號。 'index = col'。當行爲0時,寬度不重要。然而,要訪問任何其他行上的元素,還必須知道列的寬度,因爲公式會變成'index = row * numCols + col' - 所以,你所做的事情應該會崩潰。如果沒有,每次執行它都只是運氣。將COLS設置爲25意味着當i = ROWS-1和j = COLS-1時,意味着對於最後一個元素,索引計算爲索引=(4-1)* 25 +(5-1) ! Baaaad! – enhzflep

+0

@chris:它'編譯',因爲代碼調用'func()',但定義'func1()'。所以被調用的函數不是定義的函數(又名'在問題中存在拼寫錯誤')。如果您使用C99或更高版本的編譯器,則應該仍然會收到警告(至少)用於調用未聲明的函數。由於代碼使用'getch()',它可能在Windows上運行,因此使用的是古董C89編譯器(又名MSVC)。 –

回答

0

當我編譯並運行程序(固定FUNC/func1的困惑和改變的getch,在Ubuntu 12.04後),這是發生了什麼

$ gcc crashme.c -o crashme 
crashme.c: In function ‘main’: 
crashme.c:23:13: warning: passing argument 1 of ‘func1’ from incompatible pointer type [enabled by default] 
crashme.c:4:6: note: expected ‘int (*)[25]’ but argument is of type ‘int (*)[5]’ 
[email protected]:~/temp$ ./crashme 
0 0 0 0 0 
0 1 2 3 4 
0 2 4 6 8 
0 3 6 9 12 
Segmentation fault (core dumped) 

如果添加一行

printf("%ld", sizeof(x)); 

緊接在int x [聲明後,您將看到大小是4 x 5 x sizeof int(我的系統上的80)的大小,因此聲明大小可用於sizeof,對於malloc調用等非常有用。

1

這就是你使用數組符號表示指針所得到的結果。構造示例:

#include <stdio.h> 

void size(int myArray[][25], int rows, int cols) 
{ 
    printf("sizeof(int [%d][%d]) = %d\n", rows, cols, sizeof(myArray)); 
} 

int main(void) 
{ 
    int arr1[4][4]; 
    int arr2[4][5]; 
    int arr3[5][5]; 

    size(arr1, 4, 4); 
    size(arr2, 4, 5); 
    size(arr3, 5, 5); 

    printf("sizeof(int *) = %d\n", sizeof(int *)); 

    return 0; 
} 

如果嘗試運行此操作,即使傳遞的數組大小不同,所有4個大小也將相同。
C中的數組類型只是語法糖 - 多維數組在線性內存模型中沒有意義。使用線性內存模型訪問簡單數組的元素,您必須知道兩件事:基地址和索引偏移量,因此您可以編寫*(base+indexOffset)。要索引二維數組中的元素,您必須知道另外兩件事:第一維的大小及其偏移量,因此您可以編寫*(base+dimensionSize*dimensionOffset+indexOffset)。數組表示法只是爲您執行所有這些複雜的數學運算,但您仍然必須向編譯器提供所需的數據。它取決於你以確保數據的完整性:)