Makefile
CC=gcc main:main.o clean: $(RM) *.o main .PHONY:clean
main.c
#include "list.h" #include <stdio.h> typedef struct { unsigned long gp; // (group<<3)|(pnum&0x7) unsigned long on; // on or off unsigned long delay; unsigned long count; struct list_head p; }GPIO_NODE; int main(int argc, const char *argv[]) { GPIO_NODE *a1; GPIO_NODE *a2; GPIO_NODE *a3; GPIO_NODE *a4; struct list_head *q = NULL; struct list_head *q1 = NULL; GPIO_NODE *a5; LIST_HEAD(gpio_list); a1 = (GPIO_NODE *)malloc(sizeof(GPIO_NODE)); a2 = (GPIO_NODE *)malloc(sizeof(GPIO_NODE)); a3 = (GPIO_NODE *)malloc(sizeof(GPIO_NODE)); a4 = (GPIO_NODE *)malloc(sizeof(GPIO_NODE)); a1->gp = 1; a1->on = 1; a1->delay = 1; a1->count = 1; a2->gp = 2; a2->on = 2; a2->delay = 2; a2->count = 2; a3->gp = 3; a3->on = 3; a3->delay = 3; a3->count = 3; a4->gp = 4; a4->on = 4; a4->delay = 4; a4->count = 4; list_add_tail(&(a1->p), &gpio_list); list_add_tail(&(a2->p), &gpio_list); list_add_tail(&(a3->p), &gpio_list); list_add_tail(&(a4->p), &gpio_list); list_for_each_safe(q, q1, &gpio_list) { a5 = list_entry(q, GPIO_NODE, p); if(a5->gp > 3) { printf("a5->gp = %d\n", a5->gp); printf("a5->on = %d\n", a5->on); printf("a5->delay = %d\n", a5->delay); printf("a5->count = %d\n", a5->count); if (!list_empty(&gpio_list)) { list_del(q); printf("free node %d\n", a5->gp); free(a5); } } } list_for_each_safe(q, q1, &gpio_list) { a5 = list_entry(q, GPIO_NODE, p); printf("a5->gp = %d\n", a5->gp); printf("a5->on = %d\n", a5->on); printf("a5->delay = %d\n", a5->delay); printf("a5->count = %d\n", a5->count); if (!list_empty(&gpio_list)) { list_del(q); printf("free node %d\n", a5->gp); free(a5); } } return 0; }
list.h
http://files.cnblogs.com/pengdonglin137/list.rar
参考: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:
list.c:
测试代码list_test.c:
Makefile:
代码片段----内核链表使用一例,布布扣,bubuko.com
原文:http://www.cnblogs.com/pengdonglin137/p/3583896.html