前言
提示:这里可以添加本文要记录的大概内容:
任何一个软件项目都可以被划分为不同的模块,然后分给不同的人去完成。模块化编程不仅可以由多人协作,分工实现,而且还可以让我们的软件系统结构清晰,层次更加分明,更加易于管理和维护。 这便是c语言模块化编程思想的由来
提示:以下是本篇文章正文内容,下面案例可供参考
模块的编译和链接
在一个C语言软件项目中,整个软件系统可以被划分为不同的模块,然后交给不同的人去完成。这项任务将产生一下几个问题:
- 每个人在实现各自模块的过程中注意什么?
- 如何协作
- 模块如何集成到系统中去?(makefile项目管理软件)
一个C语言项目通常分为不同的模块,通常由多个文件来实现。在项目编译的过程中,编译器是以C源文件为单位进行编译的,每一个C源文件都会被编译器翻译成一个对应的目标文件。接下来链接器对每一个目标文件进行解析,将文件中的代码段,数据段分别组装,生成一个可执行的目标文件。如果程序调用了库函数,则链接器也会找到对应的库文件,将程序中的库代码一同链接到可执行文件中。
需要注意:在链接过程中,如果多个目标文件定义了重名的函数或全局变量,就会发生符号冲突,出现重定义错误。此时链接器就要对这些重复定义的符号做符号决议( 符号决议有一定的规则 )。
在一个大型项目中,可以通过控制参数来控制编译的流程:预处理,编译,汇编,链接,指定多个文件的编译顺序。但是当文件特别多时,通过使用命令行的方式来完成整个项目的编译就会特别麻烦。工程上,通常使用自动化编译工具make来编译项目,make自动编译工具依赖项目的Makefile文件。Makefile文件主要作用用来小数各个模块之间的依赖关系,生成的可执行文件,如何编译,先编译哪个,后编译哪个,Makefile都有表述。(现代工程一般使用Cmake工具)
系统模块划分
系统模块划分法
理清楚:
- 什么是系统
- 什么是模块
系统就是各种对象相互关联,相互作用形成的具有特定功能的有机整体。这些对象可以看作不同的模块。模块与模块之间是相互作用,相互关联的。系统的模块化设计就是将系统目标按模块化方式分解,设计,实现,集成。模块是模块化的产物,每一个模块都是具有特定功能的有机组成。
系统和模块的先后顺序:先有系统,有了系统目标和功能定义,然后才有模块划分,最后才有模块的实现。系统的外在功能是通过系统内多个模块之间相互作用,相互关联实现的。
如何对一个系统进行模块化划分:
-
确定系统的功能或目标(知道自己要做什么,实现什么功能和目标)
-
根据系统的功能和目标,设计出一组系统工作流程
-
根据这个工作流程,确定角色和分工,各个角色之间如何交互,如何关联。
-
角色确定后,就可以根据各个角色将系统划分成不同的模块
在实际的工程项目中,在对一个系统进行功能分析,模块划分的时候,也要根据项目的工作量,团队人数,团队员工水平等因素进行合理的划分。假如设计一个MP3播放器,支持音乐播放和录音功能。
-
系统目标:播放音乐,录音
-
基本工作流1:从磁盘读取MP3文件 > 解码 > 声卡 > 显示
-
流2:麦克风录音,AD转换 > 内存 > 声音编码 > 存入磁盘
-
角色:存储,显卡,声卡,麦克风,编解码器
-
模块:存储模块,显示模块,编解码模块
当系统比较复杂时,或者由于模块划分的比较多导致模块过多时,需要考虑进一步的分层。可以按照模块间的依赖关系,将一个系统划分为不同的层。
例如:MP3系统升级了,移植了OS,添加了文件系统模块,增加了绚丽的GUI界面。文件系统对存储模块的读写进行抽象,应用程序可以通过文件系统的read/write接口直接读写MP3歌曲文件。MP3播放界面,可以通过GUI系统留出的API直接画图。根据这些依赖关系,对系统进行分层时,可以将他们划分到不同的层中。
如果更加细节,还可以继续分层划分不同的模块。
模块的目录结构
对于一个大型的项目,需要合理的目录结构来管理和组织文件。
一个好的目录结构,首先需要结构清晰,能够体现出不同模块之间的关系。比较常见的三种目录结构:
- flat:所有的源文件都放在一个目录之下
- shallow:各个模块放在各自的模块之下,主程序文件放在项目的顶层目录之下
- deep:主程序文件和各个模块分别放在各自的模块之下
(个人常用示例, 属于flat类型):
- build // 项目构建文件夹
- lib // 库文件夹
- inc // include 头文件夹
- src // 各种源文件夹,也包含main.c
模块的封装
c语言中,一个模块一般对应一个C文件和一个头文件。模块的实现在C源文件中,头文件主要用来存放函数声明,留出模块的函数API,供其他模块调用。在别的模块中,使用预处理指令#include包含对应的头文件,就可以在当前模块中使用头文件中留出来的API。
总结
这是书中,C语言模块化编程思想的个人总结。书中拥有详细的内容,本人只是根据自己的需要进行的总结。如果您有好奇的地方可以阅读<嵌入式C语言自我修养>这本书第九章。