相比於C++98標准,C++11整型的最大改變就是多了 long long。分為兩種:long long 和unsigned long long。在C++11中,標准要求long long 整型可以在不同平台上有不同的長度,但至少有64位。我們在寫常數字面量時,可以使用LL后綴(或是ll)標識一個long long 類型的字面量,而ULL (或ull、Ull、uLL) 表示一個unsigned long long 類型的字面量。比如:
long long int lli=-900000000000000LL; // 有符號的long long 變量lli unsigned long long int ulli=-900000000000ULL; // 無符號的 unsigned long long 變量ulli。
對於有符號的,下面的類型是等價的:long long、signed long long、long long int、signed long long int; 而unsigned long long 和 unsigned long long int 也是等價的。
與 long long 整型相關的一共有3個:LONG_MIN、LONG_MAX 和ULONG_MAX, 它們分別代表了平台上最小的long long 值、最大的long long 值,以及最大的unsigned long long 值。
擴展的整型
有些整型的名字如:UINT、__int16、u64、int64_t, 等等。這些類型有的源自編譯器的自行擴展,有的則來自某些編程環境。事實上,在C++11中一共只定義了以下5種標准的有符號整型:
- signed char
- short int
- int
- long int
- long long int
標准同時規定,每一種有符號整型都有一種對應的無符號整數版本,且有符號整型與其對應的無符號整型具有相同的存儲空間大小。
在實際的編程中,由於這5種基本的整型適用性有限,所以有時編譯器出於需要,也會自行擴展一些整型。在C++11中,標准對這樣的擴展做出了一些規定。具體地講,除了標准整型之外,C++11標准允許編譯器擴展自有的所謂擴展整型。這些擴展整型的長度(占用內存的位數)可以比最長的標准整型(long long int, 通常是一個64位長度的數據)還長,也可以介於兩個標准整數的位數之間。
C++11規定,擴展的整型必須和標准類型一樣,有符號類型和無符號類型占用同樣大小的內存空間。而由於C/C++是一種弱類型語言,當運算、傳參等類型不匹配的時候,整型間會發生隱式的轉換,這種過程通常被稱為整型的提升,比如:
int(a) + (long long)b
通常就會導致變量(int)a被提升為long long類型后才與(long long)b 進行運算。而無論是擴展的整型還是標准的整型,其轉化的規則會由它們的"等級"決定。通常情況下:有如下原則:
- 長度越大的整型等級越高,比如long long int的等級會高於int。
- 長度相同的情況下,標准整型的等級高於擴展類型,比如long long int和_int64如果都是64位,則long long int類型等級更高。
- 相同大小的有符號類型和無符號類型的等級相同,long long int 和unsigned long long int的等級就相同。
而在進行隱式的整型轉換的時候,一般是按照低等級整型轉換為高等級整型,有符號的轉換為無符號。這種規則跟C++98的整型轉換規則是一致的。
如果編譯器定義一些自有的整型,即使這樣自定義的整型由於名稱並沒有被標准收入,因而可移植性並不能得到保證,但至少編譯器開發者和程序員不用擔心自定義的擴展整型與標准整型間在使用規則上(尤其是整型提升)存在不同的認識了。
longlong類型輸出
int64_t用來表示64位整數,在32位系統中是long long int,在64位系統中是long int,所以打印int64_t的格式化方法是:
printf("%ld", value); // 64bit OS printf("%lld", value); // 32bit OS
當然有跨平台的方法:
#include <inttypes.h> printf("%" PRId64 "\n", value); // 相當於64位的: printf("%" "ld" "\n", value); // 或32位的: printf("%" "lld" "\n", value);
其中,printf("abc" "def" “ghi")這樣寫多個字符串是沒有問題的。
但是,死活都編譯不過,錯誤是:error: expected ‘)’ before ‘PRId64’
找了一下這個宏的定義,/usr/include/inttypes.h:
/* The ISO C99 standard specifies that these macros must only be defined if explicitly requested. */ #if !defined __cplusplus || defined __STDC_FORMAT_MACROS # if __WORDSIZE == 64 # define __PRI64_PREFIX "l" # define __PRIPTR_PREFIX "l" # else # define __PRI64_PREFIX "ll" # define __PRIPTR_PREFIX # endif /* Macros for printing format specifiers. */ /* Decimal notation. */ # define PRId8 "d" # define PRId16 "d" # define PRId32 "d" # define PRId64 __PRI64_PREFIX "d"
原來這個是定義給c用的,C++要用它,就要定義一個__STDC_FORMAT_MACROS宏顯示打開它。
/* test_int64.cpp g++ -D__STDC_FORMAT_MACROS -o test_int64 -g -O0 test_int64.cpp */ #include <stdio.h> #include <inttypes.h> int main(int argc, char** argv){ int64_t value = 0xFFFFFFFFFFFF; printf("int64_t=%"PRId64", sizeof(int64_t)=%d\n", value, sizeof(int64_t)); }
編譯並執行:
g++ -D__STDC_FORMAT_MACROS -o test_int64 -g -O0 test_int64.cpp
./test_int64
int64_t=281474976710655, sizeof(int64_t)=8
