在C/C++中的標準定義:c++
#ifdef __cplusplus //條件編譯,判斷是c++仍是c環境
#define NULL 0 //c++環境
#else
#define NULL ((void *)0) //c語言環境
#endif
#endif
在c語言中的NULL就被替換成了((void *)0),這個總體表示的是一個指針,便是指向0地址的viod類型的指針。安全
因此咱們能夠理解爲NULL的本質就是0,這個0要看作地址,便是0x00000000。編碼
NULL爲何出現,就得明白什麼是野指針了。spa
注:雖然C標準沒有說空指針與指向內存地址0的指針相同,可是分析以後是能夠這樣理解的。(NULL又稱爲空指針常量) 指針
又叫迷途指針,即指針指向的地址是隨機的。(不指向任何合法的對象的指針)code
指針變量在定義後,不去初始化。這個時候,值就是隨機的。這時候這個指針變量就是野指針。對象
好比在棧裏定義了一個指針變量,即棧給這個指針變量分配了一個內存,而這個內存裏存的值就是該指針指向的地址,然而棧是髒的(反覆使用,不擦除),並不知道地址裏存的什麼數,也就不知道指針指向了哪裏。 blog
指針變量在定義後,不去初始化,這個時候,值就是隨機的,即指向了隨機的一段內存。咱們再去解引用時,就是去訪問一個隨機地址,那麼會有什麼樣的後果也是未知的。內存
通常有三種狀況:字符串
①指向了不可訪問的地址(系統不容許訪問的地方)
這種狀況是最好的,由於程序會報段錯誤,沒法執行。
②指向了可用的,暫時沒有用到的地方(譬如程序沒有用到的堆棧地址)
這種狀況運行時沒問題,也不會報錯。可是實際上程序是有問題的,假如以後程序因爲野指針出現了bug,就死活找不到緣由了。
③指向了可用的,而且是程序中正在被使用的地方
這種狀況野指針的解引用可能就會致使指向的那段內存的值被修改,出現一些離奇的錯誤,致使程序崩潰,數據破壞,損壞。
第一種狀況就是
(不可訪問的地址)大型商隊保鏢太強,山賊(野指針)正準備搶劫就被幹掉了,並向後面(咱們)的商隊發出了警告
第二種狀況就是
(能夠訪問,暫時沒用使用的地址)小型商隊,山賊就直接搶了,暫時並不影響繞路的咱們。
第三種狀況就是
(程序正在使用)咱們的商隊,山賊可能搶的可能咱們無法活下去(程序崩潰)
在指針的解引用以前,必定確保指針指向一個絕對可用的空間。
這時候NULL出現的很及時,常規作法
①定義指針後,將指針初始化爲NULL。
②指針使用以前綁定一個可用地址。
③在指針解引用前,去判斷是否爲NULL。
④使用完,後賦值爲NULL。
1 int a = 1; 2 int *p = NULL; //定義指針並初始化爲NULL
3 p = &a; //綁定一個可用地址
4
5 if (NULL != p) //判斷是否不等於NULL
6 { 7 *p = 10; //解引用
8 } 9
10 p = NULL; //使用完,從新賦值爲NULL
注意(小技巧):
通常將判斷指針是否相等時,不寫成if (p == NULL),而寫成if (NULL == p),緣由是== 與 = 的誤錯,程序的意思會不同。等號少寫後,if (p = NULL)不會報錯,if (NULL = p)會報錯。
①讓野指針指向一個 '安全的0地址處'
大部分cpu中,內存0地址處不能隨便訪問的,因此避免野指針的誤傷,指向0地址後的使用就會報段錯誤。幫助咱們找錯誤。
②特殊標記,即增長程序的可讀性。
表示指針是個野指針。
①'\0'是個轉義字符,ASCII編碼值是0,本質就是0.
'\0'用法是C語言字符串的結尾標誌
②'0'是個字符,ASCII編碼值是48,便是48
'0'是字符0,獲取ASCII編碼值
③0是數字0,本質也是0
比較一個int類型的數字是否等於0,或者給變量賦值。
④NULL是個表達式((void *)0),強制轉換爲void * 的0,本質也是0
用來比較指針是不是一個野指針
做者:Devil-wei