C語言自動型別轉換和強制型別轉換詳解

2020-07-16 10:04:20
計算機硬體進行算術操作時,要求各運算元的型別具有相同的大小(儲存位數)及儲存方式。例如,由於各運算元大小不同,硬體不能將 char 型( 1 位元組)資料與 int 型( 2 或 4 位元組)資料直接參與運算;由於儲存方式的不同,也不能將 int 型資料與 float 型資料直接參與運算。

然而,由於 C 語言程式設計的靈活性,在一個表示式或一條語句中,允許不同型別的資料混合運算。

C 語言的靈活性與計算機硬體的機械性是一對矛盾,如處理不好,將會產生錯誤結果。對於某些型別的轉換編譯器可隱式地自動進行,不需人工干預,稱這種轉換為自動型別轉換;而有些型別轉換需要程式設計者顯式指定,通常,把這種型別轉換稱為強制型別轉換

自動型別轉換

一個表示式中出現不同型別間的混合運算,較低型別將自動向較高型別轉換。

不同資料型別之間的差別在於資料的表示範圍及精度上,一般情況下,資料的表示範圍越大、精度越高,其型別也越“高階”。

整型型別級別從低到高依次為:

int -> unsigned int -> long -> unsigned long -> long long -> unsigned long long

浮點型級別從低到高依次為:

float -> double


1) 運算元中沒有浮點型資料時:

當 char、unsigned char、short 或 unsigned short 出現在表示式中參與運算時,一般將其自動轉換為 int 型別,特殊情況下 unsigned short 也可能轉換成 unsigned int(如 Turbo C2.0 中,short 和 int 所佔位元組數相同,unsigned short 的正數表示範圍比 int 大,故將其轉換為 unsigned int)。

int 與 unsigned int混合運算時:

int -> unsigned int

int、unsigned int 與 long 混合運算時,均轉換為 long 型別。

2) 橾作數中有浮點型資料時:

當運算元中含有浮點型資料(float 或 double)時,所有運算元都將轉換為 double 型。

例如:
3+5.3f+1.7
上述算術表示式中運算元 1.7 為雙精度浮點數,故先把 3 和單精度浮點數 5.3 自動提升為雙精度浮點數後,參與運算。運算結果為雙精度浮點數 10.0。

3) 賦值運算子兩惻的型別不一致時:

當賦值運算子的右值(可能為常數、變數或表示式)型別與左值型別不一致時,將右值型別可能提升或降低為左值型別。例如:
double d;
d=5.1f;
由於左值為雙精度浮點型,故先把右值單精度浮點型常數 5.1 提升為雙精度浮點型後,再賦值給 d,不但不丟失精度反而提高了精度。
int i;
i=5.1; //右值5.1為雙精度,左值為整型
右值雙精度浮點型 5.1 降低為左值整型,即 5.1 捨棄小數部分後,把 5 賦給整型變數 i,這種情況會丟失精度。

4) 右值超出左值型別範圍時:

更糟糕的情況是,賦值運算子右值的範圍超出了左值型別的表示範圍,將把該右值截斷後,賦給左值。所得結果可能毫無意義。例如:
char c; //char 占8位元,表示範圍-127?128
c=1025; //1025 對應二進位制形式:100 0000 0001,超出了8位元
printf("%d",c) ; //以十進位制輸出c的值
該輸出結果為 1,因為只取 1025 低 8 位 0000 0001(值為1),賦給字元型變數 c,故得到毫無意義的值。

當 return 後的表示式型別與函數的返回值型別不一致時,也會自動把 return 後表示式的值轉換為函數型別後,再返回。

當函數呼叫時,所傳實參與形參型別不一致時,也會把實參自動轉換為形參型別後再賦值。

強制型別轉換

雖然自動型別轉換不需要人工干預,使用方便,但有利也有弊,尤其當自動型別轉換是從較高型別轉換為較低型別時,將會降低精度或截斷資料,可能得不到預期的結果。

為了給程式設計人員提供更多的型別轉換控制許可權,使程式設計更加靈活,轉換的目的更加清晰,C 語言提供了可顯式指定型別轉換的語法支援,通常稱之為強制型別轉換。

強制型別轉換的格式為:

(目標型別) 表示式

例如,計算某工廠目前可出廠的產品總件數用 total 表示,該工廠共有三個車間,已知:1 車間目前完成 10.9 件,2 車間目前完成 12.7 件,3 車間目前完成 11.8 件。則:
int total;
total=(int)10.9+(int)12.7+(int)11.8;
故 total=10+12+11=33,符合題意。

而如果採用如下的自動型別轉換:
int total=10.9+12.7+11.8;
其值將為 35。因為賦值運算子右端表示式 10.9+12.7+11.8=35.4 為雙精度浮點型,而左值 total 型別為整型,將 35.4 自動轉換為整數 35 後賦給 total。與題意不符。