一、大端和小端的含义
1、大端(Big-Endian)模式
高位字节放在内存低地址,低位字节放在内存高地址(高对低,低对高)
2、小端(Litte-Endian)模式
低位地址放在内存低地址,高位字节放在内存高地址(低对低,高对高)
3、示例(0x12345678)
大端模式
低地址------------>高地址
0x12 | 0x34 | 0x56 | 0x78
优点:符号位的判定固定为第一个字节,容易判断正负
小端模式
低地址------------->高地址
0x78 | 0x56 | 0x34 | 0x12
强制转换数据无需调整字节内容,1,2,4字节的存储方式一样
二、大小端模式下的数组存储
以
unsigned int value = 0x12345678
为例,使用nsigned char buf[4]
来表示value
大端模式
高地址
-----------
buf[3] (0x78) -> 低位
buf[2] (0x56)
buf[1] (0x34)
buf[0] (0x12) -> 高位
-----------
低地址
小端模式
高地址
-----------
buf[3] (0x12) -> 低位
buf[2] (0x34)
buf[1] (0x56)
buf[0] (0x78) -> 高位
-----------
低地址
三、机器字节序的判定方法
1、判断存储起始位置
BOOL isBigEndian()
{
int a = 0x1234;
//通过将int强制类型转换成char单字节
//判断起始存储位置。即等于取b等于a的低地址部分
char b = *(char*)&a;
return b == 0x12;
}
2、联合体存放顺序
BOOL isBigEndian()
{
union NUM{
int a;
char b;
}num;
//联合体的存放顺序是所有成员从低地址开始存放
num.a = 0x1234;
return num.b == 0x12;
}
四、参见的字节序
一般操作系统是小端模式,通信协议是大端模式。
CUP或文件 | 大端序 | 小端序 | 备注 |
---|---|---|---|
PowerPC、IBM、Sun | Y | ||
x86、DEC | Y | ||
ARM | Y | Y | 两者皆可 |
Adobe PS、JPEG、MacPaint | Y | ||
BMP、GIF、RTF | Y | ||
AutoCAD | Y | Y | 两者皆可 |
Java、网络通信协议 | Y |
五、字节序的转换
1、手动转换
#define BigtoLittle16(A) (( ((uint16)(A) & 0xff00) >> 8) | \
(((uint16)(A) & 0x00ff) << 8))
#define BigtoLittle32(A) ((( (uint32)(A) & 0xff000000) >> 24) | \
(( (uint32)(A) & 0x00ff0000) >> 8) | \
(( (uint32)(A) & 0x0000ff00) << 8) | \
(( (uint32)(A) & 0x000000ff) << 24))
2、库函数转换(host to network short/int)
#include <netinet/in.h>
//16位数据类型网络字节顺序到主机字节顺序的转换
#define ntohs(n)
//16位数据类型主机字节顺序到网络字节顺序的转换
#define htons(n)
//32位数据类型网络字节顺序到主机字节顺序的转换
#define ntohl(n)
//32位数据类型主机字节顺序到网络字节顺序的转换
#define htonl(n)