2

我在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 调试器检查所有内容。这怎么可能?我无法更改方法签名,因此必须这样做。

4

6 回答 6

6

无法以这种方式将节点指针更改为函数。在函数中,您可以更改指针的内容,而不是指针的地址。要做到这一点,你必须通过你的指针指针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);
于 2012-10-01T13:54:43.810 回答
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;
}
于 2012-10-01T14:00:55.233 回答
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);

现在,您只需更改在列表上工作的所有函数,因此它们的工作方式相同,考虑到“头”仅指向列表的真正第一个节点,而不是列表本身的成员。出于所有实际目的,“真正的”头是头->下一个。

于 2012-10-01T13:57:01.980 回答
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;
}
于 2014-03-06T06:56:00.640 回答
1

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

并且不要忘记;在结构声明之后。

于 2012-10-01T13:54:45.420 回答
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;
}

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

于 2012-10-01T13:52:58.453 回答