宣告 int a[3][4] 可視為:3 個元素的陣列,每個元素是 4 個 int 的一維陣列。
a[0] → { a[0][0], a[0][1], a[0][2], a[0][3] }
a[1] → { a[1][0], a[1][1], a[1][2], a[1][3] }
a[2] → { a[2][0], a[2][1], a[2][2], a[2][3] }
| 運算式 | 型別 | 位址值 | 含義 |
|---|---|---|---|
a | int (*)[4] | 1000 | 第 0 列首址 (整個陣列首址) |
a + 1 | int (*)[4] | 1008 | 第 1 列首址 (跨越 4×2=8 bytes) |
a + 2 | int (*)[4] | 1016 | 第 2 列首址 |
a[0] / *a | int * | 1000 | 第 0 列首元素址 |
a[1] / *(a+1) | int * | 1008 | 第 1 列首元素址 |
a[i] + j | int * | 1000 + (i×4 + j)×2 | 第 i 列第 j 行元素址 |
&a[i][j] | int * | 同上 | 標準取址形式 |
a[i][j] /* 標準下標 */
*(a[i] + j) /* a[i] 退化為 int*,加 j 後解參考 */
*(*(a + i) + j) /* a 退化為 int(*)[4],a+i 指向第 i 列,解參考得 int*,再加 j 解參考 */
(*(a + i))[j] /* 同上,利用下標運算子優先序 */
編譯器產生完全相同機器碼。
a 與 *a 數值相同?a:型別 int (*)[4],值為陣列首址 (1000)。*a:解參考 a 得 a[0],型別 int [4],隨即退化為 int *,值仍為 1000 (第 0 列首元素址)。a+1 跳 8 bytes,*a+1 跳 2 bytes)。void f(int a[][4], int rows) 或 void f(int (*a)[4], int rows)。int *p = malloc(rows * cols * sizeof(int)); 存取 p[i*cols + j]。int **p = malloc(rows * sizeof(int*)); for(i) p[i] = malloc(cols * sizeof(int)); 存取 p[i][j] (非連續)。int ***:極難維護,改用結構體封裝。