使用指针指向什么点?
我在网站上找到了这个代码,用于在列表的开头插入一个节点到链表中。使用指针指向什么点?
void push(struct Node** head_ref, int new_data)
{
/* 1. allocate node */
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
/* 2. put in the data */
new_node->data = new_data;
/* 3. Make next of new node as head */
new_node->next = (*head_ref);
/* 4. move the head to point to the new node */
(*head_ref) = new_node;
}
这是呼叫 -
push(&head, 7);
功能我的问题是,为什么通过传递地址的指针,然后随后在函数内部的地址提取的值走很长的路要走。 为什么我们不能简单地传递在函数指针head
后来作出这样的分配 -
new_node->next=head_ref;
?
如果通过head
而不是&head
,行
(*head_ref) = new_node;
将不得不改为
head_ref = new_node;
然而,这将是该函数的局部变化。它不会改变调用函数中的head
的值。有两个问题:
- 调用函数将永远不会得到一个工作列表。
- 函数中分配的内存将是内存泄漏。
这解释了它!谢谢! – Vaibhav
@Vaibhav,很高兴我能够帮助。 –
调用程序中的变量头是一个指向列表头部的指针。你需要一个指向这个变量的指针,以便在push()中更新它。所以你将一个指针传递给一个包含指针的变量,以便你可以更新该变量。
你也可以写代码如下:
struct Node* push(struct Node* head_ref, int new_data)
{
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = head_ref;
return new_node;
}
,并调用它,如下所示:
head = push(head, 7);
它实现了完全一样的东西,即在头插入一个新节点然后将head
更新为指向该新节点。但在我看来,这不会是一个好的解决方案,因为它允许push()函数的调用者忘记将返回的值分配给head
,此时您将拥有孤立节点并最终导致内存泄漏。
这不一定是更糟糕的解决方案,它只是增加了要求分配回报。通过将指针传递给指向类型...的指针,您可以拥有两全其美的优点(例如,可以灵活地执行)...返回指向添加的当前节点的指针(用于分配或立即使用)。只要你正确地更新列表引用':'',那么'技术上'不会比另一个'更正确' –
这一切都与您选择的编程风格有关。使用一组函数来操作列表会使程序在结构上合理。这样你可以使它更具可读性。如果您需要从多个位置操作相同的列表或操作多个列表,它也将避免剪切-n粘贴。
你组织你的功能的方式取决于你。我个人喜欢你的例子。在这种情况下,你只需要在参数中指定一个指向头部的指针。如果从函数返回它,则在程序中使用错误指针的风险更高。
'C'有足够的工具来编写任何类型的程序。但是有时你需要遵循特定的规则来应用它们,比如你的案例中的指针地址。不是很方便,但可靠,并证明可行。作为'C'程序员,你会很快习惯它。
你也可以看看有更好的工具,使这更方便的c + +。
[Jagged array](https://en.wikipedia.org/wiki/Jagged_array) –
因为该函数也改变了'head_ref'的值。由于'head'有指针类型,所以你需要传递'push'的指针指针来更新'head'的值。 –
阅读[this](https://*.com/a/897400/971127) – BLUEPIXY