为什么在RemoveHead(节点)函数中使用** head(而不是* head)?

时间:2012-03-17 23:12:12

标签: c++ c linked-list

在本书的大多数解释中,作者坚持使用**列表传递而不是* list,但是根据我的理解,我觉得* list中没有任何错误。如果我错了,请有人详细解释我。例如,要删除链接列表的头部,作者说下面的代码是错误的。

void RemoveHead(node *head)
{
   node *temp = head-> next; /* line 1 */
   free(head);
   head = temp;
}

相反,他说必须使用以下代码

void RemoveHead(node **head)
{
   node *temp = (*head)-> next;
   free(*head);
   *head = temp;
}

5 个答案:

答案 0 :(得分:8)

在你的第一个例子中:

head = temp;

在函数外部没有任何内容,它只在函数内部将局部变量head设置为temp。无论调用者传入什么变量都将保持不变。作者是正确的,您需要使用指针或(更好的)引用(如果您使用的是C ++)。

答案 1 :(得分:3)

当传递node*作为参数时,您可以释放并修改该指针指向的内存地址的内容。但是,从函数外部看不到对指针本身执行的修改,因为指针是通过值传递的。

在第二个例子中,由于你传递了指向头指针的指针,你实际上可以修改实际的头指针,而不仅仅是它指向的内存。

因此,在第二个函数中,当执行*head = temp;时,您正在修改指针作为参数指向的地址。

因此,作者是对的。

答案 2 :(得分:3)

作者是对的。 **实际上是通过引用传递的(即你可以改变'head')。

在你的版本中(按值传递),head在调用代码中保持不变。

答案 3 :(得分:3)

好。如果要修改函数内的整数变量,可以通过引用传递它。也就是说,你传递了它的地址。

int x = 5;

void modify_value (int* x)
{
    (*x) = 7; // is not 5 anymore
}

指针是一样的。如果要修改指针。你必须通过引用传递它。也就是说,你必须传递它的地址。这是指向指针的指针。

int* ptr_x = &x;

void modify_pointer (int** ptr_x)
{
    *ptr_x = NULL; // is not &x anymore
}

答案 4 :(得分:2)

作者是对的。在您的第一个示例中,您正在修改head的本地副本 - 来电者不会注意到任何内容已发生变化。 head仍然会被释放,因此您可以在相当短的时间内完成崩溃。您需要传递一个指针来修改调用者的变量。