原理:
術語解釋:整型提升屬於類型提升的一部分。當操作符兩邊的類型的等級都小於整型(int)的範圍時,默認情況下會把該類型提升爲整型(int)進行計算。例如:對於char
類型的計算,就會提升爲對應的整型的計算。最終結果再轉爲char返回。
整型提升
當對小於int的整數類型執行操作時,將提升它們,如果該原始類型的所有值都可以用int類型
來表示,那麼該小類型將會轉換爲int
的類型。否則的話,它將被轉換爲unsigned int
。整數提升作爲通常算術轉換的一部分,用於某些參數表達式,常用的算術預算符號:一元運算符:(+,-,~,以及位操作符)。
下面的代碼片段展示了該整型提升
char c1, c2;
c1 = c1 + c2;
整型提升的優點
整型提升要求每一個變量都提升爲int
類型(c1和c2)。兩個變量的int值進行相加,然後結果被截斷爲char類型。整型提升避免了中間值的溢出。
signed char cresult, c1, c2, c3;
c1 = 100;
c2 = 3;
c3 = 4;
cresult = c1 * c2 / c3;
這個例子中,結果值爲c1c2然後除以c3。假設signed char
有8個位組成,c1c2的結果值(300)無法被表示,(8位最大值爲256)。由於整型提升原則,他們的值就可以被保存,最終結果轉爲char類型,而不會丟失數據。
整型提升的缺點
位操作符一般是作用與整型類型
上,當在比整型
類型小的類型上使用位操作符時,如果不注意,可能會產生問題。
不合法操作
這個例子中,代碼的本意是先對port取反,然後向右移動四位。如果這兩個操作符都作用在8字節的unsigned integer
上時,最終的結果將會是0x0a
,但是,操作過程中,port
首先會升級爲signed int
類型,然後可能會產生下面圖表中的結果。
uint8_t port = 0x5a;
uint8_t result_8 = ( ~port ) >> 4;
表達式 | 類型 | 值 | 備註 |
---|---|---|---|
port | uint8_t | 0x5a | |
~port | int | 0xffffffa5 | |
~port >> 4 | int | 0x0ffffffa | 值是否爲負由實現定義 |
result_8 | uint8_t | 0xfa | 截取8字節作爲unsigned |
合法的操作
在下面的例子中,port的位實現被轉換爲8個字節。下面的結果是希望的結果0x0a
uint8_t port = 0x5a;
uint8_t result_8 = (uint8_t) (~port) >> 4;
附錄:不同類型轉換規則
1、隱式轉換
C在以下四種情況下會進行隱式轉換:
1、算術運算式中,低類型能夠轉換爲高類型。
2、賦值表達式中,右邊表達式的值自動隱式轉換爲左邊變量的類型,並賦值給他。
3、函數調用中參數傳遞時,系統隱式地將實參轉換爲形參的類型後,賦給形參。
4、函數有返回值時,系統將隱式地將返回表達式類型轉換爲返回值類型,賦值給調用函數。
2、算數運算的隱式轉換
算數運算中,首先有如下類型轉換規則:
1、字符必須先轉換爲整數(C語言規定字符類型數據和整型數據之間可以通用) 。
2、short型轉換爲int型(同屬於整型) 。
3、float型數據在運算時一律轉換爲雙精度(double),以提高運算精度。
附錄引用:http://blog.csdn.net/miaouu/article/details/5213042
翻譯自:卡耐基梅隆大學 軟件研究院