博客 / 詳情

返回

指針空置類型-nullptr

先看一段代碼:

#include <iostream>
using namespace std;

void func(char* p) {
	cout << "void func(char* p)" << endl;
	cout << p << endl;
}

void func(int p) {
	cout << "void func(int p)" << endl;;
	cout << p << endl;
}

int main() {
	//int 
	func(10);
	//char*
	func(NULL);   //這裏我希望程序調用func(char* p)的函數

	system("pause");
	return 0;
}

輸出結果:

void func(int p)
10
void func(int p)
0

調用了兩次func(int p)函數,且按理説NULL指針是不能cout的

也就是説第二次調用func(NULL)也調用了一次func(int p) 並且傳入的p是0

原因:

在底層源碼中NULL這個宏是這樣定義的

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

也就是説如果源碼是C++程序NULL就是0,如果是C程序NULL表示(void*)0。那麼為什麼要這樣做呢? 是由於 C++ 中,void * 類型無法隱式轉換為其他類型的指針,此時使用 0 代替 ((void *)0),用於解決空指針的問題。這個0(0x0000 0000)表示的就是虛擬地址空間中的0地址,這塊地址是隻讀的。

正如:C++98/03 標準中,將一個指針初始化為空指針的方式有 2 種

char *ptr = 0;
char *ptr = NULL;

並且

	int* ptr1 = NULL;
	char* ptr2 = NULL;
	double* ptr3 = NULL;
	void* ptr4 = NULL;

	int* ptr5 = ptr4;//報錯:"void*"類型的值不能用於初始化"int*"類型的實體
	//是由於 C++ 中,void * 類型無法隱式轉換為其他類型的指針,此時使用 0 代替 ((void *)0),用於解決空指針的問題。
	int* ptr5 = (int*)ptr4; //強轉正確不報錯

C++11引入nullptr關鍵字用於標識空指針,是std::nullptr_t類型的(constexpr)變量。它可以轉換成任何指針類型和bool布爾類型(主要是為了兼容普通指針可以作為條件判斷語句的寫法),但是不能被轉換為整數。

nullptr是專用於初始化空類型指針,不同類型的指針變量都可以使用 nullptr 來初始化,nullptr 出現的目的是為了替代 NULL

#include <iostream>
using namespace std;

void func(char* p) {
	cout << "void func(char* p)" << endl;
	//cout << *p << endl;
}

void func(int p) {
	cout << "void func(int p)" << endl;;
	//cout << p << endl;
}

int main() {

	int* ptr1 = nullptr;
	char* ptr2 = nullptr;
	double* ptr3 = nullptr;
	void* ptr4 = nullptr;

	int* ptr5 = (int*)ptr4;

	//int 
	func(10);
	//char*
	func(nullptr);

	system("pause");
	return 0;
}

輸出結果:

void func(int p)
void func(char* p)

通過輸出的結果可以看出,nullptr 無法隱式轉換為整形,但是可以隱式匹配指針類型。在 C++11 標準下,相比 NULL 和 0,使用 nullptr 初始化空指針可以令我們編寫的程序更加健壯,因此當需要使用 NULL 時候,養成直接使用 nullptr的習慣。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.