一.字符编码
字符编码其实就是一种映射规则。由于计算机只能理解二进制,我们在屏幕上看到的英文,汉字等字符都是二进制转换后的结果。按照何种约定将字符存储在计算机中,如'a'用什么表示,称之为编码。反之,如何将存储在计算机中的二进制数据解析显示出来,称之为“解码”。
字符集指一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,字符编码指的是一套规则,将字符转换为计算机可以接受的数字系统的二进制数值。常见的字符集有ASCII字符集,Unicode字符集,GB2312字符集
ASCII(American Standard Code for Information Interchange),即美国信息交换标准代码,其是基于拉丁字母的一套计算机编码系统。
ASCII字符集:主要包括控制字符(回车键,退格,换行键);可显示字符(英文大小写字符,阿拉伯数字和西文符号)。
ASCII编码:将ASCII字符集转换为计算机可以接受的数字系统的数的规则。使用7位(bits)表示一个字符,共128个字符;但是7位编码的字符集只能支持128个字符,为了表示更多的欧洲常用字符对ASCII进行了扩展,ASCIII扩展字符集使用8位(bits)表示一个字符,共256个字符。
ASCII及扩展ASCII码,最多只能编码256个字符,因此使用ASCII可支持的字符是有限的,例如,ASCII就不能对汉字,日文,韩文等进行编码
为了消除这个严重缺陷,使各种语言可统一编码,双字节编码应运而生。在双字节字符集中一个字符可由1个或2个字节组成。这就是UTF编码,即通常所说的Unicode码。
Unicode说明:Unicode码包括UTF-8,UTF-16,UTF-32三种标准。UTF-8编码长度不固定,UTF-16占两字节,UTF-32占4字节
UTF-8在编码时,将部分字符编码为1字节,部分字符编码为2字节,部分字符编码为3字节,还有一部分编码为4字节。其中,值在0x0080以下的字符压缩成1字节,主要存放美国使用的字符,值在0x0080-0x07ff间的字符使用2字节存储,主要存放欧洲及中东地区语言字符,值在0x07ff以上的字符使用3字节存储,主要存储东亚地区的语言。
UTF-16编码占用2个字节,最多可编码65536个字符。Windows操作系统采用这种编码形式,因为这种编码可存储世界各地的大部分语言字符。而且在节省空间和简化编码这两个目标之间,提供了一个很好的折中。
UTF-32编码的每个字符都占用4个字节。一般在应用程序内部使用这种编码,由于这种编码效率不高,在网络通信,文件保存时使用得很少。
在Windows操作系统中,如果不进行特别说明,一般所说的Unicode编码均指UTF-16编码。而Linux流行的编码方案则是UTF-8
在Windows上从事软件开发的人员,笔者强烈建议在应用程序开发时使用Unicode的字符和字符串。原因可总结如下:
1.使用Unicode有利于应用程序的本地化,只需要一个二进制文件,即可支持所有语言
2.Unicode可提高应用程序执行效率,代码执行速度快,占用的内存会更少。Windows系统内部所有的操作都采用Unicode字符或字符串进行处理。所以,如果应用程序采用ASCII字符或字符串,操作系统刚会被迫分配内存,将ASCII字符或字符串转换成Unicode字符串,否则系统无法处理
3.使用Unicode可提高程序的兼容性。例如,采用Unicode编码的应用程序易于与COM组件,NET Frame集成。
Windows程序开发注意事项
1.在应用程序设计时,最好将应用程序转换为支持Unicode的形式,即使当前并不计划立即开始使用Unicode。
2.将文件字符串理解为字符的数组,而不是char或字节的数组
3.使用TCHAR通用数据类型,表示文件字符和字符串
4.注意与字符串相关的计算的差异。Unicode下字符数和字节数是不同的,而在ASCII下字符数和字节数是等同的。还有如果需申请一块内存,要记住内存是以字节为单位,而不是以字符为单位进行分配的,这意味着必须调用malloc(nChars*sizeof(TCHAR)),而不是malloc(nChars)
5.尽量避免使用printf系列函数,尤其不要使用%s和%S字段进行ASCII,Unicode字符串的相互转换
二.牢记字符串结束标志为' '
在C语言中,并没有字符串这种数据类型,其通过使用字符数组来保存字符串。C语言字符串其实就是一个以null(' ')字符结尾的字符数组。null字符表示字符串的结束,对C字符串的操作需要通过<string.h>文件中定义的字符串处理函数实现。
char szWelcome[11] = "huanying"; 也可以通过指针来访问一个字符串:通过字符指针指向存放字符串数组的首元素地址来访问字符串,如char* pszWelcome="huanying"
只有以null结束的字符数组才是字符串,否则只是一般的字符数组。C字符串,可以利用"="号进行初始化,但初始化后,不能利用"="对C字符串进行赋值操作
strlen计算的字符串长度是不包括null在内的字符长度。null是字符串的必要组成部分,但不占用字符串的长度。
定义一个字符串,一定要确保此字符串以null字符结尾。否则关于字符串的任何运算操作,都将是错误的,无法预知的
通常我们所说的字符串地址,仅指字符串的首元素的内存地址
在创建动态字符串数组时,通过new或malloc申请内存时,一定要考虑到null也占用空间,以防字符串因为无null结束符,而导致无法预测的错误。