当前位置: 首页 > news >正文

openharmony内核中不一样的双向链表

不一样的双向链表

  • 链表初识别
  • 遍历双向链表
  • 参考链接

链表初识别

最近看openharmony的内核源码时看到一个有意思的双向链表,结构如下

typedef struct LOS_DL_LIST{struct LOS_DL_LIST *pstPrev; //前驱节点struct LOS_DL_LIST *pstNext; //后继节点
}LOS_DL_LIST;

不知道大家看上面的结构体有没有发现诡异的地方?
没错,这个双向链表咋没有数据呢???
其实LOS_DL_LIST不能单独拿来用,他需要放置于内容结构体上,如下图
在这里插入图片描述
现在有个任务,给你一个LOS_DL_LIST,如何获得内容结构体的首地址?
具体如何做,我们看看下面的两个宏,并结合实际的例子来进行分析

typedef unsigned long       UINTPTR;
//获取指定结构体内的成员相对于结构体起始地址的偏移量
#define LOS_OFF_SET_OF(type, member) ((UINTPTR)&((type *)0)->member)//根据结构体成员地址、结构体类型、结构体成员名,推出结构体的首地址并强制转换
#define LOS_DL_LIST_ENTRY(item, type, member) \((type *)((void*)((char*)(item) - LOS_OFF_SET_OF(type, member))))

LOS_OFF_SET_OF的用法可以看看我的这篇博客:c语言取结构体的偏移量

#include <iostream>
#include<string>
#include<string.h>
using namespace std;
typedef unsigned long       UINTPTR;//获取指定结构体内的成员相对于结构体起始地址的偏移量
#define LOS_OFF_SET_OF(type, member) ((UINTPTR)&((type *)0)->member)//根据结构体成员地址、结构体类型、结构体成员名,推出结构体的首地址并强制转换
#define LOS_DL_LIST_ENTRY(item, type, member) \((type *)((void*)((char*)(item) - LOS_OFF_SET_OF(type, member))))typedef struct LOS_DL_LIST{struct LOS_DL_LIST *pstPrev;struct LOS_DL_LIST *pstNext;
}LOS_DL_LIST;//定义一个简单的结构体
typedef struct Book{char name[20];char author[20];double price;LOS_DL_LIST otherBook;} Book;//输出结构体信息
void print_book(Book *book){cout<<"书名:"<<book->name<<" ,作者:"<<book->author<<" ,价格:"<<book->price<<endl;
}int main(){Book book = {"三国演义", "罗贯中",100.5};Book * book_ = LOS_DL_LIST_ENTRY(&book.otherBook,Book,otherBook);cout<<(book_ == &book)<<endl;print_book(&book);print_book(book_);
}

在这里插入图片描述

从上面的结果可以看出,使用LOS_DL_LIST_ENTRY也是可以获得内容结构体的首地址

遍历双向链表

直接看我写的demo吧

#include <iostream>
#include<string>
#include<string.h>
using namespace std;
typedef unsigned long       UINTPTR;//获取指定结构体内的成员相对于结构体起始地址的偏移量
#define LOS_OFF_SET_OF(type, member) ((UINTPTR)&((type *)0)->member)//根据结构体成员地址、结构体类型、结构体成员名,推出结构体的首地址并强制转换
#define LOS_DL_LIST_ENTRY(item, type, member) \((type *)((void*)((char*)(item) - LOS_OFF_SET_OF(type, member))))typedef struct LOS_DL_LIST{struct LOS_DL_LIST *pstPrev;struct LOS_DL_LIST *pstNext;
}LOS_DL_LIST;//定义一个简单的结构体
typedef struct Book{char name[20];char author[20];double price;LOS_DL_LIST otherBook;} Book;//输出结构体信息
void print_book(Book *book){cout<<"书名:"<<book->name<<" ,作者:"<<book->author<<" ,价格:"<<book->price<<endl;
}
//头插法添加节点
void LOS_ListAdd(LOS_DL_LIST *list, LOS_DL_LIST *node)
{node->pstNext = list->pstNext;node->pstPrev = list;list->pstNext->pstPrev = node;list->pstNext = node;
}
//初始化头节点
void LOS_ListInit(LOS_DL_LIST *list)
{list->pstNext = list;list->pstPrev = list;
}//定义一个节点并初始化为双向链表节点
#define LOS_DL_LIST_HEAD(list) LOS_DL_LIST list = { &(list), &(list) }//获取双向链表中指定链表节点的下一个节点所在的结构体地址。
//接口的第一个入参表示的是链表中的头节点,第二个入参是指定的链表节点,
//第三个入参是要获取的结构体名称,第四个入参是链表在该结构体中的名称。
//如果链表节点下一个为链表头结点为空,返回NULL。
#define LOS_ListNextType(list, item, type, element) ({           \type *__t;                                                   \if ((item)->pstNext == list) {                               \__t = NULL;                                              \} else {                                                     \__t = LOS_DL_LIST_ENTRY((item)->pstNext, type, element); \}                                                            \__t;                                                         \
})//获取双向链表中第一个链表节点所在的结构体地址,接口的第一个入参表示的是链表中的头节点,
//第二个入参是要获取的结构体名称,第三个入参是链表在该结构体中的名称。如果链表为空,返回NULL。
#define LOS_ListPeekHeadType(list, type, element) ({             \type *__t;                                                   \if ((list)->pstNext == list) {                               \__t = NULL;                                              \} else {                                                     \__t = LOS_DL_LIST_ENTRY((list)->pstNext, type, element); \}                                                            \__t;                                                         \
})
///遍历双向链表,并存储当前节点的后继节点用于安全校验
#define LOS_DL_LIST_FOR_EACH_SAFE(item, next, list)      \for (item = (list)->pstNext, next = (item)->pstNext; \(item) != (list);                               \item = next, next = (item)->pstNext)//遍历双向链表
#define LOS_DL_LIST_FOR_EACH(item, list) \for (item = (list)->pstNext;         \(item) != (list);               \item = (item)->pstNext)//遍历指定双向链表,获取包含该链表节点的结构体地址,并存储包含当前节点的后继节点的结构体地址
#define LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, next, list, type, member)               \for (item = LOS_DL_LIST_ENTRY((list)->pstNext, type, member),                     \next = LOS_DL_LIST_ENTRY((item)->member.pstNext, type, member);              \&(item)->member != (list);                                                   \item = next, next = LOS_DL_LIST_ENTRY((item)->member.pstNext, type, member)) void initBook(LOS_DL_LIST *head){Book *book1 = (Book*)malloc(sizeof(Book));  //堆上分配Book *book2 = (Book*)malloc(sizeof(Book));Book *book3 = (Book*)malloc(sizeof(Book));Book *book4 = (Book*)malloc(sizeof(Book));memset(book1,0,sizeof(Book));memset(book2,0,sizeof(Book));memset(book3,0,sizeof(Book));memset(book4,0,sizeof(Book));strcpy(book1->author,"罗贯中");strcpy(book1->name,"三国演义");book1->price = 45.99;strcpy(book2->author,"曹雪芹");strcpy(book2->name,"红楼梦");book2->price = 30.3;strcpy(book3->author,"吴承恩");strcpy(book3->name,"西游记");book3->price = 50.38;strcpy(book4->author,"施耐庵");strcpy(book4->name,"水浒传");book4->price = 66.3;LOS_ListAdd(head,&(book1->otherBook));LOS_ListAdd(head,&(book2->otherBook));LOS_ListAdd(head,&(book3->otherBook));LOS_ListAdd(head,&(book4->otherBook));LOS_DL_LIST *item = NULL;LOS_DL_LIST *next = NULL;LOS_DL_LIST_FOR_EACH_SAFE(item, next, head){Book *bookbook = LOS_DL_LIST_ENTRY(item,Book,otherBook);print_book(bookbook);}
}
int main(){LOS_DL_LIST *head= (LOS_DL_LIST*)malloc(sizeof(LOS_DL_LIST));LOS_ListInit(head);initBook(head);cout<<"======================\n";LOS_DL_LIST pBook;LOS_ListInit(&pBook);Book book = {"三国演艺", "罗贯中",100.5};Book book1 = {"红楼梦", "曹雪芹",200.5};Book book2 = {"西游记",  "吴承恩",150.1};Book book3 = {"水浒传", "施耐庵",180.4};Book * book_ = LOS_DL_LIST_ENTRY(&book.otherBook,Book,otherBook);cout<<(book_ == &book)<<endl;LOS_ListAdd(&pBook,&(book.otherBook));LOS_ListAdd(&pBook,&(book1.otherBook));LOS_ListAdd(&pBook,&(book2.otherBook));LOS_ListAdd(&pBook,&(book3.otherBook));cout<<"获取双向链表下一个数据节点:\n";Book *b = LOS_ListNextType(&pBook, &book3.otherBook, Book, otherBook);if(b != NULL)print_book(b);cout<<"获取双向链表下一个数据节点结束\n\n";cout<<"获取双向链表第一个数据节点:\n";Book *firstBook = LOS_ListPeekHeadType(&pBook,Book,otherBook);print_book(firstBook);cout<<"获取双向链表第一个数据节点结束\n\n";cout<<"while 遍历:\n";LOS_DL_LIST *book_item = pBook.pstNext;while(book_item != &pBook){Book *bookbook = LOS_DL_LIST_ENTRY(book_item,Book,otherBook);print_book(bookbook);book_item = book_item->pstNext;}cout<<"while 遍历结束:\n\n";cout<<"宏定义遍历\n";LOS_DL_LIST* item = NULL;LOS_DL_LIST*next = NULL;LOS_DL_LIST_FOR_EACH_SAFE(item, next, &pBook){Book *bookbook = LOS_DL_LIST_ENTRY(item,Book,otherBook);print_book(bookbook);}cout<<"宏定义遍历结束\n\n";cout<<"for each 遍历\n";LOS_DL_LIST_FOR_EACH(item,&pBook){Book *bookbook = LOS_DL_LIST_ENTRY(item,Book,otherBook);print_book(bookbook);}cout<<"for each 遍历结束\n\n\n";Book* book_item_item = NULL;Book* book_next = NULL;LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(book_item_item, book_next, &pBook, Book, otherBook){print_book(book_item_item);}}

在这里插入图片描述

参考链接

http://weharmonyos.com/blog/01.html

相关文章:

openharmony内核中不一样的双向链表

不一样的双向链表 链表初识别遍历双向链表参考链接 链表初识别 最近看openharmony的内核源码时看到一个有意思的双向链表&#xff0c;结构如下 typedef struct LOS_DL_LIST{struct LOS_DL_LIST *pstPrev; //前驱节点struct LOS_DL_LIST *pstNext; //后继节点 }LOS_DL_LIST;不…...

大文件删除不在回收站里怎么找回

在日常办公中&#xff0c;总会有一些新的文件产生&#xff0c;和用完后的文件清理掉。有时候不小心误删文件也是常有的事。但如果大文件删除不在回收站里怎么找回呢?遇到的小伙伴们请不要别急&#xff0c;只要按照下面的方法做就行了。 正常情况下删除会进入到回收站中&#x…...

Ubuntu22.04部署Pytorch2.0深度学习环境

文章目录 安装Anaconda创建新环境安装Pytorch2.0安装VS CodeUbuntu下实时查看GPU状态的方法小实验&#xff1a;Ubuntu、Windows10下GPU训练速度对比 Ubuntu安装完显卡驱动、CUDA和cudnn后&#xff0c;下面部署深度学习环境。 &#xff08;安装Ubuntu系统、显卡驱动、CUDA和cudn…...

php的面试集结(会持续更新)

PHP 高级工程面试题汇总 php面试 1.大型的分页查询 发现当表中有很多上万条数据时&#xff0c;越后的数据用limit分页显示就越慢&#xff08;>2秒&#xff09;&#xff0c;可能是mysql的特性所致。所以花了点时间总结实现了更优解决方案&#xff0c;最终实现毫秒级响应。…...

谁在成为产业经济发展的推车人?

区域发展的新蓝图中&#xff0c;京东云能做什么&#xff1f;它的角色是什么&#xff1f;这个问题背后&#xff0c;隐藏的不仅是京东云自身的能力和价值&#xff0c;更是其作为中国互联网云厂商的代表之一&#xff0c;对“技术产业”的新论证。 作者|皮爷 出品|产业家 关于云…...

上海无纺布制造商【盈兹】申请纳斯达克IPO上市,募资1100万美元

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;来自上海的无纺布制造商【盈兹】&#xff0c;近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申请在纳斯达克IPO上市&#xff0c;股票代码为&#xff08;ETZ&#…...

Build an SAP Fiori App(一)后面更新中

1.登录 SAP BTP Trial 地址&#xff1a; https://account.hanatrial.ondemand.com 流程可以参考 点击 serviced marketplace 搜索studio 点击创建 点击创建&#xff0c;点击view subscription 点击go to application 创建完成后 添加新链接 Field Value Name ES5 - if you’…...

关于GNSS技术介绍(二)

在上期文章中&#xff0c;我们介绍了GNSS技术的发展历程、原理&#xff0c;并对不同类型的定位技术进行了介绍&#xff0c;在本期文章中我们将继续讨论GNSS的优点与应用及其测试方法和解决方案。 GNSS的优点与应用 目前GNSS技术已经成为日常生活不可或缺的一部分&#xff0c;几…...

拿到新的服务器必做的五件事(详细流程,开发必看)

目录 1. 配置免密登录 基本用法 远程登录服务器&#xff1a; 第一次登录时会提示&#xff1a; 配置文件 创建文件 然后在文件中输入&#xff1a; 密钥登录 创建密钥&#xff1a; 2.部署nginx 一、前提条件 二、安装 Nginx 3.配置python虚拟环境 1.安装虚拟环境 …...

主机防病毒攻略之勒索病毒

勒索病毒并不是某一个病毒&#xff0c;而是一类病毒的统称&#xff0c;主要以邮件、程序、木马、网页挂马的形式进行传播&#xff0c;利用各种加密算法对文件进行加密&#xff0c;被感染者一般无法解密&#xff0c;必须拿到解密的私钥才有可能破解。 已知最早的勒索软件出现于 …...

Win10系统重装过程(一键装机)

相信不少小伙伴都有刷机重装系统的过程&#xff0c;那种镜像&#xff0c;up盘&#xff0c;压缩包等多个复杂过程也折磨的大伙不堪重负&#xff0c;因此本期带来简易版一键装机相应操作。 下载地址&#xff1a; 小心点击下方链接&#xff0c;点击即下载&#xff08;3.66GB&…...

查询优化之单表查询

建表 CREATE TABLE IF NOT EXISTS article ( id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, author_id INT(10) UNSIGNED NOT NULL, category_id INT(10) UNSIGNED NOT NULL, views INT(10) UNSIGNED NOT NULL, comments INT(10) UNSIGNED NOT NULL, title VARBI…...

ChatGPT写小论文

ChatGPT写小论文 只是个人对写小论文心得?从知乎,知网自己总结的,有问题,可以留个言我改一下 文章目录 ChatGPT写小论文-1.写论文模仿实战(狗头)0.论文组成1.好论文前提:2.标题3.摘要4.关键词5.概述6.实验数据、公式或者设计7.结论&#xff0c;思考8.参考文献 0.模仿1.喂大纲…...

公共资源包发布流程详解

文章目录 公有包发布并使用npm安装git仓库协议创建及使用 npm 私有包创建及使用 group npm 私有包私有仓账密存放位置 当公司各个系统都需要使用特定的业务模块时&#xff0c;这时候将代码抽离&#xff0c;发布到 npm 上&#xff0c;供下载安装使用&#xff0c;是个比较好的方案…...

设计模式简谈

设计模式是我们软件架构开发中不可缺失的一部分&#xff0c;通过学习设计模式&#xff0c;我们可以更好理解的代码的结构和层次。 设计原则 设计原则是早于设计方法出现的&#xff0c;所以的设计原则都要依赖于设计方法。这里主要有八个设计原则。 推荐一个零声学院免费教程&…...

day35—选择题

文章目录 1.把逻辑地址转换程物理地址称为&#xff08;B&#xff09;2.在Unix系统中&#xff0c;处于&#xff08;C&#xff09;状态的进程最容易被执行3. 进程的控制信息和描述信息存放在(B)4.当系统发生抖动&#xff08;thrashing&#xff09;时&#xff0c;可以采取的有效措…...

mybatis的<foreach>标签使用

记录&#xff1a;419 场景&#xff1a;使用MyBatis的<foreach></foreach>标签的循环遍历List类型的入参。使用collection属性指定List&#xff0c;item指定List中存放的对象&#xff0c;separator指定分割符号&#xff0c;open指定开始字符&#xff0c;close指定结…...

干货 | 被抑郁情绪所困扰?来了解CBT吧!

Hello&#xff0c;大家好&#xff01; 这里是 壹脑云科研圈 &#xff0c;我是 喵君姐姐~ 我们的情绪就像是一组正弦波&#xff0c;有情绪很高涨的时刻&#xff0c;也会有情绪低落的瞬间&#xff0c;也会有情绪平稳的时候。 这种情绪上的变化非常正常&#xff0c;也正是因为这…...

每日一个小技巧:1招教你手机消除笔怎么用

在日常生活中&#xff0c;我们经常需要在手机上进行编辑和涂改&#xff0c;但是由于各种原因&#xff0c;我们可能会做出错误或者不满意的修改。这时候&#xff0c;消除笔就派上用场了。消除笔可以帮助我们在不影响其他内容的前提下&#xff0c;对错误或者不满意的修改进行撤销…...

4月26号软件更新资讯合集....

Tpflow V7.0.2&#xff0c;PHP 工作流引擎新版发布 ​欢迎使用 Tpflow V7.0.1 工作流引擎 TpFlow 工作流引擎是一套规范化的流程管理系统&#xff0c;基于业务而驱动系统生命力的一套引擎。彻底释放整个信息管理系统的的活力&#xff0c;让系统更具可用性&#xff0c;智能应用型…...

擎天租与京东集团达成战略合作,机器人服务加速进入全域场景

5月21日&#xff0c;擎天租宣布与京东集团达成全面战略合作&#xff0c;双方将围绕产品解决方案共建、渠道供应链赋能及规模化采购等方面展开深度合作。此次战略联手&#xff0c;不仅是两家标杆企业在各自优势领域的双向赋能&#xff0c;也将推动RaaS&#xff08;Robot as a Se…...

如何在Photoshop中构建AI原生工作流:SD-PPP的技术架构解析

如何在Photoshop中构建AI原生工作流&#xff1a;SD-PPP的技术架构解析 【免费下载链接】sd-ppp A Photoshop AI plugin 项目地址: https://gitcode.com/gh_mirrors/sd/sd-ppp 当我们谈论AI与创意工具的结合时&#xff0c;通常面临一个核心挑战&#xff1a;如何在保持专业…...

2026年主流一键生成论文工具全攻略(含免费额度说明)

以下是当前学术圈口碑 TOP 的6 款 AI 写论文工具&#xff0c;覆盖从选题、开题到降重、答辩的论文全流程&#xff0c;剔除冗余工具&#xff0c;每款均附分步骤实操指南场景适配技巧&#xff0c;重点突出中文论文适配性&#xff0c;新手也能快速上手&#xff0c;效率翻倍。一、全…...

极域电子教室破解指南:快速恢复电脑控制权的完整方案

极域电子教室破解指南&#xff1a;快速恢复电脑控制权的完整方案 【免费下载链接】JiYuTrainer 极域电子教室防控制软件, StudenMain.exe 破解 项目地址: https://gitcode.com/gh_mirrors/ji/JiYuTrainer 你是否曾经在学校的计算机教室中&#xff0c;面对被极域电子教室…...

企业微信 Webhook 回调详解

Webhook 回调&#xff0c;是企业微信自动化开发中最核心的能力之一。很多开发者在做企业微信自动化时&#xff0c;都会先关注“消息发送”。 但真正影响系统自动化能力的&#xff0c;其实是“消息回调”。因为只有实时接收到客户消息、群消息与事件通知&#xff0c;系统才能真正…...

【ElevenLabs福建话语音落地实战】:20年语音AI专家亲授3大避坑指南与本地化部署全流程

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;ElevenLabs福建话语音落地的行业价值与技术定位 福建话&#xff08;闽南语泉州/厦门腔&#xff09;作为联合国教科文组织认定的“严重濒危语言”&#xff0c;其语音合成能力的工程化落地&#xff0c;已超越单…...

ElevenLabs缅甸文语音准确率仅68.3%?实测对比5种预处理方案,第4种提升至92.7%(附Jupyter验证代码)

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;ElevenLabs缅甸文语音准确率实测基准与问题定位 为系统评估 ElevenLabs 对缅甸文&#xff08;Burmese, my-MM&#xff09;语音合成的准确性&#xff0c;我们在统一硬件环境&#xff08;Intel i7-11800H 32GB …...

Midjourney V6色调分离失效?3步修复色相断层、5类常见错误代码级诊断指南

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;Midjourney V6色调分离失效的本质归因 Midjourney V6 引入了更严格的色彩空间一致性约束与隐式色彩嵌入机制&#xff0c;导致传统依赖 HSV/HSL 分量操控的“色调分离”&#xff08;Color Separation&#xff0…...

如何彻底释放华硕笔记本性能:G-Helper轻量控制工具终极指南

如何彻底释放华硕笔记本性能&#xff1a;G-Helper轻量控制工具终极指南 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenboo…...

2026 毕业季 AI 论文工具硬核横评:从初稿到定稿,9 款神器帮你告别熬夜焦虑

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AI PPThttps://www.paperxie.cn/ai/dissertationhttps://www.paperxie.cn/ai/dissertation 引言&#xff1a;毕业季论文困局&#xff0c;AI 工具成破局关键 又到一年毕业季&#xff0c;本科毕业论文成为无…...