1. 整型數據類型
C語言里面的整數數據類型
類型名稱 | C語言中的關鍵字 | 注釋 |
---|---|---|
字符型 | char | 表示一個很小的整數 |
短整型 | short | 表示一個不怎么大的整數 |
整型 | int | 生活中一般的整數都可以表示 |
長整型 | long | 較大的整數 |
加長整型 | long long | 非常大的整數 |
一個整數而已,為什么會需要定義這么多不同的類型出來呢?
計算機通過晶體管的開關狀態來記錄數據。它們通常8個編為一組,我們稱之為 字節 。而晶體管有開關兩種狀態,一個字節有8個晶體管,因此一個字節可以擁有2的八次方個不同的狀態。讓每一種狀態對應一個數值,這樣一個字節可以表示256個不同數值。
晶體管狀態 | 二進制數值 | 十進制數值 |
---|---|---|
關關關關關關關關 | 00000000 | 0 |
關關關關關關關開 | 00000001 | 1 |
關關關關關關開關 | 00000010 | 2 |
關關關關關關開開 | 00000011 | 3 |
… | … | … |
開關開關開關開關 | 10101010 | 170 |
開開開開開開開開 | 11111111 | 255 |
要表示更大的數據范圍就需要更多晶體管。要知道在發明C語言的年代,計算機存儲資源是非常珍貴而稀缺的。如果只想表達0到100以內的數值,那么一個字節就足夠了,何必用兩個字節來存儲?
而如今,即使存儲資源已經較為豐富了,但是大部分的強類型語言,都延續了這個傳統。它們均提供了豐富的類型以供選用。而程序員在編寫代碼時,通常能預想到需要使用到的數據范圍的大小。這樣在處理一個數據時,可以從語言所提供的類型中選用最合適的類型來承載數據。
在C語言標準并未規定這些數據類型的大小范圍,具體的實現交由了編譯器和平臺決定。
2. 用sizeof關鍵詞來測量大小
和int
一樣,sizeof
是C語言中的一個關鍵詞。它是英文size of
連起來的合成詞。翻譯成中文就是什么東西的大小的意思。它能夠測量C語言各種實體所占用的字節大小。
如果我們想看int
所占用的字節大小,可以這樣寫sizeof(int)
。執行后這段代碼后,它的測量結果是一個整型。我們可以借助printf
函數將測量結果顯示在控制臺上。我們現在可以假設sizeof
返回的結果是int
類型的,在printf
函數中使用占位符%d
。而更準確的用法,應該用%zu
。
測量int
類型所占用的字節大小,并將結果打印在控制臺上的代碼如下:
printf("%dn", sizeof(int));
sizeof
后面既可以跟 類型,也可以跟 變量、常量。
- 跟 類型 ,測類型所占用字節的大小。
- 跟 變量 ,測變量的類型所占用字節大小。
- 跟 常量 ,測常量的類型所占用字節大小。
三種情況的示例代碼。
int a; printf("sizeof int = %dn", sizeof(int)); // 1.測類型所占用字節的大小 printf("sizeof a = %dn", sizeof(a)); // 1.測變量的類型所占用字節大小 printf("sizeof 123 = %dn", sizeof(123)); // 1.測常量的類型所占用字節大小
測試C語言提供的各種整型類型的大小
printf("sizeof char=%dn", sizeof(char)); printf("sizeof short=%dn", sizeof(short)); printf("sizeof int=%dn", sizeof(int)); printf("sizeof long=%dn", sizeof(long)); printf("sizeof long long=%dn", sizeof(longlong));
結果:char,short,int,long,long long分別占用了1,2,4,4,8個字節。至此,我們已經得知了它們所占字節大小,并且驗證了可以表示越大范圍的數據類型所占用的字節越多。值得注意的是
int
和long
均占用4個字節。這并未違反C語言標準,C語言標準規定高級別的類型取值范圍不得小于低級別的類型,但是它們可以是一致的。
3. 三位二進制表示的數值范圍
char
,short
,int
,long
,long long
分別占用了1,2,4,4,8個字節。而每個字節由8個晶體管組成,每個晶體管狀態我們稱之為位。那么char
,short
,int
,long
,long long
分別占用了8,16,32,32,64位。
太多的位不利于理解原理,暫時把問題簡化一下,試試看位數減少到3。然后,分析3位的組 合,它能表示多大范圍的數值.
晶體管狀態 | 二進制數據 | 十進制數據 |
---|---|---|
關關關 | 000 | 0 |
關關開 | 001 | 1 |
關開關 | 010 | 2 |
關開開 | 011 | 3 |
開關關 | 100 | 4 |
開關開 | 101 | 5 |
開開關 | 110 | 6 |
開開開 | 111 | 7 |
三位二進制組成的數據類型,可以表達2的3次方也就是8個數值。如果從0開始,那么可以表達從0到7的 數據范圍。 得出結論 :如果不考慮負數,那么整型數據類型可以表達的數據范圍是 假設,位數為n,則數據范圍從【0】開始,到【2的n次方-1】的數值范圍。
那負數
怎么辦?我們需要 拿出一個位來作為符號位 。用來表示這個數據是正數還是負數。在IEEE標準中,這個符號位存在于二進制的最高位。用三位二進制來示范這種情況。
晶體管狀態 | 二進制數據 | 十進制數據 |
---|---|---|
關關關 | 000 | 0 |
關關開 | 001 | 1 |
關開關 | 010 | 2 |
關開開 | 011 | 3 |
開關關 | 100 | -4 |
開關開 | 101 | -3 |
開開關 | 110 | -2 |
開開開 | 111 | -1 |
加上符號之后,現在取值范圍變為負4到3了。紅色字體的為最高位,最高位為1的表示負數。你可能會覺得有點奇怪,為什么3的二進制是011
,而負3卻是101
呢?如果簡單的加一個符號位,為什么不用111呢?那我們看看如圖中所示的3與負3相加的運算結果。
會驚奇地發現,用101來表示負3與用011表示的正3相加。結果為1000,但是由于僅有3位二進制來保 存數據,最高位1被丟棄了。結果為000,居然得到了正確的結果0。
4.數值的補碼表示法
時鐘是一個圓被分成了12個點,讓我們假設這個時鐘一步只能走一個整點。那么這個時鐘只有12種不同的模式,我們把12稱之為時鐘的模。
現在指針指向了5點,我們要讓指針回到0點。一個辦法是直接回退5個小時(5-5)。另一個辦法是繼續往前走7個小時(5+7)。
在第二種辦法中,5+7=12,而12剛好為時鐘的模,時鐘指向12的同時,也正好指向了0。要讓指針回到0點,只需要讓它加上模與當前的時間的差即可。
因此,指針回退5小時與指針前進7小時是等價的。我們可以用指針前進來代替指針后退。
將這種思想帶入到上面討論的三位二進制當中。三位二進制能表示8中不同的模式,因此它的 模 為8。要讓3回到0,我們可以讓3減去3,也可以讓3加上 模與3的差,即8-3=5。因此,我們可以把-3在三位二進制中用5的二進制101表示。
這種將用加法來等效減法的二進制表示法被稱之為補碼表示法。
正數的補碼就是其二進制本身。而正數對應的負數的補碼為:(模 - 正數)的二進制。
000 | 0 | |||
---|---|---|---|---|
001 | 1 | |||
010 | 2 | |||
負數 | 模減去正數 | 補碼 | 011 | 3 |
-4 | 8-4=4 | 100 | 100 | -4 |
-3 | 8-3=5 | 101 | 101 | -3 |
-2 | 8-2=6 | 110 | 110 | -2 |
-1 | 8-1=7 | 111 | 111 | -1 |
補碼表示法既通過最高位,區別了正數和負數。并且,巧妙地應用了溢出,所得到的計算結果也是正確的。類似于鐘表僅需要向前走就可以實現減法,計算機的電路設計中,也只需要設計加法電路。極大地簡化了計算機內部電路的復雜程度。
求一個正數對應的負數的補碼的第二種辦法:
- 先寫出這個正數的二進制。
- 從二進制的右邊開始,遇到第一個1之前,全都填0。
- 遇到第一個1之后,把1填下來。
- 1之后的全部取反。
從右往左:未遇到1填0,遇到1填1,然后全部取反
十進制 0 -1 -2 -3 -4 整數二進制 000 001 010 011 100 補碼 000 111 110 101 100
5.各種整型類型的數值范圍是多少
類型 | sizeof大小 | 二進制位數 | 取值范圍算式 | 取值范圍 |
---|---|---|---|---|
char | 1 | 1×8 = 8位 | -[2的7次方] ~ +[2的七次方 - 1] | -128 ~ +127 |
short | 2 | 2×8 = 16位 | -[2的15次方] ~ +[2的15次方 - 1] | -32,768 ~ +32,767 |
int | 4 | 4×8 = 32位 | -[2的31次方] ~ +[2的31次方 - 1] | -2,147,483,648 ~ +2,147,483,647 |
long | 4 | 4×8 = 32位 | -[2的31次方] ~ +[2的31次方 - 1] | -2,147,483,648 ~ +2,147,483,647 |
long long | 8 | 8×8 = 64位 | -[2的63次方] ~ +[2的63次方 - 1] | -9,223,372,036,854,775,808 ~ +9,223,372,036,854,775,807 |
次方數比位數少一,是因為最高位被用去做符號位了。
6. 無符號整型
如果你確定你不會用到負數,那么請使用unsigned
關鍵詞。表明這個數據類型,是不帶有符號位的。既然不帶有符號位了,那么原本留給符號位的那一個二進制位,可以用來表示數值。
類型 | sizeof大小 | 二進制位數 | 取值訪問算式 | 取值范圍 |
---|---|---|---|---|
unsigned char | 1 | 1×8 = 8位 | 0 ~ +[2的8次方 - 1] | 0 ~ +255 |
unsigned short | 2 | 2×8 = 16位 | 0 ~ +[2的16次方 - 1] | 0 ~ +65,535 |
unsigned int | 4 | 4×8 = 32位 | 0 ~ +[2的32次方 - 1] | 0 ~ +4,294,967,295 |
unsigned long | 4 | 4×8 = 32位 | 0 ~ +[2的32次方 - 1] | 0 ~ +4,294,967,295 |
unsigned long long | 8 | 8×8 = 64位 | 0 ~ +[2的64次方 - 1] | 0 ~ +18,446,744,073,709,551,615 |
-
存儲
+關注
關注
13文章
4353瀏覽量
86171 -
晶體管
+關注
關注
77文章
9745瀏覽量
138896 -
C語言
+關注
關注
180文章
7614瀏覽量
137712 -
數據類型
+關注
關注
0文章
236瀏覽量
13662 -
整數
+關注
關注
0文章
13瀏覽量
6551
發布評論請先 登錄
相關推薦
FPGA中的VHDL語言的數據類型和運算符
C預處理與C語言基本數據類型
淺析System Verilog中的整數數據類型
C程序的運行環境和C語言的數據類型
C語言-基本數據類型與位運算
plc數據類型怎么理解和應用
C語言數據類型有哪些
![<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>數據類型</b>有哪些](https://file1.elecfans.com/web2/M00/C5/16/wKgZomX6UKqAb6q4AABHS7gAoYk070.png)
評論