Linux 大小端字节序,字节序和大小端 - 梦冒险 - OSCHINA - 中文开源技术交流社区...

1. 字节顺序

字节顺序(Endian)

字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。

  计算机系统一般采用字节(Byte(8 bit ))作为逻辑寻址单位。当物理单位的长度大于1个字节时,就要区分字节顺序(Byte Order)。常见的字节顺序有两种:Big Endian(High-byte first)Little Endian(Low-byte first)Intel X86平台采用Little Endian,而PowerPC处理器则采用了Big Endian 

  endian指的是当物理上的最小单元比逻辑上的最小单元小时,逻辑到物理的单元排布关系。咱们接触到的物理单元最小都是byte,在通信领域中,这里往往是bit

2. 最高有效位、最低有效位

最高有效位(MSB: Most Significant Bit)

最高有效位(MSB),是指最左边的位,是在一个n位二进制数字中的n-1位,这个位有最高的权重(2^(n-1))。第一个或最左边的位,当这个数字被用一般的方式书写时。

最低有效位(LSB: Least Significant Bit)

最低有效位(LSB),是指最右边的位,因为写较不重要的数字到右边位置符号的协定。类似于一个十进制整数的最不重要的数字,它是在一个(最右边)位置的数字。

3. 大小端

小端Little endian低字节存放在低地址

低地址存放最低有效位(LSB),既低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

大端Big endian:高字节存储在低地址

低地址存放最高有效位(MSB),既高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

例子:比如数字0x12345678(双字、四字节)在两种节序CPU中的存储顺序如下所示:

Little Endian                                           
    低地址 --------------------------------------> 高地址
    -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  78  | 56  |  34  |  12  |
    -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Big Endian                                           
    低地址 --------------------------------------> 高地址
    -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | 12  | 34  | 56  | 78  |
    -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2. Big Endian判别一个数的正负很容易,只要取低地址的第一个字节就能确认。Little Endian长度为1,2,4字节的数,排列方式都是一样的,数据类型转换非常方便。
3. little-endian 最符合人的思维的字节序(地址低位存储值的低位,地址高位存储值的高位)。低位值小,就应该放在内存地址小的地方;高位值就应该放在内存地址大的地方。
   big-endian 最直观的字节序(地址低位存储值的高位,地址高位存储值的低位)只需要把内存地址从左到右按照由低到高的顺序写出
C++判断主机是大小端
 
 
//方法一: 
//1.原理:多字节类型强制转换类型成单字节,char单字节指向多字节低地址,即可判断大小端 
const int endian = 1; 
#define isBigEndian() ( (*(char*) &endian) == 0 ) //true大端 
#define IsLittleEndian() ( (*(char*) &endian) == 1 ) //true小端 
 
 
//2.原理:将short(2字节)强制类型转换成char单字节,b指向a的起始字节(低字节) 
void IsBigEndian() 
{ 
 short a = 0x1122; //十六进制,一个数值占4位 
 char b = *(char *)&a; //通过将short(2字节)强制类型转换成char单字节,b指向a的起始字节(低字节) 
 if( b == 0x11) //低字节存的是数据的高字节数据 
 { 
 printf("大端模式"); //是大端模式 
 } 
 else 
 { 
 printf("小端模式"); //是小端模式 
 } 
} 
 
 
//方法二: 
//原理:联合体union的存放顺序是所有成员都从低地址开始存放,而且所有成员共享存储空间 
void IsBigEndian() 
{ 
 union temp 
 { 
 short int a; 
 char b; 
 }temp; 
 temp.a = 0x1234; 
 if( temp.b == 0x12 ) //低字节存的是数据的高字节数据 
 { 
 printf("大端模式"); //是大端模式 
 } 
 else 
 { 
 printf("小端模式"); //是小端模式 
 } 
} 
 
 
 
 

4. 网络字节序、主机序

网络字节序(Network Order)

TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。

主机序(Host Orader)

整数在内存中保存的顺序,它遵循Little-Endian规则。所以当两台主机之间要通过TCP/IP协议进行通信的时候就需要调用相应的函数进行主机序(Little-Endian)和网络序(Big-Endian)的转换。

1. 在网络程序开发时 或是跨平台开发时,要注意通信双方协商好字节序。

2. 节序转换的函数:
  htons (host to network unsigned short) 把unsigned short类型从主机序转换到网络序


  htonl (host to network unsigned long) 把unsigned long类型从主机序转换到网络序 
  ntohs (network to host unsigned short) 把unsigned short类型从网络序转换到主机序


  ntohl (network to host unsigned long) 把unsigned long类型从网络序转换到主机序 

欢迎转载,转载请注明出处,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值