C++中宽字符类型(wchar_t)的编码
转载⾃: www.ituring/article/111027
问题的起因是和⼀个朋友讨论不同编码的转换问题,说到了wchar_t的类型,朋友的看法是,wchar_t的编码⽅式是utf-16,长度⼀定是16位的。我的看法不同,我认为wchar_t的长度和编码⽅式都是编译器和平台决定的,和语⾔没任何关系。
后来这个朋友为了说服我,回家把C++ Primer给我搬出来了,还给我截了个图(因为我没这本书),在这本书第30页有个表格,清楚地写着wchar_t是unicode字符,⽽最⼩尺⼨是16。既然“最⼩尺⼨是16”了,那么其他尺⼨的可能性就有了,但是编码⽅式是怎么回事?因为凭我印象,貌似没有任何⽂档规定过宽字符的编码⽅式,我想说服我朋友,但脑⼦⾥有没有证据,不知道从何说起,因此回家仔细查了查资料,算是有了个了解。
1. 宽字符的编码⽅式到底是谁定的?
这⾥有两个选择,要么是C++语⾔标准,要么是编译器作者设计的;若是前者,则编码⽅式就没有异议了,任何平台、任何编译器,都应该⼀样;但若是后者,这就完全取决于编译器制作者的想法了。那么,C++中,到底是什么情况?
我们可以翻阅下C++ ISO 2003的⽂档,在3.91章第五条,清楚地写着wchar_t的定义如下:
Type wchar_t is a distinct type whose values can represent distinct codes for all members of the largest extended character set specified among the supported locales (22.1.1). Type wchar_t shall have the same size, signedness, and alignment
requirements (3.9) as one of the other integral types, called its underlying type.
从这段描述中可以得出⼏个结论:1. wchar_t是⽤来存储所有⽀持区域的字符的;2. wchar_t的底层存储⽅式是整形,本质上也就是个整形。
其实不论是char还是wchar_t,底层的存储都是整形,因此即使你存了个字符进去,仍然会以整形的形式存储,所以这⾥⾯涉及到了⼀个转化问题,也就是我们所谈的字符编码。
⽽编码⽅式在以上的C++ ISO⽂档⾥并不到⽂字说明,因此,可以确定,编码⽅式是编译器实现的,并且是没有标准的。
那么,就引出了第⼆个问题。
2. 编码⽅式有⼏种?宽字符存储的长度⼀样吗?
先从char说起,char型的常见编码⽅式是ASCII,ASCII编码是⼀种基于8位⼆进制数的字符编码算法,是美国ANSI制定的⼀种单字符编码⽅案,能表⽰256种可能的字符,常见的字母、符号、键盘指令等,全能⽤ASCII码表⽰,⽽由于ASCII码是基于8位的编码,因此⽤这种算法的编译器,char类型都占8位。请注意因果关系,是因为⽤了ASCII,所以char才是8位,⽽不是char是8位,所以采⽤ASCII。
同理可适⽤于wchar_t类型。
wchar_t的出现,是出于程序兼容多语⾔的需求,因为在很多语⾔中,字符的数量远远⼤于256,因此需要把原字符进⾏扩容,必须能表⽰更多的字符类型。因此wchar_t出现了,wchar_t全称是wide character type,也就是宽字符。最常见的宽字符编码⽅式就是unicode了,utf-16和utf-32都是unicode编码。wchar_t也主要以这两种⽅式实现。
utf-16是完全基于ucs-2的,但存储的⽅式分为Big Endian和Little Endian,区别在于存储的顺序,⽐如字符A⽤utf-16BE的⽅式表⽰是
unicode码和ascii码区别0x0041,⽤utf-16LE的⽅式表⽰则是0x4100,我在我的机器上试了下,⽤VC10编译器,wchar_t的编码⽅式是utf-16BE。⽽在gcc下是utf-32BE。
关于各种的编码算法,资料繁多,我就不多说了。
但这个问题是解决了,那就是,wchar_t的⽬的是编码并存储所有字符集,编码⽅式和存储空间⼤⼩和语⾔⽆关,只和编译器有关,因此说wchar_t的编码⽅式是unicode是错的。C++ Primer上的描述也是不准确的。
哦,对,最后补充⼀下,unicode是兼容ASCII的,ASCII所能表⽰的字符,⽤unicode编码可以得出⼀样的值。但不兼容GBK(也就是中⽂编码),如果混⽤两种⽅式编码的字符串,需要开发者⼿动去转换。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。