C标准:L前缀和八进制/十六进制转义序列

时间:2013-04-07 18:34:54

标签: c widechar

我没有在C标准中找到解释如何处理宽字符串中的上述转义序列。

例如:

wchar_t *txt1 = L"\x03A9";
wchar_t *txt2 = L"\xA9\x03";

这些是以某种方式处理的(比如在每个字节前加上\ x00字节)或存储在内存中的方式与在此处声明的方式完全相同吗?

此外,L前缀如何根据标准运作?

修改

让我们考虑一下txt2。它将如何存储在内存中? \ xA9 \ x00 \ x03 \ x00或\ xA9 \ x03,因为它是写的?同样适用于\ x03A9。这会被视为一个宽字符还是两个单独的字节,它们将被分成两个宽字符?

EDIT2:

标准说:

反斜杠后面的十六进制数字和十六进制转义中的字母x 序列被视为构造整数的单个字符的一部分 字符常量或宽字符常量的单个宽字符。该 如此形成的十六进制整数的数值指定所需的值 性格或广泛的性格。

现在,我们有一个字面文字:

wchar_t txt = L'\xFE\xFF';

它由2个十六进制转义序列组成,因此它应被视为两个宽字符。如果它们是两个宽字符,则它们不能放入一个wchar_t空间(但它在MSVC中编译),在我的情况下,该序列被视为如下:

wchar_t foo = L'\xFFFE';

这是唯一的十六进制转义序列,因此也是唯一的宽字符。

EDIT3:

结论:每个oct / hex序列都被视为一个单独的值(wchar_t * txt2 = L“\ xA9 \ x03”;由3个元素组成)。 wchar_t txt = L'\ xFE \ xFF';不可移植 - 实现定义的功能,应该使用wchar_t txt = L'\ xFFFE';

1 个答案:

答案 0 :(得分:2)

没有处理。 L"\x03A9"只是一个数组wchar_t const[2],由两个元素0x3A90组成,同样L"\xA9\x03"是一个数组wchar_t const[3]

特别注意C11 6.4.4.4/7:

  

每个八进制或十六进制转义序列是最长的字符序列   构成逃脱序列。

还有C ++ 11 2.14.3 / 4:

  

十六进制序列中的位数没有限制。

另请注意,当您使用十六进制序列时, 负责确保您的数据类型可以保存该值。 C11-6.4.4.4 / 9实际上将此作为一项要求,而在C ++中,超出类型范围只是"实现定义"。 (如果超出类型的范围,好的编译器应该警告你。)


但是,您的代码没有意义,因为左侧既不是数组也不是指针。它应该是这样的:

wchar_t const * p = L"\x03A9";    // pointer to the first element of a string

wchar_t arr1[] = L"\x03A9";       // an actual array
wchar_t arr2[2] = L"\x03A9";      // ditto, but explicitly typed

std::wstring s = L"\x03A9";       // C++ only

在切线上:这个question of mine详细说明了字符串文字和转义序列。