#include <stdio.h>
struct list_head
{
struct list_head *next;
struct list_head *prev;
};
struct score
{
int num;
int math;
struct list_head list;
};
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
#define offsetof(TYPE, MEMBER)((size_t) &((TYPE*)0)->MEMBER)
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#define list_entry(ptr, type, member)\
container_of(ptr, type, member)
static void INIT_LIST_HEAD(struct list_head *list)
{
list->prev = list;
list->next = list;
}
static void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
static void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
static void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
static void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
static void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}
int main()
{
struct score stu1;
struct score stu2;
struct score stu3;
struct score stu4;
struct score stu5;
struct score stu6;
struct score *temp;
struct list_head *pos;
struct list_head score_head;
INIT_LIST_HEAD(&score_head);
stu1.num = 1;
stu2.num = 2;
stu3.num = 3;
stu4.num = 4;
stu5.num = 5;
stu6.num = 6;
stu1.math = 60;
stu2.math = 70;
stu3.math = 80;
stu4.math = 90;
stu5.math = 20;
stu6.math = 30;
//在表尾部插入
list_add_tail(&(stu1.list), &score_head);
list_add_tail(&(stu2.list), &score_head);
list_add_tail(&(stu3.list), &score_head);
list_add_tail(&(stu4.list), &score_head);
list_for_each(pos, &score_head)
{
temp = list_entry(pos, struct score, list);
printf("num = %d, math = %d\n", temp->num, temp->math);
}
printf("\n");
//在表头插入
list_add(&(stu5.list), &score_head);
list_add(&(stu6.list), &score_head);
list_for_each(pos, &score_head)
{
temp = list_entry(pos, struct score, list);
printf("num = %d, math = %d\n", temp->num, temp->math);
}
printf("\n");
//删除
list_del(&(stu5.list));
list_for_each(pos, &score_head)
{
temp = list_entry(pos, struct score, list);
printf("num = %d, math = %d\n", temp->num, temp->math);
}
printf("\n");
return 0;
}
运行效果:
内核双链表效果图:
大体的效果图就是如此,增加一个节点,删除一个节点都是基于这个模型展开的。
读者可以手动画画增加和删除的操作。
其实关于内核中链表的操作还有很多的函数,目前就分析这几个。其余留给自己尝试。