带功能的更新列表(不带返回值)

时间:2013-11-22 16:57:41

标签: c list

我有一个这样的清单:

typedef struct list {
     char *key;
     char *value;
     struct list *next;
} List;

在我的主要功能中使用它:

main(int argc, char *argv[]) {
    List *list;
    list = malloc(sizeof(struct list));

    list = insertToList("key", "value", list);
}

insertToList是:

List insertToList(char *key, char *value, List *list) {
    List *newNode = malloc(sizeof(struct list));
    newNode->key = malloc(strlen(key));
    strcpy(newNode->key, key);

    newNode->value = malloc(strlen(value));
    strcpy(newNode->value, value);
    newNode->next = list;
    list = newNode;

    return list;
}

这可以按预期工作,但我想通过使用指针来修改列表,这样我就不必返回列表了。我试图将& list作为参数传递给insertToList,然后用** list接收它,但是这不起作用。我该怎么做?

2 个答案:

答案 0 :(得分:0)

基本上需要的是指向指针的指针:List**

void insertToList(char *key, char *value, List** list) {
    List *newNode = malloc(sizeof(List));
    newNode->key = malloc(strlen(key));
    strcpy(newNode->key, key);

    newNode->value = malloc(strlen(value));
    strcpy(newNode->value, value);
    newNode->next = *list;
    *list = newNode;
}

List重命名为ListNode以获得更清晰

另一种方法是定义一个额外的结构List来包装'头指针'(ListNode*)。此结构可能包含其他值,例如当前列表大小。

typedef struct ListNode
{
    char *key;
    char *value;
    struct ListNode *next;
} ListNode;

typedef struct List
{
    struct ListNode* head;
} List;

void insertAtFront(char *key, char *value, List* list)
{
    ListNode *newNode = malloc(sizeof(List));
    newNode->key = malloc(strlen(key));
    strcpy(newNode->key, key);

    newNode->value = malloc(strlen(value));
    strcpy(newNode->value, value);
    newNode->next = list->head;
    list->head = newNode;
}

void insertBefore(char *key, char *value, ListNode** listNode)
{
    ListNode* newNode = malloc(sizeof(List));
    newNode->key = malloc(strlen(key));
    strcpy(newNode->key, key);

    newNode->value = malloc(strlen(value));
    strcpy(newNode->value, value);
    newNode->next = *listNode;
    *listNode = newNode;
}

答案 1 :(得分:0)

您首次考虑使用List **可能是最好的,但这可能会有用。列表中的最后一个节点不包含任何数据,因为您在main中对其进行了malloc,并且没有填充它。您可以在第一个之后插入所有新节点,然后您不需要返回列表指针,因为它没有更改。因此,在insertToList中,您可以使用以下命令插入newNode:

newNode->next = list->next;
list->next = newNode;

这样做的缺点是你的第一个节点是浪费的空间,但是你拥有它的方式,最后一个节点无论如何都浪费了空间,我们只是移动它。