【问题标题】:struct members value assignment with a loop带有循环的结构成员值赋值
【发布时间】:2013-11-05 21:36:07
【问题描述】:

我有这样的结构

struct hour_parameters{
    uint8_t VALUE_00;
    uint8_t VALUE_01;
    uint8_t VALUE_02;
    uint8_t VALUE_03;
    uint8_t VALUE_04;
    uint8_t VALUE_05;
    uint8_t VALUE_06;
    uint8_t VALUE_07;
    uint8_t VALUE_08;
    uint8_t VALUE_09;
    uint8_t VALUE_10;
    uint8_t VALUE_11;
    uint8_t VALUE_12;
    uint8_t VALUE_13;
    uint8_t VALUE_14;
    uint8_t VALUE_15;
    uint8_t VALUE_16;
    uint8_t VALUE_17;
    uint8_t VALUE_18;
    uint8_t VALUE_19;
    uint8_t VALUE_20;
    uint8_t VALUE_21;
    uint8_t VALUE_22;
    uint8_t VALUE_23;
};

struct hour_parameters hparam;

我想分配一个uint8_t x[24]hparam,我怎么能用for循环来做呢,那个

hparam.value00 = x[0];
hparam.value01 = x[1];
and so on?

【问题讨论】:

  • 为什么不用数组?
  • 是的,在上面的例子中使用数组似乎更好。但我只是想尽可能简单地举一个例子。有时,使用 struct 更方便、更易读。我只是想知道如何在 struct 中完成分配
  • 我的意思是在你的结构中使用一个数组。
  • 你是在问如何编写循环?!

标签: c loops struct variable-assignment


【解决方案1】:

你确实应该在你的结构中使用一个数组但是......

#include <string.h>
memcpy(&hparam, x, sizeof(hparam));

(我现在躲在桌子底下)

这是危险的一个原因是结构中可能存在填充。现在, 因为它们都是字节,所以你很安全。但是,从技术上讲,这种 的东西是不合法的。您可以事先做的一件事是

assert(sizeof(hparam) == sizeof(x));

如果你坚持使用 for 循环:

for(int i = 0; i != sizeof(hparam); i++) {
    ((uint8_t *)&hparam)[i] = x[i];
}

这是丑陋的,也不是太犹太。以下 Kerrek 的 cmets 提出了不这样做的理由。

【讨论】:

  • 填充并不是那么牵强。 C11 内存模型要求所有结构成员都可以单独修改,而无需发明对其他变量的写入,因此没有字节宽内存访问的架构可能需要使用填充(或没有uint8_t)。
【解决方案2】:

这应该可行:

memcpy_s( &hparam, sizeof hparam, x, sizeof x )

虽然这不是好的代码。

请注意,您的结构等同于数组,因此更好的解决方案是:

uint8_t hparam[24] = {0};
memcpy_s( hparam, sizeof hparam, x, sizeof x );

【讨论】:

    【解决方案3】:

    正如 Charlie Burns 所说,您可以将此结构用作数组,为了安全起见,如果您的编译器支持 pragma pack,则强制成员的最大对齐为 1

    #include <stdio.h>
    #include <stdint.h>
    #include <string.h>
    
    #pragma pack(push,1)
    struct hour_parameters{
        uint8_t VALUE_00;
        uint8_t VALUE_01;
        uint8_t VALUE_02;
        uint8_t VALUE_03;
        ...
    };
    #pragma pack(pop)
    
    int main(void)
    {
        struct hour_parameters hparam;
        uint8_t x[24] = {0};
    
        memcpy(&hparam, x, 24);
        printf("%u\n", hparam.VALUE_12);
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      正如@Charlie Burns 指出的那样,你想尽量避免它 除非您确切知道结构是如何填充/对齐的。 它不是可移植的编码风格。

      你也可以做一个结构赋值,比如

      hparams = *(struct hour_parameters *)x;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-20
        • 2021-05-19
        • 2016-11-05
        • 1970-01-01
        • 2013-10-07
        • 2021-08-28
        • 1970-01-01
        相关资源
        最近更新 更多