C 語言允許不同類型數據混合運算與賦值,編譯器依據嚴格規則執行「自動類型轉換」(隱式),程序員亦可使用「強制類型轉換」(顯式)掌控精度與語義。理解這兩套機制對編寫正確、高效、可移植代碼至關重要。
發生於混合類型運算、函數參數傳遞、賦值、返回值等場景。核心原則:**向「長度更長、精度更高」的類型轉換,避免精度損失**。
char、short(有符號/無符號)參與運算先提升為 int(若 int 容不下則提升為 unsigned int)。long double → 另一操作數轉為 long double。double → 轉為 double。float → 轉為 float。unsigned long long > long long > unsigned long > long > unsigned int > int。
右值轉為左值類型。若右值類型「更長/更精確」,會發生**窄化轉換**:截斷高位(整數)、捨去小數(浮點→整數)、精度損失(double→float)。編譯器通常發出警告。
#include <stdio.h>
int main() {
float PI = 3.14159f;
int r = 5, s;
s = r * r * PI; // r 提升為 int,r*r 為 int,與 PI 混合 → 雙精度計算,結果轉 int 截斷
printf("s=%d\n", s); // 輸出 78 (3.14159*25=78.53975 → 78)
return 0;
}
語法:(類型名) 表達式。功能:將表達式結果**臨時**轉為指定類型,**不改變原變量類型與值**。
(int)(x + y) ≠ (int)x + y。#include <stdio.h>
int main(void) {
float f = 5.75f;
printf("(int)f=%d, f=%f\n", (int)f, f); // 輸出:(int)f=5, f=5.750000
return 0;
}
| 場景 | 風險 | 建議 |
|---|---|---|
| 浮點→整數賦值 | 靜默截斷小數 | 顯式 (int) 或用 lrint/round 四捨五入 |
| 大整型→小整型 | 高位截斷,符號可能翻轉 | 斷言範圍或用 static_assert |
| 有符號/無符號混合 | 負數變巨大無符號數 | 統一用有符號,或顯式轉型 |
| 指針轉整數/整數轉指針 | 實現定義行為,可能截斷 | 用 uintptr_t/intptr_t,避免直接轉型 |
-Wconversion、-Wsign-conversion),靜態分析捕獲隱式窄化。