1. 程式人生 > >C程式的編碼方式

C程式的編碼方式


一、編碼

編碼是用預先規定的方法將文字、數字或其它物件編成數碼。為保證編碼的正確性,編碼要規範化、標準化,即需有標準的編碼格式。

  • 我們都知道文字在計算機中是以二進位制來進行儲存,這就需要把文字通過一定的規則轉換成二進位制來儲存。這種規則就是編碼。
  • 每個不同的國家,不同的地區都有自己不同的語言文字,這些文字通過不同的編碼,轉換成二進位制資訊進行儲存。使用什麼編碼格式編碼,就需要使用相同的格式解碼。
  • 為了便於檔案全球化交換與使用,有一些編碼規則支援了很多語言的轉換規則。通過這種編碼規則,就可以支援多種語言。
  • 常見的編碼格式有ASCII、ANSI、GBK、GB2312、UTF-8、GB2312-80和Unicode等。

二、C語言的編碼

  • C語言是 70 年代的產物,那個時候只有ASCII,各個國家的字元編碼都還未成熟,所以C語言不可能從底層支援 GB2312、GBK、Big5、Shift-JIS等國家編碼,也不可能支援 Unicode 字符集。

  • 在C語言中字元有兩種,一種是窄字元,另一種是寬字元。

    • 只有 char 型別的窄字元才使用 ASCII 編碼
    • char 型別的窄字串、寬字元和寬字串都不使用 ASCII 編碼!
  • 可以肯定的說,在現代計算機中,窄字串已經不再使用 ASCII 編碼了,因為 ASCII 編碼只能顯示字母、數字等英文字元,對漢語、日語、韓語等其它地區的字元無能為力。對於窄字串,C語言並沒有規定使用哪一種特定的編碼,只要選用的編碼能夠適應當前的環境即可,所以,窄字串的編碼與作業系統和編譯器有關。


三、程式的編碼

  • 原始檔使用什麼編碼
    原始檔用來儲存我們編寫的程式碼,它最終會被儲存到本地硬碟,或者遠端伺服器,這個時候就要儘量壓縮檔案體積,以節省硬碟空間或者網路流量,而程式碼中大部分的字元都是 ASCII 編碼中的字元,用一個位元組足以容納,所以 UTF-8 編碼是一個不錯的選擇。

    UTF-8 相容 ASCII,程式碼中的大部分字元可以用一個位元組儲存;另外 UTF-8 基於 Unicode,支援全世界的字元,我們編寫的程式碼可以給全球的程式設計師使用,真正做到技術無國界。

  • 常見的 IDE 或者編輯器使用的編碼

    • 絕大多數的編譯器,如:Xcode、Sublime、Text、Gedit、Vim等,在建立原始檔時一般也預設使用 UTF-8 編碼。
    • 奇葩 Visual Studio 它預設使用本地編碼來建立原始檔。

    • 所謂本地編碼,就是像 GBK、Big5、Shift-JIS 等這樣的國家編碼(地區編碼);針對不同國家發行的作業系統,預設的本地編碼一般不同。簡體中文字的 Windows 預設的本地編碼是 GBK。
    • 這就導致 Visual Studio在上傳github時,出現中文亂碼的現象。需要將檔案強制轉換成utf-8的編碼模式。再進行上傳。

ps :對於使用 Visual Studio 上傳github的使用者。可以使用原生代碼轉換器,將GBK->UTF-8,便於在github Desktop中檢視(github Desktop 不會轉碼,中文會出現亂碼情況)。不過 github網頁的程式碼會自動轉碼,不會出現亂碼。

  • 程式編譯時的編碼

1) 微軟編譯器使用本地編碼來儲存這些字元。不同地區的 Windows 版本預設的本地編碼不一樣,所以,同樣的窄字串在不同的 Windows 版本下使用的編碼也不一樣。對於簡體中文版的 Windows,使用的是 GBK 編碼。

2) GCC、LLVM/Clang 編譯器使用和原始檔相同的編碼來儲存這些字元:如果原始檔使用的是 UTF-8 編碼,那麼這些字元也使用 UTF-8 編碼;如果原始檔使用的是 GBK 編碼,那麼這些字元也使用 GBK 編碼。

你看,對於程式碼中需要被處理的窄字串,不同的編譯器差別還是挺大的。不過可以肯定的是,這些字元始終都使用窄字元(多位元組字元)編碼。

對於 char 型別的窄字串,微軟編譯器使用本地編碼,GCC、LLVM/Clang 使用和原始檔編碼相同的編碼。


四、編碼字符集和執行字符集

  • 站在專業的角度講,原始檔使用的字符集被稱為編碼字符集,也就是寫程式碼的時候使用的字符集;程式中的字元或者字串使用的字符集被稱為執行字符集,也就是程式執行後使用的字符集。
    • 原始檔需要儲存到硬碟,或者在網路上傳輸,使用的編碼要儘量節省儲存空間,同時要方便跨國交流,所以一般使用 UTF-8,這就是選擇編碼字符集的標準。
    • 程式中的字元或者字串,在程式執行後必須被載入到記憶體,才能進行後續的處理,對於這些字元來說,要儘量選用能夠提高處理速度的編碼,例如 UTF-16 和 UTF-32 編碼就能夠快速定位(查詢)字元。

ps :編碼字符集是站在儲存和傳輸的角度,執行字符集是站在處理或者操作的角度,所以它們並不一定相同。