C++ 笔记(28)— C++ 中 NULL和 nullptr 的区别
最近看公司代碼的時候發現在判斷指針是否為空的時候,有的時候用的是 NULL, 有的時候用的是 nullptr 感覺很奇怪,好奇心驅使我查了下兩者的區別,發現還是有很多細節需要學習的。
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 可以定義為任何空指針常量。因此,現有的代碼可以保留 NULL 的定義為 0 或 0L (32位和64位的區別),或者直接就是由 0 或者 0L 轉成的成 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 ]
第一句話大意是 空指針常量是一個值為 0 的整型字面值或一個類型為 std::nullptr_t 的 prvalue 。
2. C 中的 NULL
在 C 語言中,NULL 通常被定義為: #define NULL ((void *)0)
所以說 NULL 實際上是一個空指針,如果在 C 語言中寫入以下代碼,編譯是沒有問題的,因為在 C語言中把空指針賦給 int 和 char 指針的時候,發生了隱式類型轉換,把 void 指針轉換成了相應類型的指針。
int *pi = NULL;
char *pc = NULL;
3. C++ 中的 NULL
以上代碼如果使用 C++ 編譯器來編譯則是會出錯的,因為 C++ 是強類型語言,void* 是不能隱式轉換成其他類型的指針的,所以實際上編譯器提供的頭文件做了相應的處理:
#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif
在 C++ 中,NULL 實際上是 0。
因為 C++ 中不能把 void* 類型的指針隱式轉換成其他類型的指針,所以為了空指針的表示問題,C++引入了 0 來表示空指針,這樣就有了上述代碼中的 NULL 宏定義。
但是實際上,用 NULL 代替 0 表示空指針在函數重載時會出現問題,程序執行的結果會與我們的想法不同,舉例如下:
#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;
}
運行后輸出結果:
main.cpp: In function ‘int main()’:
main.cpp:16:14: error: call of overloaded ‘func(NULL)’ is ambiguousfunc(NULL);
報錯信息顯示有歧義。
3. C++ 中的 nullptr
為解決 NULL 代指空指針存在的二義性問題,也就是上面遇到的報錯問題,在C++11 版本中特意引入了 nullptr 這一新的關鍵字來代指空指針,如下所示
#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;
}
可以看到程序可以正常輸出與我們預期相同的結果。
4. 總結
NULL 在 C++ 中就是 0,這是因為在 C++ 中 void* 類型是不允許隱式轉換成其他類型的,所以之前 C++ 中用 0 來代表空指針,但是在重載整形的情況下,會出現上述的問題。
所以,C++11 加入了 nullptr ,可以保證在任何情況下都代表空指針,而不會出現上述的情況。
因此,建議使用 nullptr 替代 NULL ,而 NULL 就當做 0 使用。
參考:
https://blog.csdn.net/qq_18108083/article/details/84346655
總結
以上是生活随笔為你收集整理的C++ 笔记(28)— C++ 中 NULL和 nullptr 的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国文化创意产业园区
- 下一篇: 2022-2028年中国塑料鞋行业市场发