list_for_each_entry浅析_list for i in range

list_for_each_entry浅析_list for i in range

编码文章call10242025-10-22 21:53:553A+A-

Linux内核中使用的最多的是双向循环链表;

链表代码在头文件<linux/list.h>中声明,其数据结构很简单:

struct list_head {

struct list_head *next;

struct list_head *prev;

};

值得注意的是list_head通常放在自己定义的结构体中使用;

例如:

1, 定义结构体

struct stu{

int age;

char *name;

int score;

struct list_head list;

};

2, 初始化结构体及链表

struct stu *mid_stu;

mid_stu = kzmalloc(.....);

NIT_LIST_HEAD(&mid_stu->list);

3, 添加链表成员

void list_add(struct list_head *new, struct list_head *head);

4, 删除链表成员

void list_del(struct list_head *entry);

5, 遍历链表

最常用的遍历链表的方法为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))

----------------------

list_entry表示在找出ptr指向的链表节点所在的type类型的结构体首地址

#define list_entry(ptr, type, member) \

container_of(ptr, type, member)

ptr:表示和member同为相同类型的链表,此处ptr表示指向链表中的一个节点

type:表示需要寻找的结构体类型。

member:表示type类型的结构体里面的成员。

----------------------

#define container_of(ptr, type, member) ({\

const typeof( ((type *)0)->member ) *__mptr = (ptr);\

(type *)( (char *)__mptr - offsetof(type,member) );})

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4