如果char 是有符号类型,则绝对可以。 C 允许 char 为 either signed or unsigned,在 GCC 中,您可以使用 -funsigned-char and -fsigned-char 在它们之间切换。当 char 被签名时,它与 this 完全相同
char c = -65;
printf("%c", c);
当传递给printf() 时,char 变量将被符号扩展 到int,因此printf() 也会看到 -65,就像它是从常量传递的一样。 printf 根本无法区分 printf("%c", c); 和 printf("%c", -65);,因为 default promotion 在可变参数函数中。
打印结果取决于字符编码。例如,在ISO-8859-1 或Windows-1252 字符集中,您会看到¿,因为(unsigned char)-65 == 0xBF。在 UTF-8(这是一种可变长度编码)中,不允许 0xBF 作为起始位置的字符。这就是为什么您会看到 � 它是无效字节的替换字符
请告诉我为什么代码点 0 到 255 没有映射到 unsigned char 中的 0 到 255。我的意思是它们是非负数,所以我不应该只查看 UTF-8 字符集的对应值吗?
映射并不是像你想象的那样通过范围内的相对位置来完成,即代码点0映射到CHAR_MIN,代码点40映射到CHAR_MIN + 40,代码点255映射到CHAR_MAX...在二进制补码系统它通常是一个简单的映射,当被视为无符号时,它基于 位模式 的值。这是因为值通常从更广泛的类型截断的方式。在 C 中,像 'a' 这样的字符文字具有 int 类型。假设'a' 映射到某个理论字符集中的代码点 130,那么下面的行是等价的
char c = 'a';
char c = 130;
无论哪种方式,c 在转换为 char 后都会被赋值为'a',即(char)'a',这可能是一个负值
所以代码点 0 到 255 被映射到 unsigned char 中的 0 到 255。这意味着代码点代码点 0x1F 将存储在值为 0x1F 的字符(有符号或无符号)中。如果 char 是无符号的,代码点 0xBF 将映射到 0xBF,如果 char 是有符号的,则映射到 -65
我假设以上所有内容都是 8 位字符。另请注意,UTF-8 是 Unicode 字符集的编码,它不是本身的字符集,因此您无法查找 UTF-8 代码点