list_head是linux中使用非常广泛的双向列表,list_head源代码所在位置为include/linux/list.h。
以下为测试代码:
#include <stdio.h>
#include <stdlib.h>
#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200200)
struct list_head {
struct list_head *next, *prev;
};
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
static inline 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 inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
#define prefetch(x) __builtin_prefetch(x)
#define list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)
struct Student{
int id;
struct list_head list_head;
};
#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) );})
struct Student* find_student(int id, struct list_head *list_head)
{
struct list_head *cur;
list_for_each(cur, list_head) {
struct Student *ptr_stu = container_of(cur, struct Student, list_head);
if (id == ptr_stu->id)
{
return ptr_stu;
}
}
return NULL;
}
int main()
{
struct list_head list_head;
INIT_LIST_HEAD(&list_head);
for (int i = 10; i <= 100; i+=10)
{
struct Student *ptr_stu = malloc(sizeof(struct Student));
ptr_stu->id = i;
if (i == 40 || i == 60)
{
// 添加到尾部
list_add_tail(&ptr_stu->list_head, &list_head);
}
else
{
// 添加到头部
list_add(&ptr_stu->list_head, &list_head);
}
}
if (list_empty(&list_head))
{
printf("list is empty\n");
return 0;
}
// 打印
struct list_head *cur;
list_for_each(cur, &list_head) {
struct Student *ptr_stu = container_of(cur, struct Student, list_head);
printf("id = %d\n", ptr_stu->id);
}
// 删除id为50的对象
struct Student *ptr_stu = find_student(50, &list_head);
if (NULL != ptr_stu)
{
list_del(&ptr_stu->list_head);
free(ptr_stu);
ptr_stu = NULL;
}
printf("\nprint after del\n");
list_for_each(cur, &list_head) {
struct Student *ptr_stu = container_of(cur, struct Student, list_head);
printf("id = %d\n", ptr_stu->id);
}
return 0;
}
运行结果如下:
id = 100
id = 90
id = 80
id = 70
id = 50
id = 30
id = 20
id = 10
id = 40
id = 60
print after del
id = 100
id = 90
id = 80
id = 70
id = 30
id = 20
id = 10
id = 40
id = 60