zoukankan      html  css  js  c++  java
  • linux内核链表的移植与使用

    一、
       Linux内核链表为双向循环链表,和数据结构中所学链表类似,具体不再细讲。由于在内核中所实现的函数十分经典,所以移植出来方便后期应用程序中的使用。

    /*********************************** 
    文件名:kernel link list of linux.h
    作者:Bumble Bee
    日期:2015-1-31 
    功能:移植linux内核链表 
    ************************************/
    
    /*链表结点数据结构*/
    struct list_head 
    {
        struct list_head *next, *prev;
    };
    
    /***********************************
    函数名:  INIT_LIST_HEAD
    参数:    指向list_head结构体的指针
    返回值:  无
    函数功能:通过将前向指针和后向指
              针指向自己来创建一个链表表
              头
    ***********************************/
    static inline void INIT_LIST_HEAD(struct list_head *list)
    {
        list->next = list;
        list->prev = list;
    }
    
    /***********************************
    函数名:  __list_add
    参数:    @new:要插入结点的指针域
              @prev:前一个节点的指针域
              @next:后一个节点的指针域
    返回值:  无
    函数功能:在两个已知节点中插入新节点
    ***********************************/
    
    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;
    }
    extern void __list_add(struct list_head *new,
                   struct list_head *prev, struct list_head *next);
    
    /**************************************
    函数名:  list_add
    参数:    @new:要插入结点的指针域
              @head:要插入链表表头的指针域
    返回值:  无
    函数功能:在已知链表头部插入新节点
    **************************************/
    
    static inline void list_add(struct list_head *new, struct list_head *head)
    {
        __list_add(new, head, head->next);
    }
    
    
    /**************************************
    函数名:  list_add_tail
    参数:    @new:要插入结点的指针域
              @head:要插入链表表头的指针域
    返回值:  无
    函数功能:在已知链表尾部插入新节点
    **************************************/
    static inline void list_add_tail(struct list_head *new, struct list_head *head)
    {
        __list_add(new, head->prev, head);
    }
    
    /*************************************
    函数名:  list_for_each
    参数:    @pos:遍历链表的光标
              @head:要遍历链表的表头
    返回值:  无
    函数功能:实质为一个for循环,遍历链表
    *************************************/
    #define list_for_each(pos, head) 
        for (pos = (head)->next;pos != (head); 
            pos = pos->next)
    
    
    /*************************************************
    函数名:  list_entry
    参数:    @ptr:节点中list_head的地址
              @type:节点的类型
              @member:list_head 在结构体中成员的名字
    返回值:  节点的地址,已被强制转化为type型指针
    函数功能:将节点最低位置假设为0,此时取成员member
              的地址即为offset,再用list_head的地址将
              offset减去即为节点的地址
    **************************************************/
    #define list_entry(ptr, type, member) 
        container_of(ptr, type, member)
    
    #define container_of(ptr, type, member) ({            
        const typeof(((type *)0)->member) * __mptr = (ptr);    
        (type *)((char *)__mptr - offsetof(type, member)); })
    
    #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    
    
    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);
    }

    二、设计应用程序测试链表

    /**************************** 
    文件名:homework.c
    作者:Bumble Bee
    日期:2015-1-31 
    功能:测试移植的linux内核链表 
    *****************************/
    
    #include <stdio.h>
    #include "kernel link list of linux.h"
    
    struct score
    {
        int num;
        int english;
        int math;
        struct list_head list;
    };
    
    struct score stu1,stu2,stu3,*temp;
    
    struct list_head score_head,*pos;
    
    int main()
    {
        INIT_LIST_HEAD(&score_head);                    //创建链表函数
    
        stu1.num = 1;
        stu1.english = 0;
        stu1.math = 0;
        list_add_tail(&(stu1.list),&(score_head));
    
        stu2.num = 2;
        stu2.english = 1;
        stu2.math = 1;
        list_add_tail(&(stu2.list),&(score_head));
    
        stu3.num = 3;
        stu3.english = 2;
        stu3.math = 2;
        list_add_tail(&(stu3.list),&(score_head));
    
        list_del(&(stu2.list));
    
        list_for_each(pos,&(score_head))
        {
            temp = list_entry(pos,struct score,list);
            printf("No %d,english is %d,math is %d
    ",temp->num,temp->english,temp->math);
        }
    
        return 0;
    
    }

    三、运行结果

      

  • 相关阅读:
    [No000088]并行循环vs普通循环
    [No000087]Linq排序,SortedList排序,二分法排序性能比较
    [No000086]C#foreach集合被改变,报错处理方案
    [No000085]C#反射Demo,通过类名(String)创建类实例,通过方法名(String)调用方法
    [No000084]C# 使用Log4Net(1)-快速建立一个demo
    [No000082]Convert和Parse的区别/Convert.ToInt32()与int.Parse()的区别
    [No000081]SVN学习笔记1-服务端搭建
    [No00007F]2016-面经[下] 英文简历写作技巧
    [No00007E]2016-面经[中]
    [No00007D]2016-面经[上]
  • 原文地址:https://www.cnblogs.com/51qianrushi/p/4294406.html
Copyright © 2011-2022 走看看