int a[3][4]; // 3 列、4 行,共 12 個 int,連續儲存
記憶體佈局(假設起始位址 0x1000,int 4 bytes):
a[0][0] a[0][1] a[0][2] a[0][3] | a[1][0] a[1][1] a[1][2] a[1][3] | a[2][0] a[2][1] a[2][2] a[2][3] 0x1000 0x1004 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C 0x1020 0x1024 0x1028 0x102C
| 運算式 | 型別 | 值(位址) | 語意 |
|---|---|---|---|
a | int (*)[4](指向 4-int 陣列的指標) | 0x1000 | 整個二維陣列的首位址(第 0 列) |
&a | int (*)[3][4](指向 3x4 陣列的指標) | 0x1000 | 整個二維陣列的位址(型別不同,步長不同) |
a[0] | int *(退化為指向首元素) | 0x1000 | 第 0 列首元素位址 |
&a[0][0] | int * | 0x1000 | 第一個元素位址 |
*a | int *(等價於 a[0]) | 0x1000 | 第 0 列首元素位址 |
結論:`a`、`&a`、`a[0]`、`&a[0][0]`、`*a` **數值相同(0x1000)**,但**型別不同**,決定指標運算步長。
| 運算式 | 型別 | 結果位址 | 跨越元素數 |
|---|---|---|---|
a + 1 | int (*)[4] | 0x1010 | 跳過 1 列(4 個 int,16 bytes) |
*a + 1 (即 a[0] + 1) | int * | 0x1004 | 跳過 1 個 int(4 bytes) |
這是二維陣列指標運算的核心:**外層指標步長 = 內層陣列大小;內層指標步長 = 元素大小**。
// 正確:接收列數固定的二維陣列
void print_row(int (*p)[4], int rows) {
for (int i = 0; i < rows; ++i)
for (int j = 0; j < 4; ++j)
printf("%d ", p[i][j]); // p[i] 相當於 *(p+i)
}
// 呼叫
print_row(a, 3); // a 隱式轉為 int (*)[4]
若列數不固定,改用一維陣列模擬:`void print_flat(int *p, int rows, int cols)`,存取 `p[i*cols + j]`。