注:本文拷贝自我个人技术分享公众号【嵌入式技术部落】
一、大端序和小端序概念详解
字节序
字节序,又称端序,英文Endiannnes。字节序,简单点说,就是字节的存储顺序。数据都是单字节,那么不存在字节的存储顺序,对于多字节的数据,就要考虑字节的存储顺序了。典型的情况是int、double等在内存中的存放方式和网络传输的传输顺序。
字节序跟硬件的体系结构有关,和编程语言以及操作系统无关,例如在x86系列的pc上的solaris系统是小端序,sunsparc平台的solaris是大端序。
大端序(Big-endian)
大端字节序,高字节存于内存低地址,低字节存于内存高地址。
小端序(Little-endian)
小端字节序,低字节存于内存低地址,高字节存于内存高地址。
字节的高位与低位
举个例子,int a = 0x3A5C869E;那么左边3A就是高位字节,右边的9E就是低位字节,从左到右,由高到低,(注意,高低乃相对而言,比如86相对于9E是高字节,相对于5C是低字节)
地址的高位和低位
地址编号小的是低地址,地址编号大的是高地址。读数据永远是从低地址开始的!!!
二、大端序和小端序数据如何存储
小端序
数据的低字节存于内存低地址,高字节存于内存高地址。
简记:小端序就是低位对应低地址,高位对应高地址
存放二进制数:1011 0100 1111 0110 1000 1100 0001 0101
注意注意:我们在存放的时候是以一个存储单元为单位来存放,存储单元内部不需要再转变顺序啦!!
就例如下面的低位0001 0101存放在0号地址,我们不需要把它变成1010 1000,不需要!!不需要!!
存放十六进制数:B4F68C15
上面的二进制1011 0100 1111 0110 1000 1100 0001 0101转化为十六进制为B4F68C15。5对应0101,1对应0001,所以在存放的时候两个十六进制位就占用一个存储单元。
大端序
数据的高字节存于内存低地址,低字节存于内存高地址。
存放二进制数:1011 0100 1111 0110 1000 1100 0001 0101
存放十六进制数:B4F68C15
三、判断大端序和小端序
实现32位cpu中存储方式小端字节序和大端字节序的判断
#include <stdio.h>
void endiannessOne()
{
int a = 0x12345678;
char *p = (char *)&a;
if(*p == 0x12)
{
printf("%s this is big endian\n", __FUNCTION__);
}
else if(*p == 0x78)
{
printf("%s this is little endian\n", __FUNCTION__);
}
else
{
printf("%s unable to determine endian\n", __FUNCTION__);
}
}
void endiannessTwo()
{
union test
{
short a;
char b;
} c;
c.a = 0x1234;
if(c.b == 0x12)
{
printf("%s this is big endian\n", __FUNCTION__);
}
else if(c.b == 0x34)
{
printf("%s this is little endian\n", __FUNCTION__);
}
else
{
printf("%s unable to determine endian\n", __FUNCTION__);
}
}
int main()
{
endiannessOne();
endiannessTwo();
return 0;
}
pc机cpu是Inter系列,Intel系列的CPU都是按照小端序存储的。系统是ubuntu。上文我们说过,字节序跟硬件的体系结构有关,和编程语言以及操作系统无关。编译运行结果如下: