【问题标题】:Passing a linked list head through a function as address in C通过函数传递链表头作为C中的地址
【发布时间】:2015-11-23 19:58:48
【问题描述】:

我有一个关于通过函数传递 C 中链表的头部的问题。所以代码是这样的:

#include <stdio.h>
//Defining a structure of the node
struct node { 
    int data;
    struct node* next;
    };

void insert (struct node* rec, int x) {
    struct node* temp = (struct node*)malloc(sizeof(struct node));
    temp->data = x;
    temp->next = NULL;
    rec = temp; // head and rec is now pointing to the same node
}

void print(struct node* rec){
    printf("%d", rec->data); //error occurs here
    puts("");
}

main(){
    struct node *head = NULL; //head is currently pointing to NULL
    insert (head, 5); //Passing the head pointer and integer 5 to insert()
    print(head);
}

如您所见,当我尝试打印 rec->data 时发生错误。为什么会发生错误?我想既然指针rec和head都指向堆中的同一个节点,应该不会有什么问题吧?

谢谢。

【问题讨论】:

  • 你需要通过struct node**来插入,比如insert(&amp;head...。否则 head 不会改变,因为函数只接收其值的副本。
  • 你可以通过重新定义insert函数的参数来通过指针指向列表的头部
  • 另外,您可能需要temp-&gt;next = *rec(假设您传递了一个双指针),否则您将丢失列表的其余部分。
  • C 中没有引用。

标签: c pointers linked-list pass-by-reference


【解决方案1】:

您可以按照@sje397 的建议传递struct node**

但是,我建议采用以下设计(我认为这也更容易推理):

/* returns the new head of the list */
struct node *insert (struct node* current_head, int x) {
    struct node* temp = (struct node*)malloc(sizeof(struct node));
    temp->data = x;
    temp->next = current_head;
    return temp;
}

并像使用它

head = insert(head, 5);

在这种情况下,我还会将函数重命名为 push_front

为了完整起见,我认为@sje397 的含义类似于以下内容(典型的链表代码被每个 C 程序员一次又一次地重写......):

void insert(struct node **head, int x) {
    struct node* new_head = (struct node*)malloc(sizeof(struct node));
    new_head->data = x;
    new_head->next = *head;

    *head = new_head;
}

【讨论】:

  • 我明白了...@sje397 nimrodm 非常感谢您的帮助!这个指向指针的东西每次都让我感到困惑。
【解决方案2】:

在 C 中没有通过引用传递。
您的 insert 函数不是在列表中插入节点,它只是更改 head 指向的节点。由于temp-&gt;next = NULL,列表将始终包含两个节点。

另一个错误是您只是在修改头节点的本地副本。 要解决此问题,您有 3 个选择:

-可以让头节点全局化

-可以将指向头节点的指针(指向指针的指针)传递给函数。

-可以通过函数返回修改后的头节点。

【讨论】:

    【解决方案3】:

    insert 函数重新定义为:

    void insert (struct node** rec, int x) {
        struct node* temp = (struct node*)malloc(sizeof(struct node));
        temp->data = x;
        temp->next = NULL;
        *rec = temp; // head and rec is now pointing to the same node
    }
    

    【讨论】:

    • 修复了上面提到的错误,但它不是插入函数。
    • 调用这个函数会给你指向NULL的节点。因此,如果您考虑链接列表的结构,它并没有真正提供插入功能。您需要修改rec,使新节点指向它,反之亦然。
    猜你喜欢
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 2022-11-26
    相关资源
    最近更新 更多