位序

                                         位序

原文出处:http://blog.sina.com.cn/s/blog_75e9551f01013vep.html


         

位序,一般用于描述串行设备的传输顺序。一般说来大部分硬件都是采用小端序(先传低位),因此,对于一个字节数据,大部分机器上收发的顺序都一样,不会有问题,这就是为什么没有针对单字节数据的API接口鈥漬tohc鈥鈥漢tonc鈥。当然,也有例外,比如­I2C协议就是采用了大端序。这些细节只有在网络协议的数据链路层底端才会碰到,对一般的程序员来说很少涉及。

         但是在C语言中存在一种特殊的数据结构:位域。它的存在,使得C程序员能方便地进行位操作(比如在网络协议中经常出现1bit或者多bit的标示位,它们不是一个完整的字节)。但同时也引起一些难以察觉的问题,这些问题的根源仍然是前面提到的端序。

 

         与字节序一样,一个字节中的8bit顺序在不同端序的机器上并不相同。大端机器上从低地址到高地址顺寻分别是msb->lsb,如下图:

小端序的机器上则正好相反

位序_第1张图片

 

现代计算机的最小存储单位是BYTE,无法对bit寻址,因此我们无法直接观察每个字节内部bit的顺序。但是我们仍然可以通过位域来间接观察字节内部bit顺序,以印证上面的说法。

在C语言中,位域与结构体类似,其语法规定:先声明的成员位于低地址,后声明的成员位于高地址。那么下面的位域中:

typedef struct OneByte

{

     bt0 : 1;

     bt1 : 1;

     bt2 : 1;

     bt3 : 1;

     bt4 : 1;

     bt5 : 1;

     bt6 : 1;

     bt7 : 1;

}

成员bt0就位于一个字节中最低地址bit0处,成员bt7就位于一个字节的最地址bit7处。

 

我们看看下面的程序。

#include <stdio.h>

 

typedef struct OneByte

{

     char bt0 : 1;

     char bt1 : 1;

     char bt2 : 1;

     char bt3 : 1;

     char bt4 : 1;

     char bt5 : 1;

     char bt6 : 1;

     char bt7 : 1;

} ONE_BYTE;

 

int main()

{

     ONE_BYTE onebyte = {0};

    

     onebyte.bt7 = 1;

 

     printf("onebyte = %#x/r/n", *((unsigned char *)&onebyte));

 

     return 0;

}

 

bt7赋值为1后,onebyte在内存中是这个样子的:

 

 

而在VC2005中编译运行的结果如下 :

 

0x80转换成二进制是1000 0000。由于在X86(小端序)中,高地址bit7是msb,因此onebyte的值是0x80了;这就证实了前面的说法。 相应的如果是在大端序计算机中,bit7是lsb,则onebyte的值是0x01。 

你可能感兴趣的:(位序)