簡體   English   中英

鏈表頭雙指針傳遞

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

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