windows程序设计 笔记 。关于windows中的宽字符

来源:互联网 发布:爱淘宝天天特价 编辑:程序博客网 时间:2024/06/07 16:03
1.ANSI编码表示英文字符时用一个字节,表示中文用两个字节,而unicode不管表示英文字符还是中文都是用两个字节来表示。
2.简单地说,Unicode扩展自ASCII字符集。在严格的ASCII中,每个字符用7位表示,或者计算机上普遍使用的每字符有8位宽;而Unicode使用全16位字符集。
这使得Unicode能够表示世界上所有的书写语言中可能用于计算机通讯的字符、象形文字和其它符号。
3.明白Unicode和DBCS之间的区别很重要。Unicode使用(特别在C程序设计语言环境里)「宽字符集」。「Unicode中的每个字符都是16位宽而不是8位宽。」在Unicode中,没有单单使用8位数值的意义存在。相比之下,在双字节字符集中我们仍然处理8位数值。
有些字节自身定义字符,而某些字节则显示需要和另一个字节共同定义一个字符。
4.char c = 'A' ;
变量c需要1个字节来保存,并将用十六进制数0x41初始化,这是字母A的ASCII代码。
您可以像这样定义一个指向字符串的指针:
char * p ;
因为Windows是一个32位操作系统,所以指针变量p需要用4个字节保存。您还可初始化一个指向字符串的指针:


5.
宽字符: wchar_t。
WCHAR.H中的定义:typedef unsigned short wchar_t ; 16位宽!
1)
要定义包含一个宽字符的变量,可使用下面的语句:
wchar_t c = 'A' ;
2)
还可定义指向宽字符串的指针:
wchar_t * p = L"Hello!" ;
注意紧接在第一个引号前面的大写字母L(代表「long」)。
这将告诉编译器该字符串按宽字符保存-即每个字符占用2个字节。通常,指针变量p要占用4个字节,而字符串变量需要14个字节-每个字符需要2个字节,末尾的0还需要2个字节。
3)
同样,您还可以用下面的语句定义宽字符数组:
static wchar_t a[] = L"Hello!" ;
该字符串也需要14个字节的储存空间,sizeof (a) 将返回14。索引数组a可得到单独的字符。a[1] 的值是宽字符「e」,或者0x0065。
4)
您还可在单个字符文字前面使用L前缀,来表示它们应解释为宽字符。如下所示:
wchar_t c = L'A' ;
但通常这是不必要的,C编译器会对该字符进行扩充,使它成为宽字符。


6.关于长度:
1)我们都知道如何获得字符串的长度。例如,如果我们已经像下面这样定义了一个字符串指针:
char * pc = "Hello!" ;
我们可以呼叫
iLength = strlen (pc) ;结果为6.
2)但是:
wchar_t * pw = L"Hello!" ;
再次呼叫strlen :
iLength = strlen (pw) ;
现在麻烦来了。首先,C编译器会显示一条警告消息,可能是这样的内容:
'function' : incompatible types - from 'unsigned short *' to 'const char *'
这条消息的意思是:声明strlen函数时,该函数应接收char类型的指标,但它现在却接收了一个unsigned short类型的指标。您仍然可编译并执行该程序,但您会发现iLength等于1。为什么?
字符串「Hello!」中的6个字符占用16位:
0x0048 0x0065 0x006C 0x006C 0x006F 0x0021
Intel处理器在内存中将其存为:
48 00 65 00 6C 00 6C 00 6F 00 21 00
所以就把48后面的00当做是结束符了。。
3)所以要用到:
strlen函数的宽字符版是wcslen(wide-character string length:宽字符串长度),并且在STRING.H(其中也说明了strlen)和WCHAR.H中均有说明。strlen函数说明如下:
size_t __cdecl strlen (const char *) ;
而wcslen函数则说明如下:
size_t __cdecl wcslen (const wchar_t *) ;
4)
您熟悉的所有带有字符串参数的C执行时期链接库函数都有宽字符版。例如,wprintf是printf的宽字符版。这些函数在WCHAR.H和含有标准函数说明的表头文件中说明。


7.
当然,使用Unicode也有缺点。第一点也是最主要的一点是,程序中的每个字符串都将占用两倍的储存空间。此外,您将发现宽字符执行时期链接库中的函数比常规的函数大。出于这个原因,您也许想建立两个版本的程序-一个处理ASCII字符串,另一个处理Unicode字符串。最好的解决办法是维护既能按ASCII编译又能按Unicode编译的单一原始码文件。
用Tchar就是这样解决的。。
如果定义了名为_UNICODE的标识符,并且程序中包含了TCHAR.H表头文件,那么_tcslen就定义为wcslen:
#define _tcslen wcslen
如果没有定义UNICODE,则_tcslen定义为strlen:
#define _tcslen strlen
等等。TCHAR.H还用一个新的数据型态TCHAR来解决两种字符数据型态的问题。如果定义了_UNICODE标识符,那么TCHAR就是wchar_t:
typedef wchar_t TCHAR ;
否则,TCHAR就是Char:
typedef char TCHAR ;


现在开始讨论字符串文字中的L问题。如果定义了_UNICODE标识符,那么一个称作__T的宏就定义如下:
#define __T(x) L##x
这是相当晦涩的语法,但合乎ANSI C标准的前置处理器规范。那一对井字号称为「粘贴符号(token paste)」,它将字母L添加到宏参数上。因此,如果宏参数是"Hello!",则L##x就是L"Hello!"。
如果没有定义_UNICODE标识符,则__T宏只简单地定义如下:
#define __T(x) x
此外,还有两个宏与__T定义相同:
#define _T(x)__T(x)
#define _TEXT(x)__T(x)


8.
正如您在第一章所看到的那样,一个Windows程序包括表头文件WINDOWS.H。该文件包括许多其它表头文件,包括WINDEF.H,该文件中有许多在Windows中使用的基本型态定。
义,而且它本身也包括WINNT.H。WINNT.H处理基本的Unicode支持。
WINNT.H的前面包含C的表头文件CTYPE.H,这是C的众多表头文件之一,包括wchar_t的定义。WINNT.H定义了新的数据型态,称作CHAR和WCHAR:
typedef char CHAR ;
typedef wchar_t WCHAR ; // wc


9.关于指针:
#ifdef UNICODE
typedef WCHAR TCHAR, * PTCHAR ;
typedef LPWSTR LPTCH, PTCH, PTSTR, LPTSTR ;
typedef LPCWSTR LPCTSTR ;
#else
typedef char TCHAR, * PTCHAR ;
typedef LPSTR LPTCH, PTCH, PTSTR, LPTSTR ;
typedef LPCSTR LPCTSTR ;
#endif


10.
如果您希望明确定义8位字符变量和字符串,请使用CHAR、PCHAR(或者其它),以及带引号的字符串。为明确地使用16位字符变量和字符串,请使用WCHAR、PWCHAR,并将L添加到引号前面。对于是8位还是16位取决于UNICODE标识符的定义的变量或字符串,要使用TCHAR、PTCHAR和TEXT宏。


0 0
原创粉丝点击