为什么在RemoveHead(节点)函数中使用**head(而不是*head)
Why use **head (and not *head) in RemoveHead(node) function?
在书中的大多数解释中,作者坚持使用**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;
}
在您的第一个示例中:
head = temp;
在函数外不执行任何操作,只在函数内设置局部变量head
到temp
。调用方传入的任何变量都将保持不变。作者是正确的,你需要使用指针或(更好的)引用(如果你使用C++)。
好吧。当您想修改函数内部的整数变量时,可以通过引用传递它。也就是说,你传递它的地址。
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
}
作者是对的。**实际上是通过引用传递的(即,您可以更改"head")。
在您的版本(传递值)中,head在调用代码中保持不变。
当传递node*
作为参数时,您可以释放并修改该指针指向的内存地址的内容。但是,从函数外部看不到对指针本身执行的修改,因为指针是按值传递的。
在第二个例子中,由于您将指针传递给头指针,因此您实际上可以修改实际的头指针,而不仅仅是它所指向的内存
因此,在第二个函数中,当执行*head = temp;
时,您正在修改作为参数传递的指针所指向的地址。
因此,作者是对的。
作者是正确的。在第一个示例中,您正在修改head
的本地副本——调用者不会注意到任何更改。head
仍然会被释放,所以你很快就会崩溃。您需要传递一个指针来修改调用者的变量。
相关文章:
- 我们可以在不使用head指针的情况下通过使用head的简单变量而不是head的指针来实现链表吗
- 无法在我的链接列表中插入项目,head始终为NULL
- 结构之外的节点 * head 有什么作用?
- 是 C++ gcc HEAD 10.0.0 20190 相对于好友函数的错误吗?
- 如何递归"print list from tail to head"?
- 在将第一个值插入链表时尝试访问 head 时出现分段错误
- 将元素添加到 Head 的双链表
- 当使用 require 表达式指定和不使用 require 表达式指定 require 子句时,C++ gcc HEAD
- head->next 不为空
- 如何将 HEAD 签出到 libgit2 中的指定引用或标签
- CPtrList->RemoveHead() 如何导致 CInvalidArgumentException?
- 如何从对象中获取对元组尾部的引用 std::tuple<Head,Tail...>
- What is struct NIL { typedef NIL Head; }?
- "ListNode dummy{-1, head};"是什么意思?
- 将链表的头部传递给函数时。为什么我们需要通过引用来传递它,例如在 push(node* &head, int key)
- 对于不存在的对象,Amazon S3 HEAD 请求返回空响应,而不是 404
- 链表错误:语法错误:标识符'head'之前缺少';'
- 为什么在RemoveHead(节点)函数中使用**head(而不是*head)
- 如何在head中的特定节点后插入链表?c++
- 当对head元素使用引用时,C++优先级队列的行为更为恶劣