Linux內核中使用的最多的是雙向循環鏈表;
鏈表代碼在頭文件<linux>中聲明,其數據結構很簡單:/<linux>
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_for_each_entry淺析](http://p2.ttnews.xyz/loading.gif)
----------------------
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) );})
閱讀更多 AIOT小學生 的文章