You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用指针的指针删除链表节点:代码语句疑问及原理咨询

关于链表删除代码的两个问题解答

嘿,这个问题问到点子上了,我来给你一步步拆解清楚:

一、lpp = &(*lpp)->next 和 lpp = lpp->next 完全不等价,后者甚至是非法代码!

首先得明确lpp的类型:它是指向节点指针的指针(也就是struct node **),而不是节点结构体的指针(struct node *)。咱们拆开来分析:

  • 对于lpp = &(*lpp)->next:

    1. *lpp 是对二级指针解引用,得到一个struct node *(指向某个节点的指针);
    2. (*lpp)->next 是取这个节点的next成员,类型是struct node *;
    3. &(*lpp)->next 是取这个next成员的地址,类型又回到了struct node **,和lpp的类型匹配,所以这句代码是合法的,作用是让lpp指向当前节点的next指针本身。
  • 对于lpp = lpp->next:
    lpp是二级指针,它本身是一个指针变量,根本没有next成员(next是struct node结构体里的成员)。编译器看到这句会直接报错,类似「request for member 'next' in something not a structure or union」,所以这写法从语法上就不成立,更别说等价了。

二、*lpp = (*lpp)->next 是怎么实现节点删除的?

还是先从类型和逻辑入手:

  1. *lpp 代表的是链表中指向待删除节点的那个指针——这个指针可能是链表的头指针(head),也可能是某个前驱节点的next成员(比如prev_node->next);
  2. (*lpp)->next 是待删除节点的下一个节点的指针;
  3. 把*lpp赋值成(*lpp)->next,本质就是让「指向待删除节点的那个指针」直接跳过待删除节点,指向它的下一个节点。

举个实际例子:假设链表是 head -> NodeA -> NodeB -> NodeC

  • 如果要删除NodeA,那lpp就是&head,*lpp就是NodeA的指针。执行*lpp = (*lpp)->next后,head直接指向NodeB,NodeA就被从链表中剥离了;
  • 如果要删除NodeB,那lpp就是&NodeA->next,*lpp是NodeB的指针。执行赋值后,NodeA->next指向NodeC,NodeB就脱离了链表。

这种写法的妙处在于:不需要区分头节点和中间节点,用同一句代码就能处理所有删除场景,不用单独写头节点删除的特殊逻辑。当然,删除后别忘了释放待删除节点的内存(如果是动态分配的话),不然会内存泄漏~

内容的提问来源于stack exchange,提问作者user1477817

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:06:53