• 展开微博窗口
  • QQ:52619941
  • 微信:cnmemory
  • 展开分类目录
  • 还没有账号?

Memory

聊一聊字节顺序

每次提到字节顺序就只记得大端法(Big Endian)小端法(Little Endian)。因为平时开发中并不会经常用到,但偶尔又不得不提起它,所以为了加深对它的印象,今天就肤浅的聊一下自己的理解。

字节序在我的理解中就是数据在内存存储中或网络传输中的字节的排列顺序。

一般来说,一个内存地址对应一个字节,那么一组数据在内存中的存储必然会有一个顺序,而这个顺序就需要一定的规范,使得数据在读取、写入的时候才能得到一致的结果,那这个规范指的就是字节顺序,那么字节顺序又存在两种规范,即大端小端

举个例子,假设一个int型数据0x12345678在一台32位的机器上,内存地址由0x00000000开始递增。

那么大端法的存储则是如下表

内存地址 数据字节
0x00000000 0x12
0x00000001 0x34
0x00000002 0x56
0x00000003 0x78

即最高有效位存储在内存的低地址

小端法的存储则如下表

内存地址 数据字节
0x00000000 0x78
0x00000001 0x56
0x00000002 0x34
0x00000003 0x12

恰好与大端法相反,数据的最低有效位存储在内存的低地址。

这两种字节顺序也各有优劣,譬如大端法高位存放在低字节,在取符号位的时候只需要顺序读取第一个字节即可判断数据正负。

而小端法在做数据类型转换的时候则效率更高,譬如int(4字节)转short(2字节),只需要保留前面的字节。(0x78563412 => 0x7856)

显而易见,他们的优势也是对方的劣势。

在网络传输中的字节顺序,我们称之为网络字节序,根据TCP/IP协议规定,使用大端法传输数据(当然你如果想用小端法也没有问题,只需要保证收发两端都使用同样的字节序处理数据),而CPU、操作系统中数据处理的字节顺序称之为主机字节序,不同的平台可能采用不同的字节序。

利用golang来看一下我们的主机字节序:

func main() {
    i := 0x12345678
    b := byte(i)
    if b == 0x12 {
        fmt.Println("Big Endian")
    } else {
        fmt.Println("Little Endian")
    }
}

在我的机子上输出了Little Endian,说明我的主机字节序采用的是小端法

就到这儿吧~有空再来补充一下socket网络传输的字节序处理示例代码。

码字很辛苦,转载请注明来自雨林寒舍《聊一聊字节顺序》

评论

  1. hannesgao #1

    借鉴了你style.css里面的Markdown部分,谢谢~

    回复
    2021-02-16
  2. hannesgao #2

    借鉴了你style.css里面的Markdown部分,谢谢~

    回复
    2021-02-16
  3. hannesgao #3

    博主你好,请问你是如何实现的WP内用Markdown撰写文章呢

    回复
    2021-02-16
  4. hannesgao #4

    博主你好,请问你是如何实现的WP内用Markdown撰写文章呢

    回复
    2021-02-16