【问题标题】:Linked List, pointer manipulation链表,指针操作
【发布时间】:2013-02-18 07:47:06
【问题描述】:

我在head_insert 的代码下方附加了在链表头部插入一个新节点。该函数以head_insert(head) 调用。

我不确定函数的第一个参数的语法,我期待的是NodePtr,因为它已经是一个指针,见下文。

为什么代码使用 NodePtr &head 而不是 NodePtr head 只是因为 head 已经是一个指针?

void head_insert(NodePtr & head, int the_number)
{
  NodePtr temp_ptr;
  temp_ptr=new Node;
  temp_ptr->data=the_number;
  temp_ptr->link=head;
  head=temp_ptr;
}


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

typedef Node* NodePtr;

【问题讨论】:

  • 为什么代码只使用“NodePtr &head”而不是“NodePtr head”,因为 head 已经是一个指针?
  • 不要同时使用 [c] 和 [c++] 标记问题。虽然 C++ 理解 C 代码,但在 C 中被认为是好的风格在 C++ 中很少是好的风格。
  • @saraMcKnight:那应该是编辑,而不是评论。
  • 但是即使你通过每个值,head 也会改变,因为 head 持有头节点的地址
  • 我已经编辑了我的问题

标签: c++ pointers


【解决方案1】:

为什么代码只使用“NodePtr &head”而不是“NodePtr head”,因为 head 已经是一个指针?

原因是它需要函数对head 所做的任何更改才能对调用者可见。

如果 head 是通过值 (NodePtr head) 而不是通过引用 (NodePtr& head) 传递的,则不会出现这种情况:当函数将 temp_ptr 分配给 head 时,此更改将不会t 传播回调用者。通过引用传递head 解决了这个问题。

【讨论】:

  • 但是即使你通过每个值,head 也会改变,因为 head 持有头节点的地址
【解决方案2】:

您的 typedef 乍一看有点令人困惑。在 C 中,您应该传递一个 struct Node ** head 参数并将其值分配给新创建的节点:*head = temp_ptr;。这是它的样子:

void head_insert(struct Node **head, int the number)
{
    struct Node *new_head = NULL;
    // Alloc memory for new_head, etc..
    new_head->data = the_number;
    new_head->link = *head;
    *head = new_head;
}

因此,要分配*head = new_head,您需要有一个指向列表头的指针,该指针也是一个指针。否则,在函数中执行的更新将保持在本地。在您的代码中,您引用了一个指针,这与传递“双”指针的效果相同。

【讨论】:

  • 但如果我改用 head_insert(struct Node *head,...)
  • 如果你这样做了,head = new_head 不会影响函数外的head
  • 您似乎不知道堆栈行为。你应该看看这个 SO 问题:stackoverflow.com/questions/79923/…
  • 简而言之,函数参数的内存在 stack 上,这使得它们 LOCAL 到函数调用。也就是说,如果您修改 struct Node *head 参数指向的地址,它将修改相应堆栈区域上的值,该值仅与 current 函数调用有关。因此,当您退出该函数时,您将丢失分配。因此需要struct Node **head(或C++ 参考)。
  • 谢谢 Rerito...我现在明白了。您推荐的任何好教科书以供进一步阅读
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-10
相关资源
最近更新 更多