赋值语句 |
结果 |
说明 |
在不同地区运行是否会乱码 |
char c = 'z'; |
'z' |
GB2312/GBK 编码:'z' 是单字节的,c 得到的是字符 'z' 本身 |
不会,英文字母在所有地区的编码都是一样的 |
int i = 'z'; |
0x7A (122) |
GB2312/GBK 编码:'z' 是单字节的,在 int 的取值范围之内,i 得到的是字符 'z' 的编码,与 'z' 的 ASCII 值相等 |
不会,英文字母在所有地区的编码都是一样的 |
char c = '我'; |
0xD2 (210) |
GB2312/GBK 编码:'我' 是双字节的,编码值为 0xCED2,c 得到的是低位字节 0xD2,高位丢失,很显然这并不是期望的值。0xD2 在 GB2312/GBK 里面是不完整的编码,即所谓的 “半个汉字”。 |
会乱码,ANSI 编码到代码页不同的地区会乱码 |
unsigned short c = '我'; |
0xCED2 (52946) |
GB2312/GBK 编码,'我' 是双字节的,正好在 unsigned short 的取值范围之内,得到编码值为 0xCED2。 |
会乱码,ANSI 编码到代码页不同的地区会乱码 |
char s[] = { 'a', 'b', 'c', 0 }; |
"abc" |
GB2312/GBK 编码,'a', 'b', 'c' 都是单字节编码,他们给 char 数组对应的每个元素赋值的时候,都能得到正确的值。 |
不会,英文字母在所有地区的编码都是一样的 |
char s[] = { '你', '好', 0 }; |
"忝" |
GB2312/GBK 编码,'你' 的编码是 0xC4E3,'好' 的编码是
0xBAC3,他们分别赋值给 char 之后,都取了低位字节,即 s[0] = 0xE3 和 s[1] = 0xC3,这两个字符组成一个编码为 0xE3C3 的双字节字符,正好是汉字 '忝' 的 GB2312/GBK 编码。 |
会乱码,ANSI 编码到代码页不同的地区会乱码 |
char c = 'wxyz'; |
'z' |
由于单引号里面是多个字符,他们会组成 4 个字节的字符编码,编译器会提出警告,丢失放在编码高位的字节,c 得到最低位字节 'z'; |
不会,英文字母在所有地区的编码都是一样的 |
unsigned long i = 'wxyz'; |
0x7778797A (2004384122) |
由于单引号里面是多个字符,他们会组成 4 个字节的字符编码,'w'、'x'、'y'、'z' 的编码值分别为 0x77, 0x78, 0x79, 0x7A。 |
不会,英文字母在所有地区的编码都是一样的 |
char c = 'hello!'; |
编译错误 |
因为字符编码最多 4 个字节,超过 4 个字节无法编译通过。 |
|
| | | |
wchar_t c = L'我'; |
L'我' |
UTF-16 单个 char16_t 编码,直接得到字符。 |
不会,UNICODE 不会乱码 |
wchar_t c = '我'; |
L'我' |
ANSI 编码的 '我' 认为是 GB2312/GBK 编码的,程序运行时进行编码转换,转为 UTF-16 编码的对应的字符,得到 L'我'。由于产生了不必要的编码转换,少写了一个 L 会引起到不同代码页的地区出现乱码,很显然这不是我们预期的结果。 |
会乱码,ANSI 编码到代码页不同的地区会乱码 |
wchar_t c = L'𠀾'; |
0xD840 (55360) |
UTF-16 编码的 L'𠀾' 是 2 个 char16_t 的编码:0xD840, 0xDC3E,而在 Windows 系统里面的 L'𠀾' 只能得到第一个编码值 0xD840 |
不会,UNICODE 不会乱码 |
unsigned long i = L'𠀾'; |
0xD840 (55360) |
尽管 i 是 4 个字节的,能够放得下 2 个 char16_t 编码,但是 L'𠀾' 这个写法只能够得到第一个编码,所以还是 0xD840 |
不会,UNICODE 不会乱码 |
wchar_t s[] = L"𠀾"; |
L"𠀾" |
字符串长度仅受内存大小的限制,所以无论几个 char16_t 的 UTF-16 编码的字符,都可以正常放在字符串里面,得到正确的值。 |
不会,UNICODE 不会乱码 |
| | | |
char16_t c = u'我'; |
u'我' |
UTF-16 单个 char16_t 编码,直接得到字符。 |
不会,UNICODE 不会乱码 |
char16_t c = u'𠀾'; |
编译错误 |
小写英文字母 u 开头的单引号,只能表示一个 UTF-16 单个 char16_t 编码的字符,u'𠀾' 是 2 个 char16_t 编码的字符,所以无法编译通过 |
|
char16_t s[] = u"𠀾"; |
u"𠀾" |
字符串长度仅受内存大小的限制,所以无论几个 char16_t 的 UTF-16 编码的字符,都可以正常放在字符串里面,得到正确的值。 |
不会,UNICODE 不会乱码 |
| | | |
char32_t c = U'我'; |
U'我' |
大写引文字母 U 开头的是 UTF-32 编码,字符编码就是 UNICODE 码本身,所以始终是正确的 |
不会,UNICODE 不会乱码 |
char32_t c = U'𠀾'; |
U'𠀾' |
大写引文字母 U 开头的是 UTF-32 编码,字符编码就是 UNICODE 码本身,所以始终是正确的 |
不会,UNICODE 不会乱码 |
char32_t s[] = U"𠀾"; |
U'𠀾' |
大写引文字母 U 开头的是 UTF-32 编码,字符编码就是 UNICODE 码本身,所以始终是正确的 |
不会,UNICODE 不会乱码 |
| | | |
String s = _T("字符串") |
L"字符串" 或
"字符串" |
String: 根据项目的 UNICODE/ANSI 版本,相当于 UnicodeString 或 AnsiString。_T("字符串") 相当于 wchar_t [] 或 char []。C++ Builder 操作指南 → 项目的常用的重要配置 → 选择 UNICODE / ANSI |
UNICODE 版本不会乱码
ANSI 版本会乱码 |
AnsiString s = "字符串"; |
"字符串" |
GB2312/GBK 编码字符串 |
会乱码,ANSI 编码到代码页不同的地区会乱码 |
UnicodeString s = L"字符串"; |
L"字符串" |
UTF-16 编码字符串 |
不会,UNICODE 不会乱码 |
AnsiString s = L"字符串"; |
"字符串" |
运行时把 UTF-16 编码的字符串转为 ANSI 编码,即 GB2312/GBK。产生不必要的转码,并且不会从根本上解决乱码问题。例如到英国的电脑里面运行,只剩下英文和数字了,到日本的电脑里面会显示出来一部分日本 Shift-JIS 编码里面的汉字,而不是全部汉字。 |
虽然不会乱码,但是这个地区的代码页所使用的编码里面没有的字符会丢失 |
UnicodeString s = "字符串"; |
L"字符串" |
虽然变量是 UnicodeString 类型的,但是 "字符串" 是 ANSI 编码的,运行时会从 ANSI 编码转为 UTF-16 编码,这样在代码页不同的地区运行,就会乱码。 |
会乱码,ANSI 编码到代码页不同的地区会乱码 |
| | | |
WideString s = L"字符串"; |
L"字符串" |
定义变量时赋初始值,调用的是 WideString 的构造函数,构造出来一个新的 BSTR 并且赋值为 L"字符串" |
不会,UNICODE 不会乱码 |
WideString s;
s = L"字符串"; |
运行时程序崩溃 |
WideString 的 = 操作符,需要一个新创建的 BSTR 类型,而 L"字符串" 是标准 C/C++ 的字符串,当 WideString 把这个字符串当作 BSTR 销毁的时候,程序就会崩溃。 |
|
WideString s;
s = SysAllocString(L"字符串"); |
L"字符串" |
WideString 的 = 操作符,需要一个新创建的 BSTR 类型,用 SysAllocString 函数创建新的 BSTR 字符串 L"字符串"。 |
不会,UNICODE 不会乱码 |
WideString s;
s = WideString(L"字符串"); |
L"字符串" |
用 WideString 构造函数创建一个新的 BSTR 字符串,赋值给 s。 |
不会,UNICODE 不会乱码 |