小端格式和大端格式(Little-Endian&Big-Endian)

本文介绍了计算机科学中的字节序概念,包括Little-endian和Big-endian两种主要类型,并通过实例展示了不同字节序下整数在内存中的存储方式。

转载连接:http://www.cnblogs.com/passingcloudss/archive/2011/05/03/2035273.html

不同的CPU有不同的字节序类型,这些字节序是指整数在内存中保存的顺序。
最常见的有两种:
1. Little-endian:将低序字节存储在起始地址(低位编址)
2. Big-endian:将高序字节存储在起始地址(高位编址)

LE(little-endian):
最符合人的思维的字节序
地址低位存储值的低位
地址高位存储值的高位
怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说
低位值小,就应该放在内存地址小的地方,也即内存地址低位
反之,高位值就应该放在内存地址大的地方,也即内存地址高位

BE(big-endian):
最直观的字节序
地址低位存储值的高位
地址高位存储值的低位
为什么说直观,不要考虑对应关系
只需要把内存地址从左到右按照由低到高的顺序写出
把值按照通常的高位到低位的顺序写出
两者对照,一个字节一个字节的填充进去

例子1:在内存中双字0x01020304(DWORD)的存储方式。
内存地址 4000 4001 4002 4003
LE 04 03 02 01
BE 01 02 03 04
注:每个地址存1个字节,每个字有4个字节。2位16进制数是1个字节(0xFF=11111111)。

例子2:如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为
    big-endian little-endian
0x0000 0x12 0xcd
0x0001 0x23 0xab
0x0002 0xab 0x34
0x0003 0xcd 0x12

x86系列的CPU都是little-endian的字节序。

在 C 语言中,判断系统是 **大端(Big-endian)** 还是 **小端Little-endian)**,可以通过检查一个多字节数据在内存中的存储顺序来实现。 --- ## ✅ 方法一:使用联合体(Union)判断字节序 ```c #include <stdio.h> int main() { union { unsigned int i; unsigned char c[sizeof(unsigned int)]; } test; test.i = 0x01020304; if (test.c[0] == 0x01) { printf("Big-endian\n"); } else if (test.c[0] == 0x04) { printf("Little-endian\n"); } else { printf("Unknown endianness\n"); } return 0; } ``` ### 解释: - 联合体 `test` 中的 `i` `c[]` 共享同一块内存。 - 将 `i` 设置为 `0x01020304`,它是一个 4 字节的整数。 - 如果系统是 **小端模式**,最低有效字节存在低地址,即 `c[0] = 0x04`。 - 如果是 **大端模式**,最高有效字节存在低地址,即 `c[0] = 0x01`。 --- ## ✅ 方法二:使用指针方式判断字节序 ```c #include <stdio.h> int main() { unsigned int i = 0x01020304; unsigned char *c = (unsigned char *)&i; if (*c == 0x01) { printf("Big-endian\n"); } else if (*c == 0x04) { printf("Little-endian\n"); } else { printf("Unknown endianness\n"); } return 0; } ``` ### 解释: - 用指针指向 `i` 的第一个字节。 - 同样根据第一个字节的值判断大小端--- ## ✅ 方法三:封装为函数(便于复用) ```c #include <stdio.h> int is_little_endian() { int i = 1; return *((char *)&i) == 1; } int main() { if (is_little_endian()) { printf("System is Little-endian\n"); } else { printf("System is Big-endian\n"); } return 0; } ``` ### 解释: - `int i = 1`,其十六进制为 `0x00000001`。 - 如果系统是小端,第一个字节就是 `0x01`,返回真。 - 如果是大端,第一个字节是 `0x00`,返回假。 --- ## ✅ 总结 | 方法 | 说明 | 可移植性 | 推荐程度 | |------|------|----------|----------| | 使用联合体 | 简洁直观 | 高 | ⭐⭐⭐ | | 使用指针 | 更通用 | 高 | ⭐⭐⭐⭐ | | 封装为函数 | 易于复用 | 高 | ⭐⭐⭐⭐⭐ | --- ##
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值