带有循环的结构成员值赋值
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;
【讨论】:
以上是关于带有循环的结构成员值赋值的主要内容,如果未能解决你的问题,请参考以下文章