*(p + i)與p[i]在語義上 100% 等價,C 標準定義p[i]即為*(p + i)的語法糖。編譯器生成**完全相同的機器指令**。
int a[10];
int *p = a; // p 指向 a[0]
// 訪問第 i 個元素
// 寫法 1:指針算術
int val1 = *(p + i); // 1. 計算 p + i (地址 + i * sizeof(int))
// 2. 解引用獲取值
// 寫法 2:下標運算符
int val2 = p[i]; // 編譯器內部直接轉換為 *(p + i)
// 寫法 3:數組下標
int val3 = a[i]; // a 退化為指針,同樣轉換為 *(a + i)
| 表達式 | 結合順序 | 等價寫法 |
|---|---|---|
*p + i | (*p) + i | 先解引用再加 i(值運算) |
*(p + i) | *(p + i) | 先指針加法再解引用(地址運算) |
p[i] | *(p + i) | 標準定義等價 |
p[i]:語義清晰「第 i 個元素」,可讀性最高。
for (int *ptr = arr; ptr != arr + n; ++ptr) {
process(*ptr); // 避免索引計算,極致性能場景微優
}
int *p; // +1 步長 4 字節 (sizeof(int))
double *q; // +1 步長 8 字節 (sizeof(double))
struct Node *r; // +1 步長 sizeof(Node)
無論寫 *(p+i) 還是 p[i],**指針類型決定內存步長**,這才是指針算術的靈魂。