list_for_each_entry解析

list_for_each_entry解析: 
#define list_for_each_entry(pos, head, member) \ 
for (pos = list_entry((head)->next, typeof(*pos), member) ; &pos->member != (head) ; pos = list_entry(pos->member.next, typeof(*pos), member))

将上面宏 for分解如下:

1 pos = list_entry((head)->next, typeof(*pos), member) :获得 pos 指向结构体的地址 
2 &pos->member != (head) 
3 pos = list_entry(pos->member.next, typeof(*pos), member)

解析: pos = list_entry((head)->next, typeof(*pos), member) 
#define list_entry(ptr, type, member) container_of(ptr, type, member)

解析:container_of(ptr, type, member)

#define container_of(ptr, type, member) ( {const typeof(((type *)0)->member) * __mptr = (ptr);  (type *)((char *)__mptr - offsetof(type, member)); }  )

((type *)0)->member  :
((type *)0):强制转换操作 强制将 0 转换为 type类型的指针,将0强制转换为一个地址,这个地址0x0000(32位系统)指向的是类型type的数据,当然这只是我们的技巧,并不是真的在地址0x0000存放了我们的数据 struct type *p = NULL;  p->member;为什么这么写????? 有啥好处咩????原因:((type *)0)->member  : 这里的 “->” 很明显是通过 指针 操作 结构体成员 ,成员变量是member 指针就是上面的通过0强制转换的地址。所以相当于地址 0X0000是结构体类型type的首地址,通过"->" 操作type类型的成员变量 member。

typeof(((type *)0)->member) * __mptr = (ptr) :
((type *)0)->member  的作用就是得到成员变量,再通过 typeof(((type *)0)->member) 就知道member的成员类型了int* p :我们知道这是定义一个int类型的指针,在一些比较通俗的函数里,需要定义一个指针,但是不巧的是不能确定指针的类型,所以在程序里面不能写死,那么晚这时候应该怎么办?? 这个时候就需要typeof帮我们搞定。typeof(((type *)0)->member) * __mptr = (ptr) : 就是利用这个技巧, 其中 typeof(((type *)0)->member)就是member的类型, __mptr是变量,所以这句话的意思是定义一个指针变量 __mptr ,指向的类型是member的类型它初始化的值是 ptr,ptr是container_of的第一个参数。

(type *)((char *)__mptr - offsetof(type, member)) :
__mptr是前面定义的member成员类型的指针,初始化为ptr。offsetof(type, member) 是求出member在 type类型结构体中的偏移量,两者相减就是 type类型结构体的地址。强制转换为 char类型 是因为地址是以字节为单元

总结:container_of(ptr, type, member) 的作用就是 获得总结构体的地址,我们需要提供的参数是:
                          ptr : member 成员的指针 
                          type: 结构体类型 
                          member: 成员member的名字

container_of(ptr, type, member) :                           
ptr指向的是 type.member类型的数据,用来推算出以ptr指向的对象作为成员的结构体的起始地址

list_for_each_entry(type, head, member) :                         
head 组成的链表是由 type.member 为节点连接成的, head是链表头,搜寻整个链表,对type类型的数据进行处理
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux老A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值