Linus:利用二级指针删除单向链表

端侧部署与优化:让 AI 真正走进现实生活的关键技术 AI 的开发流程分为 “训练” 与 “推理” 两大阶段。在训练阶段,科研人员依托云端海量数据和高性能 GPU 算力,构建出精度优异的 AI 模型 —— 比如能识别 1000 种物体的图像分类模型、能理解人类语言的自然语言处理模型。但这些在云端 “战绩斐然” 的模型,若直接应用到现实场景中,却会面临三大 “落地困境”。从云端到端侧,从模型压缩到硬件适配,端侧部署与优化技术解决了 AI 落地的核心难题,让 AI 不再是实验室里的 “高精尖技术”,而是融入日常生活的 “实用工具”。 阅读详情

Linus大神在slashdot上回答一些编程爱好者的提问,其中一个人问他什么样的代码是他所喜好的,大婶表述了自己一些观点之后,举了一个指针的例子,解释了什么才是core low-level coding。

下面是Linus的教学原文及翻译——

“At the opposite end of the spectrum, I actually wish more people understood the really core low-level kind of coding. Not big, complex stuff like the lockless name lookup, but simply good use of pointers-to-pointers etc. For example, I’ve seen too many people who delete a singly-linked list entry by keeping track of the “prev” entry, and then to delete the entry, doing something like。(在这段话的最后,我实际上希望更多的人了解什么是真正的核心底层代码。这并不像无锁文件名查询(注:可能是git源码里的设计)那样庞大、复杂,只是仅仅像诸如使用二级指针那样简单的技术。例如,我见过很多人在删除一个单项链表的时候,维护了一个”prev”表项指针,然后删除当前表项,就像这样)”

1
2
3
4
if (prev)
     prev->next = entry->next;
else
     list_head = entry->next;

“and whenever I see code like that, I just go “This person doesn’t understand pointers”. And it’s sadly quite common.(当我看到这样的代码时,我就会想“这个人不了解指针”。令人难过的是这太常见了。) ”

“People who understand pointers just use a “pointer to the entry pointer”, and initialize that with the address of the list_head. And then as they traverse the list, they can remove the entry without using any conditionals, by just doing a “*pp = entry->next”. (了解指针的人会使用链表头的地址来初始化一个“指向节点指针的指针”。当遍历链表的时候,可以不用任何条件判断(注:指prev是否为链表头)就能移除某个节点,只要写)”

Linus举了一个单向链表的例子,但给出的代码太短了,一般的人很难搞明白这两个代码后面的含义。正好,有个编程爱好者阅读了这段话,并给出了一个比较完整的代码。他的话我就不翻译了,下面给出代码说明。

如果我们需要写一个remove_if(link*, rm_cond_func*)的函数,也就是传入一个单向链表,和一个自定义的是否删除的函数,然后返回处理后的链接。

这个代码不难,基本上所有的教科书都会提供下面的代码示例,而这种写法也是大公司的面试题标准模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
typedef struct node
{
     struct node * next;
     ....
} node;
  
typedef bool (* remove_fn)(node const * v);
  
// Remove all nodes from the supplied list for which the
// supplied remove function returns true.
// Returns the new head of the list.
node * remove_if(node * head, remove_fn rm)
{
     for (node * prev = NULL, * curr = head; curr != NULL; )
     {
         node * const next = curr->next;
         if (rm(curr))
         {
             if (prev)
                 prev->next = next;
             else
                 head = next;
             free (curr);
         }
         else
             prev = curr;
         curr = next;
     }
     return head;
}

这里remove_fn由调用者提供的一个是否删除当前实体结点的函数指针,其会判断删除条件是否成立。这段代码维护了两个节点指针prev和curr,标准的教科书写法——删除当前结点时,需要一个previous的指针,并且还要这里还需要做一个边界条件的判断——curr是否为链表头。于是,要删除一个节点(不是表头),只要将前一个节点的next指向当前节点的next指向的对象,即下一个节点(即:prev->next = curr->next),然后释放当前节点。

但在Linus看来,这是不懂指针的人的做法。那么,什么是core low-level coding呢?那就是有效地利用二级指针,将其作为管理和操作链表的首要选项。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
     }
}

同上一段代码有何改进呢?我们看到:不需要prev指针了,也不需要再去判断是否为链表头了,但是,curr变成了一个指向指针的指针。这正是这段程序的精妙之处。(注意,我所highlight的那三行代码)

让我们来人肉跑一下这个代码,对于——

  • 删除节点是表头的情况,输入参数中传入head的二级指针,在for循环里将其初始化curr,然后entry就是*head(*curr),我们马上删除它,那么第8行就等效于*head = (*head)->next,就是删除表头的实现。
  • 删除节点不是表头的情况,对于上面的代码,我们可以看到——
    1. (第12行)如果不删除当前结点 —— curr保存的是当前结点next指针的地址。
    2. (第5行) entry 保存了 *curr —— 这意味着在下一次循环:entry就是prev->next指针所指向的内存。
    3. (第8行)删除结点:*curr = entry->next; —— 于是:prev->next 指向了 entry -> next;

是不是很巧妙?我们可以只用一个二级指针来操作链表,对所有节点都一样。

如果你对上面的代码和描述理解上有困难的话,你可以看看下图的示意:

 

ref: http://coolshell.cn/articles/8990.html

机器学习——径向基函数(RBF)神经网络 目录 一、什么是基函数 二、什么是径向基函数 三、为什么RBF神经网络使用一个径向基函数作为隐含层的激活函数 四、参数训练 五、RBF网络vs BP网络和 SVM 一、什么是基函数 著名的傅里叶变换是指:n个有参(权值)的正、余弦三角函数基的和式可以等价的表示任意一个周期函数,这里的“基”和我们数学中说的坐标基或向量基含义相同,即坐标空间中任意一个向量都可以用基向量的线性和表示出来。 因此,我们引入函数空间的概念,函数空间中的每个连续函数可以表示为基函数的线性组合,就像向量空间中的每.. 阅读详情

相关推荐

BMW Trojan 样本分析

仅用于链接已经删却但是需要方便查阅的原文http://blog.youkuaiyun.com/zirconsdu/article/details/7997470 转载请注明出处http://blog.youkuaiyun.com/zirconsdu/article/details/8153813。 一些具体数据结构和具体路径隐去。   BMW木马样本分析 摘要 2011年底和某Hunter的谈话涉及到当时新检

zirconsdu的专栏 3912

LINUS:利用二级指针删除单向链表

Linus大婶在slashdot上回答一些编程爱好者的提问,其中一个人问他什么样的代码是他所喜好的,大婶表述了自己一些观点之后,举了一个指针的例子,解释了什么才是core low-level coding。

wuyangyang555的博客 390

虚拟机Ubuntu连接USRP

笔记本通过网线连接USRP。

xiaozir的博客 2310

【链表】C/C++用二级指针删除单链表结点的精妙方法

问题         给出链表头指针,删除单链表中值为给定值的某个结点,若有重复结点则只需删除第一个。 思路 采用一级指针删除链表节点         采用一级指针删除链表结点需要判断前驱结点、后续结点,代码量相对较多。 采用二级指针删除链表结点         在处理链表的问题中,尤其是删除链表结点,采用二级指针会使代码非常简洁。不需要判断前驱结点和后续结点,不需要判断是

donghuaan的博客 1228

LightningChart使用教程:创建 JS 散点图

这是对 LightningChart JS XY 图表一些有趣功能的快速技术研究,以及如何使用 LightningChart JS 创建嵌入式散点聊天和添加自定义交互。 此图表将可视化一个 XY 坐标列表以及一个额外的自定义属性,它只是一段文本。这些自定义属性将与 UI 文本元素一起显示,这些元素将与用户的鼠标移动交互。 我们将介绍的突出功能是: 什么是散点图? 如何创建散点图? 如何将自定义属性附加到数据点。 如何创建交互式 UI 文本元素。 最终结果 什么是散点图? 散点图或散点图是..

Augenstern__zyx的博客 1372

Unity集成阿里云语音AI:从麦克风录音到实时语音合成的全流程实现

本文详细介绍了在Unity中集成阿里云语音AI服务,实现从麦克风录音到实时语音合成的完整流程。通过调用阿里云的语音转文字和文字转语音接口,开发者可以快速为游戏或应用添加语音交互功能,提升用户体验。文章涵盖了环境配置、签名认证、音频处理及项目集成等核心步骤,并提供了实用的调试技巧。

weixin_29224589的博客 324

利用二级指针删除单向链表

http://coolshell.cn/articles/8990.html Linus举了一个单向链表的例子,但给出的代码太短了,一般的人很难搞明白这两个代码后面的含义。正好,有个编程爱好者阅读了这段话,并给出了一个比较完整的代码。他的话我就不翻译了,下面给出代码说明。 如果我们需要写一个remove_if(link*, rm_cond_func*)的函数,也就是传入一个单向链表

chivalry 2891

YOLOv8全网首发:CVPR2026 MixerCSeg | DEGConv方向引导边缘门控,破解细长裂缝检测难题

DEGConv通过方向先验嵌入、边缘增强卷积和动态门控三大机制,针对性解决了YOLO在处理裂缝类细长、多方向、低对比度目标时的特征提取不足问题,显著提升了裂缝检测的精度与鲁棒性。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 520

利用二级指针删除单向链表节点

// testPPointer.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include typedef struct tagNode { struct tagNode* m_next; int m_nVal; }Node, *PNode; // 通过二级指针方式

一步一步 1951

SpringCloud详细教程(下)

SpringCloud详细教程,springcloud完全教程。Springcloud微服务教程(上)的姊妹篇:介绍了其它SpringCloud组件。

鸟哥哥的专栏 4万+

simulink的电动汽车制动系统热管理仿真

本文系统研究了电动汽车制动系统热管理仿真技术。通过建立机电液多物理场耦合模型,分析了不同工况下的动态热平衡特性。提出基于MPC的动态调节和NSGA-II多目标优化算法,使电池温度波动降低60%。创新性采用石墨烯相变材料与微通道液冷复合技术,冷却系统能耗减少40%。研究构建了完整的工程验证平台,涵盖200kW电制动测试台和高精度热成像系统。展望指出,未来将结合Transformer预测和强化学习算法,进一步优化热管理策略。该研究为电动汽车制动系统热管理提供了从理论建模到工程实施的完整解决方案。

xiaoheshang_123的博客 122

Linus:利用二级指针删除单向链表

Linus大婶在slashdot上回答一些编程爱好者的提问,其中一个人问他什么样的代码是他所喜好的,大婶表述了自己一些观点之后,举了一个指针的例子,解释了什么才是core low-level coding。Linus举了一个单向链表的例子,但给出的代码太短了,一般的人很难搞明白这两个代码后面的含义。已经有几位牛人对代码作了解释,具体如下: http://wordaligned.org/art

hellominix的专栏 731

uniapp [安卓苹果App端] - errMsg“: “request:fail abort statusCode:-1 不支持的URL(-1002)Uniapp真机运行APP网络请求报错失败排查

uniapp真机运行APP,网络请求报错errMsg“: “request:fail abort statusCode:-1 不支持的URL(-1002),uni.request网路请求报错,uniApp解决请求接口报错,uniapp app端打包上线后请求报错,真机运行测试请求失败,uniapp安卓app请求报错,uniapp苹果ios平台网络请求报错,uniapp真机预览请求失败怎么办,不是跨域问题,在H5中请求可以正常发送和接收,但在真机APP上请求报错,Hbuilder真机运行app网络请求报错,全

🏆 前端领域优质创作者 3091
上一篇: 漫谈C语言随机数
下一篇: python之列表(list)
love1code
博客等级 码龄12年 19粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值