原文链接:http://blog.csdn.net/xnwyd/article/details/7359373

Linux内核链表的核心思想是:在用户自定义的结构A中声明list_head类型的成员p,这样每个结构类型为A的变量a中,都拥有同样的成员p,如下:

struct A{

int property;

struct list_head p;

}

其中,list_head结构类型定义如下:

struct list_head {

struct list_head *next,*prev;

};

list_head拥有两个指针成员,其类型都为list_head,分别为前驱指针prev和后驱指针next。

假设:

1)多个结构类型为A的变量a1...an,其list_head结构类型的成员为p1...pn

2)一个list_head结构类型的变量head,代表头节点

使:

1)head.next= p1 ; head.prev = pn

2) p1.prev = head,p1.next = p2;

3)p2.prev= p1 , p2.next = p3;

n)pn.prev= pn-1 , pn.next = head

以上,则构成了一个循环链表。

p是嵌入到a中的,p与a的地址偏移量可知,又因为head的地址可知,所以每个结构类型为A的链表节点a1...an的地址也是可以计算出的,从而可实现链表的遍历,在此基础上,则可以实现链表的各种操作。

下面是从linux内核中移植出来的简单链表,list.h和list.c:

list.h:

#ifndef _INIT_LIST_H_
#define _INIT_LIST_H_

#ifndef offsetof
/* Offset of member MEMBER in a struct of type TYPE. */
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

struct listnode
{
    struct listnode *next;
    struct listnode *prev;
};

#define node_to_item(node, container, member) \
    (container *) (((char*) (node)) - offsetof(container, member))

#define list_declare(name) \
    struct listnode name = { \
        .next = &name, \
        .prev = &name, \
    }

#define list_for_each(node, list) \
    for (node = (list)->next; node != (list); node = node->next)

#define list_for_each_reverse(node, list) \
    for (node = (list)->prev; node != (list); node = node->prev)

void list_init(struct listnode *list);
void list_add_tail(struct listnode *list, struct listnode *item);
void list_remove(struct listnode *item);

#define list_empty(list) ((list) == (list)->next)
#define list_head(list) ((list)->next)
#define list_tail(list) ((list)->prev)

#endif
list.h

相关文章: