C中具有运行时数据类型的通用队列
我想创建一个链表,它可以在运行时接受任何数据类型并显示该列表。问题在于不同数据类型的显示功能和内存管理的变化。所以我不知道怎么做。代码示例将不胜感激 编辑:缩小问题范围。这是队列结构(使用链表) 现在添加新元素和显示的调用函数如下:C中具有运行时数据类型的通用队列,c,function-pointers,singly-linked-list,vtable,C,Function Pointers,Singly Linked List,Vtable,我想创建一个链表,它可以在运行时接受任何数据类型并显示该列表。问题在于不同数据类型的显示功能和内存管理的变化。所以我不知道怎么做。代码示例将不胜感激 编辑:缩小问题范围。这是队列结构(使用链表) 现在添加新元素和显示的调用函数如下: int main() { struct queue* q; void *a; char ch; printf("do you want to add an element?(y/n)\n"); scanf("%c",&
int main()
{
struct queue* q;
void *a;
char ch;
printf("do you want to add an element?(y/n)\n");
scanf("%c",&ch);
while(ch!=n)
{
printf("Enter the element\n");
scanf("%p",a);
enqueue(q,a);
display(q);
}
return 0;
}
以下是我的排队函数定义:
void enqueue(struct queue* queue,void* item)
{
if(queue->logical_length==queue->cnt_max)
{
printf("Queue is full\n");
return;
}
else
{
struct node*temp;
temp=(struct node*)malloc(sizeof(struct node));
temp->data=malloc(queue->data_size);
temp->link=NULL;
memcpy(temp->data,item,queue->data_size);
if(queue->front==NULL)
{
queue->rear=queue->front=temp;
queue->logical_length=queue->logical_length+1;
return;
}
queue->rear->link=temp;
queue->rear=temp;
queue->logical_length=queue->logical_length+1;
}
}
这里的问题是,如果我甚至不知道数据类型,如何为数据字段分配内存。所以,若有某种方法可以找到运行时输入值的数据类型,那个就更好了
以下是我的显示功能:
void display(struct queue* queue)
{
struct node* temp;
if(queue->front==NULL)
{
printf("Queue is empty\n");
return;
}
else
{
temp=queue->front;
while(temp->link!=NULL)
{
printf("%p \t",*(void *)temp->data);
temp=temp->link;
}
printf("%p \t",*(void *)temp->data);
}
}
这里的输出总是一些随机数。您可以用两种方法之一存储数据
insert
的函数将存储控制权移交给队列;extract函数将控制权返回给调用代码。这意味着队列不需要知道指向的数据量insert
函数数据块的大小及其存储位置(void enqueue(struct queue*queue,void*item,size\u t length)
)。但是,这意味着您只能安全复制数据结构(使用memmove()
或等效工具)。许多结构不能像那样复制(想想包含指针的结构)display()
函数更改为apply()
函数,该函数具有一个函数指针:
void apply(struct queue *queue, void *data, void (*function)(const void *item, void *data));
遍历
队列
,使用队列中的当前项和传递给apply
函数的数据调用函数。此数据是指向使函数正常工作所需的任何上下文的指针。对于显示,它可能是一个文件*
,也可能是一个更复杂的结构。无论哪种方式,函数(由函数指针指向)都知道如何处理数据,因为它与数据类型一致。您可以通过两种方式之一存储数据
insert
的函数将存储控制权移交给队列;extract函数将控制权返回给调用代码。这意味着队列不需要知道指向的数据量insert
函数数据块的大小及其存储位置(void enqueue(struct queue*queue,void*item,size\u t length)
)。但是,这意味着您只能安全复制数据结构(使用memmove()
或等效工具)。许多结构不能像那样复制(想想包含指针的结构)display()
函数更改为apply()
函数,该函数具有一个函数指针:
void apply(struct queue *queue, void *data, void (*function)(const void *item, void *data));
遍历
队列
,使用队列中的当前项和传递给apply
函数的数据调用函数。此数据是指向使函数正常工作所需的任何上下文的指针。对于显示,它可能是一个文件*
,也可能是一个更复杂的结构。无论哪种方式,函数(由函数指针指向)都知道如何处理数据,因为它与数据类型相协调。您应该考虑并告诉我们更多关于您尝试执行的操作,并可能设置一些限制。在一般的情况下,你所说的听起来像是需要在C的顶部实现一些/全部C++(当然可以做到,毕竟这是Bjarne第一次做的,但是这是一些工作!)C是一个“强类型”的语言。尽管有办法克服它,但C语言适合你吗?FWIW:linux内核有一些通用LLs,由一组宏实现。使用void*
作为数据保存。显示函数需要用户函数来执行void*
。我添加了函数指针
和vtable
标记,因为这是您将要使用的。您应该考虑一下,并告诉我们,关于您尝试执行的操作,可能会设置一些限制。在一般的情况下,你所说的听起来像是需要在C的顶部实现一些/全部C++(当然可以做到,毕竟这是Bjarne第一次做的,但是这是一些工作!)C是一个“强类型”的语言。尽管有办法克服它,但C语言适合你吗?FWIW:linux内核有一些通用LLs,由一组宏实现。使用void*
作为数据保存。显示函数需要用户函数来执行void*
。我添加了函数指针
和vtable
标记,因为这是您将要使用的。第二种方法实际上不可能,因为我已经提到,我们无法判断数据的大小。关于第一个,我真的不明白。请您详细说明第二种方法是不可能的,因为我已经提到,我们不能说出数据的大小。关于第一个,我真的不明白。你能详细说明一下吗