C++11中l(wèi)onglong超長整型和nullptr初始化空指針
本文介紹 C++11 標(biāo)準(zhǔn)中新添加的 long long 超長整型和 nullptr 初始化空指針。
1. C++11:long long 超長整型
C++ 11 標(biāo)準(zhǔn)中,基于整數(shù)大小的考慮,共提供了如下表所示的這些數(shù)據(jù)類型。與此同時(shí),標(biāo)準(zhǔn)中還明確限定了各個(gè)數(shù)據(jù)類型最少占用的位數(shù)。
| 整數(shù)類型 | 等價(jià)類型 | C++11標(biāo)準(zhǔn)規(guī)定占用最少位數(shù) |
|---|---|---|
| short | short int(有符號短整型) | 至少 16 位(2 個(gè)字節(jié)) |
| signed short | short int(有符號短整型) | 至少 16 位(2 個(gè)字節(jié)) |
| signed short int | short int(有符號短整型) | 至少 16 位(2 個(gè)字節(jié)) |
| unsigned short | unsigned short int(無符號短整型) | 至少 16 位(2 個(gè)字節(jié)) |
| unsigned short int | unsigned short int(無符號短整型) | 至少 16 位(2 個(gè)字節(jié)) |
| int | int(有符號整形) | 至少 16 位(2 個(gè)字節(jié)) |
| signed | int(有符號整形) | 至少 16 位(2 個(gè)字節(jié)) |
| signed int | int(有符號整形) | 至少 16 位(2 個(gè)字節(jié)) |
| unsigned | unsigned int(無符號整形) | 至少 16 位(2 個(gè)字節(jié)) |
| unsigned int | unsigned int(無符號整形) | 至少 16 位(2 個(gè)字節(jié)) |
| long | long int(有符號長整形) | 至少 32 位(4 個(gè)字節(jié)) |
| long int | long int(有符號長整形) | 至少 32 位(4 個(gè)字節(jié)) |
| signed long | long int(有符號長整形) | 至少 32 位(4 個(gè)字節(jié)) |
| signed long int | long int(有符號長整形) | 至少 32 位(4 個(gè)字節(jié)) |
| unsigned long | unsigned long int(無符號長整形) | 至少 32 位(4 個(gè)字節(jié)) |
| unsigned long int | unsigned long int(無符號長整形) | 至少 32 位(4 個(gè)字節(jié)) |
| long long(C++11) | long long int(有符號超長整形) | 至少 64 位(8 個(gè)字節(jié)) |
| long long int(C++11) | long long int(有符號超長整形) | 至少 64 位(8 個(gè)字節(jié)) |
| signed long long(C++11) | long long int(有符號超長整形) | 至少 64 位(8 個(gè)字節(jié)) |
| signed long long int(C++11) | long long int(有符號超長整形) | 至少 64 位(8 個(gè)字節(jié)) |
| unsigned long long(C++11) | unsigned long long int(無符號超長整型) | 至少 64 位(8 個(gè)字節(jié)) |
| unsigned long long int(C++11) | unsigned long long int(無符號超長整型) | 至少 64 位(8 個(gè)字節(jié)) |
C++11 標(biāo)準(zhǔn)規(guī)定,每種整數(shù)類型必須同時(shí)具備有符號(signed)和無符號(unsigned)兩種類型,且每種具體的有符號整形和無符號整形所占用的存儲空間(也就是位數(shù))必須相同。不過需要注意的是,C++11 標(biāo)準(zhǔn)中只限定了每種類型最少占用多少存儲空間,不同的平臺可以占用不同的存儲空間。
在上表羅列的這些數(shù)據(jù)類型中,long long 超長整型是 C++ 11 標(biāo)準(zhǔn)新添加的。其實(shí)早在 1995 年,就有人提議將 long long 整形寫入 C++ 98 標(biāo)準(zhǔn),但被委員會拒絕了。而后 long long 整形被 C99 標(biāo)準(zhǔn)(C語言標(biāo)準(zhǔn)之一)采納,并逐漸被很多編譯器支持,于是 C++ 標(biāo)準(zhǔn)委員會重新決定將 long long 整形寫入 C++ 11 標(biāo)準(zhǔn)中。
如同 long 類型整數(shù)需明確標(biāo)注 "L" 或者 "l" 后綴一樣,要使用 long long 類型的整數(shù),也必須標(biāo)注對應(yīng)的后綴:
- 對于有符號 long long 整形,后綴用 "LL" 或者 "ll" 標(biāo)識。例如,"10LL" 就表示有符號超長整數(shù) 10;
- 對于無符號 long long 整形,后綴用 "ULL"、"ull"、"Ull" 或者 "uLL" 標(biāo)識。例如,"10ULL" 就表示無符號超長整數(shù) 10。
如果不添加任何標(biāo)識,則所有的整數(shù)都會默認(rèn)為 int 類型。
對于 long long 類型來說,如果想了解當(dāng)前平臺上 long long 整形的取值范圍,可以使用<climits>頭文件中與 long long 整形相關(guān)的 3 個(gè)宏,分別為 LLONG_MIN、LLONG_MAX 和 ULLONG_MIN:
1)LLONG_MIN:代表當(dāng)前平臺上最小的 long long 類型整數(shù);
2)LLONG_MAX:代表當(dāng)前平臺上最大的 long long 類型整數(shù);
3)ULLONG_MIN:代表當(dāng)前平臺上最大的 unsigned long long 類型整數(shù)(無符號超長整型的最小值為 0)。
舉個(gè)例子:
#include <iostream>
#include <iomanip>
#include <climits>
using namespace std;
int main()
{
cout <<"long long最大值:" << LLONG_MIN <<" "<< hex << LLONG_MIN <<"\n";
cout << dec <<"long long最小值:" << LLONG_MAX << " " << hex << LLONG_MAX << "\n";
cout << dec << "unsigned long long最大值:" << ULLONG_MAX << " " << hex << ULLONG_MAX;
return 0;
}程序執(zhí)行結(jié)果為(不唯一):
long long最大值:-9223372036854775808 8000000000000000 long long最小值:9223372036854775807 7fffffffffffffff unsigned long long最大值:18446744073709551615 ffffffffffffffff
此程序中,輸出了各最大值和最小值對應(yīng)的十六進(jìn)制,顯然在當(dāng)前平臺(Windows10 64位操作系統(tǒng))上,long long 超長整型占用 64 位(也就是 16 個(gè)字節(jié))的存儲空間。
2. C++11:nullptr 初始化空指針
實(shí)際開發(fā)中,避免產(chǎn)生“野指針”最有效的方法,就是在定義指針的同時(shí)完成初始化操作,即便該指針的指向尚未明確,也要將其初始化為空指針。
所謂“野指針”,又稱“懸掛指針”,指的是沒有明確指向的指針。野指針往往指向的是那些不可用的內(nèi)存區(qū)域,這就意味著像操作普通指針那樣使用野指針(例如 &p),極可能導(dǎo)致程序發(fā)生異常。
C++98/03 標(biāo)準(zhǔn)中,將一個(gè)指針初始化為空指針的方式有 2 種:
int *p = 0; int *p = NULL; //推薦使用
可以看到,我們可以將指針明確指向 0(0x0000 0000)這個(gè)內(nèi)存空間。一方面,明確指針的指向可以避免其成為野指針;另一方面,大多數(shù)操作系統(tǒng)都不允許用戶對地址為 0 的內(nèi)存空間執(zhí)行寫操作,若用戶在程序中嘗試修改其內(nèi)容,則程序運(yùn)行會直接報(bào)錯(cuò)。
相比第一種方式,我們更習(xí)慣將指針初始化為 NULL。值得一提的是,NULL 并不是 C++ 的關(guān)鍵字,它是 C++ 為我們事先定義好的一個(gè)宏,并且它的值往往就是字面量 0(#define NULL 0)。
C++ 中將 NULL 定義為字面常量 0,雖然能滿足大部分場景的需要,但個(gè)別情況下,它會導(dǎo)致程序的運(yùn)行和我們的預(yù)期不符。例如:
#include <iostream>
using namespace std;
void isnull(void *c){
cout << "void*c" << endl;
}
void isnull(int n){
cout << "int n" << endl;
}
int main() {
isnull(0);
isnull(NULL);
return 0;
}程序執(zhí)行結(jié)果為:
int n
int n
對于 isnull(0) 來說,顯然它真正調(diào)用的是參數(shù)為整形的 isnull() 函數(shù);而對于 isnull(NULL),我們期望它實(shí)際調(diào)用的是參數(shù)為 void*c 的 isnull() 函數(shù),但觀察程序的執(zhí)行結(jié)果不難看出,并不符合我們的預(yù)期。
C++ 98/03 標(biāo)準(zhǔn)中,如果我們想令 isnull(NULL) 實(shí)際調(diào)用的是 isnull(void* c),就需要對 NULL(或者 0)進(jìn)行強(qiáng)制類型轉(zhuǎn)換:
isnull( (void*)NULL ); isnull( (void*)0 );
如此,才會成功調(diào)用我們預(yù)期的函數(shù)。
由于 C++ 98 標(biāo)準(zhǔn)使用期間,NULL 已經(jīng)得到了廣泛的應(yīng)用,出于兼容性的考慮,C++11 標(biāo)準(zhǔn)并沒有對 NULL 的宏定義做任何修改。為了修正 C++ 存在的這一 BUG,C++ 標(biāo)準(zhǔn)委員會最終決定另其爐灶,在 C++11 標(biāo)準(zhǔn)中引入一個(gè)新關(guān)鍵字,即 nullptr。
在使用 nullptr 之前,需保證自己使用的編譯器支持該關(guān)鍵字。以 Visual Studio 和 codeblocks 為例,前者早在 2010 版本就對 C++ 11 標(biāo)準(zhǔn)中的部分特性提供了支持,其中就包括 nullptr;如果使用后者,則需將其 G++ 編譯器版本至少升級至 4.6.1(同時(shí)開啟 -std=c++0x 編譯選項(xiàng))。
nullptr 是 nullptr_t 類型的右值常量,專用于初始化空類型指針。nullptr_t 是 C++11 新增加的數(shù)據(jù)類型,可稱為“指針空值類型”。也就是說,nullpter 僅是該類型的一個(gè)實(shí)例對象(已經(jīng)定義好,可以直接使用),如果需要我們完全定義出多個(gè)同 nullptr 完全一樣的實(shí)例對象。
值得一提的是,nullptr 可以被隱式轉(zhuǎn)換成任意的指針類型。舉個(gè)例子:
int * a1 = nullptr; char * a2 = nullptr; double * a3 = nullptr;
顯然,不同類型的指針變量都可以使用 nullptr 來初始化,編譯器分別將 nullptr 隱式轉(zhuǎn)換成 int*、char* 以及 double* 指針類型。
另外,通過將指針初始化為 nullptr,可以很好地解決 NULL 遺留的問題,比如:
#include <iostream>
using namespace std;
void isnull(void *c){
cout << "void*c" << endl;
}
void isnull(int n){
cout << "int n" << endl;
}
int main() {
isnull(NULL);
isnull(nullptr);
return 0;
}程序執(zhí)行結(jié)果為:
int n
void*c
借助執(zhí)行結(jié)果不難看出,由于 nullptr 無法隱式轉(zhuǎn)換為整形,而可以隱式匹配指針類型,因此執(zhí)行結(jié)果和我們的預(yù)期相符。
總之在 C++11 標(biāo)準(zhǔn)下,相比 NULL 和 0,使用 nullptr 初始化空指針可以令我們編寫的程序更加健壯。
到此這篇關(guān)于C++11:longlong超長整型和nullptr初始化空指針的文章就介紹到這了,更多相關(guān)C++11 nullptr初始化空指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++實(shí)現(xiàn)MD5算法實(shí)現(xiàn)代碼
用c++實(shí)現(xiàn)了md5算法。包含 md5.h 和md5.cpp 兩個(gè)文件。主要參考百度百科 “MD5” 原理,代碼中變量命名也是參考其中的公式,程序的使用說明在md5.h 文件的末尾注釋中2013-11-11
C語言庫函數(shù)qsort的使用及模擬實(shí)現(xiàn)
這篇文章主要介紹了C語言庫函數(shù)qsort的使用及模擬實(shí)現(xiàn),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08
C語言實(shí)現(xiàn)將double/float 轉(zhuǎn)為字符串(帶自定義精度)
這篇文章主要介紹了C語言實(shí)現(xiàn)將double/float 轉(zhuǎn)為字符串(帶自定義精度),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
OpenCV圖像分割中的分水嶺算法原理與應(yīng)用詳解
這篇文章主要為大家詳細(xì)介紹了OpenCV圖像分割中的分水嶺算法原理與應(yīng)用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
C++20格式化字符串之std::format的使用與實(shí)踐
本文主要介紹了C++20格式化字符串之std::format的使用與實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-11-11
C語言函數(shù)遞歸實(shí)際應(yīng)用舉例詳解
程序調(diào)用自身的編程技巧稱為遞歸,遞歸做為一種算法在程序設(shè)計(jì)語言中廣泛應(yīng)用,這篇文章主要介紹了C語言函數(shù)遞歸實(shí)際應(yīng)用舉例的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-04-04

