C语言打印16进制出现0xffffff现象的问题剖析!

先贴上链接https://www.cnblogs.com/acool/p/4790069.html

无意中遇到的这个错误,就问了下同事,然后就上网查了下,就遇到了一篇好文章,评论也是精彩,特此记录!

只想简单解决问题的,我会把部分原文贴在下面,可供解决问题,但建议去原博客看一下!

#include <stdio.h>
int main()
{
    char c = 0xc9;
    printf("A:c = %2x\n",(unsigned char)c);
    printf("B:c = %2x\n",c & 0xff);
    printf("C:c = %2x\n",c);
    return 0;
}

程序输出如下:

A:c = c9
B:c = c9
C:c = ffffffc9

可以看到:

  把c转换成unsigned char打印是正确的。视作情况A。

  把c与 0xff做&操作后打印正确。视作情况B。

  对c不做任何处理,则问题复现了,打印出ffffffc9。视作情况C。

  情况A B是我百度来的一些解决C现象的方法。那么我们现在来逐一分析解释ABC三种情况。

  

  首先我们必须知道,printf()函数的%x(X)输出的是Int型别的16进制格式。所以char型别的c变量会被转换成Int型别。

  其次,我们的知道计算机是用补码表示数据的。关于原码,反码,补码的知识请自行充电。

情况C:

   c的补码:11001001(0xc9)。

   c的反码:11001000(0xc9)。

   c的原码:10110111(0xc9)。 

   因为char型别是带符号的,所以最高位的1这里视为负号。

   把c转换成Int型别   char  -----> Int

   Int_c的原码:10000000 00000000 00000000 00110111(把c原码的最高位1  提到最高位。其余高位补0)。

   Int_c的反码:11111111 11111111 11111111 11001000

   Int_c的补码:11111111 11111111 11111111 11001001(0xffffffc9)。

   所以打印出来看似诡异的值其实是合情合理的。如何避免?看AB情况。

情况B:

     我们在情况C的基础上将c与0xff做&操作。

     Int_c的补码:11111111 11111111 11111111 11001001(0xffffffc9)。

         &

         00000000 00000000 00000000 11111111

     最终结果为: 00000000 00000000 00000000 11001001(0xc9)。

情况A:

     我觉得情况A的处理方式才是最正规的处理办法,但是据说linux内核使用(&0xff)。

   c的补码:11001001(0xc9)。

   c的反码:11001001(0xc9)。

   c的原码:11001001(0xc9)。 

   这里强制转换c为unsigned char型别。因此最高位的1不是正负号

   把c转换成Int型别   char  -----> Int

   Int_c的原码:00000000 00000000 00000000 11001001(把c原码的最高位1  提到最高位。其余高位补0)。

   Int_c的反码:00000000 00000000 00000000 11001001

   Int_c的补码:00000000 00000000 00000000 11001001(0xc9)。

   因此打印正常。

以上是摘自https://www.cnblogs.com/acool/p/4790069.html的部分内容,若有时间还是建议到链接处看一下。

在此向前辈、大牛们致敬,让我这种菜鸟少走不少弯路!


  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值