1. 程式人生 > >安靜的改變——隱式類型提升

安靜的改變——隱式類型提升

類型轉化 自然 size img 等於 結束 轉換成 clu style

C語言中有一些隱晦的地方也是容易造成bug的根源。

先說最常見的一種類型提升:

 1 #include<stdio.h>
 2 
 3 int main(void)
 4 {
 5     int m=-1;
 6     unsigned int n=1;
 7     m>n?printf("-1>1\n"):printf("-1<=1\n");
 8 
 9     return 0;
10 }

技術分享

在還是新手的時候,對於這樣的現象很納悶,也是自己寫代碼的時候很容易出bug的地方。這裏的知識點是,當int和unsigned int比較時,int會被提升成無符號的,這樣無符號的-1提升成一個很大的正整數,肯定大於1,那麽運行結果也就不足為奇了。但是,既然知道了有這種提升存在,那麽我們就應該知道c標準到底是怎麽定義這樣的提升的。

再看下面一個:

 1 #include<stdio.h>
 2 
 3 int main(void)
 4 {
 5     unsigned int a;
 6     int  b = -7;
 7     a=6;
 8     (a+b>6)?printf(">6\n"):printf("<=6\n");
 9     printf("%u\n",a+b);
10     a=8;
11     (a+b>8)?printf(">8\n"): printf("<=8\n");/*執行加法之後,才進行類型提升*/
12     printf("
%u\n",a+b); 13 return 0; 14 }

技術分享

通過結果可以知道,在進行運算之後,才進行類型提升。當a=8,b=-7時,相加等於1,輸出顯式1<8,正確,這也證明了,-7在和8相加前,沒有提升成無符號的,而是相加之後的數是無符號的,通過a=6,b=-7相加之後為-1,然後-1提升成無符號的,結果顯示>6。

但是,這並沒有結束,繼續:

 1 #include<stdio.h>
 2 
 3 int main(void)
 4 {
 5     int a=-1;
 6     unsigned char b=1;
 7     a>b?printf("
>\n"):printf("<\n"); 8 9 return 0; 10 }

技術分享

奇怪麽,不是說好的無符號數和有符號數比較或者運算之後會提升成無符號的麽,那這裏怎麽顯示-1<1了啊?按道理-1轉換成無符號的應該大於1啊。這個測試證明了一點,我們對ANSI C標準解釋不完全。

類型提升,在ANSI C上舉了很多例子,也有點晦澀,用自己的話總結就是:

在無符號和有符號的數運算中,數據類型朝著更大的類型轉化,int和unsigned int,後者更大,故轉化成後者,int和unsigned char,前者更大,故兩者運算時,顯示的類型為int,既然為int,自然可以比較-1和1的大小。但是這裏地描述並不完全正確,因為還要考慮一個值溢出問題。

安靜的改變——隱式類型提升