進入多維數組領域,指針類型系統展現出更豐富的層次。本文將從概念建模、內存物理佈局、數組名退化規則、指向數組的指針聲明四個維度,徹底講透多維數組與指針的交互邏輯。
C 語言沒有真正的多維數組,只有一維數組的元素又是一維數組的遞歸結構。
int a; // 標量
int b[10]; // 1維:10個 int 的數組
int c[6][10]; // 2維:6個元素的數組,每個元素是 int[10]
int d[3][6][10]; // 3維:3個元素的數組,每個元素是 int[6][10]
關鍵認知: c[6][10] 不是「6行10列」的矩陣,而是包含 6 個 int[10] 的一維數組。這一定義了所有後續的指針行為。
無論維度多少,內存永遠是線性位址空間。多維數組按行主序展開:最右下標變化最快,依次向左。
int m[2][5] 內存佈局 (假設基址 0x1000, int 4B)邏輯視圖: 物理內存 (連續 10 個 int):
m[0][0] m[0][1] ... m[0][4] → 0x1000 0x1004 ... 0x1014 (第 0 行)
m[1][0] m[1][1] ... m[1][4] → 0x1018 0x101C ... 0x102C (第 1 行)
地址遞增順序:m[0][0] → m[0][1] → ... → m[0][4] → m[1][0] → m[1][1] → ...
int matrix[6][10];
int *mp = &matrix[3][8]; // 指向第3行第8列 (0-based)
printf("%d\n", *mp); // matrix[3][8]
printf("%d\n", *++mp); // matrix[3][9] ← 同行下一列
printf("%d\n", *++mp); // matrix[4][0] ← 換行!第4行第0列
這證明:內存連續性打破了邏輯維度邊界,指針遞增自然流入下一行首元素。
一維數組名退化為 int* (指向元素)。二維數組名退化為 int(*)[10] —— 指向包含 10 個 int 的數組 (即一行) 的指針。
int matrix[3][10])| 表達式 | 類型 | 值/含義 | 解引用結果 |
|---|---|---|---|
matrix | int(*)[10] | 首行地址 &matrix[0] | *matrix → int* (指向 matrix[0][0]) |
matrix + 1 | int(*)[10] | 第 2 行地址 &matrix[1] | *(matrix+1) → int* (指向 matrix[1][0]) |
matrix[1] | int* | 第 2 行首元素地址 &matrix[1][0] | *matrix[1] → int (matrix[1][0] 值) |
matrix[1][5] | int | 第 2 行第 6 列的值 | — |
| 數組聲明 | 數組名類型/值 | 指向行的指針聲明 | 指向元素的指針 |
|---|---|---|---|
int a[10] | int* / &a[0] | — | int *p = a; |
int b[3][10] | int(*)[10] / &b[0] | int (*p)[10] = b; | int *p = &b[0][0]; |
int c[2][3][4] | int(*)[3][4] / &c[0] | int (*p)[3][4] = c; | int *p = &c[0][0][0]; |