[英]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.