问题描述
我有两个结构体和常量字符数组:
I have two structs and array of const chars:
typedef struct {
int skip_lines;
int num; // count of files
int i; // number of the file to define order; extremly important to set correctly and then not to change!
char filename[70];
char main_directory[16];
char submain_directory[100];
} FILE_;
typedef struct {
FILE_ radiation_insolation[7];
FILE_ radiation_radiation[5];
FILE_ winds[9];
FILE_ pressure[1];
FILE_ humidity[1];
FILE_ temperature[4];
} FILES;
char *tables[] = {"radiation_insolation", "radiation_radiation", "winds", "pressure", "humidity", "temperature" };
我也有 FILES files;
在 main 函数中,并启动从文件加载数据的函数.所以文件的每个成员都包含数据.
I also have FILES files;
in main function and initiate function which loads data from file. So every member of the files contains data.
然后我需要像这样访问数据:
Then I need to access the data like this:
files->radiation_insolation[0].skip_lines
files->radiation_radiation[0].skip_lines
files->radiation_winds[0].skip_lines
files->pressure[0].skip_lines
files->humidity[0].skip_lines
files->temperature[0].skip_lines
我的计划是创建循环来动态处理每个成员.
My plan is to create loop to process every member dynamically.
for(i = 0; i<6; i++) {
// do some job
}
我的问题是当我需要访问时该怎么做,例如files->radiation_insolation 在循环中使用表 [i]?如何创建成员的名称,以便编译器知道要访问的成员?
My question is how to do it when I need to access e.g. files->radiation_insolation using the tables[i] in the loop? How to create the name of the member so that the compiler knows what member to access?
在 PHP 语言中可以使用类似 $files->$tables[i] 的东西.但是如何在 C 中做到这一点?
In PHP language one can use something like $files->$tables[i]. But how to do it in C?
推荐答案
在 C 中没有真正的方法可以做到这一点.结构不是表,而是更接近硬件的东西,即内存块.
There's not really a way to do this in C. Structs are not tables, but something much closer to the hardware, namely chunks of memory.
您可以创建一个 icky 宏来访问结构:
You could create an icky macro to access the struct:
// bad idea
#define FILES_ITEM(var, field, index, member) var.field[index].member
但是这样的宏只是毫无意义和不好的做法,输入所有内容会更清晰:
But such macros are just pointless and bad practice, it is much clearer to type out everything:
int main (void)
{
FILES files;
for(size_t i=0; i<7; i++)
{
files.radiation_insolation[i].skip_lines = i;
printf("%d ", files.radiation_insolation[i].skip_lines);
}
}
通常很难证明除了上述风格之外的任何其他东西都是合理的.
It will normally be very hard to justify anything else than the above style.
使用 C11,您可以通过使用联合来稍微改善这种情况,其中包含与数组组合的匿名结构:
With C11 you could improve the situation a bit by using a union, containing an anonymous structure in combination with an array:
#define FILE_ITEMS_N (7 + 5 + 9 + 1 + 1 + 4)
typedef union {
struct
{
FILE_ radiation_insolation[7];
FILE_ radiation_radiation[5];
FILE_ winds[9];
FILE_ pressure[1];
FILE_ humidity[1];
FILE_ temperature[4];
};
FILE_ items [FILE_ITEMS_N];
} FILES;
然后您可以单独访问成员:
You can then either access members individually:
files.radiation_insolation[0].skip_lines = 123;
或者作为数组:
files.items[item].skip_lines = 123;
C11 §6.7.2.1 保证工会工作:
The union is guaranteed to work by C11 §6.7.2.1:
14 结构体或联合对象的每个非位域成员都是对齐的以适合其类型的实现定义的方式.
/--/
17 在结构或联合的末尾可能有未命名的填充.
17 There may be unnamed padding at the end of a structure or union.
这意味着内部结构的所有成员都保证适当对齐,如果需要,在结构的末尾使用尾随填充.
This means that all members of the inner struct are guaranteed to be aligned appropriately, with trailing padding at the end of struct if needed.
此外,根据 C11 6.5/7,该数组还保证可以毫无问题地为各个成员设置别名:
Furthermore, the array is also guaranteed to alias the individual members with no problems, as per C11 6.5/7:
一个对象只能通过左值表达式访问其存储的值,该表达式具有以下之一以下类型:
/--/
——一个聚合或联合类型,其中包括上述类型之一成员(包括递归地,子聚合或包含联合的成员)
— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union)
这篇关于如何在C中动态访问struct的成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!