【问题标题】:Linked lists - single or double pointer to the head链表 - 指向头部的单指针或双指针
【发布时间】:2017-06-27 17:17:13
【问题描述】:

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

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

在创建函数时使用双指针指向头部有什么好处?

【问题讨论】:

  • 我会反对这种设计。最好有一个带有指向第一个和最后一个“节点”的指针的“列表”结构。这使您可以通过传入列表来修改列表,而不是直接使用节点
  • 通常,您可以使用 bool add_dnodeint(dlistint_t **head, int n) 与指向指针参数的指针和非指针返回值(或无返回值 — void),或 dlistint_t *add_nodeint(dlistint_t *head, int n) 与简单指针参数和匹配的指针返回值(用作head = add_nodeint(head, newval);)。您通常不会同时执行这两项操作——使用指向指针参数的指针并返回一个指针值。请注意,const int n 几乎毫无意义,因为n 不是指针。

标签: c linked-list


【解决方案1】:

将指针传递给指向head 的指针的原因是,对指针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;
} 

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-19
        • 2012-08-11
        • 1970-01-01
        • 2013-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多