大端:低字节存在高地址
小端:低字节存在低地址
代码
int a = 0xabcd1234;
char b = ((char*)&a)[0];
分析
- 变量
a
的定义:int a = 0xabcd1234;
表示将一个 32 位的十六进制数0xabcd1234
赋值给整数变量a
。- 在十六进制中,
0xabcd1234
表示:- 高字节到低字节依次为:
0xab
,0xcd
,0x12
,0x34
。
- 高字节到低字节依次为:
- 在内存中,这 4 个字节会按照某种字节序存储。
- x86 机器的字节序:
- x86 架构使用 小端序(Little-Endian)。
- 小端序意味着低位字节存储在低地址,高位字节存储在高地址。
- 对于
0xabcd1234
,内存中的存储顺序(从低地址到高地址)是:- 地址 0:
0x34
(最低字节) - 地址 1:
0x12
- 地址 2:
0xcd
- 地址 3:
0xab
(最高字节)
- 地址 0:
- 取地址并转换为
char*
:&a
是a
的地址,类型是int*
。(char*)&a
将int*
转换为char*
,此时它指向a
的起始地址(即最低地址)。- 在小端序下,
a
的起始地址存储的是0x34
。
- 数组访问
((char*)&a)[0]
:((char*)&a)[0]
表示取char*
指针指向的第一个字节。- 因为
char
是一个字节(8 位),所以它读取的是内存中a
的最低地址字节,即0x34
。
- 赋值给
char b
:char b = ((char*)&a)[0];
将0x34
赋值给b
。- 在 C 中,
char
通常是有符号的(signed char
),范围是128
到127
。 0x34
是十六进制数,转换为十进制是52
,属于signed char
的正数范围,因此b
的值就是52
。
结果
在 x86 机器上,char b
的值是:
- 十六进制:
0x34
- 十进制:
52
验证思路
- 如果你想验证这个结果,可以运行以下代码:
#include <stdio.h>
int main() {
int a = 0xabcd1234;
char b = ((char*)&a)[0];
printf("b = 0x%x (%d)\\n", (unsigned char)b, b);
return 0;
}
- 输出应该是:
b = 0x34 (52)
。
注意事项
- 如果
char
在你的编译器中被定义为unsigned char
(无符号字符,范围 0 到 255),结果仍然是0x34
(十进制 52),但解释为无符号数。 - x86 的小端序是关键,如果在其他架构(如大端序的 PowerPC)上运行,结果会是
0xab
(而不是0x34
)。
结论
在 x86 机器上,char b
的值是 0x34
(十进制 52
)。