转发的:https://www.ituring.com.cn/article/111027的文章

刨根问底:C++中宽字符类型(wchar_t)的编码一定是Unicode?长度一定是16位?

const_cast 发表于 2014-05-23 22:58   12753 阅读

问题的起因是和一个朋友讨论不同编码的转换问题,说到了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)的编码一定是Unicode?长度一定是16位?相关推荐

  1. C++宽字符类型wchar_t

    C++宽字符类型wchar_t 传统的字符数据类型为char,占用一个字节,存放的数据内容为ASCII编码,最多可以存放255种字符,基本的英文以及常用字符都可以涵盖 随着计算机在国际范围内普及,大量 ...

  2. The New C++ -- 基本数据类型和字面值常量 (5. 宽字符类型和宽字符字面值常量)

    注意:本章节内容设计C++11,其中部分内容可能还没有被所有编译器支持. 随着计算机技术的发展,软件国际化是不可避免的趋势.ASCII所支持的最多256种字符已经远远不能满足国际化的需求.对我们来说, ...

  3. 统计字符串中不同字符类型的个数

    public class 统计字符串中不同字符类型的个数 { /** * @param args */ public static void main(String[] args) { // TODO ...

  4. (四)C语言中的字符类型

    (四)C语言中的字符类型 C语言中的字符型数据分为字符和字符串数据两类.**字符数据是指由单引号括起来的单个字符,**如'a'.'2'.'&'等:字符串数据是指由双引号括起来的一串字符序列,如 ...

  5. C语言中宽字符和多字节字符

    C 语言原本是在英文环境中设计的,主要的字符集是7 位的ASCII 码.从此开始,8 位的byte(字节)变成最常见的字符编码单位,但是国际化软件必须能够表示不同的字符,而这些字符数量庞大,无法使用一 ...

  6. pandas 如何把时间转成index_pandas将字段中的字符类型转化为时间类型,并设置为索引...

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

  7. java 编码 类型_java字符类型采用什么编码方式

    java 的字符类型采用的是 Unicode 编码方案. Java采用UTF-16编码作为内码,也就是说在JVM内部,文本是用16位码元序列表示的,常用的文本就是字符(char)和字符串(String ...

  8. mysql中char存储中文_数据库中的字符类型存储字符和汉字的数量

    sqlServer2012(936 简体中文GBK )为例: 例如: varchar(10),只能存储10个英文字符或数字,也只能存储5个汉字: char(10),只能存储10个英文字符或数字,也只能 ...

  9. R语言将数据框中的字符类型数字转换为数值及行名变换

    1 数据框类型转换 gsetpm.rsem=as.data.frame(lapply(gsetpm.rsem,as.numeric)) #gsetpm换成自己的数据 2 行名及列名为第一行和第一列 变 ...

最新文章

  1. 给GAN一句描述,它就能按要求画画,微软CVPR新研究 | 附PyTorch代码
  2. [PHP] 算法-合并两个有序链表为一个有序链表的PHP实现
  3. 机器学习(二)——鸢尾花案例
  4. 笔记-高项案例题-2016年下-项目收尾
  5. 【Android基础】Android Toast显示消息的几种方法
  6. python协程处理海量文件_python_实战篇_使用协程gevent模块实现多任务copyA文件夹到B文件夹...
  7. mysql 组合索引 or_Mysql_组合索引和单列索引
  8. skywalking 引起 spring-cloud-gateway 的内存溢出 skywalking的bug
  9. Java 中 == 和equals()方法的不同点
  10. Servlet简单实现请求分发(类thinkphp5)
  11. oracle的基本命令,Oracle基本命令
  12. 彻底解决_OBJC_CLASS_$_某文件名“, referenced from:问题(转)
  13. Chapter 5 Blood Type——15
  14. LUOGU P3919 【模板】可持久化数组(主席树)
  15. mac版CAD 2021/CAD 2022许可检出超时怎么解决?
  16. java刷票小程序,小程序投票系统刷票
  17. python 公众号爬虫_微信公众号爬虫,看这个就足够了
  18. 计算机画图虚线,天正建筑怎么把直线变成虚线
  19. linux 4k 桌面壁纸,10个值得珍藏的4K高清壁纸网站推荐
  20. vim编辑器跳转、复制、剪切(2)

热门文章

  1. 这个第三方登录开源工具,支持市面上几乎所有主流平台!好用!
  2. 为什么阿里如此钟爱Flink?
  3. MySQL中,当 update 修改数据与原数据相同时会再次执行吗?
  4. 万字长文,说透了 Openshift4 的安装过程!
  5. ipadpro+打开html文件,iPadPro日常基本功能的使用技巧汇总
  6. imagenet 测试精度记录
  7. pybind传输list
  8. win10 检测不到显卡
  9. Pytorch上采样函数 包括interpolate
  10. 人脸识别损失函数笔记