C将节点添加到链表头部

时间:2012-10-01 13:51:07

标签: c linked-list nodes head

我在c

中创建了一个链表结构
struct node{
   int value;
   struct node* next;
};

在列表开头添加节点的方法:

void addFirst(struct node *list, int value){
    struct node *new_node = (struct node*) malloc (sizeof (struct node));
    new_node->value = value;
    new_node->next = list;
    list = new_node;
   }

我创建了一个列表(malloc和所有东西),然后调用这个方法,它在方法中添加了新节点但是当我回到我的main时,我的旧列表保持不变。使用DDD调试器检查所有内容。这怎么可能?我无法更改方法签名,所以必须这样做。

6 个答案:

答案 0 :(得分:5)

节点指针无法以这种方式更改为函数。在函数中,您可以更改指针的内容而不是指针的地址。要做到这一点,你必须传递指针struct node **list

的指针

此后如何做到:

void addFirst(struct node **list, int value){
    struct node *new_node = (struct node*) malloc (sizeof (struct node));
    new_node->value = value;
    new_node->next = *list;
    *list = new_node;
}

或者你可以这样做

struct node * addFirst(struct node *list, int value){
    struct node *new_node = (struct node*) malloc (sizeof (struct node));
    new_node->value = value;
    new_node->next = list;
    return new_node;
}

并且在你的鳕鱼中,你可以在调用这个函数后获得头部

head = addfirst(head,45);

答案 1 :(得分:5)

如果你真的需要这样做,你必须重新投射指针。像这样:

struct node *my_list = null;
addFirst((struct node *)&my_list, 123);

void addFirst(struct node *list, int value){
    struct node **real_list = (struct node **)list;
    struct node *new_node = (struct node*) malloc (sizeof (struct node));
    new_node->value = value;
    new_node->next = *real_list;
    *real_list = new_node;
}

答案 2 :(得分:3)

在C中,如果希望函数能够更改其参数中接收的值,则需要传递该值的地址。因此,要更改列表指针的值,您需要传递列表指针的地址。你的addFirst()函数应如下所示:

void addFirst(struct node **list, int value){
     struct node *new_node = (struct node*) malloc (sizeof (struct node));
     new_node->value = value;
     new_node->next = *list;
     *list = new_node;
}

在调用该函数时,您可以这样称呼它:

addFirst(&list, value);

现在,如果你想保留函数的签名,可能会改变你考虑头节点的方式。如果你声明你的头节点只是为了保存指向第一个值的指针,但是它本身不包含一个值,你可以这样做:

struct node *head;

void addFirst(struct node *list, int value){
     struct node *new_node = (struct node*) malloc (sizeof (struct node));
     new_node->value = value;
     new_node->next = list->next;
     list->next = new_node;
}

addFirst(head, 45);

现在,您只需更改列表中的所有功能,以便它们工作相同,以便考虑“head”仅指向列表的真实第一个节点但不是列表的成员本身。出于所有实际目的,“真正的”头部是头部 - 接下来的。

答案 3 :(得分:2)

我已经学会了@Vlad Lazarenko的答案,我就这样制作了代码,是不是?

addFirst((struct node**)head,123);

void addFirst(struct node **list,int value)
{
    struct node *new_node=malloc(sizeof(struct node));
    new_node->value=value;
    new_node->next=*list;
    list=&new_node;
}

答案 4 :(得分:1)

void addFirst(struct node **list, int value){
    struct node *new_node = (struct node*) malloc (sizeof (struct node));
    new_node->value = value;
    new_node->next = *list;
    *list = new_node;
}

这是正确的代码。问题是你传递的poineter struct node *list不能改变,因为它是一个堆栈变量。如果将其更改为struct node **list,则表示您正在将指针传递给列表的第一个节点。现在您可以将其更改为指向列表的新第一个节点。

答案 5 :(得分:1)

一切都很好,但在void addFirst(struct node *list, int value)函数中,list按值传递。这意味着正在复制指针,并且addFirst函数内的该指针的新地址的分配对于addFirst的调用者是不可见的。要解决此问题,您必须通过指针(struct node **)传递指针或使其成为返回值,并要求调用者将其用作新的“头”。

在结构声明后不要忘记;