字节顺序,又称端序或尾序(Endianness
),是指存储器中或在数字通信链路中,组成多字节的排列顺序。
而在计算机系统中,我们是以字节为单位的,一个字节(byte
)占8bit
。不同的数据类型,占用的字节数也各不相同。
在c
语言中,常用类型占用字节数(byte
)如下:
类型 | 32位 | 64位 |
---|---|---|
char | 1 | 1 |
short int | 2 | 2 |
int | 4 | 4 |
long int | 4 | 8 |
long long int | 8 | 8 |
char* | 4 | 8 |
float | 4 | 4 |
double | 8 | 8 |
前言
例如,我们声明一个变量:
int a = 305419896;//等同于0x12345678(16进制)
printf("&a : %p\n", &a);//打印地址
//或者 lldb debug模式下,执行命令
po &a
打印地址,得到0x7ffeefbff5fc
(printf
省略了高位0x0000
)。那么0x12345678
这四个字节如何存储呢?
0x7ffeefbff5ac | 0x7ffeefbff5ad | 0x7ffeefbff5ae | 0x7ffeefbff5af |
---|---|---|---|
0x? | 0x? | 0x? | 0x? |
这样就引入了两种不同的存储顺序:大端序列、小端序列。
x86
架构的系统(windows
、FreeBSD
、Linux
)使用的是小端模式。Mac OS
是大端模式(序列)。TCP/IP
协议规定了在网络上字节传输采用是大端模式。
那么什么是大端模式(序列),小端模式(序列)?
大端序列
big-endian
,又称大尾序,即高位字节排放在内存的低地址端(该值的起始地址),低位字节排放在内存的高地址端。
如何理解呢?我们还是接着上面的例子:
int a = 305419896;//等同于0x12345678(16进制)
printf("&a : %p\n", &a);
//或者 lldb debug模式下,执行命令
po &a
得到地址是0x00007ffeefbff5ac
,接着我们来看一下a
地址的内存布局,debug
模式下,选择view memory
,如图:
内存布局如下:
我们可以很清晰的看到,a
的高位字节0x78
存放在低地址,地为字节0x12
存放在高地址上,这就是大端序列。
0x7ffeefbff5ac | 0x7ffeefbff5ad | 0x7ffeefbff5ae | 0x7ffeefbff5af |
---|---|---|---|
0x78 | 0x56 | 0x34 | 0x12 |
小端序列
little-endian
,又称小尾序,低位字节排放在内存的低地址端(该值的起始地址),高位字节排放在内存的高地址端。
接着上面的例子,小端序列的字节存储结果:
0x7ffeefbff5ac | 0x7ffeefbff5ad | 0x7ffeefbff5ae | 0x7ffeefbff5af |
---|---|---|---|
0x12 | 0x34 | 0x56 | 0x78 |
大小端序的判断
理解了大小端序的特性,我们可以通过低地址的字节来判断了。
#include <stdio.h>
int main(int argc, char *argv[])
{
int a = 305419896;//等同于0x12345678(16进制)
char *p = (char*)&a;
if(p[0] == 0x78) {
printf("big endian\n");
}
else {
printf("little endian\n");
}
}
mac os
下输出结果:
big endian
参考链接
赏
使用支付宝打赏
使用微信打赏
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏
扫描二维码,分享此文章