有没有办法在C中创建通用数据结构并根据存储的数据类型使用函数,这种结构具有各种类型的数据,例如可以根据存储的数据打印。
例如,
假设我希望创建一个只有float的二进制搜索树,存储int。这样做的自然方法是使用int和float来创建枚举。它看起来像这样:
Typedef enum {INT, FLOAT} DataType;
Typedef struct node
{
void *data;
DataType t;
struct node *left,
*right;
}Node;
如果我想打印出来:
void printTree(Node *n)
{
if (n != NULL)
{
if (n->t == INT)
{
int *a = (int *) n->data;
printf("%d ", *a);
}
else
{
float *a = (float *) n->data;
printf("%f ", *a);
}
printTree(n->left);
printTree(n->right);
}
}
没关系,但我想将另一种数据类型存储为堆栈,查询或其他内容。这就是为什么我创建了一个不依赖于特定数据类型的树,例如:
Typedef struct node
{
void *data;
struct node *left,
*right;
}Node;
如果我想打印出来,我会使用回调函数,例如:
Node *printTree(Node *n, void (*print)(const void *))
{
if (n != NULL)
{
print(n->data);
printTree(a->left);
printTree(a->right);
}
}
但是当我尝试插入一个整数和一个浮点并将其打印出来时,它就会崩溃。我的问题是,有没有办法创建一个通用的数据结构,例程在一种情况下依赖于特定的数据类型,而另一种情况则不是,对于混合数据类型?在这种情况下,我应该创建一个存储int和float的存储结构,并在回调函数中使用类似于第一个打印代码的打印函数?
观察:我刚刚在结构中声明了一个节点并且在其上做了一切试图简化,但是想法是使用带有.h和.c的结构以及涉及数据结构的所有这些抽象。
答案 0 :(得分:4)
我建议尝试以下内容。您会注意到Node
包含tagged union,它允许指针类型,整数或浮点数。当Node
是指针类型时,将调用自定义print
函数,而在其他情况下,将使用相应的printf
格式。
typedef enum {POINTER, INT, FLOAT} DataType;
typedef struct node
{
DataType t;
union {
void *pointer;
int integer;
float floating;
} data;
struct node *left,
*right;
} Node;
void printTree(Node *n, void (*print)(const void *))
{
if (n != NULL) {
switch (n->t) {
case POINTER:
print(n->data.pointer);
break;
case INT:
printf("%d ", n->data.integer);
break;
case FLOAT:
printf("%f ", n->data.floating);
break;
}
printTree(a->left, print);
printTree(a->right, print);
}
}
答案 1 :(得分:1)
C不支持这种通用数据类型/结构。您可以选择一些选项:
如果你有机会使用Clang作为编译器,那么overload functions in C.就有了语言扩展但你必须将参数强制转换为特定的类型,因此编译器知道哪个函数打电话。
使用C ++
虽然您仍然需要转换参数,但编译器知道他必须调用哪个名为print
的可用函数。
创建一个名为print
的函数,其类似于
struct data_info {
void *data;
enum_describing_type type;
}
print
会切换并调用相应的printInt
,printFloat
等。
答案 2 :(得分:0)
uthash
是头文件的集合,提供类型化哈希表,链表等实现,所有这些都使用C预处理器宏。