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

《抽象数据类型:把数据和对数据的操作绑在一起》

前言

C 语言是一门面向过程的语言,没有 class 类,但是我们可以利用头文件.h和源文件.c分离的写法,模拟面向对象里的封装思想,也就是抽象数据类型(ADT)。 所有数据结构统一使用这套规范编写,代码整洁、复用性强,也是大厂 C 语言项目的通用写法。

一、什么是抽象数据类型 ADT

抽象数据类型分为两部分:

  1. 数据本身:用结构体保存需要存储的所有成员;
  2. 操作集合:对数据的增删改查、初始化、销毁等函数。

核心思想:隐藏内部实现细节,对外只提供接口。使用者不需要知道结构体内部如何实现,只需要调用规定函数即可完成操作。

二、C 语言实现 ADT:头文件与源文件分离

1. 头文件 list.h(对外接口,给使用者看)

头文件只放结构体声明、函数声明,所有具体实现写在.c 文件中。

// list.h #ifndef LIST_H #define LIST_H // 结构体类型声明,对外隐藏具体成员 typedef struct List List; // 对外提供的接口函数 List* List_Init(); // 初始化 void List_Insert(List* list, int val); // 插入元素 void List_Delete(List* list, int val); // 删除元素 void List_Print(List* list); // 遍历打印 void List_Destroy(List* list); // 销毁内存 #endif

2. 源文件 list.c(具体实现,内部隐藏)

// list.c #include "list.h" #include <stdio.h> #include <stdlib.h> // 完整结构体定义,只在当前文件可见 struct List { int* data; int size; int capacity; }; List* List_Init() { List* list = (List*)malloc(sizeof(List)); list->capacity = 4; list->size = 0; list->data = (int*)malloc(sizeof(int) * list->capacity); return list; } void List_Insert(List* list, int val) { list->data[list->size++] = val; } void List_Print(List* list) { for(int i = 0; i < list->size; i++) { printf("%d ", list->data[i]); } } void List_Destroy(List* list) { free(list->data); free(list); } // 删除函数省略实现 void List_Delete(List* list, int val) { }

3. 主函数 main.c(使用者调用)

#include "list.h" int main() { // 用户完全不知道List结构体内部成员 List* L = List_Init(); List_Insert(L, 10); List_Insert(L, 20); List_Print(L); List_Destroy(L); return 0; }

三、封装带来的好处

  1. 信息隐藏结构体具体成员只在.c 文件中可见,外部无法随意修改结构体内部变量,避免非法篡改数据,保证数据安全。

  2. 统一编码规范之后写链表、栈、队列、树全部沿用这套格式: 结构体 typedef、Init 初始化接口、增删查改接口、Destroy 销毁接口,代码风格高度统一。

  3. 便于维护和迭代后续优化底层实现,比如优化扩容逻辑、优化查找算法,只需要修改 list.c 文件,外部调用代码一行不用改动。

  4. 方便打包复用编译成静态库,其他人只需要拿到.h 头文件和库文件,就能直接使用数据结构,不用关心底层代码。

四、总结

抽象数据类型就是 C 语言里的 “面向对象封装”。 结构体存放属性,一系列函数作为方法,头文件暴露接口,源文件隐藏实现。 这是学习所有数据结构之前必须掌握的编码规范,熟练之后,后续手写任意数据结构都会顺手很多。

http://www.gsyq.cn/news/1647158.html

相关文章:

  • 别小看这张“钢丝网”,它一不高兴,你的生产线就得停工!
  • 基础到企业应用系列3——WPF开发漫谈
  • 把 Claude Code 的 plan mode 设为项目默认模式,先想清楚,再让它动手
  • 300个摄像头的化工园区,怎么管才高效?国标GB28181视频平台EasyGBS视频监控模块为企业构建起可视化防线
  • 小程序商城制作流程详解:附2026阿里开发者社区评分最高的3款小程序商城制作工具
  • 为什么你越努力优化,供应链反而越脆弱?
  • 《天龙八部》主要角色人生结局对比:当系统宕机时,谁能优雅退出
  • Java工程师资格证,到底值不值?别被忽悠了,真相扎心
  • SiamFC 到 SiamRPN++:5个关键改进点对比分析,FPS与精度提升路径
  • ComfyUI 学习笔记 图片制
  • ClaudeCode for VSCode:深度代码理解的AI编程协作者
  • HCI 功能规范【5. HCI data formats】(3/5)
  • 全渠道ERP寻源算法深度解析:如何同时兼顾距离、运费与库存周转率
  • 《唤醒你的AI同事:WorkBuddy从零上手》039:附录D 相关资源与社区
  • MAX9744与PIC18LF46K40的高效音频放大方案解析
  • Vben精讲:04-了解VSCode中的Git
  • Windows OpenClaw 完整安装流程 新手可视化操作附最新安装包
  • arXiv正式单飞,承诺继续免费
  • 深度学习 29 道核心试题精解:从激活函数到集成学习的 5 大高频考点
  • 3分钟解决Navicat试用期到期:Mac用户的无限重置指南
  • Koikatu HF Patch终极指南:如何轻松解锁200+插件和完整英文翻译
  • 工程合同结算管理系统测评:蓝燕云分阶段结算与进度关联
  • 带着问题去探险:亲手“设计”出 Ceph BlueStore
  • Quarto学习笔记
  • AI渐进编程之十五:长期维护里,控制层怎么松紧?
  • 4-20mA电流环与工业信号采集系统设计
  • 怎样3分钟完成专业图像分层:智能AI工具的完全指南
  • 提示词汇总_001
  • 阶段二:AI手工测试3 敏捷开发与APP发布全攻略
  • 第十三篇:Permission Model 深度解析 —— Claude Code 如何让 AI 安全执行命令