我正在尝试用 C 编写一些库并且我有这个 union :
union { INTEGER, DOUBLE, FLOAT } Types;
typedef struct X {
Type type;
union { double a, float b, int c; } val;
struct X *next;
} MyStruct;
我想要插入功能。例如,它可以是向某些结构(如树、优先级队列或其他结构)插入函数:
insertInt(..., int y), insertFloat(..., float y), insertDouble(..., double y).
而且这样我有很多冗余代码,这是不可取的。另一方面,我们有标准的字符串转换函数 atoi
, atol
, atof
位于<stdlib.h>
, 和开发库,更好的是重复代码或者以某种方式做它可能使用指向 void 的指针并用类型识别类型(在这个例子中)?
insertInt 示例:
MyStruct* insertInt(MyStruct *root, int val) {
MyStruct *newNode = (MyStruct*)malloc(sizeof(MyStruct));
newNode->next = root;
newNode->val.c = val;
newNode->type = INTEGER;
return newNode;
}
最佳答案
您可以通过为这些函数使用宏模板来避免源代码重复:
#define MAKE_INSERT_FUNC(__fname, __type, __member) \
MyStruct *__fname(MyStruct **root, __type val) { \
MyStruct *newNode = malloc(sizeof(MyStruct)); \
if (newNode) { \
newNode->next = *root; \
newNode->val.__member = val; \
newNode->type = type; \
*root = newNode; \
} \
return newNode; \
}
并以这种方式实例化函数:
MAKE_INSERT_FUNC(insertDouble, double, a);
MAKE_INSERT_FUNC(insertFloat, float, b);
MAKE_INSERT_FUNC(insertInt, int, c);
您仍然需要在头文件中编写声明:
MyStruct *insertDouble(MyStruct **root, double val);
MyStruct *insertFloat(MyStruct **root, float val);
MyStruct *insertInt(MyStruct **root, int val);
我更改了 API:insertXXX()
函数采用指向列表 root
指针的指针,因此您无需将返回值存储回原始值指针,您可以在不破坏现有列表的情况下测试分配是否失败。
请注意,与在您进行修改和修复错误时往往会变得不一致的重复源代码相比,重复代码(在本例中具有较小的变化)问题要小得多。例如,您可以修改模板以附加新节点而不是将其添加到 root
之前,所有 insertXXX 函数都将获得新行为。
关于c - union 和通用功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34844773/