直接上代码:
我这是从list.h中摘出来的,编译测试通过!
#ifndef _LIST_H_ #define _LIST_H_ #define POISON_POINTER_DELTA 0 #define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA) #define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA) struct list_head { struct list_head *next; struct list_head *prev; }; #define LIST_HEAD_INIT(name) {&(name), &(name)} #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) #if 1 static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list; } /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ 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; } /** * list_add - add a new entry * @new: new entry to be added * @head: list head to add it after * * Insert a new entry after the specified head. * This is good for implementing stacks. */ void list_add(struct list_head *new, struct list_head *head) { __list_add(new, head, head->next); } /* * Delete a list entry by making the prev/next entries * point to each other. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_del(struct list_head * prev, struct list_head * next) { next->prev = prev; prev->next = next; } /** * list_del - deletes entry from list. * @entry: the element to delete from the list. * Note: list_empty() on entry does not return true after this, the entry is * in an undefined state. */ void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } /** * list_for_each_safe - iterate over a list safe against removal of list entry * @pos: the &struct list_head to use as a loop cursor. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. */ #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) /* from kernel.h */ #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) );}) /** * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. */ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) #endif #endif
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h" struct my_struct { struct list_head list; char name[16]; int money; }; int main(void) { struct my_struct head = { .list = LIST_HEAD_INIT(head.list), .name = "boss", .money = 100 }; struct my_struct *james = (struct my_struct *)malloc(sizeof(struct my_struct)); struct my_struct *linda = (struct my_struct *)malloc(sizeof(struct my_struct)); struct my_struct *alex = (struct my_struct *)malloc(sizeof(struct my_struct)); strcpy(james->name, "james"); james->money = 20000; strcpy(linda->name, "linda"); linda->money = 30000; strcpy(alex->name, "alex"); alex->money = 40000; list_add(&james->list, &head.list); list_add(&linda->list, &james->list); list_add(&alex->list, &linda->list); struct list_head *p, *n; struct my_struct *out; list_for_each_safe(p, n, &head.list){ out = list_entry(p, struct my_struct, list); printf("%s:money=%d\n", out->name, out->money); if(strcmp(out->name, "james") == 0){ list_del(&out->list); free(out); } } printf("del one\n"); list_for_each_safe(p, n, &head.list){ out = list_entry(p, struct my_struct, list); printf("%s:money=%d\n", out->name, out->money); } return 0; }
gcc main.c
./a.out
运行效果:
james:money=20000
linda:money=30000
alex:money=40000
del one
linda:money=30000
alex:money=40000