← SEARCHABLE ARCHIVE
Computer Science · 2026-05-16

什么是大端和小端?

为什么要颠倒字节存储顺序?

INTERACTIVE READING MODE →

该博客上撰写的文章是出于教学目的而创建的。 另外,文章中的信息可能不正确,请谨慎。

在编码时,您可能已通过网络发送数据或读取特定文件。 在某些情况下,得出的值与我的预期完全不同。 这种现象的正式名称是Endianness排列法。 也就是说,它们被称为 Big Endian 和 Little Endian。

CPU在内存中存储4字节int型数据时,并不是将其作为一个整体打包,而是将其分成1字节的块,并按顺序存储在各个地址中。 这时候就看你是从最大位(MSB)开始按顺序排列,还是从最小位(LSB)开始倒序排列。 数据在内存中的放置方式完全不同。

如果你按照直观的顺序放置数字,就像一个人读取它们一样,那么它们就是大端字节序,如果你以相反的顺序放置它们以便机器更容易计算它们,那么它们就是小端字节序。 大多数现代PC,例如我们主要使用的Intel或AMD CPU,都采用小端系统。

我们自己用代码来验证一下。

#include <iostream>
#include <iomanip>

int main() {
    //4字节十六进制整数数据
    unsigned int number = 0x12345678;

    //转换指针以检查每个字节在内存中的存储方式
    unsigned char* bytePtr = reinterpret_cast<unsigned char*>(&number);

    for (int i = 0; i < sizeof(int); ++i) {
        std::cout << "&bytePtr[" << i << "] : 0x"
                  << std::hex << std::setw(2) << std::setfill('0')
                  << (int)bytePtr[i] << std::endl;
    }

    /*
     * 基于小端系统
     * &bytePtr[0] : 0x78 //最小单元 (LSB) 首先进入最低地址
     * &bytePtr[1] : 0x56
     * &bytePtr[2] : 0x34
     * &bytePtr[3] : 0x12
     *
     * 基于大端系统
     * &bytePtr[0] : 0x12 //最大单元(MSB)首先进入最低地址。
     * &bytePtr[1] : 0x34
     * &bytePtr[2] : 0x56
     * &bytePtr[3] : 0x78
     */

    return 0;
}

这里出现一个问题。无论如何都会存储相同的值, 为什么他们采用一种不直观的倒置数据存储方法,比如小尾数法? 这是由于CPU内部加法器的设计和类型转换的效率。

当CPU对两个数进行加减运算时,必须从1的位置开始计算,即最小的位数,才能进行进位。 在小端字节序中,最小单元(LSB)位于内存中的第一个地址, CPU一读取内存,就可以立即开始执行算术运算。 此外,当向下转换以将 4 字节整数截断为 1 字节(字符)时, 硬件逻辑大大简化,因为只需要提取内存的起始地址,无需额外的地址计算。

另一方面,大端字节序对于人类在查看内存转储时读取起来很直观, 当比较两个数字的大小时,它的优点是从第一个数字开始比较。 因此,为了避免交换数据时出现混乱, 在互联网协议 (TCP/IP) 等网络标准通信中,使用大端字节序作为标准。