- 現(xiàn)代C++語言核心特性解析
- 謝丙堃
- 13字
- 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)的,但是我們似乎很早就開始使用這個(gè)類型了,這其中包含了一個(gè)有趣的故事。
long long
這個(gè)類型早在1995年6月之前就由羅蘭·哈丁格(Roland Hartinger)提出申請(qǐng)加入C++標(biāo)準(zhǔn)。但是當(dāng)時(shí)的C++標(biāo)準(zhǔn)委員會(huì)以C語言中不存在這個(gè)基本類型為由,拒絕將這個(gè)類型加入C++中。而就在C++98標(biāo)準(zhǔn)出臺(tái)的一年后,C99標(biāo)準(zhǔn)就添加了long long
這個(gè)類型,并且流行的編譯器也紛紛支持了該類型,這也就是我們很早就接觸到long long
的原因。在此之后C++標(biāo)準(zhǔn)委員會(huì)在C++11中才有計(jì)劃將整型long long
加入標(biāo)準(zhǔn)中。
我們知道long
通常表示一個(gè)32位整型,而long long
則是用來表示一個(gè)64位的整型。不得不說,這種命名方式簡單粗暴。不僅寫法冗余,而且表達(dá)的含義也并不清晰。如果按照這個(gè)命名規(guī)則,那么128位整型就該被命名為long long long
了。但是不管怎么樣,long long
既然已經(jīng)加入了C++11的標(biāo)準(zhǔn),那么我們能做的就是適應(yīng)它,并且希望不會(huì)有long long long
這種類型的誕生。
C++標(biāo)準(zhǔn)中定義,long long
是一個(gè)至少為64位的整數(shù)類型。請(qǐng)注意這里的用詞“至少”,也就說long long
的實(shí)際長度可能大于64位。不過我至今也沒有看到大于64位長度的long long
出現(xiàn)。另外,long long
是一個(gè)有符號(hào)類型,對(duì)應(yīng)的無符號(hào)類型為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
類型變量的時(shí)候可以這么寫:
long long x = 65536LL;
當(dāng)然,這里可以忽略LL
這個(gè)字面量后綴,直接寫成下面的形式也可以達(dá)到同樣的效果:
long long x = 65536;
要強(qiáng)調(diào)的是,字面量后綴并不是沒有意義的,在某些場合下我們必須用到它才能讓代碼的邏輯正確,比如下面的代碼:
long long x1 = 65536 << 16; // 計(jì)算得到的x1值為0
std::cout << "x1 = " << x1 << std::endl;
long long x2 = 65536LL << 16; // 計(jì)算得到的x2值為4294967296(0x100000000)
std::cout << "x2 = " << x2 << std::endl;
以上代碼的目的是將65536
左移16位,以獲得一個(gè)更大的數(shù)值。但是,x1
計(jì)算出來的值卻是0,沒有增大反而減小了。原因是在沒有字面量后綴的情況下,這里的65536
被當(dāng)作32位整型操作,在左移16位以后,這個(gè)32位整型的值變成了0,所以事實(shí)是將0賦值給了x1
,于是我們看到x1
輸出的結(jié)果為0。而在計(jì)算x2
的過程中,代碼給65536
添加了字面量后綴LL
,這使編譯器將其編譯為一個(gè)64位整型,左移16位后仍然可以獲得正確的結(jié)果:4294967296(0x100000000)
。另外,有些編譯器可能在編譯long long x1 = 65536 << 16;
的時(shí)候顯示一些警告提示,而另一些編譯器可能沒有,無論如何我們必須在編寫代碼的時(shí)候足夠小心,避免上面情況的發(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
作為一個(gè)新的整型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)中對(duì)標(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
也加入了對(duì)其格式化打印的能力。新增的長度指示符ll
可以用來指明變量是一個(gè)long long
類型,所以我們分別使用%lld
和%llu
來格式化有符號(hào)和無符號(hào)的long long
整型了。當(dāng)然,使用C++標(biāo)準(zhǔn)的流輸入/輸出是一個(gè)更好的選擇。
- Advanced Quantitative Finance with C++
- 數(shù)據(jù)庫程序員面試筆試真題與解析
- Learning C# by Developing Games with Unity 2020
- Python數(shù)據(jù)可視化:基于Bokeh的可視化繪圖
- 匯編語言程序設(shè)計(jì)(第2版)
- UML+OOPC嵌入式C語言開發(fā)精講
- Android底層接口與驅(qū)動(dòng)開發(fā)技術(shù)詳解
- 組態(tài)軟件技術(shù)與應(yīng)用
- 利用Python進(jìn)行數(shù)據(jù)分析
- Java網(wǎng)絡(luò)編程實(shí)戰(zhàn)
- SQL Server實(shí)用教程(SQL Server 2008版)
- Red Hat Enterprise Linux Troubleshooting Guide
- Extending Unity with Editor Scripting
- 軟件測試分析與實(shí)踐
- The Statistics and Calculus with Python Workshop