日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

C++11中l(wèi)onglong超長(zhǎng)整型和nullptr初始化空指針_C 語(yǔ)言

作者:crossoverpptx ? 更新時(shí)間: 2023-02-06 編程語(yǔ)言

本文介紹 C++11 標(biāo)準(zhǔn)中新添加的 long long 超長(zhǎng)整型和 nullptr 初始化空指針。

1. C++11:long long 超長(zhǎng)整型

C++ 11 標(biāo)準(zhǔn)中,基于整數(shù)大小的考慮,共提供了如下表所示的這些數(shù)據(jù)類(lèi)型。與此同時(shí),標(biāo)準(zhǔn)中還明確限定了各個(gè)數(shù)據(jù)類(lèi)型最少占用的位數(shù)。

整數(shù)類(lèi)型 等價(jià)類(lèi)型 C++11標(biāo)準(zhǔn)規(guī)定占用最少位數(shù)
short short int(有符號(hào)短整型) 至少 16 位(2 個(gè)字節(jié))
signed short short int(有符號(hào)短整型) 至少 16 位(2 個(gè)字節(jié))
signed short int short int(有符號(hào)短整型) 至少 16 位(2 個(gè)字節(jié))
unsigned short unsigned short int(無(wú)符號(hào)短整型) 至少 16 位(2 個(gè)字節(jié))
unsigned short int unsigned short int(無(wú)符號(hào)短整型) 至少 16 位(2 個(gè)字節(jié))
int int(有符號(hào)整形) 至少 16 位(2 個(gè)字節(jié))
signed int(有符號(hào)整形) 至少 16 位(2 個(gè)字節(jié))
signed int int(有符號(hào)整形) 至少 16 位(2 個(gè)字節(jié))
unsigned unsigned int(無(wú)符號(hào)整形) 至少 16 位(2 個(gè)字節(jié))
unsigned int unsigned int(無(wú)符號(hào)整形) 至少 16 位(2 個(gè)字節(jié))
long long int(有符號(hào)長(zhǎng)整形) 至少 32 位(4 個(gè)字節(jié))
long int long int(有符號(hào)長(zhǎng)整形) 至少 32 位(4 個(gè)字節(jié))
signed long long int(有符號(hào)長(zhǎng)整形) 至少 32 位(4 個(gè)字節(jié))
signed long int long int(有符號(hào)長(zhǎng)整形) 至少 32 位(4 個(gè)字節(jié))
unsigned long unsigned long int(無(wú)符號(hào)長(zhǎng)整形) 至少 32 位(4 個(gè)字節(jié))
unsigned long int unsigned long int(無(wú)符號(hào)長(zhǎng)整形) 至少 32 位(4 個(gè)字節(jié))
long long(C++11) long long int(有符號(hào)超長(zhǎng)整形) 至少 64 位(8 個(gè)字節(jié))
long long int(C++11) long long int(有符號(hào)超長(zhǎng)整形) 至少 64 位(8 個(gè)字節(jié))
signed long long(C++11) long long int(有符號(hào)超長(zhǎng)整形) 至少 64 位(8 個(gè)字節(jié))
signed long long int(C++11) long long int(有符號(hào)超長(zhǎng)整形) 至少 64 位(8 個(gè)字節(jié))
unsigned long long(C++11) unsigned long long int(無(wú)符號(hào)超長(zhǎng)整型) 至少 64 位(8 個(gè)字節(jié))
unsigned long long int(C++11) unsigned long long int(無(wú)符號(hào)超長(zhǎng)整型) 至少 64 位(8 個(gè)字節(jié))

C++11 標(biāo)準(zhǔn)規(guī)定,每種整數(shù)類(lèi)型必須同時(shí)具備有符號(hào)(signed)和無(wú)符號(hào)(unsigned)兩種類(lèi)型,且每種具體的有符號(hào)整形和無(wú)符號(hào)整形所占用的存儲(chǔ)空間(也就是位數(shù))必須相同。不過(guò)需要注意的是,C++11 標(biāo)準(zhǔn)中只限定了每種類(lèi)型最少占用多少存儲(chǔ)空間,不同的平臺(tái)可以占用不同的存儲(chǔ)空間。

在上表羅列的這些數(shù)據(jù)類(lèi)型中,long long 超長(zhǎng)整型是 C++ 11 標(biāo)準(zhǔn)新添加的。其實(shí)早在 1995 年,就有人提議將 long long 整形寫(xiě)入 C++ 98 標(biāo)準(zhǔn),但被委員會(huì)拒絕了。而后 long long 整形被 C99 標(biāo)準(zhǔn)(C語(yǔ)言標(biāo)準(zhǔn)之一)采納,并逐漸被很多編譯器支持,于是 C++ 標(biāo)準(zhǔn)委員會(huì)重新決定將 long long 整形寫(xiě)入 C++ 11 標(biāo)準(zhǔn)中。

如同 long 類(lèi)型整數(shù)需明確標(biāo)注 "L" 或者 "l" 后綴一樣,要使用 long long 類(lèi)型的整數(shù),也必須標(biāo)注對(duì)應(yīng)的后綴:

  • 對(duì)于有符號(hào) long long 整形,后綴用 "LL" 或者 "ll" 標(biāo)識(shí)。例如,"10LL" 就表示有符號(hào)超長(zhǎng)整數(shù) 10;
  • 對(duì)于無(wú)符號(hào) long long 整形,后綴用 "ULL"、"ull"、"Ull" 或者 "uLL" 標(biāo)識(shí)。例如,"10ULL" 就表示無(wú)符號(hào)超長(zhǎng)整數(shù) 10。

如果不添加任何標(biāo)識(shí),則所有的整數(shù)都會(huì)默認(rèn)為 int 類(lèi)型。

對(duì)于 long long 類(lèi)型來(lái)說(shuō),如果想了解當(dāng)前平臺(tái)上 long long 整形的取值范圍,可以使用<climits>頭文件中與 long long 整形相關(guān)的 3 個(gè)宏,分別為 LLONG_MIN、LLONG_MAX 和 ULLONG_MIN:
1)LLONG_MIN:代表當(dāng)前平臺(tái)上最小的 long long 類(lèi)型整數(shù);
2)LLONG_MAX:代表當(dāng)前平臺(tái)上最大的 long long 類(lèi)型整數(shù);
3)ULLONG_MIN:代表當(dāng)前平臺(tái)上最大的 unsigned long long 類(lèi)型整數(shù)(無(wú)符號(hào)超長(zhǎng)整型的最小值為 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

此程序中,輸出了各最大值和最小值對(duì)應(yīng)的十六進(jìn)制,顯然在當(dāng)前平臺(tái)(Windows10 64位操作系統(tǒng))上,long long 超長(zhǎng)整型占用 64 位(也就是 16 個(gè)字節(jié))的存儲(chǔ)空間。

2. C++11:nullptr 初始化空指針

實(shí)際開(kāi)發(fā)中,避免產(chǎn)生“野指針”最有效的方法,就是在定義指針的同時(shí)完成初始化操作,即便該指針的指向尚未明確,也要將其初始化為空指針。

所謂“野指針”,又稱(chēng)“懸掛指針”,指的是沒(méi)有明確指向的指針。野指針往往指向的是那些不可用的內(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)都不允許用戶(hù)對(duì)地址為 0 的內(nèi)存空間執(zhí)行寫(xiě)操作,若用戶(hù)在程序中嘗試修改其內(nèi)容,則程序運(yùn)行會(huì)直接報(bào)錯(cuò)。
相比第一種方式,我們更習(xí)慣將指針初始化為 NULL。值得一提的是,NULL 并不是 C++ 的關(guān)鍵字,它是 C++ 為我們事先定義好的一個(gè)宏,并且它的值往往就是字面量 0(#define NULL 0)。

C++ 中將 NULL 定義為字面常量 0,雖然能滿(mǎn)足大部分場(chǎng)景的需要,但個(gè)別情況下,它會(huì)導(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

對(duì)于 isnull(0) 來(lái)說(shuō),顯然它真正調(diào)用的是參數(shù)為整形的 isnull() 函數(shù);而對(duì)于 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),就需要對(duì) NULL(或者 0)進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換:

isnull( (void*)NULL );
isnull( (void*)0 );

如此,才會(huì)成功調(diào)用我們預(yù)期的函數(shù)。

由于 C++ 98 標(biāo)準(zhǔn)使用期間,NULL 已經(jīng)得到了廣泛的應(yīng)用,出于兼容性的考慮,C++11 標(biāo)準(zhǔn)并沒(méi)有對(duì) NULL 的宏定義做任何修改。為了修正 C++ 存在的這一 BUG,C++ 標(biāo)準(zhǔn)委員會(huì)最終決定另其爐灶,在 C++11 標(biāo)準(zhǔn)中引入一個(gè)新關(guān)鍵字,即 nullptr。

在使用 nullptr 之前,需保證自己使用的編譯器支持該關(guān)鍵字。以 Visual Studio 和 codeblocks 為例,前者早在 2010 版本就對(duì) C++ 11 標(biāo)準(zhǔn)中的部分特性提供了支持,其中就包括 nullptr;如果使用后者,則需將其 G++ 編譯器版本至少升級(jí)至 4.6.1(同時(shí)開(kāi)啟 -std=c++0x 編譯選項(xiàng))。

nullptr 是 nullptr_t 類(lèi)型的右值常量,專(zhuān)用于初始化空類(lèi)型指針。nullptr_t 是 C++11 新增加的數(shù)據(jù)類(lèi)型,可稱(chēng)為“指針空值類(lèi)型”。也就是說(shuō),nullpter 僅是該類(lèi)型的一個(gè)實(shí)例對(duì)象(已經(jīng)定義好,可以直接使用),如果需要我們完全定義出多個(gè)同 nullptr 完全一樣的實(shí)例對(duì)象。

值得一提的是,nullptr 可以被隱式轉(zhuǎn)換成任意的指針類(lèi)型。舉個(gè)例子:

int * a1 = nullptr;
char * a2 = nullptr;
double * a3 = nullptr;

顯然,不同類(lèi)型的指針變量都可以使用 nullptr 來(lái)初始化,編譯器分別將 nullptr 隱式轉(zhuǎn)換成 int*、char* 以及 double* 指針類(lèi)型。

另外,通過(guò)將指針初始化為 nullptr,可以很好地解決 NULL 遺留的問(wèn)題,比如:

#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 無(wú)法隱式轉(zhuǎn)換為整形,而可以隱式匹配指針類(lèi)型,因此執(zhí)行結(jié)果和我們的預(yù)期相符。

總之在 C++11 標(biāo)準(zhǔn)下,相比 NULL 和 0,使用 nullptr 初始化空指針可以令我們編寫(xiě)的程序更加健壯。

原文鏈接:https://www.cnblogs.com/crossoverpptx/archive/2022/12/31/17016228.html

欄目分類(lèi)
最近更新