2017年11月23日
大端/小端的存储模式
1.大端:
如果是将高字节的数据存储在低地址,低字节数据存储在高地址,这种存储模式就是大端模式;
2.小端:
如果是将高字节的数据存储在高地址,低字节数据存储在低地址,这种存储模式就是小端模式;
3.对大小端模式的测试方法:
1).使用union共用体进行测试:
#include <stdio.h> #include <stdlib.h> //默认为小端模式; //使用共用体测试; union test { int a; char b; }; void main() { union test t1; char b; t1.a=1; b=t1.b; printf("%d ",b);//输出结果是1; }
2).使用指针的方式:
#include <stdio.h> #include <stdlib.h> //默认为小端模式; //使用共用体测试; void main() { int a=0; char b=*((char*)(&a)); printf("%d ",b);//输出结果是1; }
4.看似可行实则不行的测试大小端方式:位与(&)、移位(>>)、强制类型转化(type)
(1)位与运算。
结论:位与的方式无法测试机器的大小端模式。(表现就是大端机器和小端机器的&运算后的值相同的)
理论分析:位与运算是编译器提供的运算,这个运算是高于内存层次的(或者说&运算在二进制层次具有可移植性,也就是说&的时候一定是高字节&高字节,低字节&低字节,和二进制存储无关)。
(2)移位
结论:移位的方式也不能测试机器大小端。
理论分析:原因和&运算符不能测试一样,因为C语言对运算符的级别是高于二进制层次的。右移运算永远是将低字节移除,而和二进制存储时这个低字节在高位还是低位无关的。
(3)强制类型转换
同上;
5.通信系统中的大小端(数组的大小端)
(1)譬如要通过串口发送一个0x12345678给接收方,但是因为串口本身限制,只能以字节为单位来发送,所以需要发4次;接收方分4次接收,内容分别是:0x12、0x34、0x56、0x78.接收方接收到这4个字节之后需要去重组得到0x12345678(而不是得到0x78563412).
(2)所以在通信双方需要有一个默契,就是:先发/先接的是高位还是低位?这就是通信中的大小端问题。
(3)一般来说是:先发低字节叫小端;先发高字节就叫大端。实际操作中,在通信协议里面会去定义大小端,明确告诉你先发的是低字节还是高字节。
(4)在通信协议中,大小端是非常重要的,大家使用别人定义的通信协议还是自己要去定义通信协议,一定都要注意标明通信协议中大小端的问题。