链接列表 - 指向头部的单指针或双指针

时间:2017-06-27 17:17:13

标签: c linked-list

我们获得了一个任务和一个链表结构:

typedef struct dlistint_s
{
    int n;
    struct dlistint_s *prev;
    struct dlistint_s *next;
} dlistint_t; 

以及以下原型的功能:

dlistint_t *add_dnodeint(dlistint_t **head, const int n);

在创建函数时,有什么优势以及为什么会使用双指针指向头部?

3 个答案:

答案 0 :(得分:6)

将指针传递给指向head的指针的原因是,在调用函数中将看到对指针head的任何修改,并且您不必从函数返回头部。

例如,请考虑这个简单的节点:

struct Node{
    int data;
    struct Node *next;
};

将节点添加到前面列表中的功能

struct Node *add_node (struct Node *list, int n){
    struct Node *new_node = malloc(sizeof(struct Node));
    if(new_node == NULL){
        printf("Memory allocation failed\n");
        exit(EXIT_FAILURE);
    }
    new_node->data = n;
    new_node->next = list;
    return new_node;
}

如果我们需要将new_node分配给list而不是返回它,那么我们需要修改上面的函数并删除return语句并发表声明

list = new_node;

但是,不起作用!
这是因为在C中,与所有参数一样,指针是按值传递的。 这意味着list包含传递给add_node函数的指针值的副本,而不是传递给此函数本身的指针。
这就是我们需要指向指针的地方。

void add_node (struct Node **list, int n){
    struct Node *new_node = malloc(sizeof(struct Node));
    if(new_node == NULL){
        printf("Memory allocation failed\n");
        exit(EXIT_FAILURE);
    }
    new_node->data = n;
    new_node->next = *list;
    *list = new_node;
} 

答案 1 :(得分:2)

如果使用双指针,则可以传入头部的地址,以便您的函数可以修改实际指针。这样你就不需要返回新头了。

答案 2 :(得分:0)

因为如果您使用dlistint_t *head变量而不是在函数参数中使用dlistint_t **head变量,那么函数head中变量dlistint_t *add_dnodeint(dlistint_t **head, const int n);中所做的更改将是此方法的本地变量。由于您使用的是Node*,因此变量head中的更改对于该函数是本地的。如果你想在函数调用之后反映这些变化(你显然想要),那么使用dlistint_t **head