高字节和低字节:
存储器是按字节进行组织的,两个相邻的字节被称为一个字。
若存放的数据为一个字,则将每一个字的低字节存放在低地址,高字节存放在高地址,并以低地址作为该字的地址。
比如int数字为2字,四字节,写成16进制后:高字节为前8位,低字节位后8位
小端序:先存储低位字节,后存储高位字节
大端序:先存储高位字节,后存储地位字节
大端字节序,数据高字节存于内存低地址,数据低字节存于内存高地址;小端字节序反之。
这里的先后是根据地址的增长顺序说的。
将一个字视为一个对象,包含多个字节。
几乎所有的机器都是多字节对象(字)的地址是所使用的字节中最小的地址。
有两种字节次序:
- 数据的低字节为低地址 – 对应小端序
- 数据的高字节为低地址 – 对应大端序
比如给定一个16进制数,0x12345678, 0x12是数据的高字节,0x78是数据的低字节。如果说以低字节为低地址,则就是说按照地址递增的顺序,先存储数据的低位字节。
因此我们说大端序有“大自然”的外号。
即:大端序存储数据与我们的正常感觉相符合。从左往右存,左边是存储地址的低地址,但存储的是数据的高字节。比如0x123456H,12是数据的高字节,存在地址的最左边。
小端序根据低字节为低地址,低字节在右,则字的低地址也在右。从左往右看地址是递减的顺序。
这是两种端序的说法。
我们需要仅仅抓住的是:
- 字的地址是多字节对象中的最小的字节地址。
- 给定的数字左边字节是高字节,右边字节是低字节
大端存储:0x12345678 地址从左往右:低到高 但是数据是从高字节到低字节
小段存储:0x12345678 地址从左往右:高到低 同样数据从高字节到低字节
可以粗暴的记作:数据都是从高字节到低字节
不同的是地址 从左向右 大端越来越大,小端从左向右越来越小
而一个数据的地址,是指的其地址最低的那个地址,就像数组一样,一个数组的地址是数组首元素的地址
从左向右,字节的高低都是高到低,而地址小端是高到低,大端是低到高。
利用联合体来判断大小端:
//利用联合体内存共享的原理
typedef union val
{
char a;
int b;
}val;
val.b=0x12345678;
if(b.a == 0x12)
{
return -1;
}
else
{
return 1;
}
UDP/TCP/IP协议规定:把接收到的第一个字节当作高位字节看待,这就要求发送端发送的第一个字节是高位字节;
而在发送端发送数据时,发送的第一个字节是该数值在内存中的起始地址处对应的那个字节,也就是说,该数值在内存中的起始地址处对应的那个字节就是要发送的第一个高位字节(即:高位字节存放在低地址处);
由此可见,多字节数值在发送之前,在内存中因该是以大端法存放的; 所以说,网络字节序是大端字节序;
在80X86平台中,它是以小端发存放的,在发送之前需要使用系统提供的字节序转换函数htonl()将其转换成大端法存放的数值;
判断大小端的代码:
bool BigOrSmall()
{
int val = 0x12345678;
if(*(char*)&val == 0x12)
{
return true; //small
}
return false;
}