1. 程式人生 > >null和NULL和nullptr和””區別

null和NULL和nullptr和””區別

突然想到這個有趣的問題:C語言和C++對大小寫是敏感的,也就是說null和NULL是區別對待的。NULL代表空地址,null只是一個符號。便來深究,看了很多資料,總結如下:

其實null和NULL都是字串(沒啥區別,歡迎高手糾錯!),具體看它們巨集定義被定義成為什麼值。

在VS中NULL被定義為0,因為習慣上把巨集定義的所有字元都大寫,當把NULL它賦值給指標時意思為空,當然你也可以把null定義為0了,都一樣。

它們都沒定義時都只能叫符號了,定義後就有另外的意思了,你把0直接賦值給指標也行,只要指標指向0就為空。

其實NULL在有些編譯器中是賦為0了,這時你不能再去#define定義它了,否則就重定義了!

1,NULL

NULL的定義

[cpp]  

#ifdef __cplusplus  

#define NULL    0  

#else  

#define NULL    ((void *)0) 

#endif  

在C語言環境下,由於不存在函式過載等問題,直接將NULL定義為一個void*的指標就可以完美的解決一切問題。

但是在C++環境下情況就變得複雜起來,首先我們不能寫這樣的程式碼:

FILE* fp = (void*)0; //將void*直接賦值給一個指標是不合法的,編譯器會報錯。

我們只能這樣寫程式碼

[cpp]  

FILE* fp = (FILE*)0;

// or  

FILE* fp = 0;

/*

所以在C++中,NULL就被直接定義為一個整型0。在大多數情況下這並不會產生什麼問題。但是萬一有過載或者模板推導的時候,編譯器就無法給出正確結果了。比如下面的情形:

[cpp] 

voidcall_back_process(CCObject* target, void* data);  

bind(call_back_process,target, NULL); // error 函式型別是void* ,但是我們繫結的是一個整型 0。

 */

2,nullptr

C++11,其中有一個是新的關鍵字nullptr

如果我們的編譯器是支援nullptr的話,那麼我們應該直接使用nullptr來替代NULL的巨集定義。正常使用過程中他們是完全等價的。

模擬nullptr的實現:

某些編譯器不支援c++11的新關鍵字nullptr,我們也可以模擬實現一個nullptr

[cpp]

const  

class nullptr_t_t  

{  

public:  

    template<class T>          operator T*() const {return 0;}  

    template<class C, classT>  operator T C::*() const { return 0; }  

private:  

    void operator& () const; 

} nullptr_t = {};  

#undef NULL  

#define NULL nullptr_t  

3,“”

“”也表示空,但是和null有很大區別:null沒有分配空間,""分配了空間

String str1 = null;  //str引用為空

String str2 = "";  //str引用一個空串

也就是null沒有分配空間,""分配了空間,因此str1還不是一個例項化的物件,而str2已經例項化。


注意:

因為null不是物件,""是物件。所以比較的時候必須是 if(str1==null){...}和if(str2.equals("")){...}。

物件用equals比較,null用等號比較。

因此,如果str1=null;下面的寫法錯誤:

if(str1.equals("")||str1==null){//如果str1沒有值,則.... } 

正確的寫法是

if(str1==null||str1.equals("")){//先判斷是不是物件,如果是,再判斷是不是空字串}

打個比方:一個空玻璃杯,你不能說它裡面什麼都沒有,因為裡面有空氣,當然也可以把它弄成真空,null與" "的區別就象真空與空氣一樣。

Thanks.