Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3354805
  • 博文数量: 1450
  • 博客积分: 11163
  • 博客等级: 上将
  • 技术积分: 11101
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-25 14:40
文章分类

全部博文(1450)

文章存档

2017年(5)

2014年(2)

2013年(3)

2012年(35)

2011年(39)

2010年(88)

2009年(395)

2008年(382)

2007年(241)

2006年(246)

2005年(14)

分类: C/C++

2007-12-04 18:05:09

    无论你用 c/c++ 还是使用 java 都会涉及到位的操作。
   
    比如在编码的过程中经常会出现该情况,那么我们如何才能正确的根据要求进行位移呢?
我总结出一个小方法,感觉不错与大家分享。

    举个简单点的例子:
    在 java 语言中, 将 int 类型以 4个 byte 类型进行存储,这个该如何做呢?
它的具体实现如下:

    int I = 125;
    byte[] B = new byte[4];
   
    B[0] = (byte)(I >> 24);
    B[1] = (byte)(I >> 16);
    B[2] = (byte)(I >> 8);
    B[3] = (byte)I;

有的可能会写成:
    B[0] = (byte)((I >> 24) & 0xff);
    B[1] = (byte)((I >> 16) & 0xff);
    B[2] = (byte)((I >> 8) & 0xff);
    B[3] = (byte)(I & 0xff);

这两种写法都对。不过这个 “ & 0xff “ 我自已认为没什么用。最后的结果为:
    
     B[0] = 0;
     B[1] = 0;
     B[2] = 0;
     B[3] = 125;

    上面的例子可能很简单,大家一看就明白。但可能有不少人不是太了解内存中是如何对数值表示的,下面我就来给大家讲解一下。
    整型在java语言中用 32 位表示,I = 125 在内存中的所示为:

           |         |
           |  ...    |
           |---------|      ^   高地址
I的最高字   |   0     |      |
           |---------|      |
           |   0     |      |
           |---------|      |
           |    0    |      |
           |---------|      |
I的最低字   |    125  |      |
start->    |---------|      |   低地址
           |         |
           |---------|
           |         |
           |  ...    |

在上面例子中的 >>(n) 运算符是就从高位向低位移动,n 表示移动的位数。同理 << 运算符就是从低位向高位移动。

    根据上面的图,我们再一看上面的那段代码就一目了然了。现令 I=50463101 我们给出一步步的具体过程如下:
    最开始在内存中的状态:
           |         |
           |  ...    |
           |---------|      ^   高地址
I的最高字   |   3     |      |
           |---------|      |
           |   2     |      |
           |---------|      |
           |    1    |      |
           |---------|      |
I的最低字   |    125  |      |
start->    |---------|      |   低地址
           |         |
           |---------|
           |         |
           |  ...    |
      
  执行 B[0] = (byte)(I >> 24); 之后,如下图所示:
               
           |         |
           |  ...    |
           |---------|      ^   高地址
I的最高字   |   3     |      |
           |---------|      |
           |   3     |      |
           |---------|      |
           |    3    |      |
           |---------|      |
I的最低字   |    3    |      |
start->    |---------|      |   低地址
           |         |
           |---------|
           |         |
           |  ...    |    

执行 B[0] = (byte)(I >> 16); 之后,如下图所示:
           |         |
           |  ...    |
           |---------|      ^   高地址
I的最高字   |   3     |      |
           |---------|      |
           |   2     |      |
           |---------|      |
           |    2    |      |
           |---------|      |
I的最低字   |    2    |      |
start->    |---------|      |   低地址
           |         |
           |---------|
           |         |
           |  ...    |                                                 
                      
执行 B[0] = (byte)(I >> 8); 之后,如下图所示:
           |         |
           |  ...    |
           |---------|      ^   高地址
I的最高字   |   3     |      |
           |---------|      |
           |   2     |      |
           |---------|      |
           |    1    |      |
           |---------|      |
I的最低字   |    1    |      |
start->    |---------|      |   低地址
           |         |
           |---------|
           |         |
           |  ...    |   
                                                                            
 执行 B[0] = (byte)I; 之后,如下图所示:
           |         |
           |  ...    |
           |---------|      ^   高地址
I的最高字   |   3     |      |
           |---------|      |
           |   2     |      |
           |---------|      |
           |    1    |      |
           |---------|      |
I的最低字   |    125  |      |
start->    |---------|      |   低地址
           |         |
           |---------|
           |         |
           |  ...    |                               
                              
   因为在每一个取值操作中都有(byte)这个强类型转换,所以在取值时只取从 start 开始处的一个字节,即每次取的都是低地址上的一个字。这样就得到了最终的结果。

    所以根据以上说明,无论是对 4节操作,还是对8,16 等等字节操作的时候,只要将对应的内存表示画出来,等熟练之后就可以很容易的写出各种复杂的转换了。

    祝各个好运!!!!                           
                                 

                                 

                                 
                              


                              
                                                
      
      
      
      
      
      
      
      
      
                                                                        

   
阅读(905) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~