我正在为链接列表和树编写一个 c 库,我正在寻找一种解决方案来概括这些库处理的数据类型,而无需为我需要处理的每种类型创建一个列表/树库。
比如我的列表库有这些函数:
/* list.h */
typedef int list_element; // <-- need to generalize that
struct list_node {
list_element value;
struct list_node* next;
};
typedef struct list_node list_node;
typedef struct list_node* list;
extern list list_cons(list_element d, list l)
然后是我的 list.c:
/* list.c */
#include <list.h>
list list_cons(list_element d, list l){
list m = malloc(sizeof(list_node));
m->value = element_copy(d);
m->next = l;
return m;
}
现在假设在我的主程序中我必须使用一个 int 列表和一个 double 列表,我应该创建两个文件,比如 list_float.c/.h 和 list_int.c/.h
还有一些 list_element
可以是结构体,需要像 copy/isLess/isEqual 这样的函数来比较它们自己
我想在我的代码中写这样的东西:
/* main.c */
list_cons(void *data, list l);
其中 data
是指向我想要的任何类型的指针,在 list_cons
中,element_copy
适用于我传递的任何类型的数据(显然我需要复制数据而不是指向数据的指针,void* 是我必须概括函数参数类型的唯一想法)
最佳答案
作为一般性建议,您不应假定 list_cons
是构造链表的唯一方法。有时 malloc
不可用,或者用户想要在静态数组中预分配所有内容,或者想要使用自定义分配器或...
作为具体示例,您可以查看 https://github.com/torvalds/linux/blob/master/include/linux/list.h .
如果您的代码需要其他许可证,请在 xBSD Unix 源中搜索数据结构实现。
一般的想法是你只需要一个链表结构来包含下一个/上一个和类似的字段,而不是限制用户使用你的类型名称。所有迭代和基本操作都定义为预处理器宏,您可以在其上实现复杂的算法。
关于C、概括函数参数的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50552275/