模块化程序设计、条件编译、模块化程序设计与多文件编程实例、自顶向下、逐步求精、模块分解的基本原则

一、模块分解的基本原则
模块化程序设计(Modular programming)思想最早出现在汇编语言中,在结构程序设计概念提出以后,逐步完善并形成了模块化程序设计方法。按照模块化程序设计的思想,无论多么复杂的任务,都可以划分为若干个子任务。若子任务较复杂,还可以将子任务继续分解,直到分解为一些容易解决的子任务为止。可见,若要完成大规模的程序设计,必须掌握模块化程序设计方法。
C语言中的函数时功能相对独立的用于模块化程序设计的最小单位,因此,在C语言中可以把每个子任务设计成一个子函数,总任务由一个主函数和若干个子函数组成的程序完成,主函数起着任务调度的总控作用。
无论结构化方法还是面向对象方法,模块化的基本指导思想都是“信息隐藏”,即不把需要调用者直到的信息都封装在模块内部,使模块的实现细节对外不可见。按照这一指导思想,模块分解的基本原则是:高聚合、低耦合,保证每个模块的相对独立和单一。
模块化程序设计的好处是,可以先将模块各个击破,最后再将他们集成在一起完成总任务,这样不仅便于进行单个模块的设计、开发、调试、测试和维护等工作,而且还可以使得开发人员能够团队合作,按模块分配和完成任务,实现并行开发,有利于缩短软件开发的周期。
注意:模块化程序设计是指一个规模较大的系统的设计过程,表面上是将系统划分为若干子系统,任务分解为若干个子任务,其本质思想是要实现不同层次的数据或过程的抽象。在每个模块的设计过程中,可采用“自顶向下、逐步求精”的方法进行模块化程序设计。模块化程序设计是程序设计中最重要的思想之一。C语言通过模块和函数两种手段来支持这种思想。

二、自顶向下、逐步求精
抽象是处理复杂问题的重要工具,逐步求精Stepwise Refinement)就是一种具体的抽象技术,他是1971年由wirth提出的用于节后话程序设计的一种最基本的方法。
这个抽象算法由一些抽象数据及其上的操作(即抽象语言)组成,仅仅表示解决问题的一般策略和问题解决得一般结构。对抽象算法进一步求精,就进入下一层抽象。每求精异步,抽象语句和抽象数据都将进一步分解和精细化,如此继续下去。
自顶向上(Down-top)方法是先编写出基础程序段,然后在扩大、补充和升级。
自顶向下(Down-down)的程序设计方法是相对于自底向上方法而言的,它的自底向上方法的逆方法。自顶向下方法是先写出结构简单、清晰的主程序来表达整个问题;在此问题中包含的复杂子问题用子程序来实现;若子问题中还包含复杂的子问题,再用另一个子程序(即函数)来解决,知道每个细节都可以用高级语言表达为止。
显然逐步求精是一种自顶向下的程序分级和设计方法。
因此,逐步求精技术可以理解为是一种由不断地自底向上修正所补充的自顶向下的程序设计方法。有以下优点:
(1)用逐步求精方法最终得到的程序是有良好结构的程序,这样的程序具有结构清晰,容易阅读、容易修改的特点。整个程序由一些相对较小的程序子结构组成,每个子结构都具有一定的相对独立的意义,改变某些子问题的策略相对于改变相当于改变相应的局部结构的内部算法,不会影响程序的全部结构。
(2)用逐步求精方法设计程序,可简化程序的正确性验证。结合逐步求精,采取边设计边逐级验证的方法,与整个程序写完后在验证相比,可大大减少程序调试的时间和复杂度。
用逐步求精实现技术求解问题的大致步骤为:
a、对实际问题进行全局分析、决策,确定数学模型;
b、确定程序的总体结构,将整个问题分解成若干相对独立的子问题;
c、确定子问题的具体功能及其相互关系;
d、在抽象的基础上,将各个子问题逐一精细化,直到能用高级语言描述为止。

三、模块化程序设计与多文件编程实例
C编译器会单独编译每一个源文件分别生成一个目标代码,然后在链接阶段将这些目标代码连同标准函数库中的函数链接在一起,形成可执行文件。这样做的最大好处是是程序的结构更加清晰,更易于维护。
实现多文件编程,面临的两个主要问题是:如何将代码分成多个文件?如何在多个文件中共享函数?
在模块之间通过互相调用函数和共享全局变量联系起来,头文件是它们相互联系的纽带。一般地,把需要共享的函数放在一个单独的.c文件中,把共享函数的函数原型、宏定义和全局变量声明等放在一个单独的.h头文件中其他需要共享这个函数的程序用#include 包含这个头文件后,就可以调用这个函数了。
需要注意的是,头文件里对全局变量的声明要加上extern 关键字,用以声明该变量为外部变量。变量声明与变量定义不同的是:对于变量声明,编译器并不对其分配内存,因为这个变量实际是在其他模块定义的,即希望这个变量的内存是在其他模块分配的,用extern 声明表示要使用在其他模块定义的变量。如果模块内不允许使用模块外定义的函数和全局变量,只要在定义它们时加上static关键字,就能保证只能在该模块内使用它们了。

四、条件编译
如果定义了头文件a.h、b.h和源文件demo.c,在b.h中包含了a.h,在demo.cpp中同时包含了a.h和b.h,这样就会出现a.h被重复包含的问题,多重包含经常出现在需要使用很多头文件的大型程序中。使用条件编译可以解决头文件多重包含的问题。
例如,头文件GuessNumber.h写成下面这样:
#ifndef_GuessNumber_H_
#define_GuessNumber_H_
……
#endif

条件编译包括:#if , #ifdef , #ifndef , #else ,#elif #endif

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值