我目前正在构建一个数据结构的个人库,我意识到它们可以通过将其中的数据为void *来完全抽象。比如说我创建了一个链表
typedef struct node_ll {
void *data;
struct node_ll *next;
} node_ll;
假设我要创建一个结构体链表它们被定义为
struct person {
char *name;
int age;
};
那么,是否可以定义一个抽象的搜索方法
void *traverse(void *head, void* data) {}
找到一个19岁的人,名字是"约翰"?
要使列表数据结构抽象,只需在源文件中隐藏node_ll
结构的定义。头文件将只包含前向声明和api的原型:
typedef struct node_ll node_ll;
typedef struct linkedlist { node_ll *head; } linkedlist;
static inline linkedlist make_linkedlist () {
const linkedlist zero_ll = { 0 };
return zero_ll;
}
void unmake_linkedlist (linkedlist *list);
void linkedlist_add (linkedlist *list, void *data);
void linkedlist_traverse_until (linkedlist *list,
int (*visit)(void *visit_data, void *data),
void *visit_data);
linkedlist_traverse_until()
函数基本上将在每个节点上调用提供的visit()
函数,除非visit()
返回0,此时它停止。函数的实现知道如何访问node_ll
,因为它在源文件中具有struct node_ll
的完整定义。
while (node) {
if (visit(visit_data, node->data)) {
node = node->next;
continue;
}
break;
}