zoukankan      html  css  js  c++  java
  • C语言打印16进制出现0xffffff现象的问题剖析!

      今天在博问里面看到一个朋友的问题,大致是在网络程序中,打印出来的16进制数,莫名的出现ffffff。例如,某个byte真是值为0xc9,打印出来确是0xffffffc9。原博问连接如下:http://q.cnblogs.com/q/71073/

      其实类似的问题不是只在网络程序中才会出现的,看示例代码:

      1 #include <stdio.h>
      2 int main()
      3 {
      4     char c = 0xc9;
      5     printf("A:c = %2x
    ",(unsigned char)c);
      6     printf("B:c = %2x
    ",c & 0xff);
      7     printf("C:c = %2x
    ",c);
      8     return 0;
      9 }

      程序输出如下:

    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)。

       因此打印正常。

      以上分析,如有不正确的地方请各位指正。

  • 相关阅读:
    在oschina上新建项目的步骤
    将txt转为DataTable的方法
    设置IIS让网站拥有“网站目录外文件”的读写权限的操作(图文)
    从客户端****中检测到有潜在危险的 Request.QueryString 值在.net mvc下的解决方法
    动态调用类里的方法的示例(wjx)
    Pyhton忽略返回变量方法
    wsl安装Ubuntu16.04+Python2.7
    win10快速调用Shell代替GitBash
    wsl与win10文件互访
    OpenCV报错file too short解决
  • 原文地址:https://www.cnblogs.com/acool/p/4790069.html
Copyright © 2011-2022 走看看