1. 程式人生 > 其它 >C語言入門易錯點:整型提升和截斷

C語言入門易錯點:整型提升和截斷

技術標籤:c語言c++c語言補碼

C語言入門易錯點:整形提升和截斷

什麼是整型提升

    C的整形算術運算總是至少以預設整形型別的精度來進行的。為了獲得這個精度,表示式中的字元和短整型運算元再使用之前被轉轉為普通整型,這種轉換稱為整型提升。

整型提升的意義

    表示式的整型運算要在CPU的相應運算器件內執行,CPU內整型運算器(ALU)的運算元的位元組長度一般就是int的位元組長度,同時也是CPU的通用暫存器的長度。
    因此,即使兩個char型別的相加,在CPU執行時實際上也要先轉換為CPU內整型運算元的標準長度。

    通用CPU(general-purpose CPU)是難以實現兩個8位元位元組直接相加運算。所以,表示式中各種長度可能小於int長度的整型值,都必須先轉換為intunsigned int,然後才能送入CPU去執行運算。

在什麼情況下會發生?

    我們在進行邏輯運算的時候,可能一個簡單的比較或者輸出就會出現這種情況。

char num = 1;
printf("%d\n", num);
printf("%u\n", num);

執行效果為:
執行效果

  1. 第一次提升:
        我們此處將num以無符號整型的格式進行列印,此時會輸出4294967295
    也就是32位程式之下無符號整型能儲存的最大的數。
    為什莫是最大的數呢?

    因為 num的型別為char只佔用1個位元組,因為要將其以整型的格式打印出來,這時候就出現了第一次整型提升,將原本為char型別的資料轉換為了int,將其提升為整型。

我們看到將其按照整型打印出來的結果為 -1

  1. 第二次提升:

我們將其再次進行列印,不過以無符號整型的方式進行列印,但此時他輸出的是一個無符號整型能儲存的最大值。這時候出現了第二次整型提升,將char提升為unsigned int 無符號整型。為什莫輸出的是最大值呢?

計算機在儲存資料的時候都是以0 1 程式碼儲存在計算機內,正數和負數都存的是他的補碼。正數的反碼和補碼都等於他的二進位制數,負數的補碼等於他的反碼 + 1。

這時候再來看,我們是將 -1 以無符號整型的形式列印,其對應的補碼為 11111111 11111111 11111111 11111111,當提升以後會將其看為無符號,於是就將其輸出,也就是我們看到的最大值

截斷

我們先來看看這段程式碼

	char i=129;
	printf("%d\n",i);

我們不妨猜一猜,輸出的結果會是多少?經過上面的講解,在這裡,會出現整型提升,很明顯。但是輸出的結果卻和我們預料的大相徑庭。
截斷的結果
為什麼會出現這種結果,通過整型提升不是應該輸出一個129嗎?這裡我們再來了解一下,截斷。
出現整型提升時,只會將該型別的資料讀取方式改變,但是並不會改變他的儲存大小。char只有一個位元組,將一個4位元組的整數強行賦值給他,此時,他就會將溢位的位自動捨棄,只會保留他能儲存的最大位,也就是8個位元位,也就是說,經過提升和截斷以後,他的二進位制數為1111 1111將其按照整型列印時,其只能讀出8個位元位,而且8個位都是1,第一位作為符號位,即只有後7位儲存資料,固打印出來的數為: -127