问题描述
使用以下代码:
#include <stdio.h>
int main(void) {
printf("%c %c ",82,2130);
return 0;
}
我得到输出:
R R
如何将2130
转换为R
?
解决方法
在C 2018(ISO / IEC C标准的2018版)7.2.6.1.8中给出了printf
处理c
转换说明符的方式,它说:
…如果不存在
l
长度修饰符,则int
参数将转换为unsigned char
,并写入结果字符。
因此,2130被转换为unsigned char
。转换的规则在6.3.1.3中给出。在典型的C实现中,unsigned char
有8位,可以表示0到255之间的值。在这种情况下,第2款适用:
否则,如果新类型是无符号的,则通过重复添加或减去新类型所能表示的最大值,直到该值在新类型的范围内,来转换该值。
这个复杂的句子说该值以256为模降低:“比新类型可以表示的最大值多1个”是大于255的一个,即256。因此,通过重复减去256直到2130减小2130。结果在0到255范围内。将256减去8倍得出2130 − 8•256 = 82。
然后将打印代码为82的字符。 C标准没有指定用于字符的代码,但是现代C实现通常使用ASCII。在ASCII中,“ R”的代码是82。
由于问题的标题要求转换为char
,因此我要指出char
可以是带符号的也可以是无符号的。如果未签名,则转换如上所述。如果已签名且源值无法用char
表示,则转换将被6.3.1.3 3覆盖,该转换表示结果是实现定义的或引发实现定义的信号。但是,问题代码中没有转换为char
,因为已指定printf
转换为unsigned char
。
基于ASCII的int到char转换只能获得十六进制值减少的最后2位数字。所以你只看到R。