首先需要注意
漢字所佔字節數,與所使用語言自身沒有關係,是與其使用的字符集的編碼方案有關
驗證方法
1.把下面代碼保存到一個文本文體中
#include <stdio.h>
#include <string.h>
int main(){
char *a = "我";
printf("%d",strlen(a));
return 0;
}
2.在終端中用vim打開保存上面代碼的文件。
\>vim char.c ( >表示終端中輸入)
3.在vim中輸入如下 :set fileencoding 會顯示當前編碼格式。(冒號不能省略)
4.把文件編碼改爲utf-8 在打開的文件中輸入 :set fileencoding=utf-8 冒號不能省,保存文件。
5.編譯執行
>gcc char.c
>./a.out
6.重複3-5步,把第四步utf-8改爲gb2312
:set fileencoding=gb2312
7.兩次打印一個3,一個2
結論
到底C語言中的漢字佔用幾個字節,只跟其採用的字符集的編碼方案有關
gb2312中佔用2個字節,utf-8中佔用3個字節
額外介紹字符集與編碼方式
一、中文可能碰到的編碼
ANSI:最早的時候計算機ASCII碼只能表示256個符號(含控制符號),這個字符集表示英文字母足夠,其中,我們鍵盤上可見的符號的編碼範圍是從32到126(大小寫英文字母、數字、英文符號等)。但表示漢字、日語、韓語就不太夠用了,漢字常用字有3000多個。
不同的國家和地區制定了不同的標準,由此產生了 GB2312, BIG5, JIS 等各自的編碼標準。這些使用 2 個字節來代表一個字符的各種漢字延伸編碼方式,稱爲 ANSI 編碼
但是中國人也要用電腦打字,於是,中國人就研究出來了最早的中文字符集GB2312(GBK就是後來的擴展),GB2312的做法是,把ASC碼取值範圍的128~255這個區間挪用了一下,用兩個ASC碼錶示一個漢字,這樣可用的編碼範圍用十六進制表示就是0x8080到0xFFFF,這大概能表示一萬多個符號,足夠了。[注:實際沒用那麼多,GBK的範圍是8140-FEFE]
那個時候,計算機技術還不發達,各個國家搞自己的,比如臺灣,也另搞了一套,叫BIG5(俗稱:大五碼),跟大陸的也不太一樣,但方法是類似的,都是用0x80到0xFF這個區間。然後日語(有編碼JIS)、韓語等等也各搞一套。
這些國家的編碼區間都是重疊的,但同一個漢字(比如有一些漢字同時存在於簡體、繁體、日語漢字中)有不同的編碼,很混亂是不是?但也湊合用了。編碼不同導致了很多麻煩,比如一個網頁,如果你不知道它是什麼編碼的,那麼你可能很難確定它顯示的是什麼,一個字符可能是大陸簡體/臺灣繁體/日本漢字,但又是不同的幾個字。所以如果用一些很老的軟件,可能會聽說有中文版/日文版之類的,對應的版本只能在對應的系統上運行。
後來,這個對操作系統的開發實在是太困難了,因爲這意味着不同語言的版本,都要重新編碼。於是發明了Unicode。
Unicode這個東西,就是要把地球上所有的語言的符號,都用統一的字符集來表示,一個編碼真正做到了唯一。
Unicode裏有幾種編碼方案:
UTF-8:UTF-8則是網頁比較流行的一種格式:用一個字節表示英文字符,用3個字節表示漢字,準確的說,UTF-8是用二進制編碼的前綴,如果某個UTF-8的編碼的第一個字節的最高二進制位是0,則這個編碼佔1字節,如果是110,則佔2字節,如果是1110,則佔3字節……
UTF-16BE/LE:UTF-16就是Windows模式的編碼模式(Windows裏說的Unicode一般都是指這種編碼),用2個字節表示任意字符,注意:英文字符也佔2個字節(變態不?),這種編碼可以表示65536個字符,至於LE和BE,就是一個數值在內存/磁盤上的保存方式,比如一個編碼0x8182,在磁盤上應該是0x81 0x82呢?還是0x82 0x81呢?就是高位是最先保存還是最後保存的問題,前者爲BE,後者爲LE。
UTF-32:UTF-32對每個字符都使用4字節,用得很少,太費空間
二、字符集與編碼格式
對於 ASCII、GB 2312、Big5、GBK、GB 18030 之類的遺留方案來說,基本上一個字符集方案只使用一種編碼方案。
比如 ASCII 這部標準本身就直接規定了字符和字符編碼的方式,所以既是字符集又是編碼方案;而 GB 2312 只是一個區位碼形式的字符集標準,不過實際上基本都用 EUC-CN 來編碼,所以提及「GB 2312」時也說的是一個字符集和編碼連鎖的方案;GBK 和 GB 18030 等向後兼容於 GB 2312 的方案也類似。
於是,很多人受這些遺留方案的影響而無法理解字符集和編碼的關係。
對於 Unicode,字符集和編碼是明確區分的。Unicode/UCS 標準首先是個統一的字符集標準。而 Unicode/UCS 標準同時也定義了幾種可選的編碼方案,在標準文檔中稱作「encoding form」,主要包括 UTF-8、UTF-16 和 UTF-32。
所以,對 Unicode 方案來說,同樣的基於 Unicode 字符集的文本可以用多種編碼來存儲、傳輸。
所以,用「Unicode」來稱呼一個編碼方案不合適,並且誤導。