从事 VC++ 编程工作两年了,一直觉得 Windows 下编程总是有好多意义重复的宏和 API,在不知道这些东东的由来的情况下经常会不知道用哪个好,试了这个不行就换哪个。。。
这样的结果就是你不知道怎么的代码就写好了,但是不稳定,出了问题了都不知道从何下手。
听说 Linux 下编程就很简洁,一个功能只会有一个函数(看多了 Linux vs Windows 的口水战...)。
闲来无事,看了下 CharlesPetzold 的《Windows 程序设计》对 char wchar_t TCHAR LPCSTR LPCTSTR....等等做一些整理,不是很完全。
1.关于 unicode
我们知道 ANSI中一个字符用 8 位来表示,而 Unicode 则使用 16 位来表示,这就是位什么会有 TCHAR....等等出现的原因。因为 Windows 需要兼容早期的程序,并使用这个技巧能实现一次编写同时支持 ANSI和 Unicode 版本的程序。代价就是多出好多宏和定义...
2.关于字符
char 这个不用说了,C 关键字代表一个字符
wchar_t 看下它的定义:typedef unsiged short wchar_t 没错,他就是一个无符号整型,占 2 个字节,16 位,所以他就是 Unicode 的字符型。
所以 Windows 干脆重新定义一个类型:TCHAR
#ifdef _UNICODE
typedef char TCHAR;
#else
typdef wchar_t TCHAR;
#endif
这样,TCHAR 就间接的支持 ASCII 和 Unicode 了
那么 LPCSTR 什么的就迎刃而解了
#ifdef _UNICODE
typedef WCHAR TCHAR, * PTCHAR;
typedef LPWSTR LPTCH, PTCH, PTSTR, LPTSTR;
typedef LPCWSTR LPCTSTR;
#else
typedef CHAR TCHAR, * PTCHAR;
typedef LPSTR LPTCH, PTH, PTSTR, LPTSTR;
typedef LPCSTR LPCTSTR;
#endif
3.关于函数
这样一来,编码的时候,有关字符、字符串的函数就都会有两个版本例如:
extern unsigned int strlen(char *s);
extern unsigned int wcslen(wchar_t *s); // Unicode 版本
同样使用上面的方法,定义一个函数
#ifdef _UNICODE
#define _tcslen wcslen
#else
#define _tcslen strlen
#endif
但是我很不理解的,Windows 有定义了一个版本:
int lstrlen(LPCTSTR lpString);
用哪个我也不知道了,高手请指教...
4.关于字符串常量
最后讲一个常见宏:
#ifdef _UNICODE
#define _T(x) L##x
#else
#define _T(x) x
#endif
很明显,这个红也是为了兼容两个版本
5.总结
综上,当你确定你的程序Unicode 版本的时候就可以使用 Unicode 版本的字符、字符串、相关函数,也可以使用 Windows 定义的兼容函数,但是不要混用,虽然程序运行没错,总有种不伦不类的感觉,最好用就用一套。