字节序中大端字节序和小端字节序

  • 1.什么是字节序
  • 2.什么是大端字节序和小端字节序
  • 3. 为什么要有字节序
  • 4.内容参考


1.什么是字节序

  1. 字节序,又称端序尾序(英语中用单词:Endianness表示),在计算机领域中,指电脑内存中或在数字通信链路中,占用多个字节的数据的字节排列顺序。
  2. 在几乎所有的平台上,多字节对象都被存储为连续的字节序列

2.什么是大端字节序和小端字节序

  1. 计算机硬件有两种储存数据的方式:大端字节序(MSB)和 小端字节序(LSB)
  2. 字节的排列方式有两个通用规则:
  1. 大端序(Big-Endian)将数据的低位字节存放在内存的高位地址,高位字节存放在低位地址。这种排列方式与数据用字节表示时的书写顺序一致,符合人类的阅读习惯。
  2. 小端序(Little-Endian),将一个多位数的低位放在较小的地址处,高位放在较大的地址处,则称小端序。小端序与人类的阅读习惯相反,但更符合计算机读取内存的方式,因为CPU读取内存中的数据时,是从低地址向高地址方向进行读取的。
  1. 小端序例子
    将这样的数据存储在计算机中,地址从低位到高位应该是:78 56 34 12
int a=0x12345678

java 大端序小端序 大端序列和小端序列_字节序

一共四个字节的地址,假设从0x1001 ~ 0x1004;那么,对于小端字节序来说系统是这样存储的:

java 大端序小端序 大端序列和小端序列_c++_02

  1. 大端字节序(MSB)
    大端字节序就是这样存储

    由图可以看出,大端字节序的存储规则:数据的高位存储在地址的低位,数据的低位存储在地址的高位
  2. 验证大小端字节序
#include <stdio.h>

int main()
{
int     a = 0x12345678;
char    *p = NULL;
p = (char *)&a;

if(*p == 0x78)
{
    printf("小端字节序\\n");
}

if(*p == 0x12)
{
    printf("大端字节序\\n");
}

printf("p = %x\\n", *p);

return 0;
}

再来看原理:

  1. 指针会指向整形变量的首地址,当我们调用*p往a的地址里面取值时,系统会根据指针类型大小取对应大小的值(char类型的指针就会从他指向的地址往里取char类型(1个字节)大小的值)
  2. 当我们使用char类型的指针指向一个int类型的数,再通过 *p 取值时,只会去取其低地址位的1个字节的内容
  3. 取出低地址的值,结合之前的大小端的存储规则判断得出,这是大端还是小端。
  1. 再来一个例子来解释一下字节排列时的大端序和小端序。
    在内存中存放整型数值168496141 需要4个字节,这个数值的对应的16进制表示是0X0A0B0C0D,这个数值在用大端序和小端序排列时的在内存中的示意图如下:

3. 为什么要有字节序

计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。在计算机内部,小端序被广泛应用于现代 CPU 内部存储数据;而在其他场景,比如网络传输和文件存储则使用大端序。