使用LIST.h
#头文件
#ifndef __LIST_H__
#define __LIST_H__
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
/*
* Get offset of a member variable.
*
* @param[in] type the type of the struct this embedded in
* @param[in] member the name of the variable within the struct.
*/
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
/*
* Get the struct for this entry.
*
* @para[in] ptr the list head to take the element from.
* @para[in] type the type of the struct this is embedded in.
* @para[in] member the name of the variable within the struct.
*/
#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)
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---此处就是特制链表头 head
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before---此处就是特指链表头。
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* 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;
}
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = NULL;
entry->prev = NULL;
}
/**
* list_empty - tests whether a list is empty 判断链表是否为空
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* 查询要删除的函数
* 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)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.//用作循环遍历的 游标指针(临时指针)
* @head: the head for your list. //我们自己的链表 头 head
* @member: the name of the list_struct within the struct. // 链表结构体的 元素,一般就是
* 那个struct list_head 的指针元素
*/
#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_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
#endif
测试文件
#include <stdio.h>
#include "list.h"
#include "list.h"
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
int data1;
int data2;
}TEST_TYPE;
typedef struct usrList
{
int index;
int data;
struct list_head list;
} USR_LIST_TYPE;
LIST_HEAD(msg_head);
void list_print(void)
{
USR_LIST_TYPE *pmsg;
/* 根据list 遍历 整个链表,并打印信息 */
list_for_each_entry(pmsg, &msg_head, list){
printf("msg index:%d data:%d\n", pmsg->index, pmsg->data);
}
struct list_head *pos;
list_for_each(pos,&msg_head)
{
pmsg = list_entry(pos, USR_LIST_TYPE, list);
printf("msg index:%d data:%d\n", pmsg->index, pmsg->data);
}
}
int list_add_test(void)
{
USR_LIST_TYPE msg, *pmsg;
int *ptr = &msg.data;
int i;
/* insert the 10 msgs */
for(i = 0; i < 10; i++){
pmsg = (USR_LIST_TYPE *)malloc(sizeof(USR_LIST_TYPE));
pmsg->index = i + 1;
pmsg->data = (i + 1)*10;
list_add_tail(&pmsg->list, &msg_head);
}
list_print();
return 0;
}
int list_del_test(int index)
{
USR_LIST_TYPE *pmsg;
USR_LIST_TYPE *n;
#if 1
/* 根据list 遍历 整个链表,并打印信息 */
list_for_each_entry_safe(pmsg,n, &msg_head, list){
if(pmsg->index == index){
printf("del list 1 index:%d data:%d\n", pmsg->index, pmsg->data);
list_del(&pmsg->list);
free(pmsg);
}
}
printf("del success....\r\n");
#endif
#if 1
struct list_head *pos,*tmp;
list_for_each_safe(pos,tmp,&msg_head)
{
pmsg = list_entry(pos, USR_LIST_TYPE, list);
if(pmsg->index == (index +1)){
printf("del list 2 index:%d data:%d pon:%X %X\n", pmsg->index, pmsg->data,pos,&pmsg->list);
list_del(pos);
free(pmsg);
}
}
#endif
return 0;
}
int main(void) {
TEST_TYPE tests = {1,2};
int *ptr = &tests.data2;
printf("data1 offset:%d\n", offsetof(TEST_TYPE, data1));
printf("data2 offset:%d\n", offsetof(TEST_TYPE, data2));
printf("ptr addr:%d test addr:%d\n", ptr,&tests);
printf("tests addr:%d\n", container_of(ptr, TEST_TYPE, data2));
list_add_test();
list_del_test(3);
list_print();
return 0;
}