以下文字总结于网路和书籍。
1. 说说那些乱七八糟的类型名
L表示long指针,这是为了兼容Windows 3.1等16位操作系统遗留下来的,在win32中以及其他的32为操作系统中, long指针和near指针及far修饰符都是为了兼容的作用,没有实际意义。即win32中,long,near,far指针与普通指针没有区别,LP 与P是等效的。
P表示这是一个指针。
T表示_T宏,这个宏用来表示你的字符是否使用UNICODE,
如果你的程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为UNICODE字符串,否则就是标准的ANSI字符串。
STR表示这个变量是一个字符串。
C表示是一个常量,const。
LPTSTR: 如果定义了UNICODE宏则LPTSTR被定义为LPWSTR。typedef LPTSTR LPWSTR;
否则LPTSTR被定义为LPSTR。 typedef LPTSTR LPSTR;
下面列出一些常用的typedefs:
类型 MBCS Unicode
WCHAR wchar_t wchar_t
LPSTR char* char*
LPCSTR const char* const char*
LPWSTR wchar_t* wchar_t*
LPCWSTR const wchar_t* const wchar_t*
TCHAR char wchar_t
LPTSTR TCHAR*(或char*) TCHAR* (或wchar_t*)
LPCTSTR const TCHAR* const TCHAR*
由于Win32 API文档的函数列表使用函数的常用名字(例如, SetWindowText"),所有的字符串都是用TCHAR来定义的。(除了XP中引入的只适用于Unicode的API)。
LPTSTR:LPSTR、LPWSTR两者二选一,取决于是否宏定义了UNICODE或ANSI。
LPCTSTR: LPCSTR、LPCWSTR两者二选一,取决于是否宏定义了UNICODE或ANSI。TCHAR:wchar_t 、char两者二选一,取决于是否宏定义了UNICODE或ANSI。
即
#ifdef UNICODE
typedef LPWSTR LPTSTR;
typedef LPCWSTR LPCTSTR;
typedef TCHAR wchar_t;
#else
typedef LPSTR LPTSTR;
typedef LPCSTR LPCTSTR;
typedef TCHAR char;
另外CString = LPCTSTR
2. 各个数据类型的函数库
字符集 特性 实例
ANSI 操作函数function以str开头 strcpy
Unicode 操作函数function以wcs开头 wcscpy
MBCS 操作函数function以_mbs开头 _mbscpy
ANSI/Unicode 操作函数function以_tcs开头 _tcscpy(C运行期库)
ANSI/Unicode 操作函数function以lstr开头 lstrcpy(Windows函数function)
所有新的及未过时的函数function都同时拥有ANSI及Unicode两个版本。ANSI版本函数function结尾以A表示;Unicode版本函数function结尾以W表示。Windows如下定义设置:
#ifdef UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowExA
#endif // !UNICODE
3. 如何表示字符串常量?
字符集 实例
ANSI “string”
Unicode L“string”
ANSI/Unicode T(“string”)或_TEXT(“string”)或TEXT(“string”)
4. 各个类型之间的相互转换
4.1 短到长
LPSTR to LPTSTR:_T() (别名还有 _TEXT(), TEXT()),如“Hello”转换成_T("Hello")。使用L不大好,但是如果只使用了Unicode也可以用。
LPSTR to LPWSTR:可以使用L,如L"Hello"。也可以使用使用_T()。
4.2 CString到WCHAR*或者char*
4.2.1 CString和WCHAR*(wchar_t*)的转化
方法一:使用wcscpy()函数
1 | CString str("string"); |
2 | WCHAR pWchar[100]; |
3 | wcscpy(pWchar,str); |
方法二:使用wcscpy_s()函数
这个函数是上一个函数的安全版本,调用上一个函数如果pWchar的内存不足时,容易引发意味的错误,但是wcscpy_s()则不会,应该其内存大小已经指定出来了:
1 | CString str("string"); |
2 | WCHAR pWchar[100]; |
3 | wcscpy_s(pWchar,100,str); |
方法三:使用_tcscpy()函数
1 | CString str("string"); |
2 | WCHAR pStr[100]; |
3 | _tcscpy(pStr,str); |
方法四:使用_tcscpy_s()函数
同wcscpy_s()一样,_tcscpy_s()函数也是_tcscpy()函数的安全版本:
1 | CString str("string"); |
2 | WCHAR pStr[100]; |
3 | _tcscpy_s(pStr,100,str); |
4.2.2 CString和char*的转化
方法一:使用wcstombs()函数
1 | CString str("string"); |
2 | char pChar[100]; |
3 | wcstombs(pChar,str,100); |
方法二:使用wcstombs_s()函数
同上面一样,wcstombs_s()是wcstombs()的安全版本:
所以结论,为提高可移植性,定义字符串时用TCHAR、LPCTSTR和LPTSTR,转化为UNICODE时用_T而不用L。
后记:说说char~
char 虽然被称为短整形,但是char并不像int short long那样默认是signed。char的符号取决于编译器,而不是取决于C语言本身。
char的范围0~127,unsigned char的范围是0~255,signed char的范围是-127~127。char所有的值总是会同时落在signed char和unsigned char中。char的取值范围正好是signed char和unsigned char的交集。
做一个编译器的例子看看,代码如下。编译器VS2010的CMD,编译命令CL(CL.exe)。
cl xxx.c 运行结果是 ‘-1’ = -1;
cl /J xxx.c运行结果是'-1' = 255;/J是宏定义Unsigned的意思。
由此可见VS默认是signed char = char,后来设置参数又有了char = unsigned char.
由此证明char的signed还是unsigned不是c语言里的内容,取决于编译器。
#include <stdio.h>
int main(void)
{
char pear = -1;
printf("'-1'= %d\n", pear);
getchar();
return 0;
}