C编程 - 打印最高有效位为1的十六进制字符

时间:2011-12-14 17:12:43

标签: c hex

代码段

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

5 个答案:

答案 0 :(得分:4)

因为printf可变参数函数。可变参数函数的参数经历默认促销;这样做的一个结果是char参数转换为int。在您的平台上,charsigned,因此c2实际上是否定的。因此printf打印int中出现的所有前导因素(这些都是由于二进制补码表示)。

至少有3种方法可以解决这个问题:

  • 使用%02X而不是%X作为printf格式说明符。
  • 使用unsigned char而不是char(这会被提升为unsigned int,因此没有领先者
  • 将每个char明确转换为int,然后屏蔽:(int)c2 & 0xFF

[注意:这一点的推论是char c2 = 0x80的行为实际上是实现定义的;如果charsigned,则会溢出。]

答案 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。