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

C 指標步進深度解析:型別決定步長、void* 限制與強制轉換陷阱

     編輯:Java 程式設計入門

核心原則:指標算術由「所指型別大小」決定

C 語言中,指標不是單純位址數值,而是「型別 + 位址」的複合體。p + n 表示移動 n * sizeof(*p) 位元組,而非 n 位元組。

陷阱一:錯誤手動乘以 sizeof

int ar[5] = {0,1,2,3,4};
int *p = ar;
printf("%d", *(p + 3 * sizeof(int))); // 錯誤!

分析: p + 3 * 4 = p + 12,指向第 13 個 int (陣列只有 5 個),越界存取未定義行為。

正確寫法: *(p + 3) → 編譯器自動轉為 p + 3 * sizeof(int),正確指向 ar[3] (值 3)。

陷阱二:指標型別轉換與左值/右值

需求:char *p 指向 int,想跳過該 int 指向下一個 char。

錯誤嘗試

((int *)p)++; // 無效!

原因: 強制轉換 (int *)p 結果是右值 (暫時值),++ 需要左值 (可賦值變數)。實際運作的是原 p (char*),步長仍為 1 位元組。

正確做法

p += sizeof(int); // char* 步長 1,加 4 位元組正好跳過一個 int

或使用中介變數:

int *ip = (int *)p;
ip++;
p = (char *)ip;

陷阱三:void* 無法算術運算

void *vp = malloc(100);
vp + 10; // 編譯錯誤:error C2036: 'void *': unknown size

原因: void 無大小,編譯器無法計算步長。C 標準規定 void* 不支援指標算術。

解法: 轉為具體型別指標:(char *)vp + 10 或 (int *)vp + 10。

進階:指標差值運算

int arr[10];
int *p1 = &arr[2];
int *p2 = &arr[7];
ptrdiff_t diff = p2 - p1; // 結果 = 5 (元素個數),非位元組數

指標相減結果型別為 ptrdiff_t (有號整數),表示元素間距。

最佳實踐總結

  1. 永遠信任編譯器自動計算步長:寫 p + n,勿手動乘 sizeof
  2. 指標型別必須匹配所指資料:錯誤型別導致步長錯誤、存取錯誤
  3. void* 僅作通用持有,運算前必須轉型
  4. 理解左值/右值:轉型表達式不可作為 ++/--/= 左值
  5. 使用 uintptr_t/intptr_t 做整數運算:需位元組級操作時,轉整數運算再轉回

指標算術是 C/C++ 核心亦是最大坑源。牢記「型別決定步長」,拒絕手動計算,讓編譯器守護正確性。

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