9

在 C11 中,添加了一个带有前缀 u8 的新字符串文字。这将返回一个字符数组,其中文本编码为 UTF-8。这怎么可能?不是普通的字符签名吗?意味着由于符号位,它可以使用的信息少一点吗?我的逻辑将描述一串 UTF-8 文本需要是一个无符号字符数组。

4

4 回答 4

7

不是普通的字符签名吗?

charsigned还是取决于实现unsigned

此外,符号位不会“丢失”,它仍然可以用来表示信息,并且char不一定是 8 位大(在某些平台上可能更大)。

于 2012-01-11T11:44:37.340 回答
7

这里有一个潜在的问题:

如果一个实现CHAR_BIT == 8使用符号大小表示char(sochar是有符号的),那么当 UTF-8 需要 bit-pattern10000000时,这是一个负 0。所以如果实现进一步不支持负 0,那么一个给定的 UTF-8 字符串可能包含 的无效(陷阱)值char,这是有问题的。即使它确实支持负零,10000000当在.char00000000char[]

我认为这意味着对于符号幅度 C11 实现,char需要无符号。通常,是否char有符号或无符号取决于实现,但当然,如果char被签名导致无法正确实现 UTF-8 文字,那么实现者只需要选择无符号即可。顺便说一句,C++ 的非 2 补码实现一直都是这种情况,因为 C++ 允许char以及unsigned char用于访问对象表示。C 只允许unsigned char.

在 2 的补码和 1 的补码中,UTF-8 数据所需的位模式是 的有效值signed char,因此实现可以自由地制作char有符号或无符号,并且仍然能够在 中表示 UTF-8 字符串char[]。这是因为所有 256 位模式都是有效的 2 补码值,而 UTF-8 恰好不使用该字节11111111(1s 补码负零)。

于 2012-01-11T11:56:47.843 回答
1

不,符号位仍然有点!并且 UTF-8 规范本身并没有说字符必须是无符号的。

PS Wat is kookwekker voor 'n naam?

于 2012-01-11T11:48:14.117 回答
1

char 的符号无关紧要;utf8 只能通过移位和掩码操作来处理(这对于有符号类型可能很麻烦,但并非不可能)但是:utf8至少需要8 位,因此“断言(CHAR_BIT >= 8);”

逐点说明:以下片段不包含对字符值的算术运算,仅包含移位和掩码。

static int eat_utf8(unsigned char *str, unsigned len, unsigned *target)
{
unsigned val = 0;
unsigned todo;

if (!len) return 0;

val = str[0];
if ((val & 0x80) == 0x00) { if (target) *target = val; return 1; }
else if ((val & 0xe0) == 0xc0) { val &= 0x1f; todo = 1; }
else if ((val & 0xf0) == 0xe0) { val &= 0x0f; todo = 2; }
else if ((val & 0xf8) == 0xf0) { val &= 0x07; todo = 3; }
else if ((val & 0xfc) == 0xf8) { val &= 0x03; todo = 4; }
else if ((val & 0xfe) == 0xfc) { val &= 0x01; todo = 5; }
else {  /* Default (Not in the spec) */
        if (target) *target = val;
        return -1; }


len--;str++;
if (todo > len) { return -todo; }

for(len=todo;todo--;) {
        /* For validity checking we should also
        ** test if ((*str & 0xc0) == 0x80) here */
        val <<= 6;
        val |= *str++ & 0x3f;
        }

if (target) *target = val;
return  1+ len;
}
于 2012-01-11T13:06:03.917 回答