記憶體與指標

指標算術

一旦你能指向陣列的某個元素,能順手指向下一個就很方便。指標算術正是這件事:把一個整數加到指標上,讓它沿著移動那麼多個元素;或把兩個指標相減,問「它們相隔幾個元素?」。這就是你在記憶體裡行走的方式。

關鍵規則是:指標算術以被指物的大小為單位縮放,而不是以位元組為單位。若 p 是 int *(且 int 為 4 位元組),那麼 p + 1 是往前 4 個位元組——它落在下一個 int 上,而不是下一個位元組。p + 3 前進 3 * 4 = 12 個位元組。這就是為什麼對任何型別 p + 1 都代表「下一個元素」:編譯器替你把整數乘上 sizeof(被指物)。相減也一樣:q - p 給出兩者之間的元素個數(型別為 ptrdiff_t),所以兩個相隔 12 位元組的 int 指標,q - p 是 3。你可以合法地計算陣列範圍內的位址、以及陣列結尾後一格的位址(當作不解參考的停止標記),但再往外踏一步,或對指向兩個不相關物件的指標做算術,都是未定義行為。

指標算術是陣列走訪與字串掃描背後的引擎。沿著 char * 用 *p++ 走到字串的結尾字元 '\0',或把一個指標從緩衝區的開頭掃到結尾,都是指標算術在運作——快,但只要你踏出被交付的物件範圍就毫不留情。

int a[3] = {10, 20, 30}; int *p = a; ——那麼 *(p + 2) 是 30,而 (p + 2) - p 是 2(相隔兩個 int,即使位址上差了 8 個位元組)。p + 1 前進的是 sizeof(int) = 4 個位元組,不是 1。

+1 代表一個元素;相減算的是元素個數,不是位元組數。

算術只在單一個陣列物件內(以及其結尾後一格)有定義。把指標跑到陣列之外,或比較指向不同配置的指標,即使原始位址恰好看起來相鄰,也是未定義行為——這是差一錯誤與緩衝區越界的常見來源。

又稱
pointer math指標運算