在《計算機眼里的數字》這篇文章中,我曾提到,字節是計算機最小的可尋址的單位,地址對應的是1個個字節,而不是字節的每一個位。這樣編址的緣由很簡單――單個的位所能表示的信息量太少了,只有兩種狀態0和1,只有把足夠多的位組合起來才能表示足夠豐富的信息。那末為何1定要是8呢?由于大家都這么做。。。好吧,肯定1定的歷史緣由,我就不深究了。
但是,即便是8個位組成的字節,其所能表示的信息量依然是有限的,由于最多只有256中狀態組合,如果用每種狀態對應0~255之間的數字的話,那末就沒法表示256這個數。這時候候只好用兩個字節來表示大于255的數。一樣的道理,當數字大到超過兩個字節所能表示的數的極限后,就用4個字節。。。是的,你也發現了,字節數目總是翻倍增長,為何不用3個字節呢?乃至,為啥不用1.5個字節呢?對前者,是由于斟酌到對齊的緣由,這其中有太多東西要說,我就不展開了;而后者,前面其實說到了,由于沒有位的編址,沒法深入到字節內部把數據揪出來。。所以,存儲肯定會有1定的浪費,在所難免。
上面羅嗦了那末多,其實只是為了引出本文的豬腳――C語言數據類型,為何C語言要分那末多類型呢?由于對不同大小的數,所需要的存儲空間大小不同。如果都用4個字節存儲,那末肯定不用分數據類型,但是好浪費哦~所以,本著節省內存的斟酌,數據類型就誕生了。C的數據類型分為基本數據類型和復合數據類型,后者只是前者的某種組合。基本數據類型依照其在計算機中的存儲方式又分為整數類型和浮點數類型。
1、整數類型
整數類型包括char、short、int、long、long long,它們沒有小數部份。char雖然是字符類型,但是由于存儲的是ASCII碼,本質上也是按整數存儲的,所以歸為這1類。不同的整數類型具有不同的字節數,從而所占用的存儲空間不同。但是,這1點是不肯定的,準確的字節數依賴于具體的機器和編譯器――機器不但分品牌,還有32位和64位之分。下面的表格給出不同類型所占有的典型的字節數(來源《深入理解計算機系統》):
類型 | 32位機器 | 64位機器 |
char | 1 | 1 |
short | 2 | 2 |
int | 4 | 4 |
long | 4 | 8 |
long long | 8 | 8 |
char * | 4 | 8 |
float | 4 | 4 |
double | 8 | 8 |
注意,上表只是典型值,以32位為例:在有的機器上,short和int都是2個字節,long是4個字節;而有的機器上,short是2個字節,而int和long是4個字節。C語言僅僅規定:short <= int <= long,然后char是1個字節。不過,對大部份機器,上表夠用了。要查看自己機器上每種類型所占的字節數,請用sizeof(類型)來查看。
對整數類型,C還用了signed和unsigned來修飾它們,以取得有符號數和無符號數,缺省時,認為是有符號數。正如在《計算機眼里的數字》中提到的那樣,有符號數和無符號數的2進制表示多是1樣的,區分僅僅是解讀方式。
有了各種類型以后(即字節數肯定以后),就能夠規定它們所表示的數的范圍。下表是32位機器各種類型的典型取值范圍:
signed | unsigned | |
char | ⑴28 ~ 127 | 0 ~ 255 |
short | ⑶2768 ~ 32767 | 0 ~ 65535 |
int | ⑵147483648 ~ 2147483647 | 0 ~ 4294967295 |
long | ⑵147483648 ~ 2147483647 | 0 ~ 4294967295 |
long long | ⑼223372036854775808 ~ 9223372036854775807 | 0 ~ 18446744073709551615 |
這些界限值可以通過包括limits.h頭文件加以查看,比如對int值的各種范圍,可以通過打印INT_MAX INT_MIN
UINT_MAX UINT_MIN 來查看。
我們用幾個例子來看1下相同類型之間signed和unsigned的轉換。
1、將signed強迫轉換成unsigned:
運行結果以下:
可以明顯的看出,將1個負數強迫轉換為無符號數,并沒有改變其位模式(2進制表示),它依然依照原來的樣子存儲,第4行的結果證明了這1點;而前3行的結果表明,即便不做signed到unsigned的強迫類型轉換,只需要在打印時改變1下輸出格式,就可以到達一樣的效果。(這里我開始懷疑把1個變量聲明為unsigned有啥意義?)
而將1個有符號的正數轉換為同類型的無符號數又如何呢?
2、將unsigned強迫轉換成signed:
那如果正數的范圍超過了TMax呢?
結果:
注意:由于變量分為signed和unsigned,對應的常量也要分為signed和unsigned;類型前沒有修飾時,默許為signed,對應的,1個常量數字默許為signed,即有符號數。如果希望1個常量數字被當做無符號數,就要在其末尾添加字母'u'或‘U’。