修改链表中的头指针



我很难理解这段代码。我真正需要做的就是修改头指针,让它指向第一个元素。那么为什么头脑不起作用呢?改变*头的值改变这个指针指向的地方,这应该工作,对吧?我已经按引用/按值传递过了,但我觉得很难理解。有人能帮我澄清一下吗?谢谢你的帮助。谢谢。

在C/c++中,指针误用更容易出错。考虑以下C/c++代码,用于在列表前面插入一个元素:

bool insertInFront( IntElement *head, int data ){
  IntElement *newElem = new IntElement;
  if( !newElem ) return false;
  newElem->data = data;
  head = newElem; // Incorrect!
  return true;
}

前面的代码是不正确的,因为它只更新了头指针的本地副本。正确的版本传递一个指向头指针的指针:

bool insertInFront( IntElement **head, int data ){
  IntElement *newElem = new IntElement;
  if( !newElem ) return false;
  newElen->data = data;
  *head = newElem; // Correctly updates head
  return true;
}

你需要帮助来理解它们的区别,对吗?

想象第一种情况下函数的调用者:

IntElement *head;
int data;
...
insertInFront (head, data);

现在,在这种情况下,由head指向的地址被放在堆栈上,并作为参数传递给insertInFront。当insertInFront执行head = newElement;只有实参(在堆栈上)被修改。

在第二种情况下,调用者将是:
IntElement *head;
int data;
...
insertInFront (&head, data);

在这种情况下,head的地址被放在堆栈上,并作为参数传递给insertInFront。当您执行*head = newElement时,传入的address将被取消引用,以获得原始列表头的地址,并对其进行修改。

当你了解指针是什么时,它是相当简单的。在第一个代码IntElement *head中,head是指向链表的现有头部的指针。所以调用者传递的是列表头元素的地址。在insert-in-front函数中改变head的值不会改变调用者的任何东西。该地址的值被传递给你的函数——而不是在调用者那里保留该地址的东西。

你需要传递你的函数'头的地址的地址' -或IntElement **head。这将允许此函数修改调用者持有的地址-即更新链表以指向新的头部。

你不想改变head指向的值,你想改变存储在head本身的指针,所以不要使用*head,使用指向head本身的指针。Head的类型是IntElement *,所以参数应该是指向IntElement **

的指针。

当你在某个地方有一个值T x并且你想让其他函数修改它时,你传递一个指向x的指针:

T x;             // set to some value
modify_me(&x);   // will change x
/* ... */
void modify_me(T * x)
{
  *x = new_value;
}

现在将此机制应用于T = IntElement*。要修改的值本身就是指针!

(也许使用typedef会使事情看起来不那么混乱:typedef IntElement * NodePtr; .)

还要注意,你的链表是坏的,因为你从来没有设置新元素的"next"指针指向旧的头,同样,如果列表是双链接的,"previous"指针也指向旧的头。

相关内容

  • 没有找到相关文章

最新更新