大端序和小端序简介

来源:互联网 发布:类似于酷家乐的软件 编辑:程序博客网 时间:2024/04/30 02:33

大端序和小端序
一:大端字节序和小端字节序
在不同的CPU上,一个DWORD、WORD等基本数据的各个字节在内存中存储的顺序可能不一样,分为两种大端字节序和小端字节序。

大端字节序,高字节存于内存低地址,低字节存于内存高地址;小端字节序反之。如一个long型数据0x12345678

大端字节序:
          
内存低地址--> 0x12
                     0x34
                     0x56
内存高地址--> 0x78


小端字节序:

内存低地址--> 0x78          
                     0x56
                     0x34
内存高地址--> 0x12

 

二:大端序和小端序

采用大端序的CPU和采用小端序的CPU不仅在字节上是相反的,在比特位上也是相反的。
比如0x01在内存中的存储
大端序:内存低比特位 00000001 内存高比特位
小端序:内存低比特位 10000000 内存高比特位

比如0x00000001
大端序:内存低比特位 00000000 00000000 00000000 00000001 内存高比特位
小端序:内存低比特位 10000000 00000000 00000000 00000000 内存高比特位

这也是为什么我们定义位域的时候需要判断字节序。比如

struct exmpl{
#if 大端
BYTE  ver:4;
BYTE  len:4;
#else
BYTE len:4;
BYTE ver:4;
#endif
};

 

三:采用大端的系统和采用小端的系统的通信
主机字节序:各个系统当前采用的字节序,可能是大端,也可能是小端;
网络字节序:就是大端字节序。规定不同系统间通信一律采用网络字节序。

 

 

四:对于有位域情况下的操作
对于有位域情况下的操作,比如一个BYTE或一个DWORD,其中分几组比特,每组比特表示不同的意思。
这种情况如何填值?
例子1:BYTE的情况

1)定义位域的方式
struct exmpl aa;
aa.ver = VERSION_VALUE;
aa.len = LENGTH_VALUE;


2)采用位操作的方式
BYTE aa = VERSION_VALUE << 4 + LENGTH_VALUE;

采用上面两种方式最终得到的值是一样的,可以看出采用位操作方式更简洁,不需要知道采用的是大端还是小端
最后得到的BYTE值是一样的。


例子2:

1)定义位域的方式
struct exmpl2{
#if 大端
DWORD  res1:20;
DWORD  A:1;
DWORD  B:3;
DWORD  res2:8
#else
DWORD  res2:8
DWORD  B:3;
DWORD  A:1;
DWORD  res1:20;
#endif
};

struct exmpl2 aa;
aa.res1 = 0;
aa.A = VALUE_A;
aa.B = VALUE_B;
aa.res2 = 0;


2)采用位操作的方式
DWORD aa = VALUE_B << 8 + VALUE_A << 11;

上面两种方式得到的DWORD是一样的,当从网络上发送出去时,都需要转成网络序。

 

五:判断系统是采用大端还是小端的方式


typedef struct tagRegion{

   unsigned char region1:1;
    unsigned char region2:6;
   unsigned char region3:1;

} REGION;

union {
 REGION bb;
 unsigned char aa;

} cc;


int main(int argc, char* argv[])
{
    cc.bb.region1 =1;

   printf("Hello World! %d/n",cc.aa);//打印1表示小端,打印128表示大端。 
 

   return 0;
}