简体   繁体   English

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

[英]Storing values directly into C struct with an array index

I can read out all the variable values of a generic C struct (assuming all same variable types) using 我可以使用以下命令读取通用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]);
}

How can I store values equivalently, if I want to store to say member variable #10? 如果要存储说成员变量#10,如何等效存储值? This following does not work at the whichStruct[i] line, obviously, since it's not an array. 显然,由于它不是数组,因此以下操作不适用于whichStruct [i]行。 But you get the idea... 但是你明白了...

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]);
}

How can I store directly by indexing into the struct? 如何通过索引到结构直接存储? I want to write to the address directly, it seems, using something like 我想使用类似的方法直接写地址

int* address = whichStruct + index; 
*address = val;

You can use the offsetof macro to find the byte offset into the struct. 您可以使用offsetof宏来查找结构中的字节偏移量。 Then you just do some pointer arithmetic to access the field. 然后,您只需执行一些指针算法即可访问该字段。

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

Since all variables are of the same type, the fields are going to be stored next to each other, with no gaps between them. 由于所有变量都是同一类型,因此这些字段将彼此相邻存储,并且它们之间没有间隙。 Therefore, you can index into your struct like this: 因此,您可以像这样在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]);
}

Another alternative would be to replace the individual fields of your struct with an array of equivalent size, and provide a #define -d constant for each field name. 另一种方法是,以取代的个别字段struct具有同等大小的阵列,并提供一个#define为每个字段名称-d恒定。 This way your code would reflect the same meaning, and provide a way to access array elements in a natural way. 这样,您的代码将反映相同的含义,并提供一种自然方式访问数组元素的方法。

A more elaborate version of dasblinkenlight's alternate suggestion is one of my favorite things to do. dasblinkenlight的替代建议的更详尽的版本是我最喜欢做的事情之一。 You can use an X-Macro to describe the table with symbolic names for each entry. 您可以使用X宏对每个条目使用符号名来描述表。 The X-Macro lets you peel-off the symbols into an enum and then use the other data to initialize an array. X-Macro使您可以将符号剥离为enum ,然后使用其他数据初始化数组。 Edits to the table maintain the symbolic association (unless, of course, you screw it up somehow, always a possibility). 对表的编辑将保持符号关联(当然,除非您以某种方式将其弄乱,否则始终是可能的)。

#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) };

Then you can access a data member with the symbolic name. 然后,您可以使用符号名称访问数据成员。

ftab[FirstVar];

which is almost as clear as fstruct.FirstVar; 这几乎和fstruct.FirstVar;一样清晰fstruct.FirstVar; , but puts everything in an array, and FirstVar is now an index, a small integer which can be stored in a variable. ,但将所有内容放入数组中,并且FirstVar现在是一个索引,一个可以存储在变量中的小整数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM