- 現(xiàn)代C++語言核心特性解析
- 謝丙堃
- 1502字
- 2021-09-27 17:49:48
第1章 新基礎(chǔ)類型(C++11~C++20)
1.1 整數(shù)類型long long
整型long long
雖然是C++11才新加入標(biāo)準(zhǔn)的,但是我們似乎很早就開始使用這個類型了,這其中包含了一個有趣的故事。
long long
這個類型早在1995年6月之前就由羅蘭·哈丁格(Roland Hartinger)提出申請加入C++標(biāo)準(zhǔn)。但是當(dāng)時的C++標(biāo)準(zhǔn)委員會以C語言中不存在這個基本類型為由,拒絕將這個類型加入C++中。而就在C++98標(biāo)準(zhǔn)出臺的一年后,C99標(biāo)準(zhǔn)就添加了long long
這個類型,并且流行的編譯器也紛紛支持了該類型,這也就是我們很早就接觸到long long
的原因。在此之后C++標(biāo)準(zhǔn)委員會在C++11中才有計劃將整型long long
加入標(biāo)準(zhǔn)中。
我們知道long
通常表示一個32位整型,而long long
則是用來表示一個64位的整型。不得不說,這種命名方式簡單粗暴。不僅寫法冗余,而且表達(dá)的含義也并不清晰。如果按照這個命名規(guī)則,那么128位整型就該被命名為long long long
了。但是不管怎么樣,long long
既然已經(jīng)加入了C++11的標(biāo)準(zhǔn),那么我們能做的就是適應(yīng)它,并且希望不會有long long long
這種類型的誕生。
C++標(biāo)準(zhǔn)中定義,long long
是一個至少為64位的整數(shù)類型。請注意這里的用詞“至少”,也就說long long
的實(shí)際長度可能大于64位。不過我至今也沒有看到大于64位長度的long long
出現(xiàn)。另外,long long
是一個有符號類型,對應(yīng)的無符號類型為unsigned long long
,當(dāng)然讀者可能看到過諸如long long int
、unsigned long long int
等類型,實(shí)際上它們和long long
、unsigned long long
具有相同的含義。C++標(biāo)準(zhǔn)還為其定義LL
和ULL
作為這兩種類型的字面量后綴,所以在初始化long long
類型變量的時候可以這么寫:
long long x = 65536LL;
當(dāng)然,這里可以忽略LL
這個字面量后綴,直接寫成下面的形式也可以達(dá)到同樣的效果:
long long x = 65536;
要強(qiáng)調(diào)的是,字面量后綴并不是沒有意義的,在某些場合下我們必須用到它才能讓代碼的邏輯正確,比如下面的代碼:
long long x1 = 65536 << 16; // 計算得到的x1值為0
std::cout << "x1 = " << x1 << std::endl;
long long x2 = 65536LL << 16; // 計算得到的x2值為4294967296(0x100000000)
std::cout << "x2 = " << x2 << std::endl;
以上代碼的目的是將65536
左移16位,以獲得一個更大的數(shù)值。但是,x1
計算出來的值卻是0,沒有增大反而減小了。原因是在沒有字面量后綴的情況下,這里的65536
被當(dāng)作32位整型操作,在左移16位以后,這個32位整型的值變成了0,所以事實(shí)是將0賦值給了x1
,于是我們看到x1
輸出的結(jié)果為0。而在計算x2
的過程中,代碼給65536
添加了字面量后綴LL
,這使編譯器將其編譯為一個64位整型,左移16位后仍然可以獲得正確的結(jié)果:4294967296(0x100000000)
。另外,有些編譯器可能在編譯long long x1 = 65536 << 16;
的時候顯示一些警告提示,而另一些編譯器可能沒有,無論如何我們必須在編寫代碼的時候足夠小心,避免上面情況的發(fā)生。
和其他整型一樣,long long
也能運(yùn)用于枚舉類型和位域,例如:
enum longlong_enum : long long {
x1,
x2
};
struct longlong_struct {
long long x1 : 8;
long long x2 : 24;
long long x3 : 32;
};
std::cout << sizeof(longlong_enum::x1) << std::endl; // 輸出大小為8
std::cout << sizeof(longlong_struct) << std::endl; // 輸出大小為8
作為一個新的整型long long
,C++標(biāo)準(zhǔn)必須為它配套地加入整型的大小限制。在頭文件中增加了以下宏,分別代表long long
的最大值和最小值以及unsigned long long
的最大值:
#define LLONG_MAX 9223372036854775807LL // long long的最大值
#define LLONG_MIN (-9223372036854775807LL - 1) // long long的最小值
#define ULLONG_MAX 0xffffffffffffffffULL // unsigned long long的最大值
在C++中應(yīng)該盡量少使用宏,用模板取而代之是明智的選擇。C++標(biāo)準(zhǔn)中對標(biāo)準(zhǔn)庫頭文件做了擴(kuò)展,特化了long long
和unsigned long long
版本的numeric_ limits
類模板。這使我們能夠更便捷地獲取這些類型的最大值和最小值,如下面的代碼示例:
#include <iostream>
#include <limits>
#include <cstdio>
int main(int argc, char *argv[])
{
// 使用宏方法
std::cout << "LLONG_MAX = " << LLONG_MAX << std::endl;
std::cout << "LLONG_MIN = " << LLONG_MIN << std::endl;
std::cout << "ULLONG_MAX = " << ULLONG_MAX << std::endl;
// 使用類模板方法
std::cout << "std::numeric_limits<long long>::max() = "
<< std::numeric_limits<long long>::max() << std::endl;
std::cout << "std::numeric_limits<long long>::min() = "
<< std::numeric_limits<long long>::min() << std::endl;
std::cout << "std::numeric_limits<unsigned long long>::max() = "
<< std::numeric_limits<unsigned long long>::max() << std::endl;
// 使用printf打印輸出
std::printf("LLONG_MAX = %lld\n", LLONG_MAX);
std::printf("LLONG_MIN = %lld\n", LLONG_MIN);
std::printf("ULLONG_MAX = %llu\n", ULLONG_MAX);
}
輸出結(jié)果如下:
LLONG_MAX = 9223372036854775807
LLONG_MIN = -9223372036854775808
ULLONG_MAX = 18446744073709551615
std::numeric_limits<long long>::max() = 9223372036854775807
std::numeric_limits<long long>::min() = -9223372036854775808
std::numeric_limits<unsigned long long>::max() = 18446744073709551615
LLONG_MAX = 9223372036854775807
LLONG_MIN = -9223372036854775808
ULLONG_MAX = 18446744073709551615
以上代碼很容易理解,唯一需要說明的一點(diǎn)是,隨著整型long long
的加入,std::printf
也加入了對其格式化打印的能力。新增的長度指示符ll
可以用來指明變量是一個long long
類型,所以我們分別使用%lld
和%llu
來格式化有符號和無符號的long long
整型了。當(dāng)然,使用C++標(biāo)準(zhǔn)的流輸入/輸出是一個更好的選擇。
- Java范例大全
- MySQL數(shù)據(jù)庫應(yīng)用與管理 第2版
- 軟件架構(gòu)設(shè)計:大型網(wǎng)站技術(shù)架構(gòu)與業(yè)務(wù)架構(gòu)融合之道
- Mastering SVG
- 智能手機(jī)APP UI設(shè)計與應(yīng)用任務(wù)教程
- Java Fundamentals
- Extending Unity with Editor Scripting
- Emotional Intelligence for IT Professionals
- Android移動應(yīng)用項目化教程
- 超簡單:Photoshop+JavaScript+Python智能修圖與圖像自動化處理
- HTML5游戲開發(fā)實(shí)戰(zhàn)
- Microsoft HoloLens By Example
- 你好!Java
- C/C++代碼調(diào)試的藝術(shù)
- 跟小樓老師學(xué)用Axure RP 9:玩轉(zhuǎn)產(chǎn)品原型設(shè)計