【问题标题】:value in array will be printed as 0 even after changing it in c即使在 c 中更改后,数组中的值也将打印为 0
【发布时间】:2021-05-24 16:53:09
【问题描述】:

所以我使用typedef unsigned char byte; 创建了一个自定义类型,然后声明了它的一个数组,就像使用byte mem[255]; 一样。我使用mem[0] = 0x10100000; 初始化第一个值,但是当我使用printf("%d", mem[0]); 打印它时,我得到0。为什么?

【问题讨论】:

  • 0x10100000 是一个 32 位值。你的意思可能是0xa0
  • 0x10100000 大大超过了unsigned char 的存储容量您知道这不是二进制数,对吧?这是十六进制无符号文字。
  • 如果你的编译器是非常新的并且支持即将到来的C23标准(或者有一个允许它的扩展)那么你可以使用二进制integer constants使用0b前缀,如0b10100000
  • @Someprogrammerdude,如果你不是那么幸运,你可以使用一些模板技巧来到达那里:C++ binary constant/literal

标签: arrays c


【解决方案1】:

unsigned char 通常只能保存 0 到 255 之间的值。十六进制值 0x10100000 远远超出该类型的范围,因此(基本上)只使用该值的低位字节,即 0。

大概您想使用二进制常量。并非所有编译器都支持,但那些支持的编译器会将其指定为 0b10100000。对于那些不这样做的人,您可以使用十六进制值 0xA0。

【讨论】:

  • 是的,我应该改用'b',但我把他们搞混了
【解决方案2】:

您为其分配了十六进制数字0x10100000,它远大于单个字符,因此不能存储在byte 中。如果你想使用二进制数,并且你的编译器支持这个,你可以尝试使用0b10100000

【讨论】:

    【解决方案3】:

    unsigned char只能保存((1 << CHAR_BIT) - 1)的值

    你可以自己检查最大值是多少

    #include <stdio.h>
    #include <limits.h>
    
    int main(void)
    {
        printf("%u\n", (1 << CHAR_BIT) - 1);
    }
    

    在大多数系统上,它是 2550xff

    当您使用0x10100000 分配无符号字符时,只会分配最低的两个十六进制数字(在您的情况下为 0x00)。

    如果您想将所有字节从0x10100000 复制到您定义的byte 数组mem,则分配将不起作用。然后你需要复制:

    #include <stdio.h>
    #include <limits.h>
    #include <string.h>
    
    typedef unsigned char byte;
    
    int main(void)
    {
        byte mem[100];
    
        memcpy(mem, &(unsigned){0x10100000}, sizeof(0x10100000));
    
        for(size_t index = 0; index < sizeof(0x10100000); index++)
        {
            printf("mem[%zu] = 0x%hhx\n", index, mem[index]);
        }
    }
    

    输出:

    mem[0] = 0x0
    mem[1] = 0x0
    mem[2] = 0x10
    mem[3] = 0x10
    

    https://godbolt.org/z/cGYa8MTef

    为什么按这个顺序?因为运行 Godbolt 的机器使用很少的 endioan。 https://en.wikipedia.org/wiki/Endianness

    0x 前缀表示该数字是十六进制的。如果你想使用二进制数,那么 gcc 支持 0b 前缀,这不是标准的。

    mem[0] = 0b10100000

    你也可以创建.h文件

    #define b00000000   0
    #define b00000001   1
    #define b00000010   2
    #define b00000011   3
    
    /* .... */
    #define b11111110   254
    #define b11111110   255
    

    并以可移植的方式使用这些定义

    mem[0] = b10100000;
    

    【讨论】:

    • 我不小心用 b 代替了 x 并且错误地定义了它们
    【解决方案4】:

    您不能在 8 位变量 (mem[0]) 中放入 32 位值。您可能是打算这样做吗?

    *(int *)mem = 0x10100000;
    

    【讨论】:

    • 似乎不太可能。
    猜你喜欢
    • 2017-11-13
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 2021-12-09
    • 1970-01-01
    • 2020-11-18
    相关资源
    最近更新 更多