Endian ,即我们说的端模式,最开始这个词出自于《格列佛游记》。这本书根据将鸡蛋敲开的方法不同将所有的人分为两类,从圆头开始将鸡蛋敲开的人被归为Big Endian,从尖头开始将鸡蛋敲开的人被归为Littile Endian。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开。
在计算机业界,Endian 表示数据在存储器中的存放顺序(采用大小端模式对数据进行存放的主要区别在于存放的字节顺序)。 ↓↓↓
如果将一个32位的整数0x12345678存放到一个整型变量(int)中,这个整型变量采用大端或者小端模式在内存中的存储由下表所示。(注:OP0表示一个32位数据的最高字节MSB;OP3表示一个32位数据最低字节LSB)
地址偏移 | 大端模式 | 小端模式 |
0x00 | 12(OP0) | 78(OP3) |
0x01 | 34(OP1) | 56(OP2) |
0x02 | 56(OP2) | 34(OP1) |
0x03 | 78(OP3) | 12(OP0) |
如果将一个16位的整数0x1234存放到一个短整型变量(short)中。这个短整型变量在内存中的存储在大小端模式由下表所示。
地址偏移 | 大端模式 | 小端模式 |
0x00 | 12(OP0) | 34(OP1) |
0x01 | 34(OP1) | 12(OP0) |
通过上面的两个表我们可以看出:大端方式将高位存放在低地址,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;小端方式将高位存放在高地址,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
下面通过两段代码更直观的分析一下大小端的问题
1、判断大小端的简单方法
- #include <stdio.h>
- #include <stdlib.h>
- int main(void)
- {
- unsigned int i = 1;
- if(*((char*)&i) == 0)
- {
- printf("this is big endian. \n");
- }
- else if(*((char*)&i) == 1)
- {
- printf(" this is little endian. \n");
- }
- else
- {
- printf("sorry, i do not know . \n");
- }
- return 0;
- }
#include <stdio.h>
int main()
{
short int x;
char x1,x2;
x = 0x1122;
x1 = ((char *)&x)[0]; //低地址
x2 = ((char *)&x)[1]; //高地址
printf("x1=%x\n",x1);
printf("x2=%x\n",x2);
return 0;
}