代码段
char c1;
char c2;
c1 = 0X7F;
c2 = 0X80;
printf("c1 = %X\nc2 = %X\n", c1, c2);
输出
c1 = 7F
c2 = FFFFFF80
为什么c2
不能打印为80
? (我猜这与0X80的最高位为1而0x7F的MSB为0的事实有关)。如何才能将c2
打印为80
?
答案 0 :(得分:4)
因为printf
是可变参数函数。可变参数函数的参数经历默认促销;这样做的一个结果是char
参数转换为int
。在您的平台上,char
为signed
,因此c2
实际上是否定的。因此printf
打印int
中出现的所有前导因素(这些都是由于二进制补码表示)。
至少有3种方法可以解决这个问题:
%02X
而不是%X
作为printf
格式说明符。unsigned char
而不是char
(这会被提升为unsigned int
,因此没有领先者char
明确转换为int
,然后屏蔽:(int)c2 & 0xFF
。 [注意:这一点的推论是char c2 = 0x80
的行为实际上是实现定义的;如果char
为signed
,则会溢出。]
答案 1 :(得分:2)
c2
将(sign-)扩展为int
。以下将满足您的需求:
printf("c1 = %X\nc2 = %X\n", c1, ((int)c2) & 0xFF);
答案 2 :(得分:2)
根据您的需要尝试unsigned char
进行打印。这是ideone sample
unsigned char c1;
unsigned char c2;
c1 = 0X7F;
c2 = 0X80;
printf("c1 = %X\nc2 = %X\n", c1, c2);
如上所述,您看到的输出是由于符号扩展 希望这有帮助!
答案 3 :(得分:1)
为了强制printf将其视为一个字符,你需要给出“hh”修饰符。尝试:
printf("c1 = %hhX\nc2 = %hhX\n", c1, c2);
答案 4 :(得分:1)
你正在通过char
并将其读作unsigned int
s,你很幸运它可以正常工作。也就是说,char
已签署。 0x80实际上使其为负。它们显然被转换为整数然后未签名。这扩展了符号位,从而扩展了f
s。