2017-10-07 139 views
0

everyone。C語言指針:int ** Vs. int(* g)[]

我使用Visual Studio 2013(C++)和限定在主功能的2D陣列:

int _tmain(int argc, char **argv) 
{ 
    int g[3][3] = { { 1, 2, 3, }, { 4, 5, 6, }, { 7, 8, 9, }, }; 
    ... 

    return 0; 
} 

然後,我定義的函數在定義1:

定義1:

void print_array(int **arr, int kx, int ky) 
{ 
    for (int i = 0; i < kx; i++) { 
     for (int j = 0; j < ky; j++) { 
      printf("%d ", arr[i][j]); 
     } 
     printf("\n"); 
    } 
} 

我想從主要功能調用此功能:

int _tmain(int argc, char **argv) 
{ 
    int g[3][3] = { { 1, 2, 3, }, { 4, 5, 6, }, { 7, 8, 9, }, }; 

    print_array(g, 3, 3); 

    return 0; 
} 

Visual Studio的告訴我說:

Error 1 error C2664: 'void print_array(int **,int,int)' : cannot convert argument 1 from 'int [3][3]' to 'int **' 

我也知道另一種定義方法:

定義2

void print_array(int (*arr)[3], int kx, int ky) 
{ 
    for (int i = 0; i < kx; i++) { 
     for (int j = 0; j < ky; j++) { 
      printf("%d ", arr[i][j]); 
     } 
     printf("\n"); 
    } 
} 

現在,它的工作原理。

我的問題是:在我之前他們(定義1和定義2)都在舊編譯器中工作,名爲你可以正確地將數組名稱作爲int **int (*p) []傳遞給另一個函數。但是,在Visual Studio C++中,它不是。 Visual Studio C++比其他編譯器更嚴格嗎?或者我做錯了什麼?

非常感謝!

+3

數組不是指針。指針不是數組。 – EOF

+0

「*您可以將數組名稱作爲int **或int(* p)[]'*」傳遞,您可能沒有啓用它,或者簡單地忽略其他「* old *」編譯器的警告。 *或*你的記憶在欺騙你; ;-) – alk

+0

可能的重複[爲什麼我們不能用雙指針來表示二維數組?](https://stackoverflow.com/questions/4470950/why-我們使用雙指針來表示二維數組) –

回答

6

我remenbered之前,他們(定義1和定義2)無論是在舊的編譯器的工作,

如果記憶是正確的,舊的編譯器被打破。該代碼從未有效。C.

可以自由地將數組int x[3]轉換爲指針int *p。這一直都是有效的,並且有很多情況是隱含的。

但是,int (*x)[3]是一個指針,而int **y是一個指針,但它們指向的是完全不同類型的對象!您無法將int *轉換爲double *

你可以看到,xy有不同的結構,如果你畫出來:

+-------------+  +-----+ 
| int (*x)[3] | ----> | int | 
+-------------+  | --- | 
         | int | 
         | --- | 
         | int | 
         +-----+ 
         | ... | 

+---------+  +-------+  +-----+ 
| int **y | ----> | int * | ----> | int | 
+---------+  +-------+  +-----+ 
        | ... |  | ... | 

他們不看一樣在所有的,不是嗎?

+0

謝謝!非常明確的解釋!我現在使用第二種方法:int(*)[],它很合適。 – zchenkui

0

陣列和指針轉換隻能在第一級上完成,所以int*int[]很好地成爲對方,但不int**int[][]和。

實際上,int**(可以轉換爲int(*)[])指向指針的數組,其中的每一個可以指向不同地點,但很明顯的2D陣列的子陣列不能。這就是你面臨的問題。

+3

請在這裏表達什麼:「*可以轉換爲int(*)[]'*」? – alk

1

除了當它是sizeof或一元&運營商的操作數,或是使用在聲明初始化字符數組文本字符串,類型「的T N元件陣列」的表達將被轉換(「衰減」)轉換爲類型爲「指向T的指針」的表達式,並且表達式的值將是該數組的第一個元素的地址。

當調用print_array(g, 3, 3);,表達式g具有類型「的T 3元素數組」,其中T是「的int 3元素」。因此g將「衰減」以鍵入「指向T」的指針,或「指向3元素的指針」或int (*)[3]。這就是爲什麼你的第二個定義有效。

這裏有一個方便的表格,以幫助記憶的一些規則:

Type   Decays to 
————   ————————— 
T [N]   T * 
T [M][N]  T (*)[N] 
T [L][M][N]  T (*)[M][N] 
+0

謝謝John!這張桌子很棒,很清楚! – zchenkui