野指針和空指針
在堆棧上配置設定的變量初始值是不确定的,也就是說指針p所指向的記憶體位址是不确定的,後面用*p通路不确定的位址就會導緻不确定的後果,如果導緻段錯誤還比較容易改正,如果意外改寫了資料而導緻随後的運作中出錯,就很難找到錯誤原因了。像這種指向不确定位址的指針稱為“野指針”(Unbound Pointer) ,為避免出現野指針,在定義指針變量時就應該給它明确的初值,或者把它初始化為NULL:
NULL在C标準庫的頭檔案stddef.h中定義:
就是把位址0轉換成指針類型,稱為空指針,它的特殊之處在于,作業系統不會把任何資料儲存在位址0及其附近,也不會把位址0~0xfff的頁面映射到實體記憶體,是以任何對位址0的通路都會立刻導緻段錯誤。 *p = 0;會導緻段錯誤,就像放在眼前的炸彈一樣很容易找到,相比之下,野指針的錯誤就像埋下地雷一樣,更難發現和排除,這次走過去沒事,下次走過去就有事。
void*
在程式設計時經常需要一種通用指針,可以轉換為任意其它類型的指針,任意其它類型的指針也可以轉換為通用指針,ANSI在将C語言标準化時引入了void *類型, void*指針與其它類型的指針之間可以隐式轉換,而不必用類型轉換運算符。注意,隻能定義void *指針,而不能定義void型的變量,因為void *指針和别的指針一樣都占4個位元組,而如果定義void型變量(也就是類型暫時不确定的變量),編譯器不知道該配置設定幾個位元組給變量。同樣道理, void*指針不能直接Dereference,而必須先轉換成别的類型的指針再做Dereference。 void *指針常用于函數接口。