在几乎所有的机器上,多字节对象都被存储为连续的字节序列,对象的地址为所使用字节序列中最小的地址。对表示一个对象的字节序列排序有两个规则:大端法和小端法。
最低有效字节在最前面的方式被称为小端法(little endian),大多数源自以前的Digital Equipment公司的机器,以及Intel的机器都采用这种规则;最高有效字节在最前面的方式被称为大端法(big endian),IBM、Motorola和Sun Microsystems的大多数机器都采用这种规则。
LE little-endian
最符合人的思维的字节序
地址低位存储值的低位
地址高位存储值的高位
怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说
低位值小,就应该放在内存地址小的地方,也即内存地址低位
反之,高位值就应该放在内存地址大的地方,也即内存地址高位
BE big-endian
最直观的字节序
地址低位存储值的高位
地址高位存储值的低位
为什么说直观,不要考虑对应关系
只需要把内存地址从左到右按照由低到高的顺序写出
把值按照通常的高位到低位的顺序写出
两者对照,一个字节一个字节的填充进去
一个例子,假设变量x的类型为int,位于地址0x0100处,有一个十六进制值为0x01234567。地址范围0x100~0x103的字节顺序依赖于机器的类型:
地址: 0x0100 0x0101 0x0102 0x0103
大端法: 01 23 45 67
小端法: 67 45 23 01
下面是一个测试机器是大端还是小端机器的代码:
#include <stdio.h> #include <stdlib.h> int main() { union{ short s; char c[sizeof(short)]; } un; un.s = 0x0102; if(sizeof(short) == 2) { if(un.c[0] == 1 && un.c[1] == 2) printf("big endian\n"); else if(un.c[0] == 2 && un.c[1] == 1) printf("little endian\n"); else printf("unknown\n"); } else { printf("sizeof(short): %d\n", sizeof(short)); } system("pause"); return 0; }
上面代码利用了union的特性(它的变量共用内存地址空间)。