c++定義了一組表示整數、浮點數、單個字符和布爾值的算術類型(arithmetic type)。另外還有一種特殊類型void,一般用作函數返回類型,或者void指針(void *:無類型指針,可以指向任意類型的數據。可用任意數據類型的指針對void指針賦值,因此常用void指針來作為函數形參,這樣函數就可以接受任意數據類型的指針作為參數。)
c++只規定每個算術類型的最小存儲空間,並不阻止編譯器使用更大的存儲空間。比如int類型,編譯器通常使用32 bit來存儲。
| bool |
布爾型 |
- |
| char |
字符型 |
8 bit |
| wchar_t |
寬字符型 |
16 bit |
| short |
短整型 |
16 bit |
| int |
整形 |
16 bit |
| long |
長整型 |
32 bit |
| float |
單精度浮點型 |
6位有效數字 |
| double |
雙精度浮點型 |
10位有效數字 |
| long double |
擴展精度浮點型 |
10位有效數字 |
整形
表示整數、字符和布爾值的算術類型統稱整形。其中字符型有兩種,char和wchar_t,wchar_t用於擴展字符集,比如漢字和日語。bool類型表示真值true和false,可以將算術類型的任何值賦給bool對象,0值代表false,非0值代表true。
除bool類型外,其他整形可以是有符號(signed)也可以是無符號(unsigned)。int、short、long默認是signed,除非指定為unsigned,如unsigned long。unsigned int可以簡寫為unsigned。
char有三種不同的類型:普通char、signed char、unsigned char。當使用普通char,如char a;時,由編譯器決定使用哪種表示方式來表示a(signed char或unsigned char),c++標准未限定char為signed char。
對於一種8 bit類型,現在來看其整型值表示。對於unsigned型,取值范圍是0 ~ 28-1,即0 ~ 255,共256個數值。對於signed類型,取值范圍至少從-127 ~ 127,具體由編譯器決定如何實現,大多數實現為-128 ~ 127。(為什么是-128 ~ 127?我這里瞎理解一下。首先-128 ~ 127正好是256(28)個數值。這種實現最常見的策略是最高位為符號位,符號位為1,值為負,符號位為0,值為正。本來是-0到-127,+0到+127。實際數值在內存中是以補碼表示的,正數的補碼與其原碼(即該數的二進制形式)相同,+0到+127即0000 0000到0111 1111。負數的補碼是其二進制形式的符號位不變,其他位取反再加1。所以-1到-127,其補碼為1111 1111到1000 0001。現在還有一個-0,補碼的0是沒有正負的,所以+0就是0了,那-0呢?-127的補碼是1000 0001,再往下是1000 0000。再來看-128,原碼是1 1000 0000(最前面的符號位不再是最高位),符號位不變,其他位取反1 0111 1111,再加1,1 1000 0000,超出8位的最高位1舍棄,剩下1000 0000,所以補碼1000 0000可以代表-128。所以最終沒有-0,而是-128 ~ 127(共256個連續數值),對應的補碼是1000 0000 到0000 0000再到0111 1111。)
對於整形的賦值,有一個問題。如果把一個超出其取值范圍的值賦給某一類型的對象,結果如何?對於unsigned類型來說,將該值對其unsigned類型的取值數目求模,然后取所得值。比如8位的unsigned char,如果試圖賦值為336,則實際賦值為336對256求模之后的值,即80。c++允許將負值賦給unsigned對象,其結果仍然是該負數對該類型的取值個數求模后的值。例如-1賦給8位的unsigned char,結果是255。對於signed來說,由編譯器決定如何賦值,大多數編譯器處理signed類型的方式與unsigned類型類似。
當用整形變量進行計數時,最好使用unsigned,可以避免值越界導致結果為負數的可能性。當進行整形算術運算時,較少使用short,因為short的16bit存儲,容易造成越界。因為char a,a可能被當做signed,也可以被當做unsigned,所以char類型作為計算類型容易出現問題,應當避免這樣使用。在進行整形運算時,使用long類型相對於int類型可能要付出更高的性能代價。
浮點型
通常float(單精度)用一個字(32位)表示,double用兩個字(64位)表示,long double用三個或四個字(96或128位)表示。類型的取值范圍決定了浮點數的有效數字位數。實際應用中,float精度通常不夠,double至少可以保證10位有效數字,能滿足大多數計算的需要。而且很多機器上,double比float類型計算要快得多。long double提供的精度通常沒有必要,而且還需承擔額外的運行代價。
關於浮點型數據的存儲格式,遵循IEEE754標准,可參考簡要記錄浮點型數據的二進制存儲格式。
【學習資料】 《c++ primer》
