list_entry/list_for_each_entry/list_for_each_entry_safe

  • list_entry
#define list_entry(ptr, type, member)  container_of(ptr, type, member)
  1. ptr type member 分别表示 指针 / 包含指针类型的结构体类型 / 指针对应的成员
  2. contain_of的原理:已知type的成员member的地址ptr,计算type的首地址
  3. type的首地址 = ptr – size

在这里插入图片描述

container_of

  1. typeof((type *) 0)->member 获取 member的类型
  2. __mptr = ptr; 定义一个指针变量__mptr, 并将成员变量ptr的地址赋值给它
  3. Offsetof(TYPE, MEMBER) 计算成员member这个成员在type类型结构体中偏移
  4. __mptr – offsetof(type, member) 成员变量的地址减去在结构体中的偏移,就得到了结构体的首地址
  5. 1 和 2本质上并没有干什么事儿,就是定义了一个中间变量,目的是ptr和member如果传入了错误的类型编译器识别warning
#define container_of(ptr, type, member) ({			\
	const typeof(((type *)0)->member) * __mptr = (ptr);	\
	(type *)((char *)__mptr - offsetof(type, member)); })
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

  • list_for_each_entry
#define list_for_each_entry(pos, head, member) \ 
	for (pos = list_first_entry(head, typeof(*pos), member); \ 
		&pos->member != (head); \ 
		pos = list_next_entry(pos, member))

pos head member分别指宿主结构体类型的指针 宿主结构体使用的链表头
宿主结构体中的链表成员
1.pos定位到第一个宿主结构地址
2.判断不等于链表头
3.取下一个宿主结构

#define list_first_entry(ptr, type, member) \ 
	list_entry((ptr)->next, type, member) 
#define list_next_entry(pos, member) \
	list_entry((pos)->member.next, typeof(*(pos)), member) 

  • list_for_each_entry_safe
#define list_for_each_entry_safe(pos, n, head, member)          \
    for (pos = list_first_entry(head, typeof(*pos), member),    \
        n = list_next_entry(pos, member);           \
         &pos->member != (head);                    \
         pos = n, n = list_next_entry(n, member))

相比list_for_each_entry, list_for_each_entry_safe增加了一个指针n对链表的下一个数据结构进行临时存储,所以在遍历链表的时候如果需要做删除链表的操作,使用list_for_each_entry_safe可以安全的删除,不会影响后续的遍历过程。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值