在C++ Primer的第二章里面討論了該如何選擇正確的類型,這里是些自己的看法盾致,和書上的不全一樣。
char, short, int and long
-
int
類型一般是處理器最自然的長度,所以一般無特殊需求,都使用int
來做整數(shù)運(yùn)算心剥。 - 只用
char
類型來表示可打印的字符。 - 用
unsigned char
或者#typedef unsigned char BYTE
來表示一塊內(nèi)存數(shù)據(jù)背桐,比如說一個(gè)二進(jìn)制文件的內(nèi)容优烧。 -
signed char
,short
和long
通常不用。
signed integer vs unsigned integer
- 任何涉及到加減乘除算數(shù)計(jì)算的情況下链峭,都要用
signed integer
畦娄。哪怕是當(dāng)時(shí)看起來沒有產(chǎn)生負(fù)數(shù)的可能性,為了避免將來修改代碼的時(shí)候混用有符號類型和無符號類型弊仪,還是建議都是用有符號類型熙卡。 - 任何涉及到左移,右移撼短,位運(yùn)算的情況下再膳,都要使用
unsigned integer
挺勿。這個(gè)時(shí)候我們需要的變量不是一個(gè)數(shù)字曲横,而是一堆bit
。最重要的是不瓶,如果對負(fù)數(shù)右移的時(shí)候禾嫉,首位是補(bǔ)0還是1是編譯器實(shí)現(xiàn)相關(guān)的,所以不能使用有符號類型蚊丐。
Fixed-Precision Integer Types
除了int
和long
這樣子沒有規(guī)定具體大小的類型以為熙参,C++11還有一系列固定精度的整形,定義在頭文件cstdint
中麦备,它們是int8_t int16_t int32_t int64_t
和對應(yīng)的無符號類型孽椰。在這些情況下昭娩,你需要一個(gè)變量表示某個(gè)硬件上的32位的寄存器;你需要一個(gè)變量表示ipv4的地址黍匾;這些情況最好使用固定精度的整形栏渺。如果你只用個(gè)int
來表示的下,在不同的編譯器下可能會大小不一樣锐涯,而造成問題磕诊。
double Vs float
如果精度允許,首選float來提升程序性能纹腌。
- 在很多機(jī)器上霎终,計(jì)算double和float的速度是一樣的。比如說在x86的機(jī)器上升薯,double和float都會被擴(kuò)展成為80bits的浮點(diǎn)數(shù)來計(jì)算莱褒。
- 但是除了計(jì)算速度,還要考慮memory和cache的問題涎劈。double意味著需要更大的memory bandwidth保礼,以及更大的cache壓力。
- 在SIMD指令上责语,使用float也比double快炮障,因?yàn)橐粭l指令能處理更多的float數(shù)字。參考Intel 64 and IA-32 Architectures Optimization Reference Manual 里面的內(nèi)容坤候。
使用void*來表示地址類型胁赢。
- 使用unsigned int或者unsigned long來表示地址是嚴(yán)格禁止的,因?yàn)樗麄兊拈L度不是確定白筹。
- 使用
int32_t
或者int64_t
也不是好主意智末,這樣就不具有32位和64位的可移植性了。 - 如果對兩個(gè)指針做減法徒河,可以
static_cast<char*>
來計(jì)算系馆,并且使用ptrdiff_t
來保存返回值以確保可移植性顽照。 - 如果要對地址進(jìn)行位運(yùn)算由蘑,那么可以使用
intptr_t
和uintptr_t
類型,這兩個(gè)類型是C++11里面新引入的代兵。他們是個(gè)足夠大到保存指針的的integer類型尼酿。這樣子用reinterpret_cast<intptr_t>(p1);
size_t, size_type, difference_type Or integer type
為什么需要size_t, size_type, difference_type
vector<int>::size_type size = v.size();
vector<int>::difference_type diff = v.begin() - v.end();
v.size()
具體能有多大完全是平臺相關(guān)的,比如說32位CPU下植影,最大也只能是4G裳擎。但是64bit下就要大的多。所以如果使用int
或者long
之類的保存v.size()
的值思币,其可移植性不好鹿响,要么是太小無法保存其值羡微,要么是太大浪費(fèi)了效率。所以就定義了這些特別的類型惶我。
std::size_t is the unsigned integer type of the result of the sizeof operator
difference_type provides the difference between two iterators that refer to elements within the same vector.
size_type represents the number of elements in a vector.
選擇size_type還是int呢拷淘?
for (int i = 0; i < v.size(); i++); // warning in some compiler
for (vector<int>::size_type i = 0; i < v.size(); i++);
for (decltype(v.size()) i = 0; i < v.size(); i++);
個(gè)人的習(xí)慣
- 如果我在寫一個(gè)跨平臺,準(zhǔn)備給很多人用的指孤,完全無法預(yù)知要處理的數(shù)據(jù)能有多大的情況下启涯,那么肯定不能使用
int
之類的類型。但要注意恃轩,size_type
都是無符號類型结洼,如果后續(xù)需要進(jìn)行數(shù)值運(yùn)算,需要小心處理和有符號數(shù)一起計(jì)算的情況叉跛。 - 大多數(shù)情況下松忍,我的代碼的使用場景有限,我確定一個(gè)
int
肯定能夠裝下v.size()
筷厘,那么我就會使用int
鸣峭。好處不用太關(guān)心有符號和無符號混用的問題。