当前位置: 首页 > news >正文

一生一芯中有趣的C语言宏:LIST_FOREACH 链表遍历宏 - Zeeh

记录了学习 “一生一芯” 时遇到的 LIST_FOREACH 链表遍历宏。该宏的精髓在于使用 V 和 _node 双指针机制,以确保即使在复杂场景下(如用户误改指针),循环的健壮性和遍历的正确性也不会被破坏。


LIST_FOREACH的定义

#define LIST_FOREACH(L, S, M, V) ListNode *_node = NULL;\ListNode *V = NULL;\for(V = _node = L->S; _node != NULL; V = _node = _node->M)

这个定义出现在本办法学C-中文版 练习32,用于双向链表的遍历。

用途与宏展开

用途

这个宏定义实现了对双向链表的正向遍历反向遍历,其中:

参数 含义 示例
L 链表结构体指针 (List) list (例如一个包含 headtail 字段的结构体)
S 起始结点名 (Start) head (如果从头开始遍历) 或 tail (如果从尾部开始遍历)
M 移动到下一个节点的字段名 (Move) next (用于单向或向前遍历) 或 prev (用于向后遍历)
V 当前节点变量名 (Variable) curnode (用户在循环体中使用的迭代变量)

宏展开的逻辑分析

  1. 局部变量声明

    ListNode *_node = NULL;
    ListNode *V = NULL;
    
    • _node: 这是一个临时的内部工作变量,它总是指向下一个要检查的节点。在循环的初始化和步进部分,它用于保存移动

    • V: 这是用户指定的当前节点变量。在每次循环迭代中,它指向用户当前处理的节点。

  2. for循环

    for(V = _node = L->S; _node != NULL; V = _node = _node->M)
    

    很容易看懂。需要注意的是,运用了连等赋值的右结合性。例如,在步进部分 V = _node = _node->M 中:

    1. 最右边先执行: _node->M 计算出下一个节点的地址。
    2. 向左赋值: 将该地址赋给 _node,完成 _node 的移动
    3. 再向左赋值: 将 _node(已更新)的值赋给 V,完成 V 的同步

为什么同时存在V_node

在这个宏中,V_node两个宏变量是同步赋值的。那么,为什么需要同时设置这两个变量呢?

宏变量V_node的作用

变量 完整名称/别名 作用/职责核心职能
V 用户变量/当前节点 用户在循环体内部使用,代表当前正在处理的节点接口:提供给用户操作。
_node 内部变量/工作指针 宏内部使用,负责驱动循环的条件检查步进计算引擎:驱动循环逻辑。

健壮性考虑

这样设计的原因可能是出于健壮性的考虑。如果只使用一个宏变量,例如只使用V,当遍历过程中因为任何原因(例如调试、特殊逻辑、错误代码)修改了 V 的值(使其指向另一个节点,或者赋值为 NULL),那么步进表达式 V = V->M 将会彻底失败,导致:

  • 遍历跳过节点。
  • 遍历提前终止
  • 访问错误内存(如果 V 被置为非法指针)。
http://www.zskr.cn/news/12506.html

相关文章:

  • 有一个[1,5]的等概率随机函数fx(),在不改变fx()函数的情况下,利用fx()函数做出一个[1,7]的等概率随机函数。
  • 喜讯!狮桥集团成为天津市行政执法监督企业联系点,共筑法治营商新环境!
  • 当不小心误触了一个事件该如何删除呢
  • 跑腿小工具|基于微信小脚本的跑腿平台小程序设计与实现(源码+数据库+文档)
  • 烧录工具使用方法大公开:实用说明文档奉上
  • 【图床】存几张图
  • 什么是 glTF:完整指南
  • WSL2搭建wordpress遇到的一点问题
  • 430亿美元押注英国,Salesforce 加码 AI 投资
  • C# 中 ref 和 out 的学习笔记
  • NXP - 在MCUXpresso IDE中编译调试Smoothieware固件工程 - 思路 - 教程
  • 5G车载市场新格局:国产崛起,从破局者到引领者的升维之战 - 实践
  • 手撕深度学习之CUDA并行规约算法(上篇):硬核揭秘200%性能提升的GPU优化之道,从硬件特性到算法实现的完整进阶指南
  • 详细介绍:八股已死、场景当立(微服务保护篇)
  • 《“悬荡”于理想与现实之间:一份关于人机共生未来的思想实验评估》
  • 区别:RS-232、RS-422、RS-485
  • 【征文计划】深度剖析 Rokid SLAM 算法:从传感器融合到空间重建的完整技术链路 - 实践
  • 登录 Linux 自动展示 CPU/内存/磁盘挂载使用情况等信息(针对于银河麒麟调整的)
  • 解码数据结构线性表之链表
  • 高通QCS8550开发板 + DeepSeek-R1:打造智能化商场导购实践
  • 《对软件工程的初步理解》
  • B3863 [GESP202309 一级] 买文具
  • B2009 计算 (a+b)/c 的值
  • 详细介绍:【杂谈】Godot 4.5下载指南
  • 安全帽检测数据集-YOLO格式建筑工地安全图像数据-个人防护装备(PPE)目标检测算法训练-包含安全帽/无安全帽/等多类别标注-深度学习计算机视觉应用-工业安全监控系统开发-实时预警检测模型
  • WPF ItemsControl implement Select in mvvm via behavior
  • 服务器密码错误被锁定如何解决?
  • 螺纹偏弱
  • 水翼式搅拌机推荐品牌/推荐厂家/优质供应商/哪家强?
  • 100W QPS:亿级用户的社交关系如何设计?