Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
rt_list_for_each_entry
关于rtthread内链表rt_list_for_each_entry用法
发布于 2023-06-10 13:21:09 浏览:1037
订阅该版
各人对于链表的使用并不是很频繁,偶尔用一下,所以导致每次用都不记得怎么用了,都要重新分析一下逻辑,所以今天在这里记录一下用法,方便自己也方便用得到的小伙伴查阅。 具体的函数接口这里就不介绍了,RTThread的API文档里讲的很清楚,按照API接口调用就可以了,比较容易。这里主要说明rt_list_for_each_entry宏的用法,因为每次就这里不太好理解,这个宏实现的功能类似C++中用引用遍历链表,很好用的。而且RTT已经给实现了这种遍历方法如果不用总感觉自己亏了点啥😅 先看一下代码里此宏的具体定义: ```c /** * rt_list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define rt_list_for_each_entry(pos, head, member) \ for (pos = rt_list_entry((head)->next, typeof(*pos), member); \ &pos->member != (head); \ pos = rt_list_entry(pos->member.next, typeof(*pos), member)) ``` 乍一看可能有点乱,所以需要稍微梳理一下逻辑,梳理通了也就不复杂了。此宏具体的实现功能肯定是要遍历链表内的每个节点成员,所以核心就是一个for循环,可每次要用这个宏的时候第一反应就是这个宏的三个参数是什么意思来着?要传入什么?那就要先分析一下for信号里面的代码了。 for循环相信大家都知道了,一般括号内有三条语句(有时把变化语句放到循环体内,这里就只有两条语句了),第一条语句可以成为初始化语句,初始化循环变量。第二条语句是循环条件语句,为真则循环为假则退出循环。第三条语句是变量变化语句。对应到这里的宏,第一条初始化语句为``` pos = rt_list_entry((head)->next, typeof(*pos), member); ```,是一个对```pos```的赋值语句,所以这里结合代码和上面的注释就能很容易知道第一个参数```pos```就类似普通for循环的循环变量。初始化又用到了另外一个宏```rt_list_entry```,此宏相关的代码如下: ```c /** * @brief get the struct for this entry * @param node the entry point * @param type the type of structure * @param member the name of list in structure */ #define rt_list_entry(node, type, member) \ rt_container_of(node, type, member) /** * rt_container_of - return the member address of ptr, if the type of ptr is the * struct type. */ #define rt_container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member))) ``` 展开后就是一个减法计算:```(char *)((head)->next) - (unsigned long)(&((typeof(*pos) *)0)->member)```,其中```&((typeof(*pos) *)0)->member```的功能是得到```pos```类型结构体内```member```成员的偏移地址。把0地址看做一个```pos```类型的结构体,再取其中任何成员的地址就自然是其偏移地址了。所以这个宏的```pos```参数,传入的应该是你自己定义的链表节点结构体指针,此结构体内包含一个```rt_list_t```类型的```member```成员变量。所以第三个参数传入一个```member```的成员名称即可。而第二个参数```head```传入的是链表头节点内的member变量指针。所以这里for循环内的第一条初始化语句就是初始化```pos```为链表内第一个节点的自定义结构体指针。 理解到这里,第二条语句就很容易理解了,就是判断遍历的pos内的下一个节点指针是不是又回到了head(单向链表里是判断是否为NULL),是则已经遍历一遍,退出循环。 第三条语句是取```pos->member.next```也就是下一个节点对于的自己定义结构体指针。 为了方便理解上面的内容,下面给出一个简单的例子: ```c typedef struct __test_node { rt_uint16_t a; //可加入任何类型的用户自定义变量 rt_uint16_t b; rt_uint16_t c; rt_list_t member; //rt_list_entry宏传入的第三个参数要与此变量同名 }TestNode; void rt_list_test() { TestNode test_head; rt_list_init(&test_head.member); for(int i = 0; i < 10; ++i) { TestNode *new_node = rt_malloc(sizeof(TestNode)); new_node->a = i; rt_list_insert_before(&test_head.member, &new_node->member); } rt_kprintf("list_len:%d\n",rt_list_len(&test_head.member)); TestNode *list_pos; rt_list_for_each_entry(list_pos, &test_head.member, member) { rt_kprintf("a:%d\n", list_pos->a); } } ``` 运行结果: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230610/7fa6f078e0430b25528ab45bc10945df.png)
2
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
吉利咕噜2022
国防科大-军品研发
文章
18
回答
3
被采纳
2
关注TA
发私信
相关文章
1
遍历单链表,遍历过程删除满足条件的节点怎么处理比较好?
2
rt-thread使用链表组件编译报错
3
rtt单链表的rt_slist_for_each_entry编译报错
4
list_for_each_entry Keil MDK 编译失败,我已经勾选了GUN,依然不行
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
keil_MDK
SFUD
msh
ulog
C++_cpp
MicroPython
本月问答贡献
出出啊
1518
个答案
343
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
549
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
出出啊
1
篇文章
3
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部