大小端疑惑汇总

猿猿们工作中是会经常遇到内存字节序问题,字节序一般又分为:

  • 大端模式;

  • 小端模式。

网络字节序默认是大端模式。

一、定义

大端模式:高位字节存放在低地址处,低位字节存放在高地址处。
小端模式:高位字节存放在高地址处,地位字节存放在低地址处。

举例:

一个十六进制数 0x12345678,系统以一个字节为存储单位。

大端模式
Addressaa + 1a + 2a + 3
Value0x120x340x560x78
小端模式
Addressaa + 1a + 2a + 3
Value0x780x0560x340x12

至于大小端模式存在的历史原因这里就不再赘述了。这里说几个猿猿们可能疑惑的地方:

二、疑惑
1.优势

小端模式相对于大端模式的优势是在进行数值转换时,其地址是保持不变的。

    int a = 0x12345678;
    char b = (char)a;
    // b的值应该为0x78

在大端模式下,整数a的指针指向0x12,在强制转换为char类型的b时,指针需向后移动到0x78。
而在小端模式下,整数a的指针指向的是0x78,在强制转换为char类型的b时,指针是不需要移动的。对编译器来说,小端模式下数值的类型转换需更少的指令。

2、如何记住大小端

1、小端模式就是“低低高高”,也就是低地址在地位,高地址在高位。
但是针对这种记法时间久了还是会忘,囧。
2、针对第一种记法再结合下小端的优势感觉就好记些。int强制类型转换为char时是将低地址一个字节赋值给char类型,小端是不用移动指针的,所以低地址处存放的就是低字节。

3、 字符串在网络中传输到另一端要不要进行大小端转换

字节序中的低位和高位仅针对大于1个字节的类型,如int、long、short等。内存的单位是字节,char类型就是一个字节,char是不受大小端模式和网络字节序影响的,因为其在内存中就一个单元,无前后之分。
于是要不要转换分两种情况:

【发送端和接收端字节序一样】

这种情况就可以不用进行大小端转换,对端收到数据以后可正常获取到值。

【发送端和接收端字节序不一样】

我们知道数组是连续分配内存的,每个数组单元的存放空间是由数组类型决定的,但是数组单元间的前后顺序是固定了的。那么经过网络传输后,数组单元的先后顺序是不会改变的,但是数组单元的值就不好说了。如果数组类型不止占1个字节的话,就会因前后顺序问题导致单元值发生变化,进而导致整个传输内容发生变化。
1)字符串是字符数组,字符占一个字节,所以接受端没有进行大小端转换也不会影响最终的值。
2)非字符串数组,比如int a[8]这种,其数组单元是一个int类型,如果两端字节序不一样,就会导致单个int类型的单元值发生变化,进而导致整个串的内容改变。

原则上非字符串和非char类型的值在发送时都要转为网络字节序发送,接收端在收到数据之后转为主机字节序。


参考:
https://www.jianshu.com/p/65ad47c79556
https://bbs.csdn.net/topics/392164741

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值