C語言-整數類型
整數類型
Reg為寄存器
字長,是說這個寄存器是多少寬的,每個寄存器可以表示32bit數據,也是說CPU與RAM每一次傳遞的數據也是32bit
計算機內部一切都是二進制
所有的類型,只是說我們以什么方式去看待它,並不是表明,它在內部是怎么 表達的。
整數的內部表達
18 -> 00010010
-18 -> ?
我們在做十進制運算時,我們實際上總是把負號先拋掉,把它當做一個整數做運算,在運算的結果上再解決負號問題。
例如:12+(-18)-> 12-18 -> -6
12 * -18 -> -(12 * 18)
第一種方法需要在計算時需要添加符號來控制符號,不利於計算機內部的設計
第二種方法在使用時需要與中間數進行運算來判斷當前數的具體數值
兩種方法都使得計算機的輸入輸出變得復雜。
實際計算機中使用的是補碼來表示負數
補碼思想:
256是28就是256((1)00000000),28-1就是-1的補碼
補碼的意義就是拿補碼和原碼可以加出一個溢出的“零”
這樣可以直接做普通的二進制運算,不需要進行+-符號的變換
整數的范圍
高位為0,表示1-127
高位為1,表示-1 - -128
#include <stdio.h>
int main()
{
char c = 255;
int i = 255;
printf("c=%d,i=%d\n",c,i);
// 對於char c 來說為11111111最高位為1是負數
//對於int(32bit) i來說為00000000 00000000 00000000 11111111
return 0;
}
int的范圍
-232-1 ~ 232-1-1
char 表達的是-128 ~ 127(中間有0)
所有整數類型范圍,在是2n-1 ~ 2n-1-1
如果想將11111111當做一個純二進制的來看需要unsigned來表達
unsigned的意思是這個整數不以補碼的形式表示,沒有負數,使得正數的表達范圍被擴大。
00000000-11111111 unsigned表示0-255,原來是-128~127
整數越界
第二個01111111是127,加1 后本來是128,但128作為一個整數char來說,它所表達的是-128
將數的范圍想象成一個圓
對一個unsigned char來說,127+1就等於128,如果是255,+1才變成0
所以對於unsigned char來說,另一個圓
使用數的范圍可以找出int的最大數來,這也是翁凱老師留的一個小測驗。
主要思想還是不斷累加(while循環),當最后累加的數小於0時,用這個數再減1就等到int能表示的最大值
整數的格式化
所有小於int的,char、short、int都采用相同的輸出就是用%d;所有比int大的,需要用%ld
#include <stdio.h>
int main()
{
char c = -1;
int i = -1;
printf("c=%u,i=%u\n",c,i);
return 0;
}
上面結果一樣都是4294967295(-1表示全1),這個數是unsigned int所能表達的最大的數,char正常-1只有一個字節,只有最低位為1,當我們把小於int的變量傳給printf時,編譯器會把變量轉換為int傳進去,因為是有符號的,會被擴展為所有位都是1,最后作為unsigned結果就是現在這個結果。
八進制和十六進制
- 一個以0開始的數字字面量是8進制
- 一個以0x開始的數字字面量是16進制
#include <stdio.h>
int main()
{
char c = 012;
int i = 0x12;
printf("c=%d,i=%d\n",c,i);
//%o是8進制,%x是16進制
return 0;
}
//輸出結果為c=10,i=18
%d是想讓它以十進制的方式輸出。
八進制,1x8+2x1=10;十六進制,1x16+2x1=18
進制只是我們怎么去看它,並不代表在計算機內部它會表示成八進制或十六進制,
計算機內部永遠只有二進制,你在程序中寫個八進制,編譯器會替你轉成對應的十進制形式去變成二進制交給計算機
小總結:
0001 (1) 00010(2)前四個bit表達為1,后四個為2,12就可以表達前面的二進制數,16進制的兩位正好表達一個char(1個字節)
選擇整數類型
CPU每次從內存中讀一次數據,每一次向其中寫一次數據,就是一個int,如果你讓它做一個char,實際上它做的就是把32 bit的數據全部讀進來,然后從當中拿出那8 bit給你。