简体   繁体   English

如何在c或c ++中创建异构链接列表

[英]how to create a heterogeneous link list in c or c++

A link list that can hold float,integer,character,etc data and algorithm should be well and not very complex 一个可以保存浮点数,整数,字符等数据和算法的链接列表应该很好而且不是很复杂

I thought of creating a structure with void pointer that will point to subsequent nodes. 我想到了创建一个带有void指针的结构,它将指向后续节点。 but problem is that i cannot use templates with structure. 但问题是我不能使用带结构的模板。

coming down to c, i have to test each character entered by user to test whether it is integer , float or character or not.then we can proceed further 下到c,我必须测试用户输入的每个字符,以测试它是否是整数,浮点数或字符。然后我们可以进一步

please suggest an efficient algorithm/code 请建议一个有效的算法/代码

If you want to do this yourself you'll basically want to create an array or linked list of elements that encode both the data and the type of data. 如果你想自己做这件事,你基本上想要创建一个数组或链接的元素列表,它们既编码数据又编码数据类型。 You could use a struct that includes a type indicator and a union of the various types that you want to handle, and the create an array or linked list of that struct: 您可以使用包含类型指示符和要处理的各种类型的并集的结构,以及创建该结构的数组或链接列表:

typedef struct {
    int type_indicator;
    union {
        float f;
        int i;
        double d;
        void *p;
        char c;
    }
} generic_item;

generic_item generic_array[10];

I'll leave it to you to come up with an appropriate enumeration for the type indicator and to add a function pointer for your algorithm. 我将留给你为类型指示器提供一个适当的枚举,并为你的算法添加一个函数指针。 If you want a linked list instead of an array, you'll obviously also need to add a generic_item *next pointer. 如果你想要一个链表而不是一个数组,你显然还需要添加一个generic_item *next指针。

I haven't looked into the boost options that other answers link to, but I'd probably look there first before trying to roll my own solution. 我没有查看其他答案链接到的提升选项,但在尝试推出自己的解决方案之前,我可能会先查看。

Using boost::variant or boost::any . 使用boost :: variantboost :: any Depends on your needs. 取决于您的需求。

NOTE: This is a purely C answer. 注意:这是纯粹的C答案。

This data structure is what I would start out with: 我将从这个数据结构开始:

typedef struct heterogeneous_list
{
    enum { CHAR, STRING, FLOAT, INT } type;
    void *item;
    struct heterogeneous_list *next;
}

When I got the item from the user, I would store it in the list (assuming current points to the end of the list): 当我从用户那里获得该项目时,我会将其存储在列表中(假设当前点位于列表的末尾):

current->next = malloc(sizeof(heterogeneous_list));
case (/* whether the user entered a char, string, float, or int */
{
    case /* char */:
        current->next.item = malloc(sizeof(char));
        current->next.type = CHAR;
        current->next.next = NULL;
        break;
/* and so forth, for string, int, and float */
}
current = current->next;

When iterating through the list, it is easy now to process what is in the list based on type. 在遍历列表时,现在可以很容易地根据类型处理列表中的内容。 The following code assumes current is the current item in the list being looked at in an iteration (a for-loop going through the list): 以下代码假定current是迭代中查看的列表中的当前项(遍历列表的for循环):

char currentItemChar;
char * currentItemString;
float currentItemFloat;
int currentItemInt;

case (current->type)
{
    case CHAR:
        currentItemChar = *((char*) current->item);
        // process a character
        break;
    case STRING:
        currentItemString = (char*) current->item;
        // process a string
        break;
    case FLOAT: 
        currentItemFloat = *((float*) current->item);
        // process a float
        break;
    .
    .
    .
};

That's what I would do. 这就是我要做的。

http://www.boost.org/doc/libs/1_48_0/doc/html/variant.html http://www.boost.org/doc/libs/1_48_0/doc/html/variant.html

(which of course also mentions C/C++ unions before explaining what boost variants give you over this) (当然,在解释推动变体给你的东西之前,还提到了C / C ++联盟)

A heterogeneous linked list can be created by using a void * as a pointer to a data item: 可以使用void *作为指向数据项的指针来创建异构链表:

struct Node
{
    Node * previous;
    Node * next;
    void * p_data;
};

Before implementing a heterogenous container, one might ask if the design can be changed to use homegeneous containers instead. 在实现异构容器之前,可能会询问是否可以将设计更改为使用homegeneous容器。

You could do this kind of things using - as you mentioned - some void pointers in connection with some more or less tricky macros. 可以使用 - 正如你所提到的那样 - 使用一些或多或少棘手的宏来处理这些事情。

You could define a struct (or a class) containing three pointers: next, prev (for the next and the previous list element), and some kind of void* data . 您可以定义包含三个指针的结构(或类):next,prev(对于下一个和上一个list元素),以及某种void* data You could moreover store the type for each list entry (which could be realized by an enum or something equivalent). 此外,您还可以存储每个列表条目的类型(可以通过enum或类似的东西来实现)。

Moreover, you could define a macro that - given a list item - retrieves the data and automatically cast it into a given type: 此外,您可以定义一个宏 - 给定一个列表项 - 检索数据并自动将其转换为给定类型:

#define get_list_item(item, type) *(type*)(((item)->data))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM