在 printf 中可以给 %c 一个负的 int 参数吗?
Can %c be given a negative int argument in printf?
我可以在通过格式说明符 %c
打印时在 printf
中传递负整数吗?因为在打印时 int
被转换为无符号字符? printf("%c", -65);
有效吗? — 我在 GCC 上试过,但得到一个菱形字符(里面有问号)作为输出。为什么?
绝对可以,如果 char
是有符号类型。 C 允许 char
为 either 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 promotion,printf
根本无法区分 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 个代码点
我可以在通过格式说明符 %c
打印时在 printf
中传递负整数吗?因为在打印时 int
被转换为无符号字符? printf("%c", -65);
有效吗? — 我在 GCC 上试过,但得到一个菱形字符(里面有问号)作为输出。为什么?
绝对可以,如果 char
是有符号类型。 C 允许 char
为 either 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 promotion,printf
根本无法区分 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 个代码点