將陣列和矩陣傳遞給函式,作為C中指標的指標和指標
給出以下程式碼:
void foo( int* array ) { // ... } void bar( int** matrix ) { // ... } int main( void ) { int array[ 10 ]; int matrix[ 10 ][ 10 ]; foo( array ); bar( matrix ); return 0; }
我不明白為什麼我得到這個警告:
warning: passing argument 1 of ‘bar’ from incompatible pointer type
雖然’foo’的電話似乎沒問題.
謝謝 :)
那麼C社群肯定不太瞭解,可以通過掃視SO來看待.魔法是,以下所有都是完全100%,相當於:
void foo(int (*array)[10]); void foo(int array[][10]); void foo(int array[10][10]); void foo(int array[42][10]);
繪製指標和陣列的區別非常重要.陣列不是指標.陣列可以轉換為指向其第一個元素的指標.如果你有一個指標,你有這個:
-------- | ptr|-------> data --------
但是,如果你有一個數組,你可以這樣做:
--------------------------- | c1 | c2 | c3 | ... | cn | ---------------------------
使用指標,資料位於整個其他星球,但是由指標連結.陣列本身就有資料.現在,一個多維陣列只是一個數組.陣列巢狀到父陣列中.那麼你的陣列的sizeof是:
(sizeof(int) * 10) * 10
那是因為你有10個數組,它們都是10個整數的陣列.現在,如果要傳遞該陣列,則轉換它.但到什麼?指向其第一個元素的指標.元素型別不是指標,而是陣列.因此,您將指標傳遞給一個10 int的陣列:
int (*)[10] // a pointer to an int[10]
它不是int *的陣列,也不是int **.您可能會問為什麼陣列不會作為int **傳遞.這是因為編譯器必須知道行長度.如果你做了一個數組[1] [0],那麼編譯器會把一個sizeof(int)*的地址與二維陣列的開頭相隔10個位元組.它解碼指標到陣列型別中的資訊.
所以,你必須選擇上述完全等效的功能原型之一.當然,最後一個只是混亂.如果將引數宣告為陣列,編譯器將靜默地忽略在最外層維度編寫的任何數字.所以我也不會使用第二個版本.最好是使用第一個或第二個版本.需要記住的是C沒有(真正的)陣列引數!該引數將是最後的指標(在這種情況下指向陣列).
注意上面的多維情況如何與以下退化的一維情況相似.以下所有4個版本完全相同:
void foo(int *array); void foo(int array[]); void foo(int array[10]); void foo(int array[42]);
http://stackoverflow.com/questions/546860/passing-arrays-and-matrices-to-functions-as-pointers-and-pointers-to-pointers-in