Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C将节点添加到链表的头部_C_Linked List_Nodes_Head - Fatal编程技术网

C将节点添加到链表的头部

C将节点添加到链表的头部,c,linked-list,nodes,head,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->

我已经在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和所有内容),然后调用这个方法,它会在这个方法中添加新的节点,但是当我回到主列表时,我的旧列表保持不变。使用DDD调试器检查所有内容。这怎么可能?我无法更改方法签名,因此必须这样做

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
,则传递指向列表第一个节点的指针。现在,您可以将其更改为指向列表中新的第一个节点。

节点指针不能以这种方式更改为函数。在函数中,您可以更改指针的内容,而不是指针的地址。您是否必须传递指针的指针
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;
}
在你的cod中,你可以在调用这个函数后得到head

head = addfirst(head,45);

一切正常,但在
void addFirst(struct node*list,int value)
函数中,
list
按值传递。这意味着正在复制指针,
addFirst
函数的调用者看不到在
addFirst
函数中为指针分配的新地址。要解决此问题,您必须逐个指针传递指针(
struct node**
),或者将其作为返回值,并要求调用方将其用作新的“头”


别忘了
在结构声明之后。

在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);
调用该函数时,您可以这样调用它:

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);

现在,如果你想保留函数的签名,一种可能是改变你考虑头部节点的方式。如果您声明头部节点仅用于保存指向第一个值的指针,但其本身不包含值,则可以执行以下操作:

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);

现在,您只有在列表中工作的所有函数要更改,所以它们工作相同,要考虑“头”只指向列表的实际第一个节点,而不是列表本身的成员。“真正”的头实际上是头->下一步。

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

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;
}

我已经学会了@Vlad Lazarenko answer,我编写了这样的代码,对吗

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;
}

我知道可以这样做(节点**作为参数),但是没有一种方法可以像我写的那样做吗(必须有一种方法,因为在我旁边的电脑上,这个可以工作~X(:()()()()(当然?!?它不能。excpet:您有一个全局变量“head”,它用作链接列表的头,并由addFirst()调用设置。但这将非常难看。+1表示返回新头地址的建议非常难看,不可维护。(比如将一个“child”变量称为“parent”;或者用“last”而不是“next”指针构建一个链表)我从来没有说过它很漂亮。我不会这样做。但它回答了OPs的问题。