網路程式開發中常見困惑:byte 真實值 0xc9,打印卻顯示 0xffffffc9。本文通過完整代碼演示、記憶體佈局圖解、補碼運算推導,系統性拆解此現象本質,並給出工業級修正最佳實踐。
#include <stdio.h>
int main() {
char c = 0xc9; // 有號 char,值 -55
printf("A: c = %2x\n", (unsigned char)c); // 方案 A
printf("B: c = %2x\n", c & 0xff); // 方案 B
printf("C: c = %2x\n", c); // 方案 C(問題現場)
return 0;
}
輸出:
A: c = c9 B: c = c9 C: c = ffffffc9
C 標準規定:%x 對應 unsigned int。可變參函數觸發整型提升,char → int。
0xc9 = 1100 10011100 1001char (8 bit) : 1 100 1001
int (32 bit) : 1111 1111 1111 1111 1111 1111 1 100 1001
↑ 符號位複製 24 次
結果 : 0xFFFFFFC9
Linux 核心傾向方案 B(`& 0xff`),主要考慮歷史效能與宏定義便利性,現代編譯器優化下兩者機器碼通常一致。
uint8_t/unsigned charprintf("%02x", (unsigned char)byte)char 是否混用作數值與字元C99 引入 hh 長度修飾符,printf("%hhx", c) 直接按 unsigned char 處理,**無需顯式轉型**。但需確認編譯器支援度(MSVC 2013+、GCC/Clang 全支援)。
0xffffff 前綴本質是 有號 char → int 符號擴展 的必然結果。掌握「提升 → 擴展 → 解讀」鏈路,配合 unsigned char 強型別或 %hhx 現代寫法,即可從根源消除此類困擾。