linux中链表的使用【转】
转自:http://blog.csdn.net/finewind/article/details/8074990
Linux下链表的使用方法跟我们常规的不一样,通常情况下,链表的next指针都指向节点的起始位置,但linux中链表指向的是下一个节点中链表所在的地址,这是一种很好的处理方法,不用每换一种数据结构就处理,这种方法的难点在于从链表地址中推算出原始结构体的地址。整理后的代码如下:list.h[cpp] view plain copy#ifndef _LIST_H_ #define _LIST_H_ /********************************************************** 功能: 计算MEMBER成员在TYPE结构体中的偏移量 **********************************************************/ #define offsetof(TYPE, MEMBER) (unsigned long)(&(((TYPE*)0)->MEMBER)) /********************************************************** 功能: 计算链表元素的起始地址 输入: ptr: type结构体中的链表指针 type: 结构体类型 member: 链表成员名称 **********************************************************/ #define container_of(ptr, type, member) (type *)((char*)(ptr) - offsetof(type, member)) #define LIST_HEAD_INIT(name) {&(name), &(name)} struct list { struct list *prev, *next; }; static inline void list_init(struct list *list) { list->next = list; list->prev = list; } static inline int list_empty(struct list *list) { return list->next == list; } // 将new_link插入到link之前 static inline void list_insert(struct list *link, struct list *new_link) { new_link->prev = link->prev; new_link->next = link; new_link->prev->next = new_link; new_link->next->prev = new_link; } /********************************************************** 功能: 将new_link节点附加到list链表中 **********************************************************/ static inline void list_append(struct list *list, struct list *new_link) { list_insert(list, new_link); } /********************************************************** 功能: 从链表中移除节点 **********************************************************/ static inline void list_remove(struct list *link) { link->prev->next = link->next; link->next->prev = link->prev; } /********************************************************** 获取link节点对应的结构体变量地址 link: 链表节点指针 type: 结构体类型名 member: 结构体成员变量名 **********************************************************/ #define list_entry(link, type, member) container_of(link, type, member) /********************************************************** 获取链表头节点对应的结构体变量地址 list: 链表头指针 type: 结构体类型名 member: 结构体成员变量名 Note: 链表头节点实际为链表头的下一个节点,链表头未使用,相当于哨兵 **********************************************************/ #define list_head(list, type, member) list_entry((list)->next, type, member) /********************************************************** 获取链表尾节点对应的结构体变量地址 list: 链表头指针 type: 结构体类型名 member: 结构体成员变量名 **********************************************************/ #define list_tail(list, type, member) list_entry((list)->prev, type, member) /********************************************************** 返回链表下一个节点对应的结构体指针 elm: 结构体变量指针 type: 结构体类型名 member: 结构体成员变量名(链表变量名) **********************************************************/ #define list_next(elm,type,member) list_entry((elm)->member.next, type, member) /********************************************************** 遍历链表所有节点对应的结构体 pos : 结构体指针 type : 结构体类型名 list : 链表头指针 member : 结构体成员变量名(链表变量名) Note : 链表头未使用,因此遍历结束后,pos指向的不是有效的结构体地址 **********************************************************/ #define list_for_each_entry(pos, type, list, member) \ for (pos = list_head(list, type, member); \ &pos->member != (list); \ pos = list_next(pos, type, member)) /********************************************************** example function **********************************************************/ void list_example(void); #endif 测试代码:list.cpp [cpp] view plain copy#include "stdafx.h" #include "list.h" #include <stdlib.h> struct list g_list = LIST_HEAD_INIT(g_list); struct test { int a; int b; char c; struct list link; }; void CreateData(int a, int b, char c) { struct test *pdata = (struct test *)malloc(sizeof(struct test)); pdata->a = a; pdata->b = b; pdata->c = c; list_append(&g_list, &(pdata->link)); } void listTest(void) { // 创建节点 CreateData(0,0,0); CreateData(10,11,12); CreateData(20,21,22); CreateData(30,31,32); CreateData(40,41,42); // 取节点 struct list *templist = &g_list; struct test *pdata; pdata = list_entry(templist->next, struct test, link); templist = templist->next; pdata = list_entry(templist->next, struct test, link); // 遍历1 for (templist = g_list.next; templist != &g_list; templist = templist->next) pdata = list_entry(templist, struct test, link); // 遍历2 //pdata = list_head(&g_list, struct test, link); for (pdata = list_head(&g_list, struct test, link); &(pdata->link) != &g_list; pdata = list_next(pdata, struct test, link)) { pdata->a = 1; } // 遍历3 list_for_each_entry(pdata, struct test, &g_list, link) { pdata->b = 2; } }
linux中链表的使用【转】相关推荐
- linux内核中链表代码分析---list.h头文件分析(二)【转】
转自:http://blog.chinaunix.net/uid-30254565-id-5637598.html linux内核中链表代码分析---list.h头文件分析(二) 16年2月28日16 ...
- c linux time微秒_Linux基础知识(Linux系统、Linux中的链表)
Linux系统简介 Linux系统的结构及特点 Linux系统的结构图如下图所示: 从上图可以看出,Linux是一个典型的宏内核(一体化内核)结构.硬件系统上面时硬件抽象层,在硬件抽象层上面时内核服务 ...
- linux中_Linux基础知识(Linux系统、Linux中的链表)
Linux系统简介 Linux系统的结构及特点 Linux系统的结构图如下图所示: 从上图可以看出,Linux是一个典型的宏内核(一体化内核)结构.硬件系统上面时硬件抽象层,在硬件抽象层上面时内核服务 ...
- linux内核中链表代码分析---list.h头文件分析(一)
linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17:13:14 在学习数据结构时,有一个重要的知识点就是链表.对于链表的一些基本操作,它的最好学习资料就是内核中的li ...
- 超专业解析!10分钟带你搞懂Linux中直接I/O原理
导语 | 本文主要以一张图为基础,向大家介绍Linux在I/O上做了哪些事情,即Linux中直接I/O原理,希望本文的经验和思路能为读者提供一些帮助和思考. 引言 我们先看一张图: 这张图大体上描述了 ...
- linux内核链表以及list_entry--linux内核数据结构(一)
传统的链表实现 之前我们前面提到的链表都是在我们原数据结构的基础上增加指针域next(或者prev),从而使各个节点能否链接在一起, 比如如下的结构信息 typedef struct fox { un ...
- linux内核链表分析
一.常用的链表和内核链表的区别 1.1 常规链表结构 通常链表数据结构至少应包含两个域:数据域和指针域,数据域用于存储数据,指针域用于建立与下一个节点的联系.按照指针域的组织以及各个节 ...
- Linux中文件描述符1,linux内核中的文件描述符(一)--基础知识简介
原标题:linux内核中的文件描述符(一)--基础知识简介 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blo ...
- linux软中断优先级,Linux中软中断机制分析
Linux中软中断实现分析 在Linux中最多可以注册32个软中断,目前系统用了6个软中断,他们为:定时器处理.SCSI处理.网络收发处理以及Tasklet机制,这里的tasklet机制就是用来实现下 ...
最新文章
- linux vps 自动拒绝弱口令ssh扫描
- 【Android View绘制之旅】Draw过程
- [T-ARA][Goodbye, OK]
- swift Array 数组
- 笔记本禁用自带键盘攻略-------针对shift默认按下的解决方案
- 云南边境“国际新娘”享受国家防艾免费政策
- Mybatis——返回类型为 集合嵌套集合 应该如何处理
- javax.script.ScriptException: ReferenceError: xxx is not defined in eval
- Tomcat提示“XDB 的服务器 localhost 要求用户名和密码”
- finally 嵌套_学习 Rust【2】减少代码嵌套
- final关键字的用法
- [网络结构]DenseNet网络结构
- maven项目打包命令
- 按键精灵手机助手之字符串处理
- IQ不平衡数字域校准方案
- 从数字艺术品到 NFT
- 《SEM长尾搜索营销策略解密》一一2.1 起因:核心词成本过高
- C语言题目:新胖子公式 (10 分)
- SpringBoot 整合 ElasticSearch 实现京东搜索(手把手带你完成一个 “前后端分离项目”)
- 2018年秋季校招投递记录
热门文章
- 干货丨卷积神经网络工作原理的直观解释
- python如何将图片的像素矩阵绘制成图片(python,matplotlib):TypeError: Invalid shape (1, 28, 28) for image data
- (已解决)RuntimeError: CUDA error: device-side assert triggered CUDA kernel errors
- pytorch中的torch.tensor.repeat以及torch.tensor.expand用法
- 喻国明:“元宇宙”背后的未来图景
- Science公布2021年度十大科学突破,AI这项前所未有的突破上榜
- 浙江发布数字化改革标准化体系建设方案,将于2025年底建成
- 我国的人工智能芯片的市场规模及发展前景
- 原创工作发表难之叶公好龙
- 未来趋势?通过无线技术管理汽车电池,可消除90%物理布线