TAILQ结构

本文深入解析了tailq中的TAILQ_FOREACH_REVERSE函数的工作原理,包括如何通过强制类型转换从一个元素找到另一个元素,以及如何在循环中高效地遍历链表。重点在于解释了关键步骤及其背后的逻辑,帮助读者更好地理解链表操作。

tailq中的TAILQ_FOREACH_REVERSE一些说明

这个东西之前就看过一次,看了半天才搞懂,结果今天看时又看不懂了,又折腾了好久才看清楚是咋回事。
最关键的就是(*(((struct headname *)((var)->field.tqe_prev))->tqh_last))),拆解开来就是:
1。((struct headname *)((var)->field.tqe_prev)) 这一步用于将上一个elm中的field结构中的tqe_next的地址取出来,其实也就是elm中field这个struct节点的地址(请注意到该struct中只有两个元素,而且该struct的结构与headname完全一致);
2。(@1->tqh_last) 这一步用于将上一个elm中的field中的第二个元素(即tqe_prev)的地址取出来,该地址就是上一个elm的上一个elm中的field的tqe_next的地址, 而该地址恰好指向的就是上一个elm的地址
3。(*@2) 这一步用于取出指向上一个elm的地址

呵呵,真tm够绕人的,其实在步骤1里面完全可以用elm中的field这个struct来进行强制类型转化,但是由于elm中的field这个struct是个定义在elm内部的而且没有名字的struct,因此无法显示的调用类似于(struct headname *)这样的强制类型转化,因此就只好用headname这个struct name来做这件事情了。

此外,**tqh_prev得到的其实是当前elm,*tqh_prev得到的是当前elm的指针,只有tqh_prev才能逃离当前elm的怪圈,指向上一个elm的field结构的第一个元素(也即整个field struct)的地址,紧接着从这里做文章又跳到了上一个elm的上一个elm的field struct里面,哈哈,够曲折的。

这个过程中,最精妙的莫过于那个强制类型转化了,其实本质上就是在从struct的第一个元素寻找第二个元素,其实完全可以用第一个元素的地址+4(32位系统,64位系统需要+8)就可以得到,但是这种做法可移植性太差,对于那种非pod的类型就不work了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值