能否在printf中给%c一个负的int参数?

问题描述 投票:0回答:1

我可以在 printf 通过格式指定器打印时 %c 因为在印刷 int 被转换为无符号字符?是 printf("%c", -65); 有效吗?- 我在GCC上试过,但输出的是一个菱形字符(里面有问号)。为什么会这样?

c int printf
1个回答
4
投票

绝对是的,如果 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-1Windows-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码点

© www.soinside.com 2019 - 2024. All rights reserved.