對於 int a[] = {1,2,3,4};:
a(陣列名稱)在絕大多數表達式中**退化為 int***,值為 &a[0](首元素地址)。&a 類型為 int(*)[4](指向整個陣列的指標),值同 a 但類型不同。sizeof(a) 為整個陣列大小(16 bytes),非指標大小。| 表示式 | 類型 | 意義 | 等價寫法 |
|---|---|---|---|
a | int* | 首元素地址 | &a[0] |
a + i | int* | 第 i 元素地址 | &a[i] |
*(a + i) | int | 第 i 元素值 | a[i] |
&a[i] | int* | 第 i 元素地址 | a + i |
int a[2] = {1, 2};
int* pb = a; // 指向開頭
int* pe = a + 2; // 指向結尾(尾後一位)
cout << a << "|" << a[0] << "|" << *(a+1) << "|" << pb << "|" << *pb << endl;
while (pb != pe) { // 指標比較判斷結束
cout << *pb << endl;
++pb; // 移動到下一個元素
}
指標類型攜帶元素類型資訊(int* 知曉 sizeof(int))。pb++ 實際增加 sizeof(int) 位元組,非單純 +1 位元組。這是 C/C++ 指標運算的核心設計。
int m[2][3] = {{1,2,3},{4,5,6}};
int (*p)[3] = m; // 指向含 3 int 陣列的指標
cout << p[1][2]; // 6,等價 m[1][2]
cout << *(*(p+1)+2); // 同樣 6
void foo(int arr[]) // 實為 void foo(int* arr)
void foo(int* arr) // 完全等價
void foo(int arr[10]) // 10 被忽略,仍為指標
**陣列大小資訊丟失**,函式內無法用 sizeof(arr) 取得元素數。**解決方案**:傳遞長度參數、使用標準容器、C++20 std::span。
| 誤區 | 正確認知 |
|---|---|
int* p = a; 以為複製了陣列 | 僅複製首元素地址,共享同一記憶體 |
sizeof(p) 以為得到陣列大小 | 得到指標大小(4/8 bytes),非陣列大小 |
以為 a++ 合法 | 陣列名稱非常數指標,不可修改(a = a+1 錯誤) |
以為 int a[] = b; 可複製陣列 | 不可用陣列初始化另一陣列,需 std::copy 或逐元素賦值 |
std::array(固定大小)、std::vector(動態大小),保留大小資訊、支援範圍 for、邊界檢查。data() 取得指標、size() 取得長度。std::span 提供非擁有權的陣列/容器視圖,完美替代 (ptr, len) 組合。陣列與指標的「退化」關係是 C/C++ 記憶體模型的基石。理解 a ≡ &a[0]、指標運算按元素大小位移、函式參數實為指標,能避免 90% 的陣列相關 Bug。現代開發應善用標準庫容器封裝底層細節,僅在必要時觸及裸指標。