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
    标记,因为这是您将要使用的。第二种方法实际上不可能,因为我已经提到,我们无法判断数据的大小。关于第一个,我真的不明白。请您详细说明第二种方法是不可能的,因为我已经提到,我们不能说出数据的大小。关于第一个,我真的不明白。你能详细说明一下吗