在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);
}
因为你的系统是小端的。
32位整数0x11223344
存储在内存0x44 0x33 0x22 0x11
中
在大端系统上,它将被存储为:0x11 0x22 0x33 0x44
BTW大多数流行的uP都是小端。
字节存储在内存中的顺序是平台上字节顺序的函数。在这种情况下,您的系统是little-endian,因此您观察到它们构成的int
的较高地址处的字节包含最高有效位(在您的2147483648示例中,它是最高有效位的单个1
位) )。
在计算机经常被要求处理大于它们可以在一个步骤中处理的数字的时代,加法和减法通常要求计算机首先处理数字的低阶部分,就像人们处理数字一样手。如果正在添加123到678并且通过添加每个加数的最后一个数字(3和8)开始,则可以确定结果1的最后一个数字,将其写下来,并且除了事实之外还要忘记它在一个人甚至不得不看看加数的任何其他部分之前,这是一个进位。然后可以使用前一个数字的进位添加中间数字,并且知道结果的中间数字是0而不必查看任一操作数的第一个数字。然后可以计算结果的第一个数字。
如果通过将1添加到7开始,则一个人无法确定地写出结果的第一个数字,直到一个人也处理了第二个和第三个数字。因此,要么必须跟踪所有数字,直到完成计算,或者愿意从早期数字写下不正确的结果,然后如果有进位则调整它们。不那么好或有效。
虽然可以先将较大的数字存储在内存中,但仍然从小端开始执行计算,但如果对象的地址直接标识将要使用的第一部分,则地址计算往往更有效。因此,大多数系统在更重要的部分之前将每个对象的最不重要部分存储在存储器中。