ANSI字符和Unicode字符与字符串数据类型

来源:互联网 发布:四川网络协会 编辑:程序博客网 时间:2024/06/10 07:56

          我们知道C语言用char数据类型来表示一个8位ANSI字符。默认情况下,在源代码中声明一个字符串时,C编译器会把字符串中的字符转换成8位char数据类型构成的一个数组。

          Microsoft的C/C++编译器定义了一个内建的数据类型wchar_t,它表示一个16位的UnicodeUTF-16)  字符。因为早期版本的Microsoft编译器没有提供这个内建的数据类型,所以编译器只有在指定了/Zc:wchar_t编译器开关时,才会定义这个数据类型。默认情况下,在Microsoft Visual Studio  中新建一个C++项目时,这个编译器开关是指定的。建议始终指定这个编译器开关,这样才能借助于编译器天生就能理解的内建基元类型来更好地操纵Unicode字符。

         注意   在编译器内建对wchar_t的支持之前,有一个C头文件定义了一个wchar_t数据类型:typedef unsigned short wchar_t;

声明Unicode字符和字符串的方法如下所示:

       // 一个16位字符

       wchar_t c = L'A';

      // 一个数组,包含最多99个16 位字符以及一个16位的终止0
      wchar_t szBuffer[100] = L"A String";

字符串之前的大写字母L通知编译器该字符串应当编译为一个Unicode字符串。当编译器将此字符串放入程序的数据段时,会使用UTF16来编码每个字符。在这个简单的例子中,在每个ASCII字符之间都用一个0来间隔。  
为了与C语言稍微有一些隔离,Microsoft Windows团队希望定义自己的数据类型。于是,在Windows头文件WinNT.h中,定义了以下数据类型:
 
     typedef char CHAR; // An 8-bit character
     typedef wchar_t WCHAR; // A 16-bit character
 
除此之外,WinNT.h头文件还定义了一系列能为你提供大量便利的数据类型,可以用它处理字符和字符串指针: 
     // Pointer to 8-bit character(s)
     typedef CHAR *PCHAR;
     typedef CHAR *PSTR;

     typedef CONST CHAR *PCSTR 
      // Pointer to 16-bit character(s)
     typedef WCHAR *PWCHAR;
     typedef WCHAR *PWSTR;
     typedef CONST WCHAR *PCWSTR;

注意  
        仔细查看WinNT.h,会看到如下定义:  
                 typedef __nullterminated WCHAR *NWPSTR, *LPWSTR, *PWSTR;  
        前缀__nullterminated是一个头部注解(header annotation),它描述一个类型如何作为函数的参数和返回值使用。在Visual Studio企业版中,可以在项目属性中设置代码分析(Code Analysis)选项。这样会把/analyze开关添加到编译器的命令行中。这样一来,假如你的代码调用函数的方式违反了头部注解所定义的语义,编译器就会检测到这类问题。注意,只有编译器的企业版才支持这个/analyze开关。为保证本书所提供的代码的可读性,所有header annotation都已被删除。要想更多地了解header annotation语言,请参考MSDN文档“HeaderAnnotations”,网址是http://msdn2.microsoft.com/En-US/library/aa383701.aspx。

          
在源代码中,具体使用哪种数据类型并不重要,但建议你尽量保持一致,以增强代码的可维护性。就我个人而言,作为Windows程序员,我会坚持使用Windows数据类型,因为这些数据类型与MSDN文档相符,有利于增强代码的可读性。

另外,你在写代码的时候,可以让它使用ANSI或Unicode字符/字符串都能通过编译。 WinNT.h定义了以下类型和宏: 
       #ifdef UNICODE  
       typedef WCHAR TCHAR, *PTCHAR, PTSTR; 
       typedef CONST WCHAR *PCTSTR;
       #define __TEXT(quote) quote // r_winnt  
       #define __TEXT(quote) L##quote  
       #else  
       typedef CHAR TCHAR, *PTCHAR, PTSTR;
       typedef CONST CHAR *PCTSTR;
       #define __TEXT(quote) quote  
       #endif

      #define TEXT(quote) __TEXT(quote)

利用这些类型和宏(少数不太常用的没有在这里列出)来写代码,无论使字符,它都能通过编译。例如:
                  // 如果定义了UNICODE,就是一个16位字符;否则就是一个8位字符
                  TCHAR c = TEXT('A');  
                  // 如果定义了UNICODE,就是由16位字符构成的一个数组;否则就是8位字符的一个数组
                 TCHAR szBuffer[100] = TEXT("A String");

原创粉丝点击