嵌入式開發中常見困惑:char buf = 0xBF; printf("%x", buf); 輸出 ffffffbf 而非預期 bf。本文從類型提升、補碼表示、參數傳遞三個層面徹底講透。
char buf[10] = {0};
buf[0] = 0xBF;
printf("%x\n", buf[0]); // 輸出:ffffffbf (預期 bf)
buf[1] = 0x7F;
printf("%x\n", buf[1]); // 輸出:7f (正常)
char 是否帶符號char = signed char0xBF = 1011 1111b,最高位 1 → 負數(-65)printf 是可變參數函數,... 部分發生默認參數提升:
char/short → int(或 unsigned int)float → double有符號 char 提升時進行符號擴展:
0xBF (char, 8bit) → 0xFFFFFFBF (int, 32bit, 兩補碼)
0x7F (char, 8bit) → 0x0000007F (int, 32bit, 最高位 0 無擴展)
%x 對應 unsigned intint(負數補碼全 1 高位)f| 方法 | 代碼 | 原理 | 推薦度 |
|---|---|---|---|
| 強制無符號轉換 | printf("%x", (unsigned char)buf[0]); | 提升為 unsigned int,高位補 0 | ⭐⭐⭐⭐⭐ |
| 定義為 unsigned char | unsigned char buf[10]; | 源頭消除符號擴展 | ⭐⭐⭐⭐ |
| 掩碼取低 8 位 | printf("%x", buf[0] & 0xFF); | 位運算後提升為非負 int | ⭐⭐⭐ |
printf("%x", 0xBF); // 輸出 bf
0xBF 無後綴默認類型為 int(非負),無符號擴展問題,直接匹配 %x。

uint8_t/unsigned char 存儲字節數據printf("%02x", (unsigned char)byte);(補齊兩位)-funsigned-char 強制 char 為無符號(影響 ABI,謹慎用於現有項目)-Wformat/-Wformat-signedness 捕獲類型不匹配ffffffXX 本質是 有符號 char 負值 → 符號擴展為 int → %x 按無符號解讀** 的組合產物。理解「類型提升規則」是攻克 C 語言變參函數陷阱的金鑰。