在 printf 中可以给 %c 一个负的 int 参数吗?

Can %c be given a negative int argument in printf?

我可以在通过格式说明符 %c 打印时在 printf 中传递负整数吗?因为在打印时 int 被转换为无符号字符? printf("%c", -65); 有效吗? — 我在 GCC 上试过,但得到一个菱形字符(里面有问号)作为输出。为什么?

绝对可以,如果 char 是有符号类型。 C 允许 chareither signed or unsigned and in GCC you can switch between them with -funsigned-char and -fsigned-char。当对 char 进行签名时,它与 this

完全相同
char c = -65;
printf("%c", c);

当传递给 printf() 时,char 变量将被 符号扩展 int 所以 printf() 也会看到-65 就像它是从常量传递的一样。由于可变参数函数中的 default promotionprintf 根本无法区分 printf("%c", c);printf("%c", -65);

虽然打印结果取决于字符编码。例如在 ISO-8859-1 or Windows-1252 字符集中你会看到 ¿ 因为 (unsigned char)-65 == 0xBF。在 UTF-8(可变长度编码)中,0xBF 不允许作为起始位置的字符。这就是为什么您会看到 � 这是无效字节的替换字符

Please tell me why the code point 0 to 255 are not mapped to 0 to 255 in unsigned char. I mean that they are non-negative so shouldn't I just look through the UTF-8 character set for their corresponding values?

映射并不是按照你想象的范围内的相对位置来完成的,即code point 0映射到CHAR_MIN,code point 40映射到CHAR_MIN + 40,code point 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 是有符号的,则代码点 0xBF 将映射到 -65

我假设上述所有内容都是 8 位字符。另请注意,UTF-8 是 Unicode 字符集的 encoding,它本身 not 是一个字符集,因此您无法查找 UTF -8 个代码点