将字符数组转换为整数

13
#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

有人能帮我解决吗?


3
“b”不是“0x4030201”,你的意思是“int b = *(int *)&a[0];”吗? - Tugrul Ates
1
是的,我打错了。谢谢。我已经更正了。 - Learner
@KerrekSB,这怎么帮助将“字符数组转换为整数”? - Z boson
@Zboson:呃,等一下,太多混淆了。关键是:要将“字符数组解释为整数”,您需要1)制作一个整数,2)逐个访问其字节,3)将给定的数组值写入这些新字节中,4 )读取第1步中制作的整数。 - Kerrek SB
@KerrekSB,我理解你说的是复制而不是转换(不是重新解释)。我实际上想要与OP得到的完全相同的结果(0x4030201),但我不想使用int b = *(int *)&a[0]来产生未定义行为。我猜我必须使用一个联合体,但它没有起作用。无论如何,如果我做错了,我会问一个问题,现在我还是坚持使用int b = *(int *)&a[0] - Z boson
显示剩余4条评论
3个回答

16

当你告诉编译器创建一个数组时,就像这样:

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] 是一个指向值为 MemoryAddress0char 指针,它指向一个 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


6

你所使用的机器是小端字节序,这意味着大小超过一个字节的整数会先存储最低有效字节。

需要注意的是,由于x86架构的普及,现在大多数架构都采用小端字节序。


如果我使用的是大端机器,结果将会是0x1020304吗? - Learner
2
小端机器先存储最不重要的字节,而不是位。这是一个打字错误吗? - Fabian Knorr
@Learner,如果Trion是正确的,那么它应该是0x01020304,我认为他是正确的。 - quantum

1

因为您的系统是小端字节序。在小端字节序系统中,多字节整数的第一个字节被解释为最不重要的字节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接