| 運算 | 結果型別 | 語意 |
a / a+i | 行指標 int (*)[COLS] | 指向第 i 行首地址 |
*a / *(a+i) / a[i] | 列指標 int* | 指向第 i 行首元素(列指標) |
**a / *a[i] / *(*(a+i)+j) | int | 元素值 a[i][j] |
&a[i] / &a[i][0] | 行指標 int (*)[COLS] | 第 i 行首地址 |
地址等價關係(重點)
以下表達式**數值相等**(地址相同),但**型別不同**:
a + i
a[i]
*(a + i)
&a[i]
&a[i][0]
型別差異決定指標運算步長:
- 行指標
+1 → 跨越一整行(COLS * sizeof(int) 位元組)。
- 列指標
+1 → 跨越一個元素(sizeof(int) 位元組)。
完整對照表(假設 int a[3][4])
| 表達式 | 型別 | 代表意義 | 地址值 |
a | int (*)[4] | 第 0 行首地址 | 基址 |
*a | int* | a[0][0] 地址 | 基址 |
a[0] | int* | a[0][0] 地址 | 基址 |
&a[0] | int (*)[4] | 第 0 行首地址 | 基址 |
a+1 | int (*)[4] | 第 1 行首地址 | 基址 + 16 |
a[1] | int* | a[1][0] 地址 | 基址 + 16 |
*a+1 | int* | a[0][1] 地址 | 基址 + 4 |
*(a+1) | int* | a[1][0] 地址 | 基址 + 16 |
&a[1] | int (*)[4] | 第 1 行首地址 | 基址 + 16 |
a[1][0] | int | 元素值 | — |
函數參數傳遞二維陣列
// 1. 指定列數(行數可變)
void func(int a[][4], int rows);
// 2. 行指標
void func(int (*a)[4], int rows);
// 3. 一維陣列模擬(手動計算索引)
void func(int* a, int rows, int cols); // a[i*cols + j]
常見錯誤
int** p = a; **錯誤**!a 是行指標 int (*)[4],非 int**。
- 混淆
*a+1(列指標+1)與 *(a+1)(行指標+1 再解引用)。
sizeof(a) 在陣列定義處為整個陣列大小,傳入函數退化為指標後為指標大小。
總結
二維陣列名本質是**行指標**。掌握 *(行→列)、&(列→行)的型別轉換,以及**地址數值相同但型別決定步長**的核心原理,即可靈活操作二維陣列指標。
- 上一篇文章: C++ const 深度解析:參數、回傳值、成員函數與 mutable 例外
- 下一篇文章: C/C++ sprintf 完整使用指南:格式化、浮點數控制、字串連接、位址輸出與回傳值技巧
Copyright ©
程式碼之家 All Rights Reserved