指針加減整數**不是**普通數值運算,而是以**指向類型大小**為單位在內存中跳躍。本文通過案例演示指針增減、差值運算的規則與陷阱。
設指針 ptr,指向類型大小 S = sizeof(*ptr)。
ptr + n → 地址增加 n * S 字節。ptr - n → 地址減少 n * S 字節。ptr2 - ptr1 → 返回兩指針之間的**元素個數差** (需同類型、同數組)。char a[20];
int *ptr = (int*)a; // 強制轉換,不改變 a 類型
ptr++; // ptr 向高地址移動 sizeof(int)=4 字節
圖解: ptr 初指向 a[0..3],ptr++ 後指向 a[4..7]。
int arr[20] = {0};
int *ptr = arr;
for (int i=0; i<20; ++i) {
(*ptr)++; // 元素值 +1
ptr++; // 指針移到下一元素
}
char a[20] = "You_are_a_girl";
int *ptr = (int*)a;
ptr += 5; // 移動 5 * sizeof(int) = 20 字節,直接越過數組邊界
語法合法,但運行時訪問越界屬 UB,**程序員自負**。
char a[20] = "You_are_a_girl";
char *p = a;
char **ptr = &p; // ptr 指向 p (類型 char*)
問題: ptr++ 後 **ptr 輸出什麼?
o。a[4] → 輸出 a。ptr 類型 char**,指向類型 char* (大小 4/8 字節)。ptr++ 使地址 +4,新地址 &p + 4 **不再指向有效變量**。解引用導致**隨機值或崩潰**。教訓: 指針算術**完全由指針自身類型決定**,與它指向的變量內容無關。
ptrdiff_t,**元素個數差**。| 運算 | 條件 | 結果類型 | 含義 |
|---|---|---|---|
ptr + n | n 為整數 | 同指針類型 | 向高地址移 n 個元素 |
ptr - n | n 為整數 | 同指針類型 | 向低地址移 n 個元素 |
ptr2 - ptr1 | 同類型、同數組 | ptrdiff_t | 元素個數差 |
ptr1 + ptr2 | — | 非法 | 編譯錯誤 |
arr[i] 而非指針算術,可讀性更強。assert(ptr >= begin && ptr < end) 防越界。for (T *p = begin, *end = begin+N; p != end; ++p)。int* → char*) 後算術步長改變,**極易出錯**,封裝在內部函數並詳寫註釋。掌握指針算術的本質——**類型驅動的地址位移**,即可從容應對各種複雜指針場景。