范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

开源C语言库Melon双向链表使用

  本篇主要介绍开源C语言库Melon的双向链表使用,对开源C库感兴趣的读者可以访问:
  github.com/Water-Melon/Melon。链表简介
  先简单介绍一下什么是双向链表。可以参考下图:
  简单来说,链表是将一个一个的结点,通过指针连接起来。而双向链表则是每一个结点不仅记录了指向下一结点的指针,也记录了指向前一结点的指针。
  Melon中的双向链表属于上图中带有尾部结点的双向链表。
  双向链表的优势:结点的插入和删除操作的时间复杂度为O(1),所以应对频繁插入和删除的场景,是非常适合的。双向链表使用
  我们先定义一个自定义结构体类型:typedef struct test_s {     int val; } test_t;
  后续的介绍中,我们要做的就是使用Melon的链表组件对这个结构进行改造,将其构建成一个双向链表。
  在Melon中,双向链表有两种实现。两种实现进行对比也各有其特点,因此读者在了解各自特点后,可根据自己需要进行选择使用。第一种实现
  我们直接上代码,然后再进行说明:#include  #include  #include "mln_defs.h"  typedef struct test_s {     int val;     struct test_s *prev;     struct test_s *next; } test_t;  MLN_CHAIN_FUNC_DECLARE(test, test_t, static inline void, ); MLN_CHAIN_FUNC_DEFINE(test, test_t, static inline void, prev, next);  int main(void) {   int i;   test_t *head = NULL, *tail = NULL, *t;    for (i = 0; i < 10; ++i) {     t = (test_t *)malloc(sizeof(test_t));     if (t == NULL) {         fprintf(stderr, "malloc failed. ");         return -1;     }     t->val = i;     t->prev = t->next = NULL;     test_chain_add(&head, &tail, t);   }    for (t = head; t != NULL; t = t->next) {     printf("%d ", t->val);   }   return 0; }
  这段代码中,main函数中的内容很简单,利用一个for循环,malloc10个test_t结构,然后将其val填充数值。随后利用test_chain_add函数将这些结点连成一个链表。然后利用for循环遍历结点并打印val的值。
  下面问题就来了,test_chain_add哪里来的?
  我们看到main前有两个MLN_CHAIN_FUNC_xxx的宏,这两个宏是在Melon的mln_defs.h头文件中定义的,用来对链表的插入和删除函数进行定义和声明的。MLN_CHAIN_FUNC_DECLARE第一个参数:函数名前缀第二个参数:自定义结构体类型第三个参数:函数返回值及函数类型第四个参数:函数参数限制属性(本例没有使用)MLN_CHAIN_FUNC_DEFINE第一个参数:函数名前缀第二个参数:自定义结构体类型第三个参数:函数返回值及函数类型第四个参数:自定义结构中用于访问前一结点的指针成员名字第五个参数:自定义结构中用于访问下一结点的指针成员名字
  这两个宏会定义和声明两个函数,分别名为:test_chain_add和test_chain_del,这两个函数的原型类似如下形式:void (*chain_op)(type **head, type **tail, type *node);
  第一个参数为双向链表首指针的指针,第二个参数为双向链表尾指针的指针,第三个参数为要被操作的结点指针。特点
  这种实现方案的好处是:插入和删除函数可以被定义成inline或者增加一些其他属性。并且在遍历链表时,只需要访问自定义结点的prev和next指针即可。
  缺点是:使用者需要知道自定义结构中自己加入的prev和next成员名字,以及如果定义了很多双向链表,则需要配套定义很多插入和删除函数,会增加可执行程序的体积。第二种实现
  这种实现可能比较常见了。我们直接看代码:#include "mln_list.h" #include "mln_defs.h" #include   typedef struct {     int        val;     mln_list_t node; } test_t;  int main(void) {     int i;     test_t *t;     mln_list_t sentinel = mln_list_null();      for (i = 0; i < 3; ++i) {         t = (test_t *)calloc(1, sizeof(*t));         if (t == NULL)             return -1;         mln_list_add(&sentinel, &t->node);         t->val = i;     }     for (t = mln_container_of(mln_list_head(&sentinel), test_t, node);           t != NULL;           t = mln_container_of(mln_list_next(&t->node), test_t, node))     {         printf("%d ", t->val);     }     return 0; }
  主函数的行为与第一种实现的代码是完全一样的。差别在于如下几方面:引入了mln_list.h头文件test_t中不再是添加prev和next成员,而是加入一个固定类型的成员,即mln_list_t类型的node成员。双向链表的首尾指针改为了一个名叫sentinel的mln_list_t类型变量。链表插入函数不再是自定义前缀函数,而是一个固定名称的函数名为mln_list_add.访问链表首结点使用mln_list_head宏想获取链表结点所在的宿主结构(即本例的test_t)指针,需要使用mln_defs.h中的mln_container_of宏。特点
  这种实现的优劣分别是:
  优势:使用者不需要关心链表的具体实现细节,只需要在自定义类型中引入mln_list_t类型成员即可。并且函数的插入和删除操作都是固定名称的,分别为:mln_list_add和mln_list_remove。
  劣势:对链表结点所属的宿主结点(test_t)的访问需要借助mln_container_of宏,这看上去并不如第一种实现中那么直观。且链表操作函数都是非inline的,因此频繁调用的开销会高于第一种实现。
  事实上,感兴趣的读者可能会发现,第二种双向链表(mln_list.c),是使用第一种双向链表来实现的。结语
  感谢阅读,感兴趣的读者可以访问Melon库查看更多细节,Melon是一个无依赖且开箱即用的开源C语言库,并且有配套的中英文文档。
  Github传送门:
  github.com/Water-Melon/Melon

为安倍流泪的女记者自杀的真正目的是什么?为安倍流泪的女记者曾颖在日本自杀了。曾经在安倍晋三被刺事件中,因为她直播时哽咽引发的网络喧嚣不断发酵,让她无法支撑日常的工作和生活。她感觉到自己很委屈。再三发文为安倍洗白之后。就在广州穿浴袍跳楼女子发声还是在校大学生,得知男友外遇冲动所为7月21日,广州天河区万菱汇大楼一女子穿着浴袍跑到窗外站立的视频在网络引发热议。事后,女子被消防人员援救进房间内。一些视频拍摄者在传播视频时称,该女子是小三被捉奸逃到窗外,该女子事电影市场暑期档上半场交出满意答卷原标题截至7月22日总票房突破40亿元(引题)电影市场暑期档上半场交出满意答卷(主题)今晚报讯(记者丁晓晨)暑期档进程过半,中国电影市场持续升温,截至7月22日21时34分,202六七十年代父辈们怀旧的老牌香烟,几毛钱都是奢侈品,你们认得吗那时候刚11岁,偷学抽烟就是黄金葉,三分钱两根。大前门,三分钱一根。还被老师发现惩罚抽纸卷牛粪沫,后来被奶奶逮住告诉我爷爷,爷爷说没事男孩子抽烟没什么。心里乐开了花,爷爷就带我去房除了高温热浪,欧洲的大面积干旱正在加剧粮食与能源危机除了刷新历史纪录的高温热浪,欧洲旱情可能会触发更多隐患,干旱和缺水正在影响当地能源生产并削减农作物产量。欧盟委员会联合研究中心最新发布的7月旱情监测报告显示,欧盟及英国总计44的土外媒综述俄乌运粮协议或缓解粮食危机据美国有线电视新闻网网站7月22日报道,联合国秘书长古特雷斯22日说,乌克兰和俄罗斯达成一项协议,乌克兰黑海港口由此将得以恢复出口重要谷物,这是一项旨在缓解全球粮食危机的重大外交突我国不再新建500米以上高楼全球超500米以上的高楼就10座,我们就占了一半以上。全球高楼排行阿拉伯联合酋长国沙特阿拉伯美国韩国这四个国家各占一座。国内则是由上海深圳广州天津北京台湾六家各占一座。这其中上海的数字中国发展报告(2021年)发布我国建成全球规模最大网络基础设施本报讯(记者林瑞琪林文婧)数字经济总量稳居世界第二5G基站总量占全球60以上网络基础设施全球规模最大自2017年党的十九大报告明确提出建设数字中国以来,数字中国建设从夯基垒台到积厚为什么网上白酒比店里的便宜?网购白酒到底靠不靠谱,看完就懂了为什么网上白酒比店里的便宜?网购白酒到底靠不靠谱,看完就懂了以前的网络不发达,物流也没有现在这么便捷,人们购买白酒的主要途径就是商店超市百货门市等线下实体门店。基本就是进去挑好东西我国超千万人患痛风,元凶是豆制品?这3种食物才是嘌呤大户老张最近处于深深的自责之中,因为自己年轻时候的放肆,现如今连正常走路都变成了奢望。老张二十多岁的时候,第一次出现大脚趾红肿,伴有明显的疼痛,但是没有明显的诱因。到当地医院就诊,被确吃晚饭时,经常喝点白酒的人,最后身体都咋样了?早知早受益金樽清酒斗十千,玉盘珍羞直万钱推杯换盏,何尝不是人生一大幸事。不过,有不少人却有这样的疑问吃晚饭时,经常喝点白酒的人,最后都咋样了?一位来自江苏某酒厂的退休师傅说我以前在酒厂上班那
女单4强出炉!国乒主力被阻击,世界前2全出局,王艺迪险遭爆大冷2022年全国乒乓球锦标赛结束了女单四分之一决赛的争夺,随着王曼昱顺利击败范思琦,女单四强全部产生,分别是孙铭阳陈幸同王艺迪王曼昱。令人感到意外的是,赛会前两号种子世界排名第一和第13!国乒连爆5大冷门男双争冠热门出局,女单世界冠军也遭淘汰北京时间2022年11月10日,全国乒乓球锦标赛爆出5个大冷门。其中,单打赛场爆出3个冷门,分别是孙颖莎13不敌孙铭阳张瑞23不敌石洵瑶周启豪13不敌牛冠凯。另外,男双赛场爆出2个2位黑马进4强!国乒陪练淘汰世界第一,对阵王艺迪,樊振东战00后2位黑马进4强!国乒陪练淘汰世界第一,对阵王艺迪,樊振东战00后。2022年乒乓球全国锦标赛单打14决赛已经结束了,男单和女单4强已经出炉,其中男单4强是樊振东,林高远,刘丁硕,牛小麦价格继续上涨!11月8日最新行情国内小麦市场依旧在继续上涨,本轮上涨已经持续了一个半月的时间,中间仅有的两次小幅度回调也是转瞬即逝,支撑价格上涨的原因,之前的文章已经赘述过多次,无非就是供应端或主动(卖跌不卖涨)人有四种衰老模式,看看你是哪一种?想延缓衰老,方法不同人和人之间的衰老有什么不同?有人60多岁时心脏依然强健,但肾脏却已开始衰竭有人可能拥有30岁的肾脏,却经常出现免疫力低下的疾病。人有四种衰老模式,看看你是哪一种?四种衰老模式肾型衰芝加哥农产品期价8日下跌新华社芝加哥11月8日电(记者徐静)芝加哥期货交易所玉米小麦和大豆期价8日全线下跌。当天,芝加哥期货交易所玉米市场交投最活跃的12月合约收于每蒲式耳6。675美元,比前一交易日下跌三季度净利润下滑欧派家居回应广州日报讯(全媒体记者赵方圆)面对三季度净利润出现罕见的两位数同比下滑,欧派家居董事长姚良松回应称今年19月份行业遇冷,也暴露了公司经营管理层面的一些小瑕疵,公司及时复盘研判,并已温铁军实体国家向发达国家出口,等于商品与资本双重输出纵观现如今世界上的发达国家,基本上都是二战之后搭上了经济高速发展的快车。在如今社会发展中,我们能看到一个很明显的现象,发达国家一般从事脑力劳动或者高科技产业,而发展中国家就成为他们主张学习国外躺平的,看看加拿大环球新闻今天的这个报道报道主要讲目前儿童看病等候时间长药品短缺导致父母和医生的压力很大。现在到医院看急诊的数量比去年同期增加20。一些非处方退烧止痛药,到处买不到,家长很焦虑。这是加拿大不列颠哥伦比亚省文化之窗严防名校父母输出鸡娃理念哈佛爸牛津妈常春藤学姐清华北大本硕加中科院博导爸爸近年来,打着此类名校标签的育儿账号在各网络平台层出不穷。对此,有政协委员提交了关于严防名校父母输出鸡娃理念抵消双减工作成效的提案,原来这种发际线问题可自愈,早点知道就好了生活压力工作压力越来越大不少人脑袋上的头发日渐稀疏但有一种情况与男性绝缘只有新手妈妈需要面对的脱发是产后脱发!许多妈妈在生产后会出现严重的脱发情况轻轻梳头都会有大把大把头发脱落不仅