C 编程 - 打印最高有效位为 1 的十六进制字符
代码片段
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
?
The code snippet
char c1;
char c2;
c1 = 0X7F;
c2 = 0X80;
printf("c1 = %X\nc2 = %X\n", c1, c2);
outputs
c1 = 7F
c2 = FFFFFF80
why is it that c2
does not print as 80
? (i'm guessing it's something to do with the fact that the most significant bit of 0X80 is 1 while the MSB of 0x7F is 0). how can i get c2
to print as simply 80
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
因为
printf
是一个可变参数函数。可变参数函数的参数经历默认提升;这样做的效果之一是char
参数被转换为int
。在您的平台上,char
是signed
,因此c2
实际上是负数。因此,printf
打印int
中出现的所有前导(这些是由于二进制补码表示)。有(至少)3 种方法可以解决此问题:
使用%02X
而不是%X
作为printf
格式说明符。unsigned char
而不是char
(这会提升为unsigned int
,因此没有前导)int
,然后掩码:(int)c2 & 0xFF。
[注:其推论是
char c2 = 0x80
的行为实际上是实现定义的;如果char
是signed
那么这将会溢出。]Because
printf
is a variadic function. Arguments to variadic functions undergo the default promotions; one effect of this is thatchar
arguments are converted toint
. On your platform,char
issigned
, soc2
is actually negative.printf
is therefore printing all the leading ones that occur in theint
(these are due to two's-complement representation).There are (at least) 3 methods to work around this:
Use%02X
rather than%X
as yourprintf
format specifier.unsigned char
rather thanchar
(this gets promoted tounsigned int
, so no leading ones)char
s toint
, and then mask:(int)c2 & 0xFF
.[Note: The corollary of this is that the behaviour of
char c2 = 0x80
is actually implementation-defined; ifchar
issigned
then this will overflow.]c2
得到(符号)扩展为int
。以下将满足您的要求:c2
gets (sign-)extended toint
. The following will do what you require:尝试使用
unsigned char
根据您的需要进行打印。这是一个 ideone 示例正如已经提到的,您看到的输出是由于符号扩展造成的。
希望这有帮助!
Try
unsigned char
to print as per your need. Here is a ideone sampleAs mentioned already the output you are seeing is due to sign extension.
Hope this helps!
为了强制 printf 将其视为字符,您需要给出“hh”修饰符。尝试:
in order to force printf to treat that as a character, you need to give the "hh" modifier. try:
您正在传递
char
并将它们读取为unsigned int
,您很幸运它能够正常工作。也就是说,char
已签名。 0x80 实际上使它成为负数。它们显然被转换为整数,然后无符号。这扩展了符号位,从f
开始。You're passing
char
s and having them read asunsigned int
s, you're lucky it works at all. That said,char
is signed. 0x80 actually makes it negative. They are apparently being converted to ints and then unsigned. That extends the sign bit, thence thef
s.