程式碼:
int i = 289;
char c = i; // 編譯警告:隱式轉換可能遺失資料
printf("%d", c); // 輸出 33,而非 289
為什麼 289 變成 33?這不是 Bug,是整型提升與截斷規則的必然結果。
289 (十進制)
= 1 0010 0001 (二進制,9 位)
= 0000 0001 0010 0001 (16 位 int 表示)
char 只有 8 位 → 截取低 8 位
低 8 位 = 0010 0001 = 0x21 = 33 (十進制)
char 有號性實作定義(通常有號),unsigned char 則為 0~255#include <stdio.h>
#include <limits.h>
int main() {
int i = 289;
signed char sc = i; // 實作定義,通常 -128~127
unsigned char uc = i; // 0~255
printf("i=%d, sc=%d, uc=%u\n", i, sc, uc);
// 輸出:i=289, sc=33, uc=33
return 0;
}
| 場景 | 風險 | 防範 |
|---|---|---|
網路協議解析 uint16_t → uint8_t | 高位截斷導致協議解析錯誤 | 顯式 & 0xFF 或驗證範圍 |
檔案格式讀取 int → char | 負數變正數、大數變小數 | 用 uint8_t、int32_t 明確寬度類型 |
遞迴/迴圈計數器 int → char | 超過 127 產生負數導致無限迴圈 | 計數器用 int 或 size_t |