为什么需要字符编码?
计算机只能处理数字,即0和1,如果要处理文本,就必须先把文本转换为数字才能处理。
字节是计算机存储数据的基本单位!
而字符是人类文明创造的符号,汉字、英文字母、标点符号、特殊符号都是字符。
0~31以及127(共33个)是控制字符,例如:LF(换行),CR(回车).
32156(共95个)是字符,4857为0到9共十个阿拉伯数字,65~122是大小的英文字母,其余的是字符,运算符等.
0-127 标准ascii码,127-255扩展ascii码,扩展主要存储西欧国家的一些字符
素材内容来源:jiesengmianfei.cn
一、字符编码的历史
最开始:
计算机只认识数字,我们在计算机里一切数据都是以数字来表示,因为英文符号有限
所以在规定使用的字节的最高位是0,每一个字节都是以0~127之间的数字来表示,比如A对应65,a对应97。
这就是美国标准信息交换码-ASCLL。
之后:
随着计算机在全球的普及,很多国家和地区都把自己的字符引入了计算机,例如汉字。
此时发现一个字节能表示数字范围太小,不能包含所有的中文汉字,那么就规定使用两个字节来表示一个汉字。
规定:原有的ASCLL字符的编码保持不变仍然使用一个字节表示,为了区别一个中文字符与两个ASCLL码字符相区别。
中文字符的每个字节最高规定为1,这个规范就是GB2312编码,
后来在GB2312的基础上增加了更多的中文字符,例如汉字,也就出现了GBK。
新的问题,在中国是认识汉字的,但是如果把汉字传递给其他国家,该国家的码表中没有收录汉字,其实就显示了另一个符号或者乱码。
为了解决各个国家因为本地化字符编码带来的影响,咱们就把全世界所有的符号统一进行编码-Unicode编码。
此时某一个字符在全世界任何地方都是固定的,比如哥,在任务地方都是以十六进制的54E5来表示。
Unicode的编码字符都占有2个字节大小。
二、程序上字符编码的区别
1.程序源文件编码
程序源文件编码是指保存程序源文件内容所使用的编码方案,该编码方案可在保存文件的时候自定义。
通常在简体中文windows环境下,各种编辑器(包括visual studio)新建文件缺省编码都是GB18030,所以不特别指定的话,windows环境下的c++源文件的编码通常为GB18030(GB18030兼容GBK);在linux环境下,默认的为UTF-8编码。
2.c++程序内码
源程序编译后,c++中的字符串常量变成一串字节存放在可执行文件中,内码指的是在可执行文件中,字符串以什么编码进行存放。这里的字符串常量指的是窄字符(char)而不是宽字符(wchar_t)。宽字符通常都是以Unicode(VC使用UTF-16BE, gcc使用UTF-32BE)存放。
通常简体中文版的VC使用内码为GB18030,而gcc使用内码缺省为UTF-8,单可以通过-fexec-charset参数进行修改。(可以通过在程序中打印字符串中每个字节的16进制形式来判断程序使用的内码)。
3.运行环境编码
运行环境编码指的是,执行程序时,操作系统或终端所使用的编码。程序中输出的字符最终要转换为运行环境编码才能显示,否则就会出现乱码。
常用的简体中文版的windows环境编码是GB18030,linux下最常用的环境编码是UTF-8。
这三种编码之间的区别?
程序源文件【源文件编码】—>(编译器编译) ---->目标文件【程序内码】----> (运行后输出信息)---->输出【运行环境编码】
编译器需要正确识别源文件的编码,把源文件编译为目标文件,并把源文件中的以源文件编码的字符串转换为以程序内码编制的字符串保存在目标文件中。
如果源程序中的为窄字符串常量,则程序运行时,直接将目标文件中对应的内码字符串输出;若为宽字符串常量,则程序运行时c++标准库需要正确识别终端的运行环境编码,并把程序的输出转换为运行环境所使用的编码,以便正确显示。