摘要:和宋體標(biāo)準(zhǔn)不僅定義了指針空值常量,也定義了其指針空值類型,也就表示了指針空值類型并非僅有一個(gè)實(shí)例。標(biāo)準(zhǔn)嚴(yán)格規(guī)定了數(shù)據(jù)間的關(guān)系。
在C++程序開發(fā)中,為了提高代碼的健壯性,一般會(huì)在定義指針的同時(shí)會(huì)完成初始化操作(避免出現(xiàn)野指針),在指針指向尚未明確的情況下,都會(huì)給指針初始化為空指針。在C++98/03標(biāo)準(zhǔn)中,將一個(gè)指針初始化為空指針的方式有兩種:
char *my_ptr = 0;char *my_ptr = NULL;
在底層源碼中 NULL 這個(gè)宏是這樣定義的:
#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif#endif
可以看出,NULL可能被定義為字面常量0,或者是定義為無類型指針(void*)0
。
原因: 由于 C++ 中, void *
類型無法隱式轉(zhuǎn)換為其他類型的指針,此時(shí)使用 0 代替 ((void *)0)
,用于解決空指針的問題。這個(gè) 0(0x0000 0000)表示的就是虛擬地址空間中的 0 地址,這塊地址是只讀的。但是無論采用什么樣的定義方式,我們在使用空值的指針時(shí),都不可避免地會(huì)遇到一些麻煩;
如下代碼:
#include using namespace std;void fun(char *c){ cout << "void func(char *c)" << endl;}void fun(int i){ cout << "void func(int i)" << endl;}int main(){ // 想要調(diào)用重載函數(shù) void func(char *p) func(NULL); //注:如果使用gcc編譯,NULL轉(zhuǎn)化為內(nèi)部標(biāo)識 __null,該語句會(huì)編譯失敗 // 想要調(diào)用重載函數(shù) void func(int i) func(0); func((char*)0); return 0;}
輸出:
void func(int i)void func(int i)void func(char *c)
雖然調(diào)用func(NULL)
; 最終鏈接到的還是void func(int p)
和預(yù)期是不一樣的;
原因: C++ 中將NULL
定義為字面常量 0,并不能保證在所有場景下都能很好的工作,比如,函數(shù)重載時(shí),NULL
和 0 無法區(qū)分;
在C++11新標(biāo)準(zhǔn)中,出于兼容性的考慮,字面常量0的二義性并沒有被消除;但是新標(biāo)準(zhǔn)為二義性給出了新的答案,就是使用 nullptr
;在C++11 新標(biāo)準(zhǔn)中, nullptr
是一個(gè)所謂“指針空值類型”的常量;指針空值類型被命名為 nullptr_t
。
可以在支持 nullptr
的頭文件(csddef)中找到如下定義:
typedef decltype(nullptr) nullptr_t;
使用 nullptr_t
的時(shí)候必須#include(#include有些頭文件也會(huì)間接#include,比如),而 nullptr
則不用。
大概就是由于 nullptr
是關(guān)鍵字,而 nullptr_t
是通過 decltype
推導(dǎo)而來的緣故。
對上述程序進(jìn)行修改:
#include using namespace std;void fun(char *c){ cout << "void func(char *c)" << endl;}void fun(int i){ cout << "void func(int i)" << endl;}int main(){ //調(diào)用重載函數(shù) void func(char *p) func(nullptr); //調(diào)用重載函數(shù) void func(int i) func(0); return 0;}
結(jié)果:
void func(char *c)void func(int i)
可以看出,nullptr
無法隱式轉(zhuǎn)換為整形,但是可以隱式匹配指針類型。在 C++11 標(biāo)準(zhǔn)下,相比NULL
和 0,使用 nullptr
初始化空指針可以令我們編寫的程序更加健壯。
C++11標(biāo)準(zhǔn)不僅定義了指針空值常量nullptr
,也定義了其指針空值類型nullptr_t
,也就表示了指針空值類型并非僅有nullptr
一個(gè)實(shí)例。通常情況下,也可以通過nullptr_t
來聲明一個(gè)指針空值類型的變量(即使看起來用途不大)。
除去nullptr
及nullptr_t
以外,C++中還存在各種內(nèi)置類型。C++11標(biāo)準(zhǔn)嚴(yán)格規(guī)定了數(shù)據(jù)間的關(guān)系。常見的規(guī)則簡單地列在了下面:
①、所有定義為
nullptr_t
類型的數(shù)據(jù)都是等價(jià)的,行為也是完全一致。②、
nullptr_t
類型數(shù)據(jù)可以隱式轉(zhuǎn)換成任意一個(gè)指針類型。③、
nullptr_t
類型數(shù)據(jù)不能轉(zhuǎn)換為非指針類型,即使使用reinterpret_cast()的方式也是不可以的。 ④、
nullptr_t
類型數(shù)據(jù)不適用于算術(shù)運(yùn)算表達(dá)式。⑤、
nullptr_t
類型數(shù)據(jù)可以用于關(guān)系運(yùn)算表達(dá)式,但僅能與nullptr_t類型數(shù)據(jù)或者指針類型數(shù)據(jù)進(jìn)行比較,當(dāng)且僅當(dāng)關(guān)系運(yùn)算符為==、<=、>=等時(shí)返回true。
①、在C++11標(biāo)準(zhǔn)中,nullptr
類型數(shù)據(jù)所占用的內(nèi)存空間大小跟void*
相同的,即:
sizeof(nullptr_t) == sizeof(void*)
注:nullptr
是否是(void *)0
的一個(gè)別名?
不是,盡管兩者看起來很相似,都可以被轉(zhuǎn)換為任何類型的指針,但兩者在語法層面有著不同的內(nèi)涵。nullptr
是一個(gè)編譯時(shí)期的常量,它的名字是一個(gè)編譯時(shí)期的關(guān)鍵字,能夠?yàn)榫幾g器所識別。而(void*)0
只是一個(gè)強(qiáng)制轉(zhuǎn)換表達(dá)式,其返回的也是一個(gè) void *
指針類型。最為重要的是,在C++語言中,nullptr
到任何指針的轉(zhuǎn)換是隱式的,而 (void*)0
則必須經(jīng)過類型轉(zhuǎn)換后才能使用。
可以關(guān)注公眾號:Kevin的嵌入式學(xué)習(xí)站,創(chuàng)作不易,但您的點(diǎn)贊、關(guān)注、收藏就是對我最大的鼓勵(lì)!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/123502.html
文章目錄 前言extern C引用1.概念2.語法3.引用特性4.常量引用5.引用做函數(shù)返回值6.引用注意點(diǎn)7.傳值、傳引用效率比較 內(nèi)聯(lián)函數(shù)1.概念2.特性 auto關(guān)鍵字1.概念2.auto的使用細(xì)則3.auto不能推導(dǎo)的場景 基于范圍的for循環(huán)(C++11)使用條件 指針空值nullptr 前言 承接上文入門篇1,博主這次將會(huì)繼續(xù)更新以下內(nèi)容:extern ,引用 ,內(nèi)聯(lián), a...
摘要:在大型的工程中,自己定義的變量函數(shù),類名與其他人定義的相沖突等問題。使用標(biāo)準(zhǔn)輸出控制臺和標(biāo)準(zhǔn)輸入鍵盤時(shí),必須包含頭文件以及標(biāo)準(zhǔn)命名空間。缺省參數(shù)概念缺省參數(shù)是聲明或定義函數(shù)時(shí)為函數(shù)的參數(shù)指定一個(gè)默認(rèn)值。 目錄 前言 1.命名空間 1.1命名空間定義 1.2 命名空間使用 2. C++的輸入和...
摘要:第一步打開項(xiàng)目下的文件,在文件中輸入我們的函數(shù)的原型聲明代碼。這行代碼注冊一個(gè)原型為的函數(shù),當(dāng)這個(gè)函數(shù)被執(zhí)行的時(shí)候,我們的函數(shù)將被運(yùn)行時(shí)調(diào)用。原文地址開發(fā)擴(kuò)展之原生函數(shù)定義 在上一篇中我們在hellozapi擴(kuò)展中我們定義了幾個(gè)常量,但是一個(gè)有用的擴(kuò)展,必須得有函數(shù),沒有函數(shù)的擴(kuò)展啥用沒有,如果您覺得定義函數(shù)很難的話,您又錯(cuò)了,zendAPI就是為了讓您生活變得美好而生的,而不會(huì)讓事情...
閱讀 1628·2021-11-16 11:45
閱讀 2559·2021-09-29 09:48
閱讀 3327·2021-09-07 10:26
閱讀 1850·2021-08-16 10:50
閱讀 1883·2019-08-30 15:44
閱讀 2708·2019-08-28 18:03
閱讀 1908·2019-08-27 10:54
閱讀 1832·2019-08-26 14:01