2010-07-22 138 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,因为它的最后一个元素后,扭转了原来的第一个元素。所以你放弃了所有其他元素。