gpt4 book ai didi

c - 不使用点运算符访问结构成员

转载 作者:太空狗 更新时间:2023-10-29 15:52:46 25 4
gpt4 key购买 nike

我什至不知道,我问的是不是愚蠢的事情。我不是要你为我写任何代码,而是要以更好的方式做某事的想法。

我有一个包含大量这样的项目的结构:

typedef struct _myStruct
{
int int1;
char char1;
int int2;
:
:
int int50;
}myStruct;

我有另一个枚举,它对 myStruct 中的每个项目都有一个条目。

enum
{
eINT1,
eCHAR1,
eINT2,
:
:
eINT50
} PARAMETER_ID;

我想为每种数据类型编写一个函数 [比如一个用于 int,一个用于 char,一个用于字符串等],它返回 myStruct 成员的值,当 PARAMETER_ID 作为输入给出。

例如,我需要一个 int GetInt(PARAMETER_ID) 函数,它在将 eINT1 作为参数传递时返回 int1 的值。同样,我将使用 char GetCharacter(PARAMETER_ID)float GetFloat(PARAMETER_ID)

结构中的项数可能很大。因此,为每个项目使用 switch-case 将不是一个可行的选择。

我能想到的唯一其他选择是使用结构变量的地址和 offsetof() 函数来计算参数的地址,然后通过 memcpying所需的字节到一个变量。在那种情况下,我需要在某处保留每个参数的偏移量,但这不是问题。

我正在寻找替代方案来执行此操作。任何帮助将不胜感激。

谢谢。

最佳答案

大型开关 是一个不错的可行选择。

您也可以使用预处理器技巧。

你可以有一个包含

mystruct.def文件
 INTFIELD(int1)
CHARFIELD(char1)
INTFIELD(int2)

等等... 然后你会多次包含它;声明结构:

 struct _myStruct {
#define INTFIELD(F) int F;
#define CHARFIELD(F) char F;
#include "mystruct.def"
#undef INTFIELD
#undef CHARFIELD
};

声明枚举(使用e_int1而不是eINT1)

 enum field_en {
#define INTFIELD(F) e_##F,
#define CHARFIELD(F) e_##F,
#include "mystruct.def"
#undef INTFIELD
#undef CHARFIELD
};

要实现访问器,

 int get_int(struct _myStruct*s, enum field_en f)
{
switch (f) {
#define INTFIELD(F) case e_##F: return s->F;
#define CHARFIELD(F) /*nothing*/
#include "mystruct.def"
#undef INTFIELD
#undef CHARFIELD
default: return 0;
}}

我并不是说这是更好或更易读的代码,但这种编程风格确实出现在某些 C 或 C++ 程序中(例如 GCC 内部及其 gcc/tree.def)

如果你的代码是一个非常大的代码库,并且你准备好花几天的时间工作(例如因为你有很多这样的 struct 并且不想玩这样的把戏)你可能会考虑使用 MELT 进行 GCC 扩展(一种扩展 GCC 的高级领域特定语言)来帮助你;您可能可以制作一个 MELT 扩展来为您生成访问器函数。

您还可以说服您的老板从临时描述文件(使用 awkpython 或其他)。 GCC 为其选项文件做了这样的技巧,例如gcc/common.opt

最后,如果包含 _myStruct 的 header 非常神圣以至于不允许您触摸它,并且它的格式非常干净,您可以制作一个临时的(例如 awk) 脚本来获取声明并处理它。

注意,一个好的编译器会将密集的 switch 语句优化为需要常数时间的索引跳转,即使在数百个情况下也是如此。

关于c - 不使用点运算符访问结构成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14931174/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com