当前位置: 首页 > 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.jsqmd.com/news/1135165/

相关文章:

  • 基于DHDMS层级全息折叠压缩的P=NP形式化证明与通用自举编译器工程实现
  • 仿 TCMalloc 高并发内存池的设计与实现
  • Claude Code 权限模式的真正分水岭,不是快慢,而是信任半径
  • 从 SE11 到 CDS,在 Eclipse ADT 里写出第一张销售订单 CDS View
  • 基础到企业应用系列3——WPF开发漫谈
  • 第四代半导体为何聚焦氧化镓?
  • Docker 部署 milvus
  • C#上位机+YOLO全栈实战:从工业相机采集到缺陷检测完整落地
  • 3步掌握Advanced XRay:告别盲目挖矿的Minecraft透视模组终极指南
  • 华为OD机试真题 新系统 2026-06-14 C++ 实现【分析电网负载均衡】
  • 把 Claude Code 的 plan mode 设为项目默认模式,先想清楚,再让它动手
  • vim python Vim里敲Python,别只盯着这章!全网资源多到让你怀疑人生
  • 300个摄像头的化工园区,怎么管才高效?国标GB28181视频平台EasyGBS视频监控模块为企业构建起可视化防线
  • 07-02 · LLM 最新论文速览
  • 高校实验室内网论文AIGC合规校验系统踩坑与自研实现全记录
  • Advia Elementor Theme Review: Is It Right for Your Consulting or Financial Services Site, How to Ins
  • ElasticSearch调优实践(二)
  • 抖音批量下载工具:一键获取无水印视频与音乐原声
  • 为什么你越努力优化,供应链反而越脆弱?
  • 小程序商城制作流程详解:附2026阿里开发者社区评分最高的3款小程序商城制作工具
  • Linux下的磁盘管理
  • 《唤醒你的AI同事:WorkBuddy从零上手》038:附录C 推荐技能清单
  • AD74413R与MK20DN128VFM5的高精度工业信号处理方案
  • 小程序制作工具实测对比:餐宝盈/BBWEYY/比文云/Framer/Unicorn Platform(2026年7月更新)含零代码SAAS、AI编程、源码定制交付
  • 音视频上层架构
  • SiamFC 到 SiamRPN++:5个关键改进点对比分析,FPS与精度提升路径
  • Java工程师资格证,到底值不值?别被忽悠了,真相扎心
  • 《天龙八部》主要角色人生结局对比:当系统宕机时,谁能优雅退出
  • Tomcat 运行html文件出现乱码,终极解决方案
  • ComfyUI 学习笔记 图片制