在 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

如果您尝试将多个元素分配给一个元素,编译器会选择适合的第一个元素 0x0041L'x' 是指单个宽字符。


VS2019会对wchar_t wc = L' 459'发出警告,除非警告级别设置为小于3,但不建议这样做。使用警告级别 3 或更高级别。

wchar_t 是原始类型,不是 unsigned shorttypedef,但它们在 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 个元素 + 空终止字符)