突然想到這個有趣的問題: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.
源博客地址:http://blog.csdn.net/cc1949/article/details/51249555