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

高效解耦:自定义内核链表实现指南(简化版)

文件结构

文件结构如下:

- kernelList.h // 通用链表节点定义及核心操作(不含Data)
- kernelList.c // 通用链表操作实现(不含Data依赖)
- data.h // Data结构定义及相关操作声明
- data.c // Data结构相关操作实现
- main.c // 测试代码(调用拆分后的接口)

具体实现

1. kernelList.h(通用链表模块,移除 Data 依赖)

仅保留链表节点( ListNode )及通用操作,不涉及 Data 结构:

#ifndef KERNELLIST_H
#define KERNELLIST_H
#include <stdio.h>
#include <stdlib.h>
// 通用链表节点(仅含前驱和后继指针,与用户数据解耦)
typedef struct list_node 
{struct list_node *prev; // 前驱指针struct list_node *next; // 后继指针
} ListNode;
// 初始化链表节点(前后指针指向自身)
static inline void list_init(ListNode *n) 
{n->prev = n;n->next = n;
}
// 头插法:在head后插入新节点
static inline void list_add_head(ListNode *head, ListNode *new_node) 
{new_node->next = head->next;new_node->prev = head;head->next->prev = new_node;head->next = new_node;
}
// 尾插法:在head前插入新节点(尾部)
static inline void list_add_tail(ListNode *head, ListNode *new_node) 
{new_node->prev = head->prev;new_node->next = head;head->prev->next = new_node;head->prev = new_node;
}
// 从链表中删除节点
static inline void list_del(ListNode *n) 
{n->prev->next = n->next;n->next->prev = n->prev;
}
#endif

2. kernelList.c(通用链表操作实现,无 Data 依赖)

        仅实现 kernelList.h 中声明的通用操作(本示例中均为 static inline 函数,无需额外实现,故文件可空或仅保留说明):

#include "kernelList.h"

3. data.hData 结构定义及相关操作)

独立定义 Data 结构(嵌入 ListNode ),并声明 Data 相关操作:

#ifndef DATA_H
#define DATA_H
#include "kernelList.h"
#include <stddef.h> // 用于offsetof
// 用户数据结构(嵌入链表节点)
typedef struct 
{int data; // 实际存储的数据ListNode node; // 嵌入通用链表节点
} Data;
// 从链表节点反向获取Data(核心:通过节点找数据)
#define get_data(n) (Data*)((char*)(n) - offsetof(Data, node))
// 创建Data节点(分配内存并初始化)
Data* create_data(int value);
// 遍历并打印Data链表
void data_show(ListNode *head);
// 根据数据值查找Data节点
Data* data_find(ListNode *head, int value);
// 销毁Data链表(释放所有节点)
void data_destroy(ListNode *head);
#endif

4. data.cData 相关操作实现)

实现 data.h 中声明的操作,依赖通用链表接口但不侵入链表模块:

#include "data.h"
// 创建Data节点(初始化数据和链表节点)
Data* create_data(int value) 
{Data *d = (Data*)malloc(sizeof(Data));if (!d) return NULL;d->data = value;list_init(&d->node); // 调用通用链表初始化return d;
}
// 遍历并打印Data链表
void data_show(ListNode *head) 
{ListNode *p = head->next; // 从head下一个节点开始printf("链表数据:");while (p != head) { // 回到head时结束Data *d = get_data(p); // 通过节点获取Dataprintf("%d ", d->data);p = p->next;}printf("\n");
}
// 根据数据值查找Data节点
Data* data_find(ListNode *head, int value) 
{ListNode *p = head->next;while (p != head) {Data *d = get_data(p);if (d->data == value) {return d; // 找到返回Data}p = p->next;}return NULL; // 未找到
}
// 销毁Data链表(释放所有节点)
void data_destroy(ListNode *head) 
{ListNode *p = head->next;while (p != head) {ListNode *temp = p;p = p->next;free(get_data(temp)); // 释放Data节点}list_init(head); // 重置头节点
}

5. main.c(测试代码,调用拆分后接口)

调整为使用 data.h 和通用链表接口:

#include "data.h" // 包含Data相关接口
#include "kernelList.h" // 包含通用链表接口
int main(int argc, char *argv[]) 
{// 定义头节点(哨兵,不存数据)ListNode head;list_init(&head); // 调用通用链表初始化// 1. 插入数据Data *d1 = create_data(111);list_add_tail(&head, &d1->node); // 尾插(通用接口)Data *d2 = create_data(222);list_add_head(&head, &d2->node); // 头插(通用接口)Data *d3 = create_data(333);list_add_head(&head, &d3->node); // 头插(通用接口)// 2. 打印链表(Data专属操作)data_show(&head); // 输出:333 222 111// 3. 查找数据(Data专属操作)Data *found = data_find(&head, 222);if (found) printf("找到数据:%d\n", found->data); // 输出:找到数据:222// 4. 删除数据if (found) {list_del(&found->node); // 通用删除接口free(found); // 释放Data}data_show(&head); // 输出:333 111// 5. 销毁链表(Data专属操作)data_destroy(&head);return 0;
}

核心思路

        1. 解耦通用链表与用户数据kernelList 模块仅负责 ListNode 的初始化、增删等通用操作,不依赖任何用户数据类型(如 Data ),可复用为其他数据类型的链表基础。

        2. Data 独立管理Data 作为用户数据类型,单独定义在 data.h / data.c 中,通过get_data 宏关联 ListNode ,实现节点数据的反向查找,且所有 Data 相关操作(创建、打印、查找、销毁)均在独立文件中实现。

        3. 接口清晰:通用操作( list_init / list_add 等)与用户数据操作( data_show / data_find 等)分离,降低模块间耦合度。

        拆分后,若需新增其他用户数据类型(如 Student Product ),只需复用 kernelList 模块,新增对应的数据文件(如 student.h / student.c )即可,无需修改链表核心代码。

http://www.dtcms.com/a/326883.html

相关文章:

  • LLM智能:从语言模型到通用智能体的技术跃迁
  • Java多线程基础总结
  • Python类装饰器:优雅解决描述符属性命名难题
  • 内存作假常见方案可行性分析
  • 【15-多类别分类和多标签分类】
  • SSE流式输出分层与解耦、用户自动结束语错误处理
  • 基于FPGA的热电偶测温数据采集系统,替代NI的产品(一)FPGA 测温研究现状
  • 【Python修仙编程】(20) 参悟参数真谛,林羽内力大增
  • 前端工程化:pinia
  • 【Leetcode】随笔
  • 【MATLAB 2025a】安装离线帮助文档
  • 学习嵌入式之IMAX6ULL——GUN工具链+点灯+SDK开发裸机驱动
  • 计算机网络:ovn数据通信都是用了哪些协议?
  • Java String类:不可变性的核心奥秘
  • Evaluation Warning: The document was created with Spire.XLS for Pyth用Python实现Excel转PDF并去除Spire.XLS水印
  • 银河通用招人形机器人强化学习算法工程师了
  • Python 类元编程(类工厂函数)
  • C语言(06)——二、八、十、十六进制的相互转换
  • Webpack Loader 完全指南:从原理到配置的深度解析
  • TRL - Transformer Reinforcement Learning 传递给SFTTrainer的数据集
  • 【linux】企业高性能web服务器
  • 多路转接 select
  • FinQ4Cn: 基于 MCP 协议的中国 A 股量化分析
  • CSS预处理器之Sass全面解析与实战指南
  • PowerDesigner生成带注释的sql方法
  • 腾讯前端面试模拟详解
  • 分享一款基于STC32G12K128单片机的螺丝机供料器控制板 ES-IO2422 S4
  • 浅谈 LangGraph 子图流式执行(subgraphs=True/False)模式
  • [鹧鸪云]光伏AI设计平台解锁电站开发新范式
  • Kubernetes生产环境健康检查自动化指南