[英]Linked list head double pointer passing
我在一些書/教程中看到了這一點。
將頭指針(鏈接列表)傳入函數時,需要將其作為雙指針傳遞。
例如://這是為了反轉頭部指向第一個節點的鏈表。
void nReverse(digit **head)
{
digit *prev=NULL;
digit *curr=*head;
digit *next;
while(curr!=NULL)
{
next=curr->next;
curr->next=prev;
prev=curr;
curr=next;
}
*head=prev;
return;
}
這很好用。
當我使用單指針時,它也有效,
void nReverse(digit *head)
{
digit *prev=NULL;
digit *curr=head;
digit *next;
while(curr!=NULL)
{
next=curr->next;
curr->next=prev;
prev=curr;
curr=next;
}
head=prev;
return;
}
我嘗試使用頭指針打印列表。 這兩個功能都很好。
我錯過了什么嗎?
謝謝,
這是非常類似C的代碼,而不是C ++。
基本上,當按值傳遞某些內容時,該函數會對數據副本進行操作:
void foo(int i)
{
i = 5; // copy is set to 5
}
int x = 7;
foo(x);
// x is still 7
在C中,您改為傳遞指向變量的指針,並可以這樣改變它:
void foo(int* i)
{
*i = 5; // whatever i points to is set to 5
}
int x = 7;
foo(&x);
// x is 5
對你而言,它不是一個int
,而是一個digit*
。 (導致指向指針。)
在C ++中,引入了引用。 引用是另一個對象的別名。 所以你會做這樣的事情:
void foo(int& i) // i is an alias to another value
{
i = 5; // x is set to 5
}
int x = 7;
foo(x); // pass x as alias, not address of x.
// x is 5
引用通常是首選,因為它強制您實際引用對象,並簡化調用和操作代碼。
當然在C ++中你不會自己實現一個列表,你可以使用std::list
。
最后一個head=prev;
上一個head=prev;
不會更改第二個示例中傳遞的指針的值。 對於此功能而言,該行是否必要取決於您自己。 但是有區別。
你是如何測試它“工作正常”的? 您是否能夠迭代列表並打印出節點的值並看到它們實際上已被反轉? 第一個函數(可能稱為nReverse(&list);
更改 list
指向的內容,第二個函數nReverse(&list);
更改 (因此對於第二個函數,您如何知道哪個節點是列表的開頭,畢竟它只是更改了...) 。
在第一個示例中,您傳入的內容仍然指向列表的“開頭”。
在第二個示例中,它指向列表的末尾(這是您開始時的開始,但此后已移動)。
雙重間接的原因是nReverse
可以修改調用者的指針,因為在反轉列表之后,列表的頭部現在是一個不同的節點。
在第二個版本中,您正在修改函數本地的head
副本,因此調用者仍然具有對舊頭節點的引用,現在它是尾部。
雙指針傳遞的原因(第一個例子)是你想要改變列表的頭部。 由於您正在反轉列表,因此在完成反轉后,頭應指向列表的最后一個元素。
digit* list;
// initialize list
nReverse(&list);
// now list is pointing to the last element of the chain (and not the first)
如果你不使用雙指針,那么list仍將指向原來的第一個元素,下一個現在指向NULL,因為它是反轉后的最后一個元素。 所以你放棄了所有其他元素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.