使用数组索引将值直接存储到C struct中

时间:2015-05-29 02:07:05

标签: c arrays struct sizeof memcpy

我可以使用

读出通用C结构的所有变量值(假设所有相同的变量类型)
struct whichstruct{
  float firstVar;
  float ...
  ...
};
whichstruct whichStruct;

void printParams(structType *whichStruct) {
  // Print out all values of a struct.
  float *startVar = &(whichStruct->firstVar);
  int numElements = sizeof(*whichStruct) / sizeof(startVar);
  for (int i = 0; i < numElements; ++i)
    printf("%d: %f\r\n", i, startVar[i]);
}

如果我想存储成员变量#10,我如何能等价地存储值?显然,以下内容在whichStruct [i]行中不起作用,因为它不是数组。但是你明白了......

void setParams(structType *whichStruct, const int whichVar, const float val) {
  // whichVar is the struct's member variable to access (2nd, 3rd, etc)
  float *startVar = &(whichStruct->firstVar);
  int numElements = sizeof(*whichStruct) / sizeof(startVar);
  int index = sizeof(startVar) * whichVar; // How many bytes into the struct?
  whichset[index] = val; // <-- trying to poke the value at the struct's correct byte address
  printf("#%d = %f\r\n", whichVar, whichStruct[index]);
}

如何通过索引直接存储到结构中?我想用

之类的东西直接写入地址
int* address = whichStruct + index; 
*address = val;

3 个答案:

答案 0 :(得分:3)

您可以使用offsetof宏来查找结构中的字节偏移量。然后你只需要做一些指针算法来访问该字段。

*((float *) (((void *)&whichStruct) + offsetof(whichstruct, firstVar))) = val;

答案 1 :(得分:2)

由于所有变量属于同一类型,因此这些字段将彼此相邻存储,它们之间没有间隙。因此,您可以像这样索引struct

void setParams(structType *whichStruct, const int whichVar, const float val) {
    float *startVar = &(whichStruct->firstVar);
    startVar[whichVar] = val;
    printf("#%d = %f\r\n", whichVar, whichStruct[index]);
}

另一种替代方法是使用等效大小的数组替换struct的各个字段,并为每个字段名称提供#define - d常量。这样,您的代码将反映相同的含义,并提供一种以自然方式访问数组元素的方法。

答案 2 :(得分:0)

一个更精致的版本的dasblinkenlight的替代建议是我最喜欢做的事情之一。您可以使用X-Macro来描述具有每个条目的符号名称的表。 X-Macro允许您将符号剥离为enum,然后使用其他数据初始化数组。对表格的编辑保持了符号关联(当然,除非你以某种方式搞砸了,总是有可能)。

#define FLOATTAB(_) \
    _(FirstVar, 1.0) \
    _(SecondVar, 2.0) \
    /* end FLOATTAB */
#define FLOATTAB_NAME(a,b) a,
enum { FLOATTAB(FLOATTAB_NAME) };
#define FLOATTAB_DATA(a,b) b,
float ftab[] = { FLOATTAB(FLOATTAB_DATA) };

然后,您可以使用符号名称访问数据成员。

ftab[FirstVar];

几乎与fstruct.FirstVar;一样清晰,但是将所有内容都放在一个数组中,FirstVar现在是一个索引,一个可以存储在变量中的小整数。