C++ 笔记(28)— C++ 中 NULL和 nullptr 的区别
最近看公司代碼的時(shí)候發(fā)現(xiàn)在判斷指針是否為空的時(shí)候,有的時(shí)候用的是 NULL, 有的時(shí)候用的是 nullptr 感覺很奇怪,好奇心驅(qū)使我查了下兩者的區(qū)別,發(fā)現(xiàn)還是有很多細(xì)節(jié)需要學(xué)習(xí)的。
1. NULL 在 C/C++ 中的定義
先來看下 C99 是怎么定義 NULL 的:
NULL can be defined as any null pointer constant. Thus existing code can retain definitions of NULL as 0 or 0L, but an implementation may also choose to define it as (void*)0. This latter form of definition is convenient on architectures where sizeof(void*) does not equal the size of any integer type. It has never been wise to use NULL in place of an arbitrary pointer as a function argument, however, since pointers to different types need not be the same size. The library avoids this problem by providing special macros for the arguments to signal, the one library function that might see a null function pointer.
大意就是: NULL 可以定義為任何空指針常量。因此,現(xiàn)有的代碼可以保留 NULL 的定義為 0 或 0L (32位和64位的區(qū)別),或者直接就是由 0 或者 0L 轉(zhuǎn)成的成 void* 。
接下來我們來看下 C++ 14(N4296)中所定義的 null pointer。
A null pointer constant is an integer literal (2.13.2) with value zero or a prvalue of type std::nullptr_t.
A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type. Such a conversion is called a null pointer conversion. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion (4.4). A null pointer constant of integral type can be converted to a prvalue of type std::nullptr_t. [ Note: The resulting prvalue is not a null pointer value. —end note ]
第一句話大意是 空指針常量是一個(gè)值為 0 的整型字面值或一個(gè)類型為 std::nullptr_t 的 prvalue 。
2. C 中的 NULL
在 C 語言中,NULL 通常被定義為: #define NULL ((void *)0)
所以說 NULL 實(shí)際上是一個(gè)空指針,如果在 C 語言中寫入以下代碼,編譯是沒有問題的,因?yàn)樵?C語言中把空指針賦給 int 和 char 指針的時(shí)候,發(fā)生了隱式類型轉(zhuǎn)換,把 void 指針轉(zhuǎn)換成了相應(yīng)類型的指針。
int *pi = NULL;
char *pc = NULL;
3. C++ 中的 NULL
以上代碼如果使用 C++ 編譯器來編譯則是會(huì)出錯(cuò)的,因?yàn)?C++ 是強(qiáng)類型語言,void* 是不能隱式轉(zhuǎn)換成其他類型的指針的,所以實(shí)際上編譯器提供的頭文件做了相應(yīng)的處理:
#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif
在 C++ 中,NULL 實(shí)際上是 0。
因?yàn)?C++ 中不能把 void* 類型的指針隱式轉(zhuǎn)換成其他類型的指針,所以為了空指針的表示問題,C++引入了 0 來表示空指針,這樣就有了上述代碼中的 NULL 宏定義。
但是實(shí)際上,用 NULL 代替 0 表示空指針在函數(shù)重載時(shí)會(huì)出現(xiàn)問題,程序執(zhí)行的結(jié)果會(huì)與我們的想法不同,舉例如下:
#include <iostream>
using namespace std;void func(void* t)
{cout << "func1" << endl;
}void func(int i)
{cout << "func2" << endl;
}int main()
{func(NULL); return 0;
}
運(yùn)行后輸出結(jié)果:
main.cpp: In function ‘int main()’:
main.cpp:16:14: error: call of overloaded ‘func(NULL)’ is ambiguousfunc(NULL);
報(bào)錯(cuò)信息顯示有歧義。
3. C++ 中的 nullptr
為解決 NULL 代指空指針存在的二義性問題,也就是上面遇到的報(bào)錯(cuò)問題,在C++11 版本中特意引入了 nullptr 這一新的關(guān)鍵字來代指空指針,如下所示
#include <iostream>
using namespace std;void func(void* t)
{cout << "func1" << endl;
}void func(int i)
{cout << "func2" << endl;
}int main()
{func(nullptr); // func1return 0;
}
可以看到程序可以正常輸出與我們預(yù)期相同的結(jié)果。
4. 總結(jié)
NULL 在 C++ 中就是 0,這是因?yàn)樵?C++ 中 void* 類型是不允許隱式轉(zhuǎn)換成其他類型的,所以之前 C++ 中用 0 來代表空指針,但是在重載整形的情況下,會(huì)出現(xiàn)上述的問題。
所以,C++11 加入了 nullptr ,可以保證在任何情況下都代表空指針,而不會(huì)出現(xiàn)上述的情況。
因此,建議使用 nullptr 替代 NULL ,而 NULL 就當(dāng)做 0 使用。
參考:
https://blog.csdn.net/qq_18108083/article/details/84346655
總結(jié)
以上是生活随笔為你收集整理的C++ 笔记(28)— C++ 中 NULL和 nullptr 的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国文化创意产业园区
- 下一篇: 2022-2028年中国塑料鞋行业市场发