6.用链表外的结构体地址来进行遍历,而不用链表的地址进行遍历
1>funtion:
遍历链表,所不同的是它是根据链表的结构体地址来进行遍历。大多数情况下,遍历链表的时候都需要获得链表节点数据项,也就是说list_for_each()和list_entry()总是同时使用。与list_for_each()不同,这里的pos是数据项结构指针类型,而不是(struct list_head 类型。
Linxu提供了以下函数:
list_for_each_entry
list_for_each_entry_safe
list_for_each_entry_reverse
list_for_each_entry_safe_reverse
2>函数接口
list_for_each_entry(pos,head,member)
pos:用于遍历的指针,只是它的数据类型是结构体类型而不是strut list_head 类型
head:链表头指针
member:该数据项类型定义中list_head成员的变量名。
list_for_each_entry_safe(pos,n,head,member)
pos:用于遍历的指针,只是它的数据类型是结构体类型而不是strut list_head 类型
n: 临时指针用于占时存储pos的下一个指针
head:链表头指针
member:该数据项类型定义中list_head成员的变量名。
list_for_each_entry_rverse(pos,head,member)
pos:用于遍历的指针,只是它的数据类型是结构体类型而不是strut list_head 类型
head:链表头指针
member:该数据项类型定义中list_head成员的变量名。
list_for_each_entry_safe_reverse(pos,n,head,member)
pos:用于遍历的指针,只是它的数据类型是结构体类型而不是strut list_head 类型
n: 临时指针用于占时存储pos的下一个指针
head:链表头指针
member:该数据项类型定义中list_head成员的变量名。
3>函数实现
(1)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))
这个函数是根据member成员遍历head链表,并且将每个结构体的首地址赋值给pos,这样的话,我们就可以在循环体里面通过pos来访问该结构体变量的其他成员了。大多数情况下,遍历链表的时候都需要获得链表节点数据项,也就是说list_for_each()和list_entry()总是同时使用。与list_for_each()不同,这里的pos是数据项结构指针类型,而不是struct list_head 类型。
(2)list_for_each_entry_safe(pos,n,head,member)实现
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
list_for_each_entry_safe与list_for_each_entry功能相同,不同的是list_for_each_entry_safe主要用于链表删除时进行遍历操作。
(3) list_for_each_entry_reverse实现
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
逆向遍历链表。功能和list_for_each_entry相同,不同的是采用逆序遍历。与list_for_each_prev不同的是这里的pos是数据项结构指针类型,而不是struct list_head 类型。
(4)list_for_each_entry_safe_reverse实现
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
逆向遍历链表,与list_for_each_entry_reverse不同的是该函数主要用于删除操作时进行遍历。与list_for_each_prev_safe不同的是这里的pos是数据项结构指针类型,而不是struct list_head 类型