#include <stdio.h>
int main(){
unsigned char a[4] = {1, 2, 3, 4};
int b = *(int *)&a[0];
printf("%d\n", b);
return 0;
}
我就是无法理解为什么b
的结果是0x4030201
。
有人能帮我解决吗?
当你告诉编译器创建一个数组时,就像这样:
unsigned char a[4] = {1, 2, 3, 4};
这些数字按照以下顺序被放置在内存中:
MemoryAddress0: 0x01 -> a[0]
MemoryAddress1: 0x02 -> a[1]
MemoryAddress2: 0x03 -> a[2]
MemoryAddress3: 0x04 -> a[3]
&a[0]
是一个指向值为 MemoryAddress0
的 char
指针,它指向一个 1 字节的值 0x01
(int*)&a[0]
是一个强制类型转换后的指针,它具有相同的值 MemoryAddress0
,但这次是 int*
类型,因此指向四个连续的字节。
我们日常使用的大多数计算机都是 小端 的,这意味着它们将多字节值存储在内存中,从最不重要的字节到最重要的字节。
当一个 int*
指向四个字节的内存时,它遇到的第一个字节是最不重要的字节,第二个字节是第二个最不重要的字节,依此类推。
MemoryAddress0: 0x01 -> 2^0 term
MemoryAddress1: 0x02 -> 2^8 term
MemoryAddress2: 0x03 -> 2^16 term
MemoryAddress3: 0x04 -> 2^24 term
因此,这个4字节整数值变成了0x01*2^0 + 0x02*2^8 + 0x03*2^16 + 0x04*2^24
,等于0x04030201
。
你所使用的机器是小端字节序,这意味着大小超过一个字节的整数会先存储最低有效字节。
需要注意的是,由于x86架构的普及,现在大多数架构都采用小端字节序。
因为您的系统是小端字节序。在小端字节序系统中,多字节整数的第一个字节被解释为最不重要的字节。
0x4030201
),但我不想使用int b = *(int *)&a[0]
来产生未定义行为。我猜我必须使用一个联合体,但它没有起作用。无论如何,如果我做错了,我会问一个问题,现在我还是坚持使用int b = *(int *)&a[0]
。 - Z boson