🦄個人主頁:小米里的大麥-CSDN博客
🎏所屬專欄:C++_小米里的大麥的博客-CSDN博客
🎁代碼托管:C++: 探索C++編程精髓,打造高效代碼倉庫 (gitee.com)
??操作環境:Visual Studio 2022
目錄
1. 0 和空指針
2. NULL
3. nullptr
總結?
共勉
在C/C++中,0
、NULL
和 nullptr
都表示指針的空值,但它們有不同的語義和使用場景。
1. 0
和空指針
在C和C++98中,數字 0
常常被用作空指針的表示。因為C語言規定整型常量 0
可以隱式轉換為任意類型的指針值,所以使用 0
作為空指針值是合法的。
int* p1 = 0; // 合法,p1 是空指針
但是,使用 0
來表示空指針時,代碼的可讀性和可維護性較差,因為 0
既可以表示數值也可以表示指針。因此C++引入了 NULL
來代替 0
。
2. NULL
NULL
是在C語言的標準頭文件 <stddef.h>
或 C++ 的 <cstddef>
中定義的宏,通常定義為 ((void*)0)
或單純的 0
。在C++98中,它仍然可能會與整型 0
混淆,因為它本質上是 0
。
/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else /* __cplusplus */
#define NULL ((void *)0)
#endif /* __cplusplus */
#endif /* NULL */
使用 NULL
來表示空指針可以提高代碼的可讀性,避免誤將數字 0
和指針值混淆。 但因為 NULL
是宏,使用它仍然有一些潛在的問題,尤其是當函數重載涉及不同類型時。
#include <iostream>void Fun(int p) {std::cout << "Fun(int)" << std::endl;
}void Fun(int* p) {std::cout << "Fun(int*)" << std::endl;
}int main() {Fun(0); // 調用 Fun(int)Fun(NULL); // 調用 Fun(int) 因為 NULL 被定義為 0
}
在這個例子中,Fun(NULL) 實際上調用了 Fun(int),而不是期望的 Fun(int*),因為 NULL 被解釋為 0。
3. nullptr
為了解決 0
和 NULL
的這些問題,C++11 引入了新的關鍵字 nullptr
,這是一個明確的空指針類型,可以確保它只能用于指針上下文中。
int* p1 = nullptr; // p1 是空指針
與 0
和 NULL
不同,nullptr
是類型安全的,不能被隱式轉換為其他類型(如整型)。它不會產生函數重載歧義問題,因此推薦在C++11及之后的代碼中使用 nullptr
。
#include <iostream>void Fun(int p) {std::cout << "Fun(int)" << std::endl;
}void Fun(int* p) {std::cout << "Fun(int*)" << std::endl;
}int main() {Fun(nullptr); // 明確調用 Fun(int*)
}
總結?
雖然他們三者區別并不大,但是,在一些特殊情況還是需要進行區分使用的。
0
:C/C++98中,既可表示整數值,也可表示空指針,但可能產生混淆。NULL
:通過宏定義來表示空指針,雖然提高了可讀性,但依然可能與整型0
混淆。nullptr
:C++11引入,明確表示空指針,解決了0
和NULL
的問題,推薦使用。
在現代C++中,優先使用 nullptr
來表示空指針,確保代碼更安全和清晰。