首先,一些standard語言:
6.3.2.1左值,數組和功能代號
...
3除非是sizeof操作符或的操作數一元&運算符,或者是一個用於初始化數組的字符串,具有「數組類型」類型的表達式將轉換爲類型爲「指向類型的指針」的表達式,該表達式指向數組對象的初始元素,而不是一個左值。如果數組對象具有寄存器存儲類,則行爲未定義。
鑑於聲明
int myarray[3][3];
的類型的myarray
是 「的int
3元素數組的3元素數組」。由規則上面去,當你寫
MyFunction(myarray, 3, 3);
的表達myarray
具有從「的int
3元素數組的3元素數組」到「指針3的類型隱式轉換(「衰變」)元素數組int
「或int (*)[3]
。
因此,你的函數原型將需要
int MyFunction(int (*array)[3], int row, int col)
注意int **array
是不一樣int (*array)[3]
;指針算術將會不同,所以你的下標不會指向正確的位置。請記住,數組索引被在指針運算來定義:a[i]
== *(a+i)
,a[i][j] == *(*(a + i) + j)
。 a+i
將產生不同的值,具體取決於a
是int **
還是int (*)[N]
。
該特定的例子假定你總是傳遞的int
一個NX3元件陣列;如果您想要處理任何NxM大小的陣列,則不會非常靈活。要解決這個問題的方法之一是明確地傳遞數組的第一個元素的地址,所以你只是傳遞一個簡單的指針,然後計算出正確的手動偏移:
void MyFunction(int *arr, int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
printf("%d", a[i*col+j]);
}
int main(void)
{
int myarray[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
...
MyFunction(&myarray[0][0], 3, 3);
因爲我們通過一個簡單的指針int
,我們不能在MyFunc
中使用雙下標; arr[i]
的結果是一個整數,而不是一個指針,所以我們必須在一個下標操作中計算數組中的完整偏移量。請注意,這個技巧只適用於真正的多維數組。
現在,一個**
可以指示組織在二維結構中的值,但是它是以不同方式構建的。例如:
void AnotherFunc(int **arr, int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
printf("%d", arr[i][j]);
}
int main(void)
{
int d0[3] = {1, 2, 3};
int d1[3] = {4, 5, 6};
int d2[3] = {7, 8, 9};
int *a[3] = {d0, d1, d2};
AnotherFunc(a, 3, 3);
...
}
去由規則如上所述,當表達式d0
,d1
,並d2
出現在初始值設定爲a
,它們的類型全部從「的int
3元素數組」到「指針轉換int
「。類似地,當表達a
出現在調用AnotherFunc
,其類型是從「指針的3元素數組int
」轉換爲「指針指向int
」。
請注意,在AnotherFunc
我們下標兩個尺寸,而不是像我們在MyFunc
中那樣計算偏移量。這是因爲a
是指針值的數組。表達式arr[i]
得到我們第指針從位置arr
的值偏移;然後我們從該指針值中找到第j個整數值偏移量。
下表可以幫助 - 它顯示了不同類型的數組表達式,它們腐爛什麼根據其聲明(T (*)[N]
爲指針類型,而不是一個數組類型,因此它不會腐爛):
Declaration Expression Type Implicitly Converted (Decays) to
----------- ---------- ---- --------------------------------
T a[N] a T [N] T *
&a T (*)[N]
*a T
a[i] T
T a[M][N] a T [M][N] T (*)[N]
&a T (*)[M][N]
*a T [N] T *
a[i] T [N] T *
&a[i] T (*)[N]
*a[i] T
a[i][j] T
T a[L][M][N] a T [L][M][N] T (*)[M][N]
&a T (*)[L][M][N]
*a T [M][N] T (*)[N]
a[i] T [M][N] T (*)[N]
&a[i] T (*)[M][N]
*a[i] T [N] T *
a[i][j] T [N] T *
&a[i][j] T (*)[N]
*a[i][j] T
a[i][j][k] T
高維數組的模式應該清晰。
我發現這在啓動C編程時非常有用:http://cslibrary.stanford.edu/102/PointersAndMemory.pdf – helpermethod 2010-10-18 05:03:30
查看了c-faq(http:// c- faq.com/aryptr/index.html) – pmg 2010-10-18 15:36:09