許多開發者在轉換語言(Java、C#)多年後重拾 C/C++,最容易栽在指標運算上。這道經典面試題完美揭示了 &a(陣列指標)與 a(首元素指標)在指標位移時的本質差異。
int main(int argc, char *argv[]) {
int a[] = {1,2,3,4,5};
int* p = (int*)(&a + 1);
cout << "a = " << *(a+1) << endl;
cout << "p = " << *(p-1) << endl;
return 0;
}
a = 2
p = 5
| 運算式 | 類型 | 位移單位 | 實際位址變化 |
|---|---|---|---|
a | int*(指向首元素) | sizeof(int) | a+1 指向 a[1] |
&a | int(*)[5](指向整個陣列) | 5*sizeof(int) | &a+1 指向陣列結尾 a[5] |
p = (int*)(&a+1) | 強制轉為 int* | sizeof(int) | p-1 退回一個 int 大小,落在 a[4](值 5) |
&a 是「陣列指標」,+1 跨越整個陣列;轉為 int* 後,-1 僅退一個 int。a、&a、&a[0] 數值相等,但編譯器眼中類型截然不同。void* 或強制轉型掩蓋邏輯錯誤。「C/C++ 的指標運算看似簡單,實則暗藏類型系統的精妙設計。搞懂這道題,才算真正踏入指標的大門。」