【问题标题】:Why does it look like arrays are indexed backways in a c union?为什么看起来数组在 c 联合中反向索引?
【发布时间】:2019-09-11 23:39:48
【问题描述】:

在 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);
}

【问题讨论】:

标签: c char int union unsigned


【解决方案1】:

因为你的系统是小端的。

32位整数0x11223344存储在内存中0x44 0x33 0x22 0x11

在大端系统上,它将被存储为:0x11 0x22 0x33 0x44

顺便说一句,大多数流行的 uP 都是小端。

【讨论】:

    【解决方案2】:

    字节在内存中的存储顺序是您平台上字节序的函数。在这种情况下,您的系统是 little-endian,因此您观察到它们构成的 int 的较高地址的字节包含最高有效位(在您的 2147483648 示例中,它是单个 1 位最重要的数字)。

    【讨论】:

    • 感谢您的回答;这是否意味着这段代码不能在所有系统上移植......?
    • @professorcolm 正确;可移植的 C 代码将不包含特定于任何特定字节序的算术或逻辑
    【解决方案3】:

    在计算机经常被要求处理大于单个步骤所能处理的数字的时代,加法和减法通常要求计算机首先处理数字的低阶部分,就像一个手工处理数字。如果一个人将 123 加到 678 并开始添加每个加数(3 和 8)的最后一个数字,那么人们将能够确定结果 1 的最后一个数字,把它写下来,然后忘记它,除了有是一个进位,在一个人甚至必须查看加数的任何其他部分之前。然后可以将中间数字与前一个数字的进位相加,并知道结果的中间数字是 0,而无需查看任一操作数的第一位数字。然后可以计算结果的第一位。

    如果一个人一开始是把 1 加到 7 上,那么在处理完第二个和第三个数字之前,一个人将无法确定地写出结果的第一个数字。因此,要么必须跟踪所有数字,直到完成计算,要么愿意写下早期数字的错误结果,然后在有进位时调整它们。没有那么好或没有效率。

    虽然可以先将较大的数字存储在内存中,但仍然从较小的一端开始执行计算,但如果对象的地址直接标识了它的第一部分,那么地址计算往往会更有效。用过的。因此,大多数系统在内存中将每个对象的最不重要的部分存储在更重要的部分之前。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-17
      • 2020-05-31
      • 2016-12-13
      • 1970-01-01
      • 2017-12-23
      • 1970-01-01
      • 1970-01-01
      • 2021-08-31
      相关资源
      最近更新 更多