首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

不再害怕指針(二):指針算術運算完全指南

     編輯:關於C語言

前言

指針加減整數**不是**普通數值運算,而是以**指向類型大小**為單位在內存中跳躍。本文通過案例演示指針增減、差值運算的規則與陷阱。

基本規則

設指針 ptr,指向類型大小 S = sizeof(*ptr)。

  • ptr + n → 地址增加 n * S 字節。
  • ptr - n → 地址減少 n * S 字節。
  • ptr2 - ptr1 → 返回兩指針之間的**元素個數差** (需同類型、同數組)。

案例 1:int 指針遍歷 char 數組

char a[20];
int *ptr = (int*)a; // 強制轉換,不改變 a 類型
ptr++; // ptr 向高地址移動 sizeof(int)=4 字節

圖解: ptr 初指向 a[0..3],ptr++ 後指向 a[4..7]。

案例 2:指針遍歷數組

int arr[20] = {0};
int *ptr = arr;
for (int i=0; i<20; ++i) {
    (*ptr)++; // 元素值 +1
    ptr++;    // 指針移到下一元素
}

案例 3:大步長跳躍

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 輸出什麼?

  • 誤區 A:以為步長 1 → 輸出 o。
  • 誤區 B:以為步長 4 指向 a[4] → 輸出 a。
  • 正解: ptr 類型 char**,指向類型 char* (大小 4/8 字節)。ptr++ 使地址 +4,新地址 &p + 4 **不再指向有效變量**。解引用導致**隨機值或崩潰**。

教訓: 指針算術**完全由指針自身類型決定**,與它指向的變量內容無關。

指針差值運算

  • 同類型、指向同一數組的指針相減 → 返回 ptrdiff_t,**元素個數差**。
  • 不同數組、不同類型相減 → **未定義行為**。
  • 指針**不能相加** (無意義),只能減。

總結速記表

運算條件結果類型含義
ptr + nn 為整數同指針類型向高地址移 n 個元素
ptr - nn 為整數同指針類型向低地址移 n 個元素
ptr2 - ptr1同類型、同數組ptrdiff_t元素個數差
ptr1 + ptr2—非法編譯錯誤

最佳實踐

  1. 優先使用下標 arr[i] 而非指針算術,可讀性更強。
  2. 必須用指針算術時,配合 assert(ptr >= begin && ptr < end) 防越界。
  3. 遍歷數組推薦:for (T *p = begin, *end = begin+N; p != end; ++p)。
  4. 異構指針轉換 (int* → char*) 後算術步長改變,**極易出錯**,封裝在內部函數並詳寫註釋。

掌握指針算術的本質——**類型驅動的地址位移**,即可從容應對各種複雜指針場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved