二级指针操作链表技巧

问题源于我在知乎刷到的一个回答: 能分享你C指针用得最灵活(飘)的一次吗?

文中提到了Linus关于无头节点单项链表的删除操作给出的一种新的思路, 我觉得对理解指针非常有帮助, 所以在这里详细描述一下这件事.

从我学习数据结构起, 对不含头节点的单向链表的删除操作, 做法常是: 借用pre指针搜索. 这种情况下避免不了对于链表中第一个节点的特判(第一个节点没有pre).

Linus提到了一种借助二级指针避免该分支的方法.

void remove_if(node ** head, remove_fn rm)
{
    for (node** curr = head; *curr; )
    {
        node * entry = *curr;
        if (rm(entry))
        {
            *curr = entry->next;
            free(entry);
        }
        else
            curr = &entry->next;
    }
}

指针的内容就是地址, int *p = a 也就意味着变量p 中保存着变量a的地址. 所以参数head在内存中的含义为:

list的内存布局

假如要删除node2, 那么改变*curr实际上就是改了node1的next成员.


创建于: 2022-11-20T23:40:30, Lastmod: 2023-09-24T18:08:59