数据结构-内核的双向循环链表-简单实现
Posted muzihuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构-内核的双向循环链表-简单实现相关的知识,希望对你有一定的参考价值。
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
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); }
$: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
以上是关于数据结构-内核的双向循环链表-简单实现的主要内容,如果未能解决你的问题,请参考以下文章