在c中创建无符号整数和4字节数组的并集时,字节的顺序似乎相反。为什么会这样?
对于具有二进制表示形式的整数10000000 00000000 00000000 00000000, 我期望b [0] = 10000000,b [1] = 00000000等。
#include <stdio.h>
#include <stdlib.h>
typedef union intByteRep{
unsigned int i; // 00000000 00000000 00000000 00000000
unsigned char b[4]; // b[0] b[1] b[2] b[3] - What we would expect
// b[3] b[2] b[1] b[0] - What is happening
} intByteRep;
char *binbin(int n);
int main(int argc, char **argv) {
intByteRep ibr;
ibr.i = 2147483648; // 10000000 00000000 00000000 00000000
for(int i = 0; i < 4; i++){
printf("%s ", binbin(ibr.b[i]));
}
printf("\n"); // prints 00000000 00000000 00000000 10000000
for(int i = 3; i >= 0; i--){
printf("%s ", binbin(ibr.b[i]));
}
printf("\n"); // prints 10000000 00000000 00000000 00000000
return 0;
}
/*function to convert byte value to binary string representation*/
char *binbin(int n)
{
static char bin[9];
int x;
for(x=0; x<8; x++)
{
bin[x] = n & 0x80 ? '1' : '0';
n <<= 1;
}
bin[x] = ' ';
return(bin);
}
答案 0 :(得分:2)
因为您的系统是小端的。
32位整数0x11223344
存储在存储器0x44 0x33 0x22 0x11
在大端系统上,它将存储为:0x11 0x22 0x33 0x44
顺便说一句,大多数流行的uP都是小字节序。
答案 1 :(得分:2)
字节在内存中的存储顺序取决于您平台上的字节序。在这种情况下,您的系统是低位优先的,因此您观察到它们构成的int
较高地址处的字节包含最高有效位(在您的2147483648示例中,该位是单个{{1 }}位的最高有效位。
答案 2 :(得分:1)
在通常需要计算机处理单个步骤中无法处理的数字的时代,加法和减法通常要求计算机首先处理数字的低阶部分,就像处理一个数字一样。手工处理数字。如果将123与123相加,并以每个加数的最后一位(3和8)开始,则可以确定结果1的最后一位,将其写下来,而不必理会是一个进位,甚至不必看加数的任何其他部分。然后,可以将中间数字与前一个数字的进位相加,并知道结果的中间数字为0,而不必查看任何一个操作数的第一位。然后可以计算结果的第一位。
如果开始时将1加到7,则只有在处理完第二个和第三个数字后,才能确定地写入结果的第一个数字。因此,要么要么一直跟踪所有数字直到完成计算,要么愿意写下较早数字的不正确结果,然后在有进位的情况下进行调整。不太好或没有效率。
虽然可以先将较大的数字存储在内存中,但仍然从小端开始执行计算,但是如果对象的地址直接标识出对象的第一部分,则地址计算会更有效。用过的。因此,大多数系统将每个对象的最低有效部分存储在内存中,然后再存储最高有效部分。