| Unicode字符是ASCII字符编码的扩展。在ASCII中,每个字符用7位表示,而Unicode是完全的16位编码字符形式。这样,就使Unicode可以把世界上所有的书写语言都在计算机中用字符的形式表示出来。Unicode影响到了计算机业的方方面面,其中对操作系统和基于其上的编程语言的影响最大。Unicode的出现动摇了ASCII字符在计算机中的支配地位,而Unicode最终取代ASCII是整个计算机界正在努力实现的目标。
在Windows操作系统中,基于NT内核的系统是从底层支持Unicode的,如Windows NT、Windows 2000和Windows XP等。Windows 98中只有一小部分支持Unicode。从编程语言的角度来看,传统的C语言通过对宽字符集的支持来支持Unicode。
由于在计算机中,每个字符被定义为8位,而Unicode要占16位,所以可以用双字符的字符集(DBCS:Double_Byte Character Set)来解决Unicode的表示问题。同时,又可以保持与ASCII字符集的兼容性。
在Unicode中,每一个字符的宽度不再是8位,而是16位。这就使Unicode在理论上可以表示65 536个不同的字符,完全可以包括世界上常用的任何文字语言符号,也包括数学和货币的符号。ISO 10646-1对Unicode代码的范围做了明确的规定,为不同的语言、数学及货币符号限定了所占用的空间。这样,在全球范围内就初步统一了文字符号在计算机中表示的问题。
在C语言中,涉及到的字符都只占一个字节,即Sizeof(char)返回为1。引入Unicode和宽字符的概念后,char数据类型没有改变。
在C语言中的宽字符是基于数据类型wchar_t上的,例如:
typedef unsigned short wchar_t;
从上可以看出,wchar_t数据类型与无符号短整数类型相同,都是16位宽。用下面的语句可以定义一个宽字符的变量:
wchar_t x = ‘A’;
这个字符所占的字节数不再是1,而是2。另外,还可以用以下的语句定义一个指向宽字符串的指针:
wchar_t *p = L” HELLO, WORLD!”
其中,在第一个引号前面的大写字母L表示“long”。它将通知编译器该字符串是以宽字符保存的,也就是必须为每个字符准备两个字节的空间,整个字符串要占用的空间是26个字节(包括末尾有一个0所占的2个字节)。如果不怕麻烦,前一个语句可以这样写:
wchar_t x = L‘A’;
但事实上,这是没有必要的,因为数据类型已经告诉编译器这个字符要占用双字节空间。
在Windows系统中,为了解决同一个源代码既可以按ASCII编译,又可以按Unicode编译的问题,就必须针对不同的环境给出解决方案。头文件TCHAR.H解决了这个问题。下面是其中的定义:
#ifdef UNICODE
#define _ _T(x) L # # x
#else
#define _ _T(x) x
#endif
这样,只需对字符串加工即可让程序自己判断所处的系统环境,以采用不同的处理编译方式。定义字符串如下:
_ _T(“HELLO,WORLD”);
另外,在TCHAR.H中还定义了以下两个相同的宏:
#define _T(x) _ _T(x)
#define _TEXT(x) _ _T(x)
可以根据需要使用哪一个宏,当然用户也可以定义自己的宏,但为了程序的通用性和可读性,不提倡这样做。
宽字符的表示问题解决了,但以往的库函数对宽字符是否支持呢?下面做一个实验,调用函数strlen来显示在前面定义的宽字符串的长度,例如:
int nLength = strlen(p);
但是,编译器通常会给出如下一条警告消息:
‘function’: incompatible types – from ‘unsigned short *’ to ‘const char *’
这表明数据类型产生了冲突,原有的库函数对宽字符并不支持。在这种情况下,惟一的办法是将含有字符串参数的函数全部重写。事实上,这件事情已经做到了。与 上一篇:Win32 API基础 下一篇:MySql noinstall-5.1.34-win32 配置 |