漢字到底佔幾個字節丨C

這裏寫圖片描述


首先需要注意

漢字所佔字節數,與所使用語言自身沒有關係,是與其使用的字符集的編碼方案有關


驗證方法

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」來稱呼一個編碼方案不合適,並且誤導

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章