基础02:内存的大小端 - higoge/blog GitHub Wiki

封面

本文介绍内存的大小端,中间有一段代码需要有一点点C语言基础。

1. 源头

内存的大小端,始于鸡蛋的大小端,你信么?至于你信不信,我反正信了。
Jonathan Swift的《格列佛游记》(Gulliver's Travels):Lilliput和Blefuscu这两个强国在过去的36个月中一直在苦战。战争的原因:大家都知道,吃鸡蛋的时候,原始的方法是打破鸡蛋较大的一端,可以那时的皇帝的祖父由于小时侯吃鸡蛋,按这种方法把手指弄破了,因此他的父亲,就下令,命令所有的子民吃鸡蛋的时候,必须先打破鸡蛋较小的一端,违令者重罚。然后老百姓对此法令极为反感,期间发生了多次叛乱,其中一个皇帝因此送命,另一个丢了王位,产生叛乱的原因就是另一个国家Blefuscu的国王大臣煽动起来的,叛乱平息后,就逃到这个帝国避难。据估计,先后几次有11000余人情愿死也不肯去打破鸡蛋较小的端吃鸡蛋。Danny Cohen一位网络协议的开创者,第一次使用这两个术语指代字节顺序,后来就被大家广泛接受。

2. 大小端的定义

小端(Little-Endian)就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
大端(Big-Endian)就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
举个栗子:
如果int num = 0x12345678,那么大小端的存放方式分别如下表。

     | 低 | --> | --> | 高

----- | ----- | ----- | ----- | ----- 内存地址 | 0x7fff6380d99c | 0x7fff6380d99d | 0x7fff6380d99e | 0x7fff6380d99f 大端 | 12 | 34 | 56 | 78 小端 | 78 | 56 | 34 | 12

3. 大小端的优势

小端模式 :强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。 大端模式 :符号位的判定固定为第一个字节,容易判断正负。

4. 常见的大小端

一般操作系统都是小端,而通讯协议、Java是大端的。
CPU方面:
大端 : PowerPC、IBM、Sun
小端 : x86、DEC、DSP
ARM既可以工作在大端模式,也可以工作在小端模式,根据可以由硬件来选择。

5. 判断大小端的代码

/**
 * 文件名: endian1.c
 * 通过int最低内存地址的字节转换成char进行判断
 */

#include <stdio.h>

int main()
{
    int num = 0x12345678;
    char n0 = ((char *) &num)[0];
    char n1 = ((char *) &num)[1];
    char n2 = ((char *) &num)[2];
    char n3 = ((char *) &num)[3];

    if (n0 == 0x12) {
        printf("this is Big Endian\n");
    } else {
        printf("this is Little Endian\n");
    }

    // 内存从低到高分别打印四个字节的内容
    printf("%p: 0x%x\n", &n0, n0);
    printf("%p: 0x%x\n", &n1, n1);
    printf("%p: 0x%x\n", &n2, n2);
    printf("%p: 0x%x\n", &n3, n3);
    return 0;
}
/**
 * 文件名: endian2.c
 * 通过联合体进行判断
 * 联合体union的存放顺序是所有成员都从低地址开始存放
 */
#include <stdio.h>

int main()
{
    union NUM {
        int a;
        char b;
    } num;

    num.a = 0x12345678;

    if (num.b == 0x12) {
        printf("this is Big Endian\n");
    } else {
        printf("this is Little Endian\n");
    }

    return 0;
}

总结

  1. 如果内从从低到高,那么小端模式与日常看到顺序的相反,大端模式则相同。
  2. x86是小端模式。

练习

  1. 调试代码,判断你的系统是大端模式还是小端模式。
⚠️ **GitHub.com Fallback** ⚠️