大小端(Endian)是指多字节整数在内存中存储的方式。在计算机中,一个多字节整数由多个字节组成,而不同的机器和处理器在存储多字节整数时会有两种不同存储方式,分别为大端字节序和小端字节序。
以一个4字节整数0x12345678为例,在大端字节序中存储为12 34 56 78,在小端字节序中存储为78 56 34 12。大端字节序是指在内存中较高的地址保存数值的低位字节,而较低的地址保存数值的高位字节;小端字节序则相反,在内存中较高的地址保存数值的高位字节,而较低的地址保存数值的低位字节。
C语言中对于大小端字节序,一般使用联合体来判断。如下:
#include <stdio.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");elseprintf("unknown\n");}else {printf("sizeof(short) = %d\n", sizeof(short));}return 0;
}
上述代码中,联合体的大小等于short的大小,可以通过访问其低位字节和高位字节的方式来判断是大端字节序还是小端字节序。如果联合体的低地址保存的是s的高位字节,那就表明该机器是小端字节序。
大端和小端的区分方式在所有字节正序列出来后表现是完全相反的(即在大端字节序中,先写的字节的地址编号越大;而在小端字节序中,先写的字节的地址编号越小),因此只需将一个数的二进制表示按字节分割后列出来,即可判断其是否为大端字节序或小端字节序。
假设某个整数在内存中按照如下方式存储:
十六进制表示: 12 34 56 78
二进制表示: 00010010 00110100 01010110 01111000
根据这个数字的存储方式可以判断出这个系统是大端还是小端,以下是两种方式的比较:
- 大端字节序:低地址存放高位字节,高地址存放低位字节
内存地址 | 存放数据 |
---|---|
0x1000 | 0x12 |
0x1001 | 0x34 |
0x1002 | 0x56 |
0x1003 | 0x78 |
- 小端字节序:低地址存放低位字节,高地址存放高位字节
内存地址 | 存放数据 |
---|---|
0x1000 | 0x78 |
0x1001 | 0x56 |
0x1002 | 0x34 |
0x1003 | 0x12 |
这里假设内存中存储的数值是0x12345678,通过在内存中查看数值的存储方式可以发现,在大端字节序中,最高位字节的数值存储在最低地址的位置上,即0x12存储在了0x1000的位置;而在小端字节序中,最高位字节的数值存储在最高地址的位置上,即0x12存储在了0x1003的位置上。