文章目录
- 大小端模式的概念
- 两种模式出现原因
- 两种模式的优劣
- 大小端的应用情景
- 判断机器的字节序
大小端模式的概念
当我们查看数据在内存中的存储情况时,我们经常会发现一个很奇怪的现象,什么现象呢?
int main()
{int i = 12;return 0;
}
数据在内存中的存放方式似乎和我们想象的顺序不太一样,在我们的常规认知不一样,在我们的常规认知中,它的存放方式应该是 00 00 00 0c
,那造成这个现象的原因是什么呢?
这是因为在内存中存放数据通常会采用两种不同的存储模式:大端存储和小端存储。
-
大端存储模式:是指 数据的低位 保存在 内存的高地址 中,数据的高位 保存在 内存的低地址 中。
这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。 -
小端存储模式:是指 数据的低位 保存在 内存的低地址 中, 数据的高位 保存在 内存的高地址 中。
这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
用图举例:
用表举例:
32bit宽的数 0x12345678
在CPU内存中的存放方式(假设从地址 0x4000
开始存放)为:
数据高位 -> 数据低位0x12345678
内存地址 | 小端模式 | 大端模式 | |
---|---|---|---|
高地址 | 0x4003 | 0x12 | 0x78 |
0x4002 | 0x34 | 0x56 | |
0x4001 | 0x56 | 0x34 | |
低地址 | 0x4000 | 0x78 | 0x12 |
两种模式出现原因
为什么会有大小端模式之分呢? 这是因为:
- 有些变量类型的大小大于一个字节,如:16bit的short型,32bit的long型(要看具体的编译器)。
- 有些处理器的位数大于8位,例如16位或者32位的处理器。那么其中的寄存器的宽度必定大于一个字节。
总而言之,就是一个字节无法满足我们的存储需求,因此就诞生了大端小端这两种存储模式。
两种模式的优劣
大端小端没有谁优谁劣,各自优势便是对方劣势:
- 小端模式 :
- 强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
- CPU做数值运算时从内存中依次从低位到高位取数据进行运算,直到最后刷新高位的符号位,这样的运算方式会更高效。
- 大端模式 :符号位的判定固定为第一个字节,容易判断正负。
大小端的应用情景
一般操作系统都是小端,而JAVA、通讯协议是大端的。
对于处理器而言:
- 小端模式:Intel的80X86系列芯片,ARM处理器默认采用小端、但可以切换成大端。
- 大端模式:KEIL C51、PowerPC、IBM、Sun。
判断机器的字节序
那么我们该如何判断当前机器的字节序是大端还是小端?
以 int
变量 i=258
为例,i
的16进制形式为 i=0102
,用图来表示 i
以两种方式存储的结果:
在 小端存储模式 中 最低位字节 存放的为 02
,大端存储模式 中放的为 00
。因此可以通过强制转换的方法,将一个四个字节的 int
数据截断为一个字节的 char
数据,即可得到这个低位的数据,再进行判断,如果为 02
则说明该机器为 小端存储模式
,如果为 00
则说明为 大端存储模式
。
代码实现:
int main()
{int i = 258;char ch = (char)i;if (ch == 02)printf("小端存储\n");elseprintf("大端存储\n");return 0;
}
运行结果:
验证: