日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

NULL、0、nullptr的区别?

發(fā)布時(shí)間:2025/6/15 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NULL、0、nullptr的区别? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
NULL、0、nullptr


1.C的NULL
在C語言中,我們使用NULL表示空指針,也就是我們可以寫如下代碼:
int *i = NULL;
foo_t *f = NULL;


實(shí)際上在C語言中,NULL通常被定義為如下:
#define NULL ((void *)0)
也就是說NULL實(shí)際上是一個(gè)void *的指針,然后吧void *指針賦值給int *和foo_t *的指針的時(shí)候,隱式轉(zhuǎn)換成相應(yīng)的類型。而如果換做一個(gè)C++編譯器來編譯的話是要出錯(cuò)的,因?yàn)镃++是強(qiáng)類型的,void *是不能隱式轉(zhuǎn)換成其他指針類型的,所以通常情況下,編譯器提供的頭文件會(huì)這樣定義NULL:


#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif


2.C++的0

因?yàn)镃++中不能將void *類型的指針隱式轉(zhuǎn)換成其他指針類型,而又為了解決空指針的問題,所以C++中引入0來表示空指針,這樣就有了類似上面的代碼來定義NULL。實(shí)際上C++的書都會(huì)推薦說C++中更習(xí)慣使用0來表示空指針而不是NULL,盡管NULL在C++編譯器下就是0。為什么C++的書都推薦使用0而不是NULL來表示空指針呢?我們看一個(gè)例子:

在foo.h文件中聲明了一個(gè)函數(shù):

void bar(sometype1 a, sometype2 *b);
?
這個(gè)函數(shù)在a.cpp、b.cpp中調(diào)用了,分別是:
a.cpp:

bar(a, b);

b.cpp:

bar(a, 0);
?
好的,這些代碼都是正常完美的編譯運(yùn)行。但是突然在某個(gè)時(shí)候我們功能擴(kuò)展,需要對(duì)bar函數(shù)進(jìn)行擴(kuò)展,我們使用了重載,現(xiàn)在foo.h的聲明如下:

void bar(sometype1 a, sometype2 *b);
void bar(sometype1 a, int i);
?
這個(gè)時(shí)候危險(xiǎn)了,a.cpp和b.cpp中的調(diào)用代碼這個(gè)時(shí)候就不能按照期望的運(yùn)行了。但是我們很快就會(huì)發(fā)現(xiàn)b.cpp中的0是整數(shù),也就是在overload resolution的時(shí)候,我們知道它調(diào)用的是void bar(sometype1 a, int i)這個(gè)重載函數(shù),于是我們可以做出如下修改讓代碼按照期望運(yùn)行:
bar(a, static_cast<sometype2 *>(0));


我知道,如果我們一開始就有bar的這兩個(gè)重載函數(shù)的話,我們會(huì)在一開始就想辦法避免這個(gè)問題(不使用重載)或者我們寫出正確的調(diào)用代碼,然而后面的這個(gè)重載函數(shù)或許是我們幾個(gè)月或者很長(zhǎng)一段時(shí)間后加上的話,那我們出錯(cuò)的可能性就會(huì)加大了不少。貌似我們現(xiàn)在說道的這些跟C++通常使用0來表示空指針沒什么關(guān)系,好吧,假設(shè)我們的調(diào)用代碼是這樣的:

foo.h

void bar(sometype1 a, sometype2 *b);

a.cpp
bar(a, b);
b.cpp
bar(a, NULL);


當(dāng)bar的重載函數(shù)在后面加上來了之后,我們會(huì)發(fā)現(xiàn)出錯(cuò)了,但是出錯(cuò)的時(shí)候,我們找到b.cpp中的調(diào)用代碼也很快可能忽略過去了,因?yàn)槲覀冇玫氖荖ULL空指針啊,應(yīng)該是調(diào)用的void bar(sometype1 a, sometype2 *b)這個(gè)重載函數(shù)啊。實(shí)際上NULL在C++中就是0,寫NULL這個(gè)反而會(huì)讓你沒那么警覺,因?yàn)镹ULL不夠“明顯”,而這里如果是使用0來表示空指針,那就會(huì)夠“明顯”,因?yàn)?是空指針,它更是一個(gè)整形常量。

在C++中,使用0來做為空指針會(huì)比使用NULL來做空指針會(huì)讓你更加警覺。

3.C++ 11的nullptr

雖然上面我們說明了0比NULL可以讓我們更加警覺,但是我們并沒有避免這個(gè)問題。這個(gè)時(shí)候C++ 11的nullptr就很好的解決了這個(gè)問題,我們?cè)贑++ 11中使用nullptr來表示空指針,這樣最早的代碼是這樣的,

foo.h
void bar(sometype1 a, sometype2 *b);
a.cpp
bar(a, b);
b.cpp
bar(a, nullptr);
在我們后來把bar的重載加上了之后,代碼是這樣:

foo.h

void bar(sometype1 a, sometype2 *b);
void bar(sometype1 a, int i);
a.cpp

bar(a, b);

b.cpp

bar(a, nullptr);

這時(shí)候,我們的代碼還是能夠如預(yù)期的一樣正確運(yùn)行。

在沒有C++ 11的nullptr的時(shí)候,我們?cè)趺唇鉀Q避免這個(gè)問題呢?我們可以自己實(shí)現(xiàn)一個(gè)(《Imperfect C++》上面有一個(gè)實(shí)現(xiàn)):

const
class nullptr_t
{
public:
? ? template<class T>
? ? inline operator T*() const
? ? ? ? { return 0; }


? ? template<class C, class T>
? ? inline operator T C::*() const
? ? ? ? { return 0; }
?
private:
? ? void operator&() const;
} nullptr = {};
?
雖然這個(gè)東西被大家討論過很多次了,但是我覺得還是有必要再討論一下,畢竟在C++ 11還沒有普及之前,我們還是應(yīng)該知道怎么去避免問題,怎么很快的找到問題。

總結(jié)

以上是生活随笔為你收集整理的NULL、0、nullptr的区别?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。