一切始於一個百度知道的問題:206 210 176 174 214 236 187 219 這串 ASCII 碼代表什麼中文?答案竟是「我愛朱慧」。這激發了作者對 C 語言中漢字編碼存儲機制的深入探索之旅。
在 GB2312/GBK 等中文編碼體系下,一個漢字佔用兩個字節(16 bits)。C 語言中 char 型別僅 1 字節,因此輸出漢字時需連續輸出兩個 %c 格式字元,對應高低位字節:
printf("%c%c%c%c%c%c%c%c", 206,210, 176,174, 214,236, 187,219);
// 輸出:我 愛 朱 慧
對應關係如下:
作者編寫循環程式,測試 129~247 範圍內的字節組合,記錄了大量雙字節對應的漢字(如 186+186=漢、187+187=換、191+191=靠 等),但始終未找到「你」字。這反映了 GB2312 編碼並非簡單的線性映射,而是分區位碼(區碼 16-55,位碼 1-94)。
參考資料二指出:C/C++ 中漢字以兩個有號字節(負數)形式存儲。利用這一特性,可直接打印漢字的內部編碼:
char s[] = "你";
printf("%d %d\n", s[0], s[1]); // 輸出:-60 -29
將這兩個負數作為 %c 參數傳給 printf,即可正確輸出「你」。最終完美實現「我愛你」:
printf("%c%c%c%c%c%c\n", 206,210, 176,174, -60,-29);
GB2312 編碼 = 區位碼 + 0xA0A0(即高低位各加 160)。
例如「啊」區位碼 1601 → 區碼 16+160=176,位碼 01+160=161 → 機內碼 B0A1(有號字節為 -80, -95)。
char 處理。char 表示高位元組(MSB=1)的結果,並非錯誤。"中文" 讓編譯器處理編碼轉換。