判断big endian和little endian的方法

 
不一样体系的CPU在内存中的数据存储每每存在着差别。例如,Intel的x86系列处理器将低序字节存储在起始地址,而一些RISC架构的处理器,如IBM的370主机使用的PowerPC或Motorola公司生产的CPU,都将高序字节存储在起始位置。这两种不一样的存储方式被称为little-endian和big-endian。
little-endian是x86系列CPU的数据存储方式,即将低序的部分存储在前面。而big-endian是将高序部分存储在前面。例如,要存储0xF432,little-endian将以32F4存储,而使用big-endian与此相反,将存储为F432,如图13.2所示。
程序p13.1.c讲解了如何判断系统是使用big-endian仍是little-endian实现数据存储的。程序中使用的方法以下所示。
 
 
图13.2   big-endian与little-endian方式数据存储示例
(1)利用联合的特色。联合中的数据成员是共享存储空间的,所分配的空间为数据成员中最大所需的内存数。程序定义了名为endian_un的联合体,其中包含两个数据成员,一个是short类型的数据成员(在32位系统上,short类型的长度是2字节),一个是字符类型的字符数组,字符数组的元素个数为short类型的字节数。
程序将var赋值为0x0102。因为联合结构的特色,bits字符串数组中一样存储了0x0102这一数值。经过判断字符串中的低位和高位存储的内容,就能够知道系统是little-endian仍是big-endian的。

#includehtml

int main(int argc, char **argv)  {          union {            short  s;        char   c[sizeof(short)];      } un;web

        un.s = 0x0102;          if (sizeof(short) == 2) {                  if (un.c[0] == 1 && un.c[1] == 2)                          printf("big-endian\n");                  else if (un.c[0] == 2 && un.c[1] == 1)                          printf("little-endian\n");                  else                          printf("unknown\n");          } else                  printf("sizeof(short) = %d\n", sizeof(short));编程

        exit(0);  }数组

 

(2)经过强制类型转换实现。程序中经过取flag变量的地址,得到起始空间的存储内容。若是起始空间存储的是数据的低位内容,则表示存储方式为little-endian,不然为big-endian。
程序的具体代码以下:
//使用类型的强制转换实现little-endian与big-endian的判断
int is_little_endian(void)
{
  unsigned short flag=0x4321;
  if (*(unsigned char*)&flag==0x21)
    return 1;
  else
    return 0;
}

使用gcc编译p13.1.c,得到名为p13.1的可执行文件。执行该程序,具体输出以下。能够看到x86系统的内存数据存储方式为little-endian方式。
[program@localhost charter13]$ gcc -o p13.1 p13.1.c 
[program@localhost charter13]$ ./p13.1 
judged by first method, little-endian
judged by second method, little-endian
[program@localhost charter13]$
之因此介绍big-endian和little-endian,是由于这一数据存储方式不只影响程序在不一样硬件平台中的移植,并且在网络编程中也要考虑字节顺序的问题。为了不兼容性的问题,网络中的数据传输都使用了从高到低的顺序存储方式。所以,若是要将数据从低位字节优先(little-endian)的机器上发往网络,必须首先进行转换。而big-endian的机器是不须要转换的。
Linux系统提供了htons、htonl、ntohs、ntoh这4个函数用于进行字节顺序的转换。其中,h是host的缩写,n表示network。最后一个字符若是是s,表示short类型,若是是l,表示为long类型。4个函数的具体定义以下: uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);   htonl/htons:表示主机字节顺序转换成网络字节顺序,htonl函数和htons函数的区别在于参数长度存在差别。   ntohl/ntohs:表示网络字节顺序转换成主机字节顺序,ntohl函数和ntohs函数的区别在于参数长度存在差别。
相关文章
相关标签/搜索