带有循环的结构成员值赋值

Posted

技术标签:

【中文标题】带有循环的结构成员值赋值【英文标题】: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 中完成分配 我的意思是在你的结构中使用一个数组。 你是在问如何编写循环?! 【参考方案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;

【讨论】:

以上是关于带有循环的结构成员值赋值的主要内容,如果未能解决你的问题,请参考以下文章

使用双指针为结构成员赋值

JAVA中的成员变量不赋值默认是0吗?

C中结构体内有一个成员是二维数组,可以直接赋值另一个一维数组吗?

如何给C语言结构体中的成员赋默认值

构造函数中的 C# 赋值给成员......不会改变它

类和结构体的区别