2010-07-22 82 views
3

我在某本書/教程中看到了這個。鏈接列表頭雙指針傳球

當您將頭部指針(鏈接列表)傳入函數時,您需要將它作爲雙指針傳遞。

例如: //這是爲了顛倒頭部指向第一個節點的鏈接列表。

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; 
} 

我嘗試用頭指針打印清單。這兩個功能都正常工作。

我錯過了什麼嗎?

感謝,

+2

順便說一句:如果函數返回'void',則不需要它的最後一行是'return;'。 – 2010-07-22 20:42:14

+2

您可能需要[更好的書](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 – GManNickG 2010-07-22 20:45:24

+0

使用std :: list 。 – Puppy 2010-07-22 20:57:36

回答

4

這是非常類似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

+0

嘿,謝謝。我只是想到了:)而且是的。在同一本書中找到答案:) – JohnH 2010-07-23 01:29:59

2

這最後head=prev;不會在第二個例子中改變傳遞指針的值。該功能對於此功能是否必要取決於您。但是有一個區別。

你是怎麼測試它「工作正常」的?你是否可以迭代列表並打印出節點的值並看到它們實際上已經被顛倒了?第一個函數(大概叫nReverse(&list);更改什麼list指向什麼,第二個不要(第二個你怎麼知道哪個節點是列表的開始,畢竟它只是改變了...)

0

在第一個示例中,您傳入的內容仍指向列表的「開始」。

在第二個示例中,它指向列表的末尾(這是開始時,當你開始,但已經移動)。

0

雙重間接的原因是nReverse可以修改調用者的指針,因爲在反轉列表之後,列表的頭部現在是不同的節點。

在第二個版本中,您正在修改函數本地的head的拷貝,所以調用者仍舊引用舊的頭節點,它現在是尾部。

0

雙指針傳遞的原因(第一個例子)是您想要更改列表的頭部。由於您正在反轉列表,因此在完成反轉後頭部應該指向列表的最後一個元素。

digit* list; 
// initialize list 
nReverse(&list); 
// now list is pointing to the last element of the chain (and not the first) 

如果不使用雙指針,然後列出仍將指向其下一現在指向NULL,因爲它的最後一個元素後,扭轉了原來的第一個元素。所以你放棄了所有其他元素。