先从字符char数据类型讲起
下面的语句定义并初始化了一个只包含一个字符的变量:
char c = 'A';
变量c需要1个字节来保存,并将用十六进制数0x41初始化,这是字母A的ASCII代码。
定义一个指向字符串的指针:
char * p;
因为Windows是一个32位操作系统,所以指针变量p需要用4个字节保存。
初始化一个指向字符串的指针:
char * p = "Hello!";
p用4个字节保存,字符串保存在静态内存中并占用7个字节----6个字节保存字符串,另1个字节保存终止符0
定义字符数组:
char a[10];
在这种情况下,编译器为该数组保留了10个字节的存储空间。表达式sizeof(a)将返回10。
如果该数值是全局的,可使用像下面的语句来初始化一个字符数组:
char a[] = "Hello!";
如果将该数组定义为一个函数的局部变量,则必须将它定义为一个static变量:
static char a[] = "Hello!";
无论哪种情况,字符串都存储在静态程序内存中,并在末尾添加0,这样就需要7个字节的存储空间。
宽字符
c中的宽字符基于wchar_t数据类型(wchar.h):
typedef unsigned short wchar_t;
因此,wchar_t数据类型与无符号短整型相同,都是16位宽。
要包含一个宽字符的变量,可使用下面的语句:
wchar_t c = 'A';
变量c是一个双字节值0x0041,是Unicode表示的字母A。
指定宽字符串的指针:
wchar_t * p = L"Hello!";
第一个引号前面的大写字母L。这将告诉编译器该字符串按宽字符保存----即每个字符占用2个字节。
通常,指针变量p要占用4个字节,而字符串变量需要14个字节----每个字符需要2个字节,末尾的0还需要2个字节。
同样,还可以用下面的语句定义宽字符数组:
static wchar_t a[] = L"Hello!";
该字符串也需要14个字节的存储空间,sizeof(a)将返回14。索引数组a可得到单独的字符。a[1]的值是宽字符“e”,或者0x0065。
注意:第一个引号前面的L非常重要,并且在两个符号之前必须没有空格。只有带有L,编译器才知道需要将字符串存为每个字符2字节。
库函数
功能 字符版本 通用 宽字符版本
计算字符串长度 strlen lstrlen wcslen
打印 printf wprintf
复制字符串 strcpy lstrcpy
lstrcpyn
连接字符串 strcat lstrcat
比较字符串 strcmp lstrcmp
lstrcmpi
维护单一源代码:宏定义 _TEXT () _T()
使用Unicode有一个缺点,程序中的每个字符串都将占用两倍的存储空间。
因此,需要维护既能按ASCII编译又能按Unicode编译的单一源代码文件。
如果定义了名为_UNICODE的标识符,并且程序中包含了TCHAR.H头文件,那么:
#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;
如果定义了_UNICODE标识符,那么一个称作__T的宏就定义如下:
#define __T(x) L##x
.##是连接符,把前后两段连接起来,L(“代表long”)表示Unicode,这将告诉编译器该字符串按宽字符保存----即每个字符占用2个字符,可以把x 当作一个变量。
例如 _T("hello world")
这样当#define _T(x) L##x
_T("hello world") 相当于 L"hello world"
如果没有定义_UNICODE标识符,则__T宏只简单地定义如下:
#define __T(x) x
此外,还有两个宏与__T定义相同:
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
注意包含头文件<TCHAR.h>。
其中WINNT.H头文件还定义了一个宏,如果定义了UNICODE标识符:
#define __TEXT(quote) L##quote
如果没有定义标识符UNICODE
#define __TEXT(quote) quote
此外,TEXT宏可这样定义:
#define TEXT(quote) __TEXT(quote)
这与TCHAR.H中定义_TEXT宏的方法一样,只是不必理会下划线。
一个很好的编程习惯,在所有字符串前加上宏定义
例:
MessageBox (NULL, TEXT("Hello world!"), NULL, MB_OK);
如果您希望明确定义8位字符变量和字符串,请使用CHAR,PCHAR(或者其他),以及带引号的字符串。为明确地使用16位字符变量和字符串,请使用WCHAR、PWCHAR,并将L添加到引号前面
这里精选了头文件中一些实用的说明数据类型语句:
typedef CHAR * PCHAR, * LPCH, * PCH, * NPSTR, * LPSTR, * PSTR;
typedef CONST CHAR * LPCCH, * PCCH, * LPCSTR, * PCSTR;
前缀N和L标示“near”和“long”,指的是16位Windows中两种大小不同的指针。在Win32中near和long指针没有区别。