我可以在 printf
通过格式指定器打印时 %c
因为在印刷 int
被转换为无符号字符?是 printf("%c", -65);
有效吗?- 我在GCC上试过,但输出的是一个菱形字符(里面有问号)。为什么会这样?
绝对是的,如果 char
是一个有符号的类型。C允许char是有符号或无符号的 而在GCC中,你可以在它们之间用 -funsigned-char
和 -fsigned-char
. 当char被签署时,它和这个完全一样。
char c = -65;
printf("%c", c);
当传递给printf的时候 char
变量将 扩号 到 int
所以printf也会看到-65,就像从一个常量传递过来一样。printf
根本没有办法区分 printf("%c", c);
和 printf("%c", -65);
由于在变量函数中默认推广。
打印结果 取决于字符编码 虽然。例如在。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
将被分配一个值为 'a'
后,即 (char)'a'
,可能是一个负值
所以代码点0到255 是 映射到0到255的无符号char中。这意味着代码点代码点0x1F将被存储在一个值为0x1F的char(有符号或无符号)中。如果char是无符号的,代码点0xBF将被映射为0xBF,如果char是有符号的,代码点将被映射为-65。
以上的东西我都假设是8位char。另外要注意的是,UTF-8是Unicode字符集的一种编码,它本身不是一个字符集,所以不能查UTF-8码点