转载自: http://www.ituring.com.cn/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的方式表示是0x0041,用utf-16LE的方式表示则是0x4100,我在我的机器上试了下,用VC10编译器,wchar_t的编码方式是utf-16BE。而在gcc下是utf-32BE。

关于各种的编码算法,资料繁多,我就不多说了。

但这个问题是解决了,那就是,wchar_t的目的是编码并存储所有字符集,编码方式和存储空间大小和语言无关,只和编译器有关,因此说wchar_t的编码方式是unicode是错的。C++ Primer上的描述也是不准确的。

哦,对,最后补充一下,unicode是兼容ASCII的,ASCII所能表示的字符,用unicode编码可以得出一样的值。但不兼容GBK(也就是中文编码),如果混用两种方式编码的字符串,需要开发者手动去转换。

C++中宽字符类型(wchar_t)的编码的更多相关文章

  1. java中的字符,字节和编码

    1. 编码问题的由来,相关概念的理解 1.1 字符与编码的发展 从计算机对多国语言的支持角度看,大致可以分为三个阶段:   系统内码 说明 系统 阶段一 ASCII 计算机刚开始只支持英语,其它语言不 ...

  2. pandas将字段中的字符类型转化为时间类型,并设置为索引

    假设目前已经引入了 pandas,同时也拥有 pandas 的 DataFrame 类型数据. import pandas as pd 数据集如下 df.head(3) date open close ...

  3. 04Windows中的字符类型

    1. Windows 中常用的数据类型定义 //WinNt.h中定义 typedef unsigned short wchar_t; //A 16-bit character typedef char ...

  4. Javascript中的string类型使用UTF-16编码

    2019独角兽企业重金招聘Python工程师标准>>> 在JavaScript中,所有的string类型(或者被称为DOMString)都是使用UTF-16编码的. MDN DOMS ...

  5. 宽字符wchar_t和窄字符char——putwchar、wprintf

    宽字符wchar_t 与 窄字符char 先说下窄字符char,这个大部分读者应该很清楚,char类型的变量占一个字节(byte)(也就是8个bit(比特)),能表示256个字符,那char的范围有两 ...

  6. 彻底弄懂UTF-8、Unicode、宽字符、locale

    目录 Unicode.UCS UTF8 宽字符类型wchar_t locale 为什么需要宽字符类型 多字节字符串和宽字符串相互转换 最近使用到了wchar_t类型,所以准备详细探究下,没想到水还挺深 ...

  7. [转帖]彻底弄懂UTF-8、Unicode、宽字符、locale

    彻底弄懂UTF-8.Unicode.宽字符.locale linux后端开发   已关注   彻底弄懂UTF-.Unicode.宽字符.locale unicode 是字符集 utf-8是编码格式.. ...

  8. C++ 宽字符(wchar_t)与窄字符(char)的转换

    了解 长度 宽字符wchar_t的长度16位,可以用来显示中文等除英文外的其他文字, 窄字符    char   的长度  8 位,只能处理英文. 哪里可以见到 在VS2010, 2012, 2013 ...

  9. Python学习笔记 (2.2)Python中的字符编码问题及标准数据类型之String(字符串)

    Python3中的String类型 首先,Python中没有字符类型,只有字符串类型.单个字符按照长度为1的字符串处理,这对于曾是OIER的我来说有点不适应啊. 字符串的表示方法 最常用的就是用一对双 ...

随机推荐

  1. 八大排序算法——冒泡排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 1.  相邻两个数两两相比,n[i]跟n[j+1]比,如果n[i]>n[j+1],则将连个数进行交换, 2.  j++, 重复以上步骤,第一趟结束后,最大数就会被确定 ...

  2. jQ如何选中被选中的单选按钮的值

    alert($("label input[name=logintpye]:checked").val());

  3. Win强制删除文件windows批处理强行删除文件

    一般情况下选中文件或文件夹可以直接删除文件,但是有些情况下例如:文件非常规命名.找不到文件位置等就无法直接删除. 针对这种情况可以用 bat批处理文件 删除,一下就是该方法的步骤 新建一个文件:*** ...

  4. 20165326 java实验五

    实验五 网络编程与安全 一.实验内容 任务一: 结对实现中缀表达式转后缀表达式的功能 MyBC.java 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java 这个代码在 ...

  5. Python学习二十八周(vue.js)

    一.指令 1.一个例子简单实用vue: 下载vue.js(这里实用1.0.21版本) 编写html代码: <!DOCTYPE html> <html lang="en&qu ...

  6. brand new start

    做了约两年半的安全,留下了约五十多篇笔记,从电脑搬过来,免的丢了

  7. java基础(1)IntelliJ IDEA入门和数组操作 解决idea启动速度慢--配置JVM

    一. IntelliJ IDEA入门 1 快捷键和技巧 智能补全代码,比如只写首字母按回车: psvm+Enter :public stactic void main(String[] args) s ...

  8. AspectJ的拓展学习--织入顺序和通知参数指定

    前言: 其实spring的aop非常的强大, 因此研究一下AspectJ还是有必要, 而不是仅仅停留在初级的阶段. 比如spring的事务是基于aop来实现的, 如果不能深入的研究, 可能很多知识点, ...

  9. Arch Linux 的休眠设置

    https://wiki.archlinux.org/index.php/Power_management/Suspend_and_hibernate_(简体中文)https://wiki.archl ...

  10. RESTful Loads

    RESTful 一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制. 概述 ...