目录
💖 前言
如有理解不对的地方,欢迎各位指出,大家共同交流和学习。 如有帮助,请点赞加支持! 送人玫瑰手有余香!🌹🌹🌹
💖 何为大端小端
根据数据在内存中的排列方式不同分为大端模式和小端模式,也叫大端、小端。
💖 为什么会有大小端
小端最符合人的思维,即:地址低位存储值的低位,地址高位存储值的高位。计算机电路先处理低位字节,效率比较高,因为计算机都是从低位开始的,所以计算机的内部处理都是小端字节序。但是,人类习惯读大端字节序,所以,除了计算机的内部处理,其他场合几乎都是大端字节序,比如网络传输和文件储存。
🏆 大端
大端是指低字节存储在高地址(对操作数的存储方式是从高字节到低字节);
以一个16进制数0x12345678
在内存的存储方式为例:
🏆 小端
小端是指低字节存储在低地址(对操作数的存储方式是从低字节到高字节);
以一个16进制数0x12345678
在内存的存储方式为例:
💖 大小端判断
不同的平台,默认的大小端模式是不同的,在我们开发的过程中,我们需要明白所使用平台的存储模式,从而正确处理数据。
🏆 Windows平台
💚 方法1:
在VS中,直接在程序中打断点,查看内存即可
结合前面的定义,可以看出:低位的0x78存储在地址较小的位置(小端)
💚 方法2:
根据联合体来判断该系统是大端还是小端, 因为联合体变量是从低地址存储的。
int fun(int v)
{
union test
{
int i;
char c;
};
test te;
te.i = v;
if (te.c == 1)
{
cout << "小端" << endl;
}
else
{
cout << "大端" << endl;
}
return 0;
}
🏆 Linux平台
可以使用lscpu 命令直接查看CPU相关信息。这里,以我自己电脑上的虚拟机为例,进行演示,如下:
因此,两者查询结果一致,均为小端模式。
💖 大小端转换
在开发的过程中,我们往往需要对数据进行大小端转换。
例子如下:
//大小端转换
short Swap2Short(short ivalue)
{
ivalue = ((ivalue & 0x00ff) << 8) | ((ivalue & 0xff00) >> 8);
return ivalue;
}
int Swap2Int(int ivalue)
{
ivalue = ((ivalue & 0x00ff) << 8) | ((ivalue & 0xff00) >> 8);
return ivalue;
}
int main()
{
cout << fun(1); //返回0为大端,返回1为小端 小端
cout << fun(Swap2Int(1)); //大端
system("pause");
return 0;
}
💖 常见大小端场景
💚 x86系列的CPU一般采用小端的字节序
💚 网络字节顺序采用大端排列方式,因为,它是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确理解。
💚 PowerPC通常是大端模式
💖 Linux中的大小端转换函数
🏆 小端转大端
htonl
将主机unsigned int 型数据转换成网络字节序;
htons
将主机unsigned short型数据转换为网络字节序;
🏆 大端转小端
ntohl
将网络字节序转为主机unsigned int 型数据;
ntohs
将网络字节序转为主机unsigned short型数据;