码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构-内核的双向循环链表-简单实现

时间:2016-03-03 17:32:50      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:

list.h

技术分享
#ifndef LIST_H__
#define LIST_H__

struct list_head
{
    struct list_head *prev ;
    struct list_head *next ;
};

#define LIST_HEAD_INIT(name)        { &(name), &(name) }
#define LIST_HEAD(name)             struct list_head name = LIST_HEAD_INIT(name)
#define __list_for_each(pos, head)  for (pos = (head)->next; pos != (head); pos = pos->next)


/*
  const typeof( ((type *)0)->member ) *__mptr = (ptr);
     --->定义类型为(typeof获取member的类型)的指针* __mptr,并将ptr的值(实际地址)赋值给__mptr;
  (type *)( (char *)__mptr - offsetof(type,member) );
     --->用member实际的地址 - 偏移地址 就是数据结构实例的地址;
*/
#define container_of(ptr, type, member) ({                      const typeof( ((type *)0)->member ) *__mptr = (ptr);                (type *)( (char *)__mptr - offsetof(type,member) );})


//offsetof宏:member成员到type结构实例类型的高度:
//假设type结构的实例的地址是0 强转成char(*),再找到->member,就找到member距离结构体实例的偏移
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)


//ptr->cur:指向成员member的地址
//member:成员在结构实例内部的名称,如果为数组,需要下标
//type->struct score_st需要返回的结构实例类型
#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;
}

static inline void list_add(struct list_head *new, struct list_head *head)
{
    __list_add(new, head, head->next);
}


#endif
View Code

main.c

技术分享
#include <stdio.h>
#include <stdlib.h>
#include "list.h"

#define NAMESIZE    32
//定义结构体
struct score_st
{
    int id ;
    char name[NAMESIZE] ;
    int math ;
    int chinese ;
    struct list_head node ;//*PREV *NEXT
};
//打印函数
static void print_s(struct score_st *d) 
{
    printf("%d %s %d %d \n",d->id ,d->name , d->math , d->chinese);
}



int main()
{
    int i ; 
    struct score_st *datap ;
    struct list_head *cur ;
    //1.创建头
    LIST_HEAD(head);
    //2.头部插入8个节点并赋值
    for(i = 0 ; i < 8 ; i++)
    {   
        datap = malloc(sizeof(*datap));
        if(datap == NULL)
            exit(1);
        datap->id = i ; 
        snprintf(datap->name,NAMESIZE ,"stu%d",i);
        datap->math = rand()%100;
        datap->chinese = rand()%100;
        list_add(&datap->node,&head);
    }   
    //3.打印链表
    __list_for_each(cur, &head)
    {   
        datap = list_entry(cur,struct score_st,node);
        print_s(datap);
    }   
    //4.查找链表内部id为5的节点
    __list_for_each(cur, &head)
    {   
        datap = list_entry(cur,struct score_st,node);
        if(datap->id == 5)
            break;
    }   
    //5.查找结果并打印
    if(cur == &head)
        printf("can not find \n");
    else
        print_s(datap);
    exit(0);
}
View Code

$:make main

ps:内核的代码可以查看:

root # cd /usr/src/kernels/2.6.32-358.el6.x86_64/include/linux/

查找关键字:

root # grep "#define container_of(" -R .
//.  --->当前路径
//R--->递归查找

涉及到的.h文件有:

  kernel.h-----container_of

  list.h---------双向循环链表的实现

  stddef.h-----offsetof

数据结构-内核的双向循环链表-简单实现

标签:

原文地址:http://www.cnblogs.com/muzihuan/p/5239397.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!