通过了解char和wchar_t这两个类型的区别,我对ANSI字符集和UNICODE字符集有了些新的认识。
我最初认为以下代码(2)是通不过编译的,认为L'e'只能对宽字符类型赋值,因为L会告诉编译器后面跟着的字符或者字符串会用UNICODE编码存储,L'e'就被存储为两个字节0x0065,但事实不是这样,L'e'成功的赋值给了char变量c,只不过在赋值时高字节00被截断,就相当于赋值了0x65,即unsigned short给char赋值,wchar_t相当于unsigned short,尽管编译正确也不能加L,因为这样不但浪费一个字节空间也容易引起误会。
(1)char c = 'e';
(2)char c = L'e';//编译通过,且值与(1)一致
再试下中文字符定义,全部编译通过,但(3),(4)的值与'的'是不同的,因为中文无法用8位char表示,只能用宽字符类型wchar_t表示,所以高位截断后剩余的值是错误的。
(3)char c = '的';//c值为-60
(4)char c = L'的';//c值为-124 ,
(5)wchar_t c = L'的';//c为30340 = '的'
虽然单个字符可以编译通过,那么是否字符串也可以编译通过呢?看以下代码,通过试验编译器拒绝(7)这种定义,因为类型不匹配,假设编译器允许程序员这样定义,L"Hello"使用UNICODE方式存储变为:0x0048 0x0065 0x006C 0x006C 0x006F 0x0021,然后从首个不为'\0'的字节开始对char数组赋值,首个不为'\0'的字节是0x48,即H,但之后遇到'\0'说明字符串结束了,最终str变为长度为1的字符串,这与语句的本意是不同的。
(6)char str[] = "Hello";
(7)char str[] =L"Hello";//编译失败,error C2440: “初始化”: 无法从“const wchar_t [5]”转换为“char []”