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

发布于 2024-12-21 05:48:05 字数 308 浏览 2 评论 0原文

代码片段

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

-柠檬树下少年和吉他 2024-12-28 05:48:05

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

有(至少)3 种方法可以解决此问题:

  • 使用 %02X 而不是 %X 作为 printf 格式说明符。
  • 使用 unsigned char 而不是 char (这会提升为 unsigned int,因此没有前导)
  • 显式转换您的每个 <代码>字符到int,然后掩码:(int)c2 & 0xFF。

[注:其推论是 char c2 = 0x80 的行为实际上是实现定义的;如果charsigned那么这将会溢出。]

Because printf is a variadic function. Arguments to variadic functions undergo the default promotions; one effect of this is that char arguments are converted to int. On your platform, char is signed, so c2 is actually negative. printf is therefore printing all the leading ones that occur in the int (these are due to two's-complement representation).

There are (at least) 3 methods to work around this:

  • Use %02X rather than %X as your printf format specifier.
  • Use unsigned char rather than char (this gets promoted to unsigned int, so no leading ones)
  • Explicitly convert each of your chars to int, and then mask: (int)c2 & 0xFF.

[Note: The corollary of this is that the behaviour of char c2 = 0x80 is actually implementation-defined; if char is signed then this will overflow.]

晨光如昨 2024-12-28 05:48:05

c2 得到(符号)扩展为 int。以下将满足您的要求:

printf("c1 = %X\nc2 = %X\n", c1, ((int)c2) & 0xFF);

c2 gets (sign-)extended to int. The following will do what you require:

printf("c1 = %X\nc2 = %X\n", c1, ((int)c2) & 0xFF);
许仙没带伞 2024-12-28 05:48:05

尝试使用 unsigned char 根据您的需要进行打印。这是一个 ideone 示例

unsigned char c1;
unsigned char c2;
c1 = 0X7F;
c2 = 0X80;
printf("c1 = %X\nc2 = %X\n", c1, c2);

正如已经提到的,您看到的输出是由于符号扩展造成的。
希望这有帮助!

Try unsigned char to print as per your need. Here is a ideone sample

unsigned char c1;
unsigned char c2;
c1 = 0X7F;
c2 = 0X80;
printf("c1 = %X\nc2 = %X\n", c1, c2);

As mentioned already the output you are seeing is due to sign extension.
Hope this helps!

以往的大感动 2024-12-28 05:48:05

为了强制 printf 将其视为字符,您需要给出“hh”修饰符。尝试:

printf("c1 = %hhX\nc2 = %hhX\n", c1, c2);

in order to force printf to treat that as a character, you need to give the "hh" modifier. try:

printf("c1 = %hhX\nc2 = %hhX\n", c1, c2);
节枝 2024-12-28 05:48:05

您正在传递 char 并将它们读取为 unsigned int ,您很幸运它能够正常工作。也就是说,char 已签名。 0x80 实际上使它成为负数。它们显然被转换为整数,然后无符号。这扩展了符号位,从 f 开始。

You're passing chars and having them read as unsigned ints, 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 the fs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文