1.大小端定义:
大端:数据高位对应低地址
小端:数据高位对应高地址
解释:数据的高低位是对于要存储的数据而言的,高低地址是针对内存来说的(内存以字节为单位)。
比如:0X87 65 43 21,数据的高位是87,低位是21
大端模式在内存中存放数据:
低地址-----> 高地址
0X87 ,0X65 ,0X43 ,0X21
小端模式在内存中存放数据:
低地址----->高地址
0X21 ,0X43 ,0X65 ,0X87
2.用共用体的方式来测试:
原理:利用共用体的成员共享同一块内存,并且同时只能访问一个成员变量,成员变量的地址都是相同的。先对int型的变量a赋值。假设这是32位的系统,int型占4个字节,对int型的变量赋值1,这个1可能被放在高地址,也可能被放在低地址,由此可以判断大小端。这里有个隐含条件,不管是int型变量还是char型变量,起始地址都是一样的,起始地址都是四个字节里最低的那个字节的地址。当对a赋值后,四个字节里存放的数据情况:
大端则存储的4个字节:
低地址----->高地址
0X0 ,0X0 ,0X0 ,0X1
小端则存储的4个字节:
低地址----->高地址
0X1 ,0X0 ,0X0 ,0X0
示例代码:
typedef union
{
int a;
char b;
}t_union;
int main(void)
{
t_union u1;
memset(&u1, 0, sizeof(t_union));
u1.a = 1;
if(u1.b == 1)
{
printf("当前是小端模式\n");
}
else
{
printf("当前是大端模式\n");
}
return 0;
}
用指针的方式测试大小端:
原理:用指针的方式来测试大小端,本质上和用共用体来测试是一样的。都是把1赋值给int型变量,然后去判断这个1是存放在高地址还是低地址。假设int型变量的4个字节,在大小端下,各自被赋值为1后,4个字节里保存的数据:
大端则存储的4个字节:
低地址----->高地址
0X0 ,0X0 ,0X0 ,0X1
小端则存储的4个字节:
低地址----->高地址
0X1 ,0X0 ,0X0 ,0X0
示例代码:
int main(void)
{
int a = 1;
char *p = NULL;
p = (char *)&a;
printf("*p = %d\n",*p);
if(*p == 1)
{
printf("当前是小端模式\n");
}
else
{
printf("当前是大端模式\n");
}
return 0;
}
3. 补充:
位与运算、移位运算、强制类型转换都不能测试大小端,因为编译器会自动处理,可自行写代码验证。在通信中,大小端是十分重要的,也就是先发低字节还是先发高字节。通信前必须确认好大小端,否则不能正确解析传送过去的数据。