通用双向链表的设计(参考Linux系统中的实现)
通常我们设计设计链表都是将数据域放在里面,这样每次需要使用链表的时候都需要实现一个链表,然后重新实现它的相关操作,这里参考Linux系统中的设计实现了一个通用的双向链表,只需要在你的结构里面有一个这个链表的域,就可以使用链表的相关操作了。
注意:这个通用的双向链表是参考Linux系统中的实现,它使用了typeof这个功能,所以有些编译器可能不支持。我是再Windows系统中使用MinGW下使用GCC编译的。
// list.h
#ifndef _list_h
#define _list_h
typedef struct _list_head {
struct _list_head *prev,*next;
} list_head;
#define offsetof(TYPE,MEMBER) ( (size_t) &((TYPE*)0)->MEMBER )
#define container_of(ptr,type,member) ({\
const typeof( ((type*)0)->member ) *__mptr = (ptr);\
(type*)( (char*)__mptr - offsetof(type,member) );})
#define list_empty(head) ( head->next==0&&head->prev==0 )
/* get the member of list object
* @ptr pointer to list_head
* @type the type of container which contains list_head field
* @memeber field name in the container
* @return return pointer to the container
*/
#define list_entry(ptr,type,member) container_of(ptr,type,member)
/* add a new node after `head`
*/
void list_add(list_head *head,list_head *node);
/* delete a node
*/
void list_del(list_head *node);
#endif
/
// list.c
#include "list.h"
/* add a new node after `head`
*/
void list_add(list_head *head,list_head *node) {
if(list_empty(head)) {
head->next = head;
head->prev = head;
}
node->next = head->next;
node->prev = head;
head->next->prev = node;
head->next = node;
}
/* delete a node
*/
void list_del(list_head *node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
///
// test.c
#include <stdio.h>
#include <assert.h>
#include "list.h"
typedef struct _task {
int id;
list_head next;
} task;
#define task_next(t) ( container_of(t->next.next,task,next) )
void task_print(task *t) {
printf("#%d -> ",t->id);
}
void task_foreach(task *head,void (*callback)(task *)) {
task *p = head;
do {
callback(p);
p = task_next(p);
}
while (p!=head);
}
// use task like a list
void test_list() {
task t1={1,{0,0}},
t2={2,{0,0}},
t3={3,{0,0}},
t4={4,{0,0}},
t5={5,{0,0}};
list_add(&t1.next,&t2.next);
list_add(&t2.next,&t3.next);
list_add(&t3.next,&t4.next);
list_add(&t4.next,&t5.next);
task_foreach(&t1,task_print);
}
int main(int argc, char *argv[]) {
test_list();
return 0;
}
编译运行
gcc test.c list.h list.c -o test
.\test.exe
下载代码
通用双向链表的设计(参考Linux系统中的实现)相关推荐
- linux无密码sudo,在Linux系统中运行没有sudo密码的特定命令
本文介绍在Linux操作系统中运行没有sudo密码的特定命令的方法. 背景 我在AWS上部署了Ubuntu系统上的脚本,此脚本的主要目的是检查特定服务是否以固定间隔运行(确切地说每隔一分钟),并且如果 ...
- Linux系统中提示/usr/bin/ld: cannot find -lxxx错误的通用解决方法
Linux系统中提示/usr/bin/ld: cannot find -lxxx错误的通用解决方法 参考文章: (1)Linux系统中提示/usr/bin/ld: cannot find -lxxx错 ...
- Linux系统自动备份脚本,供参考的Linux系统中自动执行分段备份脚本
供参考的Linux系统中自动执行分段备份脚本 发布时间:2014-04-21 15:49:00来源:红联作者:tioced 以下脚本仅做学习参考,需加到/etc/crontab文件,每天执行一次的脚本 ...
- 如何在Linux系统中安装DBeaver通用数据库工具
DBeaver是一个开源.功能齐全.跨平台的通用数据库管理工具和SQL客户端,可在Linux操作系统.Windows和macOS 系统上运行. DBeaver支持80多个数据库管理系统,包括Postg ...
- linux动态库ppt,LINUX系统中动态链接库创建与使用补充_区块链白皮书代写|市场计划书项目PPT设计_Tbleg...
区块链白皮书代写 大家都知道,在WINDOWS系统中有很多动态链接库(以.DLL为后缀文件,DLL即Dynamic Link Library).这种动态链接库,和静态函数库不同,它里面函数并不是执行程 ...
- 浅谈 Linux 系统中的 SNMP Trap 【转】
文章来源:浅谈 Linux 系统中的 SNMP Trap 简介 本文讲解 SNMP Trap,在介绍 Trap 概念之前,首先认识一下 SNMP 吧. 简单网络管理协议(Simple Network ...
- Linux 系统中的 SNMP Trap
简介 本文讲解 SNMP Trap,在介绍 Trap 概念之前,首先认识一下 SNMP 吧. 简单网络管理协议(Simple Network Management Protocol)是一种应用层协议, ...
- Linux 系统中的 SNMP Trap及常用OID
浅谈 Linux 系统中的 SNMP Trap 转载: http://www.ibm.com/developerworks/cn/linux/l-cn-snmp/ 本文讲解 SNMP Trap,在介绍 ...
- linux查找最近访问的文件,教您在Linux系统中查找最近修改的文件/文件夹
如果您使用Linux系统进行日常操作,则主目录文件将随时间急剧增加.如果您有成千上万个文件,很可能不记得最近更改的文件名,本文将教您在Linux系统中查找最近修改的文件/文件夹.另外,如果要检查出于任 ...
最新文章
- qtablewidget限制输入类型_对敏感型电子信号输入实施过压保护的可靠新方法
- 计算价格, java中浮点数精度丢失的解决方案
- python下载代码-python下载大文件代码
- SQL Server 2005中创建CLR存储过程
- 架构漫谈:我心中的架构
- 关于Server Tomcat v8.0 Server at localhost failed to start的解决办法
- NeurIPS 2021 | 图上不均衡表示学习新视野:基于拓扑结构的不均衡学习
- 直播 | AAAI 2021最佳论文:比Transformer更有效的长时间序列预测
- java对嵌入式_Java用于嵌入式系统的优点
- 【抓包工具】HttpWatch(功能详细介绍)
- Blocking/Non-Blocking VS Sync/Async VS Overlapped
- Oracle最新的Java 8更新破坏了您的工具-它是如何发生的?
- 全文搜索Apache Lucene简介
- web开发项目,web前端CSS全局样式,面试必问
- MFC遍历指定目录下的所有文件/文件夹(不遍历子目录)
- UIViewController生命周期的理解
- kafka是什么_Kafka的Controller Broker是什么
- python建模 决策_决策树python建模中的坑 :ValueError: Expected 2D array, got 1D array instead:...
- mysql 数据脱敏
- c语言怎么用右移代替除法,除法和算术右移之间的巧妙取代
热门文章
- linux shell中21的含义
- 本题主要考查指针与数组
- Silverlight+WCF 实战-网络象棋最终篇之对战视频-下篇[客户端发送与服务端中转](六)...
- Design Pattern: Singleton 模式
- Android碎片化难题:手游兼容性测试应该适配哪些机型?
- SVN关于忽略xcuserdata目录
- 隐藏Apache Nginx PHP版本号
- AFNetworking 下载文件断点续传操作
- Config Sharepoint 2013 Workflow PowerShell Cmdlet
- android异步任务详解 AsynTask[转 杨瓦瓦]