[操作系统] 字节序中的大端序和小端序的区别
发布日期:2021-05-18 08:09:09 浏览次数:20 分类:精选文章

本文共 2442 字,大约阅读时间需要 8 分钟。

字节序:从右到左与从左到右的数据存储方式

默认情况下,人类读取文字时是从右往左进行的,这与计算机处理数据的方式恰好相反。这就是为什么我们称之为小端序(Little-Endian)。因为计算机从内存中读取数据时,通常是从低位(右边)到高位(左边)进行的,这与人类的阅读习惯完全相反。


什么是字节序?

字节序(Endianness)是计算机科学中一个非常重要的概念,它决定了多字节数据在内存中或通信链路中的存储顺序。简单来说,就是一个8位或16位或32位的数字,如何在计算机中被分解成各个字节并存储的位置。

在几乎所有的编程语言和平台中,多字节对象都会被存储为连续的字节序列。例如,在Go语言中,一个int类型的变量占用4个字节,它们会被连续存储在内存中的相邻位置。


字节序的两种主要规则

字节序有两种主要的排列方式:大端序(Big-Endian)和小端序(Little-Endian)。

  • 大端序(Big-Endian):

    • 数据的低位字节(右边)存放在内存的高位地址(左边)。
    • 这种排列方式与人类阅读文字的顺序一致,符合自然习惯。
  • 小端序(Little-Endian):

    • 数据的低位字节(右边)存放在内存的低位地址(右边)。
    • 这种排列方式与人类阅读习惯相反,但更符合计算机内部的处理方式,因为CPU通常从低地址(右边)开始读取内存。

  • 为什么需要字节序?

    很多人可能会问,为什么不统一使用大端序呢?答案是,计算机内部处理数据时,通常需要高效地操作低位字节。例如,计算机的算术逻辑单位(ALU)从低位开始进行运算,因此更适合使用小端序。

    在实际应用中:

    • 小端序:常用于计算机内部存储数据,尤其是CPU的 registers 和内存。
    • 大端序:常用于网络通信和文件存储,因为这些场景需要确保数据在不同系统之间的兼容性。

    Go语言对字节序的支持

    Go语言在处理字节序时非常灵活,它会根据目标平台的字节序自动调整。具体来说:

    • 大端序(Big-Endian)使用binary.BigEndian包装。
    • 小端序(Little-Endian)使用binary.LittleEndian包装。

    例如:

    package main
    import (
    "encoding/binary"
    "fmt"
    "unsafe"
    )
    const INT_SIZE = int(unsafe.Sizeof(0)) // 64位系统,8字节
    func systemEdian() {
    var i = 0x01020304
    fmt.Printf("&i: 0x%x, %v\n", i, i)
    bs := (*[INT_SIZE]byte)(unsafe.Pointer(&i))
    if bs[0] == 0x04 {
    fmt.Printf("系统字节序是小端序\n")
    } else {
    fmt.Printf("系统字节序是大端序\n")
    }
    }
    func testBigEndian() {
    var testInt int32 = 0x01020304
    fmt.Printf("%d 用大端序:\n", testInt)
    testBytes := make([]byte, 4)
    binary.BigEndian.PutUint32(testBytes, uint32(testInt))
    fmt.Printf("int32 到 bytes: %x \n", testBytes)
    convInt := binary.BigEndian.Uint32(testBytes)
    fmt.Printf("bytes 到 int32: %d\n\n", convInt)
    }
    func testLittleEndian() {
    var testInt int32 = 0x01020304
    fmt.Printf("%x 用小端序:\n", testInt)
    testBytes := make([]byte, 4)
    binary.LittleEndian.PutUint32(testBytes, uint32(testInt))
    fmt.Printf("int32 到 bytes: %x \n", testBytes)
    convInt := binary.LittleEndian.Uint32(testBytes)
    fmt.Printf("bytes 到 int32: %d\n\n", convInt)
    }
    func main() {
    systemEdian()
    fmt.Println("")
    testBigEndian()
    testLittleEndian()
    }

    测试结果

    运行上述代码可以看到:

    &i: 0xc000084000 系统字节序是小端序
    temp: 0x4, 0xc000084000
    temp: 0x3, 0xc000084001
    temp: 0x2, 0xc000084002
    temp: 0x1, 0xc000084003

    大端序测试结果:

    16909060 用大端序:int32 到 bytes: [1 2 3 4] bytes 到 int32: 169090601020304

    小端序测试结果:

    04030201 用小端序:bytes 到 int32: 16909060

    总结

    字节序是计算机科学中的一个重要概念,它决定了数据在内存中的存储顺序。大端序与人类阅读习惯一致,而小端序则与计算机的读取方式相符。在实际应用中,两种字节序都有其特定的用途。通过Go语言的binary包装,我们可以轻松地在开发过程中切换字节序,确保数据在不同环境下的兼容性。

    上一篇:[MySQL]varchar和char的的区别是什么
    下一篇:[GO]mysql中支持表情emoji字符的几个修改点

    发表评论

    最新留言

    留言是一种美德,欢迎回访!
    [***.207.175.100]2025年05月10日 03时02分44秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章

    elasticsearch 查询_Elasticsearch地理信息存储及查询之Geo_Point 2023-01-24
    embedding层_【预估排序】Embedding+MLP: 深度学习预估排序通用框架(一) 2023-01-24
    excel中最常用的30个函数_Excel玩转数据分析常用的43个函数! 2023-01-24
    flink sql设置并行度_Flink 参数配置和常见参数调优 2023-01-24
    go 字符串替换_Go 每日一库之 quicktemplate 2023-01-24
    hex editor neo下载_口袋妖怪爆焰黑手机版下载-口袋妖怪爆焰黑手游下载v4.3.0 安卓版... 2023-01-24
    hibernate mysql 关联查询_spring-boot hibernate 双向关联查询的坑 2023-01-24
    hive 建表_sqoop的使用之导入到hive和mysql 2023-01-24
    hp工作站z8装Linux,惠普Z8G4双路最小工作站 2023-01-24
    html上传图片直接保存到数据库中,Editor上传图片路径存入数据库中怎么弄? 2023-01-24
    html游戏玩不了,WinXP网页游戏玩不了怎么办有哪些解决方法 2023-01-24
    html转jsp_JSP详解 2023-01-24
    ICLOUD储存空间要升级吗_有人像我一样需要恢复苹果手机icloud空间ios备份时 微信卡住不动了吗(已解决)... 2023-01-24
    image unity 原始尺寸_Unity基础教程-对象管理(十一)——生命周期(Growth and Death)... 2023-01-24
    iphone打字怎么换行_手持iPhone?你可能并不知道的小技巧! 2023-01-24
    jaccard相似度_自然语言处理之文本相似度计算 2023-01-24
    java http delete_java积累---HttpDelete请求方式传递参数 2023-01-24
    java swing数据库,如何在Java swing中查看数据库结果集 2023-01-24
    java xmpp 群聊,使用XMPPFramework openfire创建聊天室 2023-01-24
    java 反义_java中一些常用的英语 2023-01-24