繁体   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