简单理解字节序

        字节序,一种简称,表示为内存中存储的字节的顺序,但仅仅是某一结构的存储字节的顺序,不影响总体结构。

起源

...

发展

...

基础

      这里重点说一下字节序基础知识和用途。

      字节序目前分为两种,大端字节序(big-endian,BE)和小端字节序(little-endian,LE)。在我们的编程惯性中,我们用得最多的是大端字节序,比如 unsigned int tmp = 0x1234; 那么 大单字节序的机器而言,tmp在内存的值为 0x1234,小端字节序机器而言,tmp在内存里面的值就是0x3412。所以我们惯性才是大端字节序。

  1. 为什么要存在大端与小端。

     这个问题其实是有必要的,如果大小端统一的话,对于我们程序员来说也就少了一些必要的编程考虑。对于大端和小端我比较接受网上的一个说法,"计算机的寻址都是一个起始地址加偏移量寻址的,小端的话就可以在寻址方面比较直观,因此可以带来一些额外的效果"。

     对于两者为什么要并存的问题其实很难讲清楚,并且由于我的知识局限也没办法展开来讲。但是不可争议的时,随机时代的发展,市面上确实无法在短期内统一字节序。

  2. 编程中的注意

很多时候我们编程都是用一个最直观的方式来的,对于一般情况,这些无伤大雅。但是对于数据传输的时候,如果不注意就会发送一段与网络字节序不一样的字节序,或者接受一段与当前机器字节序不符合的数据,对于这样的结果往往是网络抓包发现数据有问题,然后再仔细研究一下数据,最后找到原因,在代码中加入字节序的判断。

一般为了代码能够在不同平台运行,并且在不同字节序的机器上运行得出同样的结果,运行如下代码,看看是不是和想象中的结果一样。

/**
* test for BE and LE
*/
#include 

union test{
      int a;
      char b[4];
      float c;
      short d; 
};

int main(){
      union test t;
      t.a = 128;
      printf("int = %d,\nshort=%d,\nfloat%f\n",t.a,t.d,t.c);
      printf("%d-%d-%d-%d",t.b[0] - '\0' ,t.b[1] - '\0',t.b[2] - '\0',t.b[3] - '\0');
      scanf("%d",&t.a);
}


所以我们往往会在使用一些结构的时候加上一些判断,比如下面比较拙劣的判断:

int endian = 1;//default BE
union _t_{
  short a;
  char b[2];
};
_t_ _t;
_t.a  = 1
if(_t.b[0] -'\0' == 1)  endian = 0;// LE
#define __ENDIAN__ endian

在之后的使用中如果有涉及字节序的问题就需要判断一下。具体视情况而定。

网络字节序

网络传输中,都是使用大端字节序。

你可能感兴趣的:(简单理解字节序)