一、大小端存储介绍
大端存储:将数据的低位字节放到高地址处,高位字节放到低地址处
小端存储:将数据的高位字节放到高地址处,低位字节放到低地址处
那么什么是 高 / 低 位字节,什么是 高 / 低 位地址?
高位字节与低位字节:
以十进制数来说,当一个数列 1 2 3 4 按照升序排序时,数据的最低有效位(LSB)是最右边的数据,称为数据的低位(也叫低位字节)。数据的最高有效位(MSB)是最左边的数据,称为数据的高位(也叫高位字节)。
因此 数列 1 2 3 4 中,1 为高位字节,4为低位字节。
高位地址与低位地址:
在计算机的内存存储中,为了便于管理存储的数据,会以十六进制的方法对数据存储的地址进行编号,值较大的为高地址,值较小的为低地址。
地址编号以0x0000开始,以0xFFFF结束,如图所示:
介绍完高低位地址和高低位字节,给出一个十六进制数 0x11223344 (0x11为高位字节)
在大端存储模式下:存储数的顺序为 0x11 0x22 0x33 0x44
在小端存储模式下:存储数的顺序为 0x44 0x33 0x22 0x11
二、为什么会有大小端之分
因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的int型。另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
三、如何判断机器是大端还是小端
对于大端小端存储来说,我们可以通过存储一个int类型的数据1,int类型的1在内存中的存储为0x000001,我们可以通过判断1存储位置中,第一个字节是什么来判断大端还是小端,当大端存储时,第一个字节为0,当小端存储时,第一个字节为1
int main()
{
int i = 1;
char ret = *((char*)&i);
//获取i存储的内存地址指针,将其转换为char*类型,提取第一个字节地址指针
//再将获取得到的地址指针进行解引用
//1在内存中存储为0x000001
//如果第一个字节为0,说明机器是大端存储,低位字节1存储在高位地址
//如果第一个字节为1,说明机器是小端存储,低位字节1存储在低位地址
if (ret == 0)
{
printf("大端存储");
}
else
{
printf("小端存储");
}
}
还有另一种利用联合体的方法判断机器是大端还是小端存储。
int check_sys()
{
union Un
{
char c;
int i;
}u;
u.i = 1;
return u.c;//返回1 就是小端
//返回0 就是大端
}
int main()
{
int ret = check_sys();
if (ret == 0)
{
printf("大端存储");
}
else
{
printf("小端存储");
}
return 0;
}
在联合体Un中,char类型数据和int类型数据共用一个字节,省去了获取一个字节的步骤。
最后运行结果: