• 微信号
  • 微信号
您当前的位置:首页 > 学海无涯 > 茑语花香>C语言到底使用什么编码?

C语言到底使用什么编码?

孤峰 孤峰家 2023-06-18 81人阅读

C语言是 70 年代的产物?那个时候只有 ASCII?各个国家的字符编码都还未成熟?所以C语言不可能从底层支持 GB2312、GBK、Big5、Shift-JIS 等国家编码?也不可能支持 Unicode 字符集。

稍微有点C语言基本功的读者可能认为C语言使用 ASCII 编码?字符在存储时会转换成对应的 ASCII 码值?这也是错误的?你被大学老师和教材误导了?在C语言中?只有 char 类型的窄字符才使用 ASCII 编码?char 类型的窄字符串、wchar_t 类型的宽字符和宽字符串都不使用 ASCII 编码?

wchar_t 类型的宽字符和宽字符串使用 UTF-16 或者 UTF-32 编码?这个在上节已经讲到了?现在只剩下 char 类型的窄字符串?下面称为窄字符串?没有讲了?这就是本节的重点。

对于窄字符串?C语言并没有规定使用哪一种特定的编码?只要选用的编码能够适应当前的环境即可?所以?窄字符串的编码与操作系统和编译器有关。

但是?可以肯定的说?在现代计算机中?窄字符串已经不再使用 ASCII 编码了?因为 ASCII 编码只能显示字母、数字等英文字符?对汉语、日语、韩语等其它地区的字符无能为力。

讨论窄字符串的编码要从以下两个方面下手。 源文件使用什么编码

源文件用来保存我们编写的代码?它最终会被存储到本地硬盘?或者远程服务器?这个时候就要尽量压缩文件体积?以节省硬盘空间或者网络流量?而代码中大部分的字符都是 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。

对于编译器来说?它往往支持多种编码格式的源文件。微软编译器、GCC、LLVM/Clang?内嵌于 Xcode 中?都支持 UTF-8 和本地编码的源文件?不过微软编译器还支持 UTF-16 编码的源文件。如果考虑到源文件的通用性?就只能使用 UTF-8 和本地编码了。

窄字符串使用什么编码

前面讲到?用 puts 或者 printf 可以输出窄字符串?代码如下?

"C语言中文网"和"http://c.biancheng.net"就是需要被处理的窄字符串"程序运行后"它们会被载入到内存中。你看"这里面还包含了中文"肯定不能使用 ASCII 编码了。

1) 微软编译器使用本地编码来保存这些字符。不同地区的 Windows 版本默认的本地编码不一样"所以"同样的窄字符串在不同的 Windows 版本下使用的编码也不一样。对于简体中文版的 Windows"使用的是 GBK 编码。

2) GCC、LLVM/Clang 编译器使用和源文件相同的编码来保存这些字符"如果源文件使用的是 UTF-8 编码"那么这些字符也使用 UTF-8 编码"如果源文件使用的是 GBK 编码"那么这些字符也使用 GBK 编码。

你看"对于代码中需要被处理的窄字符串"不同的编译器差别还是挺大的。不过可以肯定的是"这些字符始终都使用窄字符"多字节字符"编码。

正是由于这些字符使用 UTF-8、GBK 等编码"而不是使用 ASCII 编码"所以它们才能包含中文。

那么"为什么很多初学者会误认为C语言使用 ASCII 编码呢"

不管是在课堂跟着老师学习"还是通过互联网自学"初学者都是从处理英文开始的"对于英文来说"使用 GBK、UTF-8、ASCII 都是一样的"GBK、UTF-8 都兼容 ASCII"初学者根本察觉不出用了哪种编码。

另外"很多大学老师和书籍作者也经常会念叨"字符在存储时会被转换成对应的 ASCII 码"在读取时又会从 ASCII 码转换成对应的字符实体"大家需要熟悉 ASCII 编码"它是C语言处理字符的基础"这从很大程度上给初学者造成一种错误印象"C语言和 ASCII 编码是绑定的"C语言使用 ASCII 编码。 总结

对于 char 类型的窄字符"始终使用 ASCII 编码。

对于 wchar_t 类型的宽字符和宽字符串"使用 UTF-16 或者 UTF-32 编码"它们都是基于 Unicode 字符集的。

对于 char 类型的窄字符串"微软编译器使用本地编码"GCC、LLVM/Clang 使用和源文件编码相同的编码。

另外"处理窄字符和处理宽字符使用的函数也不一样"

<stdio.h> 头文件中的 putchar、puts、printf 函数只能用来处理窄字符"

<wchar.h> 头文件中的 putwchar、wprintf 函数只能用来处理宽字符。

你看"仅仅是字符的处理"C语言就能玩出这么多花样"让人捉摸不透"不容易学习。这是因为"C语言是一种较为底层和古老的语言"既有历史遗留问题"又有贴近计算机底层的特性。不过"一旦搞明白这些繁杂的底层问题"你的编程内功将精进一个层次"这也许就是学习C语言的乐趣。

【拓展】编码字符集和运行字符集

站在专业的角度讲"源文件使用的字符集被称为编码字符集"也就是写代码的时候使用的字符集"程序中的字符或者字符串使用的字符集被称为运行字符集"也就是程序运行后使用的字符集。

源文件需要保存到硬盘"或者在网络上传输"使用的编码要尽量节省存储空间"同时要方便跨国交流"所以一般使用 UTF-8"这就是选择编码字符集的标准。

程序中的字符或者字符串"在程序运行后必须被载入到内存"才能进行后续的处理"对于这些字符来说"要尽量选用能够提高处理速度的编码"例如 UTF-16 和 UTF-32 编码就能够快速定位"查找"字符。

编码字符集是站在存储和传输的角度"运行字符集是站在处理或者操作的角度"所以它们并不一定相同。

转载:感谢您阅览,转载请注明文章出处“来源从小爱孤峰知识网:一个分享知识和生活随笔记录的知识小站”。

链接:C语言到底使用什么编码?http://www.gufeng7.com/niaolang/467.html

联系:如果侵犯了你的权益请来信告知我们删除。邮箱:119882116@qq.com

标签: