什么是ANSI编码?
尽管ANSI是美国国家标准学会,ANSI编码是一种对ASCII码的拓展,为了支持更多语言,用2个字节表达1个字符。例如GB2312、GBK、GB18030都是ANSI编码的一种。
为什么早期VC++对ANSI C89之后的标准支持不好?
准确的说,微软公司的C语言编译器是C++编译器的附带品。微软公司一直在为C++标准和编译器做工作,对于C语言却并不感冒。即使,Windows操作系统NT内核源代码早期就是用C语言来写,他们宁愿让大家写C++代码。早期,很多开发者都对VC++支持C标准太旧而抱怨过。
为什么VS编译UTF-8格式源代码, 代码中字符串却是ANSI编码?
说到底,问题的根源在于源代码编码是给编译器看的,可以是任何编码,只要编译器支持的编码就可以,最终生成机器码不存在编码一说。但,源代码中的字符串是实打实会交给控制台或者GUI程序展示,它的编码正确性很重要,一旦不匹配就很可能乱码。所以,源代码中字符串的编码,编译器一般采用贴近本机操作系统的默认编码,Windows当然是ANSI编码,Linux平台一般为UTF-8编码。这就出现和源代码编码不一致的情况了。例如,OS默认是ANSI编码,UTF-8格式源代码,字符串"我"在VC编译依然是GB2312编码CE D2. 假设字符串变量出现在如下demo.c中:
- cl /source-charset:utf-8 demo.c "我"对应: CE D2.
- cl /utf-8 demo.c "我"是UTF-8编码,对应: E6 88 91.
- cl /execution-charset:gb2312 demo.c "我"对应: CE D2.
- cl /execution-charset:utf-8 demo.c "我"是UTF-8编码,对应: E6 88 91.
字符串默认编码
随着编程语言逐渐国际化,字符串并不总是早期的ASCII码,中文也逐渐进入编程语言的世界。不同编程语言和编译器因设计差异,字符串默认编码也可能存在差异。
- GCC/G++/Clang/Clang++编译的C/C++代码默认字符串为UTF-8编码,MSVC默认字符串为ANSI编码。ObjC编译器是GCC或Clang, 跟随编译器的特性,NSString字符串默认编码也是UTF-8.
- 可通过objdump -x -s a.out获取字符串常量的数值。
- Rust字符串默认编码也是UTF-8编码,可用str.as_bytes()获取原始数据。
- Swift 5之前字符串默认编码是ASCII(如果字符串每个字符都是ASCII码)和UTF-16,Swift 5之后(包含)默认编码为UTF-8.
- Go默认字符串原始数据为UTF-8编码,通过[]byte(str)获取原始字节数据。
- Java/C#字符串原始数据是UTF-16编码(字符串被加载到内存中的编码),尽管java编译出.class文件可能是UTF-8编码。
若文章对您有帮助,欢迎关注 程序员小迷 。助您在编程路上越走越好!
微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。
我是 程序员小迷 (致力于C、C++、C#、Android、iOS、Java、Kotlin、Objective-C、Swift、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。