Linux中关于内核链表的代码实例分享
发布时间 - 2017-08-08 00:00:00 点击率:次这篇文章主要介绍了linux中的内核链表实例详解的相关资料,链表中一般都要进行初始化、插入、删除、显示、释放链表,寻找节点这几个操作,需要的朋友可以参考下
Linux中的内核链表实例详解
链表中一般都要进行初始化、插入、删除、显示、释放链表,寻找节点这几个操作,下面我对这几个操作进行简单的介绍,因为我的能力不足,可能有些东西理解的不够深入,造成一定的错误,请各位博友指出。
A、Linux内核链表中的几个主要函数(下面是内核中的源码拿出来给大家分析一下)
1)初始化:
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0) // ptr为struct list_head,其中包括两个指针next和prev,这里已经可以看出内核链表是双向循环链表2)尾部插入:
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
} //尾部插入,传入的参数是新节点中的两个指针和头结点中的两个指针3)头部插入函数
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
} //头插入函数,传入的参数是新节点中的两个指针和头结点中的两个指针4)删除节点函数
static inline void list_del(struct list_head *entry) //传入要删除节点中的指针域
{
__list_del(entry->prev, entry->next);//两个参数分别为所删除节点前一个节点和后一个节点
entry->next = (void *) 0;//删除节点后置为空
entry->prev = (void *) 0;
}5)显示函数(如果要打印出链表中的信息的话要自己写成打印的函数,比如printf,因为这个其实是一个遍历的函数,没有显示的功能)
#define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /* 这个函数用于遍历链表 pos为节点指针, head是头结点中的两个指针的地址 member为各节点中的指针域 */
6)删除链表
#define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) //这里面的pos和n都是list_head指针,n指针是用于在删除时不让链表断链
7)寻找节点(这也是用的内核中的遍历函数)
#define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ &pos->member!= (head); \ pos = list_entry(pos->member.next, typeof(*pos), member))
B.下面来段代码给大家看看具体的运用方法
#include"kernel.h" #include#include #include typedef struct list_node { int data; struct list_head list;//节点的指针域是被封装在struct list_head这个结构体内 //这个结构体中包括struct list_head *next,*prev }*node,node1; node init_head(node head)//初始化空链表 { head = (node)malloc(sizeof(node1));//为节点分配空间 if(head == NULL) { perror("head"); return NULL; } INIT_LIST_HEAD(&(head->list));//#define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0)//调用内核中的初始化函数,传入的参数是 //节点的中两个指针,即struct list_head结构体中的两个指针 return head; } node insert_tail(node head,int data)//尾部插入函数 { node new = (node)malloc(sizeof(node1));//为新节点分配空间 if(new == NULL)//判断一下分配空间是否成功 { perror("new:"); return NULL; } new->data = data; list_add_tail(&(new->list),&(head->list));//调用内核中的从尾部插入的函数,传入的参数为新节点中的两个指针 //和头结点中的两个指针 return 0; } head_insert_node(node head,int data)//头插入函数 { node new;//创建一个新节点 new = (node)malloc(sizeof(node1));//为新节点分配空间 if(new == NULL)//判断一下分配空间是否成功 { perror("new:"); return 0; } new->data = data; list_add(&(new->list),&(head->list));//调用内核中从头插入的函数,传入的参数为新节点的两个指针和头结点的两个指针 return 0; } node search_node(node head,int data)//寻找节点函数 { node p = NULL; list_for_each_entry(p,&(head->list),list) //内核中的遍历函数 { if(p->data == data) //p即为需要找的节点 { printf("found the data:%d\n",p->data); goto OK; } } puts("not found the data!"); return NULL; OK: return p; } int show_node(node tmp) { if(tmp == NULL) { puts("tmp is NULL!"); return -1; } printf("the data is %d\n",tmp->data); return 0; } int delete_node(node head,int data) { node p = NULL; list_for_each_entry(p,&(head->list),list) { if(p->data == data) { printf("found the data which you want to delete!\n"); goto f; } } f: list_del(&(p->list)); free(p); return 0; } int show_list(node head) { node p = NULL; list_for_each_entry(p,&(head->list),list) { printf("data:%d\n",p->data); } return 0; } int delete_list(node head)//删除链表函数 { node p,q; list_for_each_entry_safe(p,q,&(head->list),list)//这是内核中的安全删除函数 { list_del(&(p->list)); free(p); } list_del(&(head->list)); free(head); return 0; } int main(int argc,char **argv) { node head; node tmp; head = init_head(head);//初始化空链表函数 insert_tail(head,45);//从末尾插入函数 insert_tail(head,55); insert_tail(head,65); head_insert_node(head,75);//从头插入函数 show_list(head); //显示链表函数 tmp = search_node(head,55);//寻找结点函数 show_node(head); delete_node(head,55); //show_list(head); delete_list(head);//删除链表函数 return 0; }
# linux
# 链表
# 遍历
# 这几个
# 都要
# 都是
# 是一个
# 这是
# 几个
# 我对
# 给大家
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Java类加载基本过程详细介绍
如何快速查询网站的真实建站时间?
Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载
长沙企业网站制作哪家好,长沙水业集团官方网站?
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?
Python3.6正式版新特性预览
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
如何选择可靠的免备案建站服务器?
JavaScript如何实现类型判断_typeof和instanceof有什么区别
如何快速生成ASP一键建站模板并优化安全性?
Laravel如何优化应用性能?(缓存和优化命令)
Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】
进行网站优化必须要坚持的四大原则
Laravel路由怎么定义_Laravel核心路由系统完全入门指南
如何在Ubuntu系统下快速搭建WordPress个人网站?
Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】
北京的网站制作公司有哪些,哪个视频网站最好?
laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
制作公司内部网站有哪些,内网如何建网站?
如何在IIS7上新建站点并设置安全权限?
深入理解Android中的xmlns:tools属性
标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
Laravel模型事件有哪些_Laravel Model Event生命周期详解
开心动漫网站制作软件下载,十分开心动画为何停播?
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
大学网站设计制作软件有哪些,如何将网站制作成自己app?
Android自定义控件实现温度旋转按钮效果
Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】
Laravel如何使用查询构建器?(Query Builder高级用法)
使用豆包 AI 辅助进行简单网页 HTML 结构设计
魔毅自助建站系统:模板定制与SEO优化一键生成指南
Laravel如何编写单元测试和功能测试?(PHPUnit示例)
Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复
Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践
ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
如何彻底卸载建站之星软件?
5种Android数据存储方式汇总
如何批量查询域名的建站时间记录?
Edge浏览器怎么启用睡眠标签页_节省电脑内存占用优化技巧
如何用西部建站助手快速创建专业网站?
大连网站制作公司哪家好一点,大连买房网站哪个好?
如何在橙子建站中快速调整背景颜色?
Laravel怎么实现验证码(Captcha)功能
Laravel如何处理CORS跨域请求?(配置示例)
高防服务器租用指南:配置选择与快速部署攻略
Laravel怎么实现模型属性的自动加密


!= (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))