计算机编码原理——不同数据类型存储中文编码
作者以前在Windows平台编程时,对于字符串显示中文以及不同的字符集编码格式不太理解。最近编写资料用到这部分知识,便通过自己的分析和参考资料做了简单运用,下面我们一起分析常用的编码集与中文编码!
章节预览:
1.字符数组存储GB2312中文编码
2.GB2312标准
3.输出乱码原理
4.整数存储GB2312中文编码
5.Uncode
6.UTF-8
7.整数存储UTF-8中文编码
章节内容:
字符数组存储GB2312中文编码:
首先,我们通过字符数组输出“你好”,参考代码:
unsigned char testch[4] = {0};
memcpy(testch, “你好”, strlen(“你好”));
printf("%s|", testch);
得出的结果为:你好烫烫烫烫
|
首先,我们分析testch输出的信息:
我们定义一个256字节的字符数组保存testch值:
unsigned char testch2[256] = {0};
memcpy(testch2, testch, 255);
展开testch2:
- testch2 0x00aff9f0 "你好烫烫烫烫
" unsigned char [256]
[0] 196 ‘?’ unsigned char
[1] 227 ‘?’ unsigned char
[2] 186 ‘?’ unsigned char
[3] 195 ‘?’ unsigned char
[4] 204 ‘?’ unsigned char
[5] 204 ‘?’ unsigned char
[6] 204 ‘?’ unsigned char
[7] 204 ‘?’ unsigned char
[8] 204 ‘?’ unsigned char
[9] 204 ‘?’ unsigned char
[10] 204 ‘?’ unsigned char
[11] 204 ‘?’ unsigned char
[12] 10 ’
’ unsigned char
[13] 0 unsigned char
Byte13值为0,程序输出的testch信息到这里终止。
然后,我们分析testch输出的信息内容:
GB2312规定对匹配的每个字符采用两个字节表示,在VS2010编译器中可以这么认为(与GB2312标准定义有出入):
当前字节值为0-128时,采用国际Ascll码表方式计算,当前字节信息会以Ascll码表对应符显示;
当前字节值大于或等于129时,后面的一个字节与当前字节被认为是一个GB2312编码匹配(采用两个字节位数合并成一个16位数字(低字节在低8位,高字节在高8位)),数字值如果在GB2312编码内,将显示GB2312中的对应信息,否则(数字值如果不在GB2312编码内)按照单个字节显示。
GB2312标准:
GB2312是中国主要官方字符集的注册名称,用于简体中文字符。GB缩写为国家标准,由中国国家标准总局1980年发布,1981年5月1日开始使用。GB2312编码共收录汉字6763个,其中一级汉字3755个,二级汉字3008个。
GB2312规定对收录的每个字符采用两个字节表示,第一个字节为“高字节”,对应94个区;第二个字节为“低字节”,对应94个位,所以它的区位码范围是:0101-9494。区号和位号分别加上0xA0就是GB2312编码。例如最后一个码位是9494,区号和位号分别转换成十六进制是5E5E,0x5E+0xA0=0xFE,所以该码位的GB2312编码是FEFE。
GB2312编码范围为0xA1A1—0xFEFE,其中汉字的编码范围为0xB0A1-0xF7FE,第一字节0xB0-0xF7(对应区号:16——87),第二个字节0xA1-0xFE(对应位号:01—94)。
输出乱码原因:
当我们使用字符数组存储信息并且没有做字符串结尾(最后一个字节置为空字符)时,将会发生“内存访问越位”的情况,因为,VS2010编译器会自动把未使用的栈内存空间按字节全部初始化为0xCC(无符号204),当两个字节都为0xCC时,显示为GB2312编码中的“烫”汉字。
整数存储GB2312中文编码:
unsigned short:
在32位编译器中,一个unsigned short类型占用2个字节,我们可以通过unsigned short数组保存数据,并输出“你好”:
unsigned short sho[3] = {58308,50106,0};
printf("%s", sho);
第一个值:58308 转成二进制数字为 1110 0011,1100 0100,中文“你”;
第二个值:50106 转成二进制数字为 1110 0011,1011 1010,中文“好”;
第三个值:作为空字符使用。
位数顺序:左高右低。
unsigned int:
在32位编译器中,一个unsigned int类型占用4个字节,输出“你好”:
unsigned int sho[2] = {3283805124,0};
printf("%s", sho);
第一个值:3283805124 转成二进制数字为 1100 0011 1011 1010,1110 0011 1100 0100,中文“你好”;
第二个值:作为空字符使用。
使用unsigned int类型存储GB2312数据时,采用2个字节为一组,3、4字节(中文“好”)在左,1、2字节(中文“你”)在右, 组内顺序也是左高右低。
long long:
在大部分编译器中,一个long long类型占用8个字节,输出“你好呀”:
long long sho = 208708629619652;
printf("%s", &sho);
参数值:208708629619652 或 十六进制 0xBDD1C3BAE3C4 转成二进制数字为:
1011 1101 1101 0001,1100 0011 1011 1010,1110 0011 1100 0100,中文“你好呀”;
使用long long类型类型存储GB2312数据时,存储形式与int相同。示例中我们只输出3个GB2312字符,6、7字节为空字符使用。
在这里我们可以看出使用无符号类型和有符号类型输出的结果相同,大部分示例中采用无符号类型只是为了方便参考数据。
Uncode:
在非 Unicode 环境下,由于不同国家和地区采用的字符集不一致,很可能出现无法正常显示所有字符的情况。微软公司使用了代码页(Codepage)转换表的技术来过渡性的部分解决这一问题,即通过指定的转换表将非 Unicode 的字符编码转换为同一字符对应的系统内部使用的 Unicode 编码。
MultiByteToWideChar是一种windows API 函数,该函数映射一个字符串到一个宽字符(Unicode)的字符串。
UTF-8:
UTF-8是针对Unicode的一种可变长度字符编码,它可以用来表示Unicode标准中的任何字符,UTF-8将每个Unicode字符编码为1到4个八位字节的可变数字,其中八位字节的数目取决于分配给Unicode字符的整数值。这是对Unicode文档的有效编码,主要使用US-ASCII字符,因为它将范围在U + 0000到U + 007F之间的每个字符表示为一个八位字节。
整数存储UTF-8中文编码:
long long:
由于UTF-8字符集存在字节不确定因素,直接使用long long类型输出“你好”:
system(“chcp 65001”); //在VS2010编译器中,我们选择向控制台输出UTF-8信息
long long sho = 208520219770340;
printf("%s", &sho);
参数值:208520219770340 或十六进制 0xBDA5E5A0BDE4 转成二进制数字为:
1011 1101 1010 0101 1110 0101, 1010 0000 1011 1101 1110 0100,中文“你好”;
示例中“你”、“好”分别占用三个字节,6、5、4字节(中文“好”)在左,3、2、1字节(中文“你”)在右, 组内顺序也是左高右低。
- 点赞
- 收藏
- 分享
- 文章举报
- 计算机组成原理——关于数据对齐存储
- 计算机存储单位与Java数据类型
- VC编程中常用数据类型和函数在不同编码格式下的对应关系
- ibatis自定义数据类型在不支持中文的数据库存储汉字
- mysql如何选择合适的数据类型存储不同的数据
- 关于计算机中数据类型存储的对齐问题
- oracle不同数据类型存储空间的实例比较
- Base64编码与解码原理和使用及复杂数据的存储
- Redis学习笔记(十五)Redis数据类型底层编码和实现原理
- Base64编码与解码原理和使用及复杂数据的存储
- ase64编码与解码原理和使用及复杂数据的存储
- 字符串不同存储形式代表的不同数据类型 及 返回值为引用要十分注意
- MATLAB 不同颜色空间的图像存储的数据类型
- 计算机网络原理(3)数据编码技术
- C语言中不同数据类型在内存中的存储格式研究
- 深入浅出计算机组成原理学习笔记:存储器层次结构全景-数据存储的大金字塔长什么样?(第35讲)...
- java不同数据类型在内存中的存储方式
- int类型数据在计算机中的存储
- QString内部仍采用UTF-16存储数据且不会改变(一共10种不同情况下的编码)
- SharedPreference 存储不同类型数据的工具类