NULL和nullptr的區別與聯絡

2021-08-14 11:02:29 字數 3123 閱讀 2957

1、空指標,null pointer,不指向任何物件,在試圖使用乙個指標之前必須要檢查這個指標是不是空指標。

2、舉例子:

int *p1=nullptr;     等價於: int *p1=0;    // 直接將 p1 初始化為字面值常量 nullptr 或者 字面值常量 0。

int *p2=null;      等價於:int *p2=0;

int *p3=0;           

3、null 是乙個預處理器變數,在標頭檔案 cstdlib 中定義為 0 值。預處理器是執行在編譯過程之前的一段程式,預處理變數不屬於命名空間 std,它是由預處理器負責管理。當用到乙個預處理變數時,在編譯時,預處理器會自動把它替換為實際值,因此使用 null 初始化指標和使用 0 初始化指標是一樣的。

nullptr 是乙個字面值常量,它可以被轉化為任何其他型別的指標。

另外,把int 型變數直接賦值給指標是錯誤的操作,即使int 型變數等於0 也不行!

int zero=0;    int *p=zero;    (錯誤,不能把int 型變數直接賦值給指標!)

1、測試1:

[cpp]view plain

copy

#include 

using

namespace

std;  

void

go(int

num)  

cout<<"go num"

<

void

go(char

*p)  

cout"go p"

<

void

main()    

2、測試2:(  null是0。nullptr是空指標void*。)

[cpp]view plain

copy

#include 

using

namespace

std;  

void

go(int

num)  

cout<<"go num"

<

void

go(void

*p)  

cout<<"go p"

<

intmain()    

3、在強調一下,null 在c++中的定義僅僅是 0,僅此而已。

4、參考:

(1)引出話題:

有人喜歡使用null作為空指標常量使用,例如:int* p = null;

也有人直接使用0值作為空指標常量,例如:int* p = 0;

前者可能覺得:null作為空指標常量,名字很形象,可讀性較強。後者可能覺得:null並不是c/c++語言的關鍵字,而是乙個在

標準庫標頭檔案中定義的巨集,因此要使用null,可能需要直接或簡介地包含標頭檔案,比較麻煩。

(2)null是乙個巨集,在c/c++標準中,它的值只乙個空指標常量(null pointer constant)。

而在c語言中,常數0 和(void *)0 都是空指標常量。c++中(暫且忽略c++11新標準),常數0 是,但(void *)0 不是。

以gcc的巨集定義為例:

[cpp]view plain

copy

#if defined(__cplusplus)

# define null 0    // c++中使用0作為null的值

#else

# define null ((void *)0)    // c中使用((void *)0)作為null的值

#endif

(3)為什麼c 中 (void*)0 是空指標常量,而c++中不是?

答:因為c 語言中任何型別的指標都可以(隱式地)轉換為 void* 型,反過來也行。

而c++ 中void* 型不能隱式地轉換為別的型別指標(例如:int  *p = (void *) 0;  使用c++編譯器編譯會報錯)。

既然c/c++標準中,常數0 都可作為空指標常量,為什麼不統一使用0?

答:個人覺得由於(void*)0 更能體現指標的意義,而常數0 更多的時候是用作整數。

因此,c語言中null 定義選擇了(void *) 0。(僅供參考)

(4)c++11中為什麼要引入nullptr?

考慮著這樣乙個函式過載的情形:

[cpp]view plain

copy

#include 

void

foo(

int) {}     

// #1

void

foo(

char

*) {}   

// #2

intmain()    

從字面上來講,null是個空指標常量,我們可能會覺得:既然是個指標,那麼應該呼叫#2。但事實上呼叫的卻是#1,因為c++中null擴充套件為常數0,它是int型。

根本原因就是:常數0既是整數常量,也是空指標常量。

為了解決這種二義性,c++11標準引入了關鍵字nullptr,它作為一種空指標常量。

[cpp]view plain

copy

void

foo(

int) {}     

// #1

void

foo(

char

*) {}   

// #2

intmain()    

[cpp]view plain

copy

再簡化一點就是  

void

f(int

i)  

void

f(int

*p)  

呼叫f(null)  

gcc編譯會提示過載歧義  

呼叫f(nullptr)一切正常  

結論:  如果使用 nullptr 初始化物件,就能避免 0 指標的二義性的問題。

NULL和nullptr的區別

null是0 nullptr是空指標void include void go int num void go char p void main 在看例子就比較清晰了 void go int num void go void p int main 結果 1 在c語言中null代表空指標。例如 int ...

NULL和nullptr的區別

欲善其事,必先利其器 首先要知道表示空指標有兩種方法,1.是null 2.是c 11推出的nullptr。那為什麼c c 有了null,為什麼還要在c 11中推出nullptr呢?在c語言中,null被定義為 define null void 0 在核心為巨集定義。首先需要了解巨集定義在程式的中的使...

C 中NULL和nullptr的區別

看起來null和nullptr都是代表空指標,但是null在過載函式的時候卻匹配到了引數為int的那個版本。這是因為在c 中,null的定義一般是這樣的 ifdef cplusplus define null 0 else define null void 0 endif cplusplus 可以看...