【问题标题】:Dynamic method of calling structures in CC中调用结构的动态方法
【发布时间】:2020-04-10 08:53:18
【问题描述】:

我有一个项目,其中涉及为我公司使用的一些软件编写 C 程序。我希望它尽可能高效,但是软件引用我正在使用的信号的方式有点不稳定。我正在使用 4 组 96 个信号;这些信号分为 32 个组,每组 3 个成员。自动生成的头文件为每个组定义了一组宏(我认为),而不是使用这些信号的通用函数(存在通用函数,但没有关于它们如何工作的文档)。

每个组的定义如下...

typedef struct {
//struct members
} AB_A_Group_A_Network

每个结构都有一组宏(?)定义如下...

void AB_A_Group_ZF_Network_Init(AB_A_Group_A_Network *pAbc)
{
    double values[6]
    ...
    pAbc->Member_1 = values[3] //array positions vary
    pAbc->Member_2 = values[4]
    pAbc->Member_3 = values[5]
}

该软件的技术支持建议我执行以下操作,但我希望有更好的方法来执行此操作。当然这是一个很长的方法,但如果需要,我可以用 python 脚本编写它。这 250 多行代码将在我的应用程序中为每个数据集每秒运行一次。

AB_A_Group_A_Network GroupA;
AB_A_Group_B_Network GroupB;
//...and so on
AB_A_Group_ZF_Network GroupZF;

AB_A_Group_A_Network_Init(&GroupA);
AB_A_Group_B_Network_Init(&GroupB);
//...and so on
AB_A_Group_ZF_Network_Init(&GroupZF);

CD_Array_Set(0,GroupA.Member_1); //a custom array function meant to interface with the software
CD_Array_Set(1,GroupA.Member_2);
//...and so on
CD_Array_Set(95,GroupZF.Member_96);

//...Repeat 3 times for 4 sets of data (Data sets A-D), with checks to see if that data exists

我想过做这样的事情,但我不确定你是否可以以这种方式使用 char 数组。我将添加免责声明,对 C 语言没有太多经验,所以这看起来/听起来真的很愚蠢。这不是工作代码,只是意识流。如果可能的话,我也不确定这样做是否会最终失去效率。我对其他方法完全开放。

char groupName[70] = "AB_*_Group_*_Network";
char dataset = 'A';
char group = 'A';
char member = '1';
char groupInit[70]

//write a loop to increment dataset alphabetically
//check if dataset exists
groupName[3] = dataset;

//write a sub-loop to increment group alphabetically (each set has 32 groups)
groupName[27] = group;

//use groupName in place of struct name (not sure how or if this is possible with my current methods)

groupInit = strncat(groupName, "_Init", 5);

//use groupInit in place of _init macro name

//write a sub-loop to increment member numerically (each group has 3 members)
char member[10] = "Member_*";
member[7] = member;

CD_Array_Set(i,groupName.member);

长方法真的是最好的方法吗?感谢您提供任何建议!

【问题讨论】:

  • 您不能从字符串中动态引用变量和类型。这些名称都是在编译时解析的。
  • 您可以查看带有标记粘贴的宏,因此您不必重复每个变量声明和初始化的所有公共部分。
  • AB_A_Group_A_NetworkAB_A_Group_B_NetworkAB_D_Group_ZF_Network 等有何不同? typedefstruct 你只使用一次似乎很奇怪。一个相同结构的数组(根据需要使用函数指针和unions)可以将问题简化为几个循环。
  • "CD_Array_Set(95,GroupZF.Member_96);" 与“信号分为 32 个组,每个组 3 个成员”相矛盾。应该是95%3=2,即CD_Array_Set(95,GroupZF.Member_2);
  • @LegendofPedro 他们每个人都几乎完全相同,每个成员在 values[] 中的确切位置有所不同。我的项目中的支持​​文件是计算机生成的,文件中的结构看起来不像这样;我假设开发人员只是让软件尽可能灵活。结构通常可以很好地放入数组吗?

标签: c arrays struct char


【解决方案1】:

没有办法在运行时动态地从字符串中引用变量和类型名称。但是您可以在宏中使用令牌粘贴来避免所有重复代码。

#define INIT_GROUP(dataset, group) \
AB_ ## dataset ## _Group_ ## group ## _Network Group ## group; \
AB_ ## dataset ## _Group_ ## group ## _Network_Init(&Group ## group); \
CD_Array_Set(0,Group ## group .Member_1); \
CD_Array_Set(1,Group ## group .Member_2); \
...
CD_Array_Set(95,Group ## group .Member_96);

不幸的是,预处理器中没有循环,因此您必须在宏中编写所有 96 个CD_Array_Set 行。

使用此宏,您可以编写:

INIT_GROUP(A, A)
INIT_GROUP(A, B)
...
INIT_GROUP(A, ZF)

【讨论】:

  • 这个答案真的很有帮助! “预处理器中没有循环”是指我不能用变量替换 CD_Array_Set(0,Group ##group .Member_1) 中的 0 吗?该数字或行与我要替换的其他行有何不同?另外,使用这种方法,我似乎可以使用INIT_GROUP(i, j) 行编写一个循环,只要我单独设置数组即可。这是正确的吗?
  • 在程序运行之前变量不会得到值,宏会在编译时展开。
  • INIT_GROUP(i, j) 将扩展为 AB_i_Group_j_Network Groupj; ...。变量将仅以文本形式合并,而不是它们的值。
【解决方案2】:

自动生成的 C 代码

在 C 中可以做这样的事情,但它需要 ugly 宏。

我首先要看的是

一个旧的 Stackoverflow 问题:https://stackoverflow.com/a/12591965/8964221

其中提到的要点:https://gist.github.com/epatel/3786323

但是! 我会考虑让它无错误并正常工作所消耗的时间。 将其转换为您的需求不会那么容易。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    • 2015-11-18
    • 1970-01-01
    • 2011-02-22
    • 2013-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多