博客 / 詳情

返回

C語言中的整型提升

整型提升

什麼是整型提升?為什麼要使用整型提升?整型提升是如何進行的?

1.整型提升

在c語言中,一些表達式在求值的過程中,操作數可能需要轉換為其他類型,這種轉換,我們程序員是看不見的,稱其為隱式類型轉換,而整型提升就是之一

1.1什麼是整型提升

在C語言中計算整數的時候,會將整型家族中小於4字節的類型(char ,short),自動變為4字節也就是int類型,而這個自動轉換的過程,我們稱作整型提升

1.2為什麼使用整型提升

使用原因和硬件有關,CPU中負責整數運算的部件整數運算器ALU以及通用寄存器,能夠一次性處理的數據的大小為4byte也就是32位的二進制數,剛好是C語言中一個int的大小(這是32位cpu的一次性處理數據的大小,64位是8字節),為了能保證CPU的高效運算,C語言會默認把小於四個字節的整型數據提升到四個字節(64位的CPU同樣會先提升到int,而int在主流編譯器中依舊是4字節,不知道有沒有8字節的,無論是32位CPU還是64位CPU,只有當操作數本身無法用int存放時,才會使用更長字節的整型)

舉個例子
long long a = 100;
int b = 200;
long long c =a + b;
//此時,我們在計算a+b時,編譯器就會對b進行整型提升,以便於和8byte的long long 類型計算
char d = 20;
b = d + b;
//同理在計算d+b時,會對d進行整型提升,提升為四字節的int
1.3截斷

你可能會問,如果上面的例子中我c不是long long類型怎麼辦,計算結果是8byte難道我用int型也能裝下嗎?
並非如此,因為此時會發生截斷。

1.3.1什麼是截斷

在數據類型中,大字節數的數值放到小字節數的變量中時,超出變量存儲範圍的二進制位(高位)將會被直接丟棄,這個行為被稱為截斷

舉個例子
char a = 10;
int b = 10;
int c = 10;
a = b + c;
//此時就會發生截斷
//00000000 00000000 00000000 00010100  20的32位補碼
//當放進1byte的char中時,會發生截斷,變為00010100,但結果依舊是20
但是,當被截斷的數值過大,就有可能會導致數值丟失

2.整型提升的過程

對於有符號數,符號位為1時(負數),在補碼的高位補1,直至補到想要提升到的字節數(bit位數)
對於有符號數,符號位為0時(正數),在補碼的高位補0,直至補到想要提升到的字節數(bit位數)
對於無符號數,在補碼的高位補0,直至補到想要提升到的字節數(bit位數)

舉個例子
#include<stdio.h>
int main(void)
{
	char a = 0;
	int b = 10;
	int c = 10;
	a = b + c;
	printf("%d",a);
	return 0;
}
//b+c的值為20,補碼為00000000 00000000 00000000 00010100
//賦值給a時,會發生截斷,所以a存的補碼為00010100,但值依舊是20
//由於printf函數在打印時打印的是int,但a卻是char,此時會發生整型提升
//20是正整數(char默認為signed char),所以在高位補0,補碼為00000000 00000000 00000000 00010100
再舉一個例子
#include<stdio.h>
int main(void)
{
	char a = 0;
	int b = 100;
	int c = 100;
	a = b + c;
	printf("%d",a);
	return 0;
}
//此時計算結果為200,補碼為00000000 00000000 00000000 11001000
//賦值給a,發生截斷,補碼為11001000
//由於a為signed char,所以最高位為符號位
//當我們將它以int類型打印時,會發生整型提升,最高位為1,我們補1
//11111111 11111111 11111111 11001000  補碼
//原碼就等於補碼加1再按位取反(先求反碼和直接求補碼的結果是一樣的,區別就是一個減一取反,一個取反加一)
//10000000 00000000 00000000 00111000(記住符號位不變)原碼
我們發現此時的結果變為了-56

上面的例子數據就發生了問題,原本是200,結果變成了-56,這也是使用整型提升時要注意的,無符號數也是按規則來,這裏不單獨舉例了

user avatar pudongping 頭像 zilliz 頭像 tingtr 頭像 TwilightLemon 頭像 mylxsw 頭像 xiaojiu_625c14980f596 頭像 yimin333 頭像 yaha_5f66c6f02983e 頭像 phytium_developers 頭像 emanjusaka 頭像 software_arch 頭像 kubesphere 頭像
18 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.