簡體   English   中英

修改鏈表中的頭指針

[英]Modifying head pointer in a linked list

我無法理解這段代碼。 我真正需要的是將頭指針修改為指向第一個元素。 那么為什么不開始工作呢? 更改*指針指向的頭部更改的值,這應該有效,對吧? 我已經通過引用/傳遞值讀取了傳遞,但我發現很難理解。 有人可以幫忙解釋一下嗎? 感謝您的幫助。 謝謝。

在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時,將取消引用此傳入的地址以獲取原始列表頭的地址,並進行修改。

當你了解指針是什么時,它相當簡單。 在第一個代碼IntElement *head ,head是指向鏈表的現有頭部的指針。 所以調用者傳入列表的head元素的地址。 更改前插入功能中的head值不會在調用者處更改ANYTHING。 該地址的值傳遞給您的函數 - 而不是將該地址保留在調用者處。

你需要傳遞你的函數'頭部地址'或IntElement **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;

另請注意,您的鏈接列表已被破壞,因為您從未將新元素的“下一個”指針設置為指向舊頭,如果列表是雙向鏈接,則類似於“上一個”指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM