在 C 中,如果我将 'successive wchar_t characters' 放入 wchar_t 变量中会发生什么?
In C, what would happen if I put 'successive wchar_t characters' into a wchar_t variable?
#include <stdio.h>
wchar_t wc = L' 459';
printf("%d", wc); //result : 32
我知道 'space' 在 ASCII 码 table 中是 'decimal 32'。
我不明白的是,据我所知,如果没有足够的 space 供变量存储值,则该值将是原始值的 'last digits'。
例如,如果我将二进制值“1100 1001 0011 0110”放入单字节变量中,它将是“0011 0110”,即原始二进制值的 'the last byte'。
但是上面的代码显示了原始值的 'the first byte'。
我想知道当我执行上面的代码时内存级别发生了什么。
_int64 x = 0x0041'0042'0043'0044ULL;
printf("%016llx\n", x); //prints 0041004200430044
wchar_t wc;
wc = x;
printf("%04X\n", wc); //prints 0044 as you expect
wc = L'\x0041\x0042\x0043\x0044'; //prints 0041, uses the first character
printf("%04X\n", wc);
如果您分配的整数值过大,编译器会采用适合 2 个字节的最大值 0x0044
。
如果您尝试将多个元素分配给一个元素,编译器会选择适合的第一个元素 0x0041
。 L'x'
是指单个宽字符。
VS2019会对wchar_t wc = L' 459'
发出警告,除非警告级别设置为小于3,但不建议这样做。使用警告级别 3 或更高级别。
wchar_t
是原始类型,不是 unsigned short
的 typedef
,但它们在 Windows 中都是 2 个字节(在 linux 中是 4 个字节)
注意'abcd'
是4个字节。 L
前缀表示每个元素 2 个字节(在 Windows 中),因此 L'abcd'
是 8 个字节。
要查看 wc
中的内容,让我们看一下 Unicode 字符 L'X'
,它具有 0x0058
的 UTF-16 编码(类似于最多 128 的 ASCII 值)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
wchar_t wc = L'X';
wprintf(L"%c\n", wc);
char buf[256];
memcpy(buf, &wc, 2);
for (int i = 0; i < 2; i++)
printf("%02X ", buf[i] & 0xff);
printf("\n");
return 0;
}
输出将是 58 00
。它不是 00 58
因为 Windows 在小端系统上运行并且字节被翻转。
另一个奇怪的事情是 UTF16 对某些代码点使用 4 个字节。所以你会收到这一行的警告:
wchar_t wc = L'';
相反,您想使用字符串:
wchar_t *wstr = L"";
::MessageBoxW(0, wstr, 0, 0); //console may not display this correctly
这个字符串将是 6 个字节(2 个元素 + 空终止字符)
#include <stdio.h>
wchar_t wc = L' 459';
printf("%d", wc); //result : 32
我知道 'space' 在 ASCII 码 table 中是 'decimal 32'。
我不明白的是,据我所知,如果没有足够的 space 供变量存储值,则该值将是原始值的 'last digits'。
例如,如果我将二进制值“1100 1001 0011 0110”放入单字节变量中,它将是“0011 0110”,即原始二进制值的 'the last byte'。
但是上面的代码显示了原始值的 'the first byte'。
我想知道当我执行上面的代码时内存级别发生了什么。
_int64 x = 0x0041'0042'0043'0044ULL;
printf("%016llx\n", x); //prints 0041004200430044
wchar_t wc;
wc = x;
printf("%04X\n", wc); //prints 0044 as you expect
wc = L'\x0041\x0042\x0043\x0044'; //prints 0041, uses the first character
printf("%04X\n", wc);
如果您分配的整数值过大,编译器会采用适合 2 个字节的最大值 0x0044
。
如果您尝试将多个元素分配给一个元素,编译器会选择适合的第一个元素 0x0041
。 L'x'
是指单个宽字符。
VS2019会对wchar_t wc = L' 459'
发出警告,除非警告级别设置为小于3,但不建议这样做。使用警告级别 3 或更高级别。
wchar_t
是原始类型,不是 unsigned short
的 typedef
,但它们在 Windows 中都是 2 个字节(在 linux 中是 4 个字节)
注意'abcd'
是4个字节。 L
前缀表示每个元素 2 个字节(在 Windows 中),因此 L'abcd'
是 8 个字节。
要查看 wc
中的内容,让我们看一下 Unicode 字符 L'X'
,它具有 0x0058
的 UTF-16 编码(类似于最多 128 的 ASCII 值)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
wchar_t wc = L'X';
wprintf(L"%c\n", wc);
char buf[256];
memcpy(buf, &wc, 2);
for (int i = 0; i < 2; i++)
printf("%02X ", buf[i] & 0xff);
printf("\n");
return 0;
}
输出将是 58 00
。它不是 00 58
因为 Windows 在小端系统上运行并且字节被翻转。
另一个奇怪的事情是 UTF16 对某些代码点使用 4 个字节。所以你会收到这一行的警告:
wchar_t wc = L'';
相反,您想使用字符串:
wchar_t *wstr = L"";
::MessageBoxW(0, wstr, 0, 0); //console may not display this correctly
这个字符串将是 6 个字节(2 个元素 + 空终止字符)