天天看点

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 :编码字符集是站在存储和传输的角度,运行字符集是站在处理或者操作的角度,所以它们并不一定相同。