主要内容 #
- 自顶而下的概念
- 优点
- 举例
1. 自顶而下的概念 #
”自顶向下,逐步求精“是一种通过分解问题来逐步完成程序设计的方式。就好像我们经历过无数的考试一样,当你遇到一题数学题或者物理题时,你是怎样想问题和解决问题的呢?大概都是通过已知条件,逐步求解而得到最终的答案。而程序设计也与此类似,当你面对一个复杂的问题要用程序来解决时,不能直接解决或者太过于困难,你就可以将复杂的问题分解开来,由超级大分为大的、中的、小的、超小的,直到能用很直接的方法解决,最后逐个解决小问题,组合而解决大问题。
2. 优点 #
程序的层次分明、结构清晰, 便于调试。
如果对问题没有分割,代码肯定是冗长,没有清晰的结构和层次,不利于对代码的调试。而通过“自顶向下,逐步求精”来设计,代码由许多小部分组成,出现问题时检查一个个小部分就可以找到bug所在,从而解决。
便于集体开发程序
通过“自顶向下,逐步求精”来设计,就可以将一个大程序分解成一个个小模块,交给团队不同人员来完成,便于集体开发程序,提高效率。
3. 举例: #
3.1 问题描述 #
期末考试过后,C语言程序设计课的老师交待下来这样一个任务:现在给你一份班级的成绩单,其中记录了全班所有22个同学的成绩,老师想让你编写一个程序,可以输入全班的所有成绩,然后查找到最高分数,最后将最高分数打印出来。
我们知道,算法是描述解决某一个问题的步骤,而步骤反映到问题描述中就是其中的各个动词(或者表示某个动作或操作过程的词)。于是“自顶向下”纵观整个问题描述,会发现这样几个动词:输入、查找和打印。再加上这些动词作用的对象(宾语),很快我们就知道了整个问题应该被划分为这样几个模块:输入成绩、查找最高成绩、打印最高成绩。这些模块对应到程序代码就是:inputscores()、findmax()以及printmax()函数。整个过程用下图可以表示:
3.2 模块 #
获得了整个程序的模块划分,实际上我们已经有了整个程序的雏形:
#include <stdio.h> // 输入所有成绩模块 void inputscores(int* pscores,int count) { // 等待实现... } // 查找最高成绩模块 int findmax(int* pscores,int count) { // 等待实现... return 0; } // 打印最高成绩模块 void printmax(int max) { // 等待实现... } // 在主函数中,以顺序结构组织这些模块, // 就实现了整个算法,完成了整个程序 int main() { // 定义辅助的学生总数和保存成绩的数组 const int COUNT = 73; int scores[COUNT]; // 输入所有成绩 inputscores(scores,COUNT); // 查找最高成绩 int max = findmax(scores,COUNT); // 打印最高成绩 printmax(max); return 0; }
精益求精 #
接下来就该“逐步求精”,逐个实现这些模块对应的具体函数了:
// 输入所有成绩模块 void inputscores(int* pscores,int count) { printf("Please input the scores:\n"); // 循环结构 for(int i = 0; i < count; ++i) { scanf("%d",pscores); ++pscores; } } void printmax(int max) { // 顺序结构 printf("The max score is %d.",max); }
而对于算法的关键步骤“查找最高成绩”模块对应的findmax()函数,因为逻辑相对比较复杂一些,就需要我们对这个模块做进一步的分解,将其拆分成基本的结构单元。在整个查找的过程中,我们首先需要遍历数组中的所有数据,所以整体而言,它是一个循环结构。在循环结构内部,我们还需要判断当前成绩是否大于已知的最好成绩,如果大于,则将当前成绩作为新的已知最好成绩,否则什么都不作。因为这里涉及到了根据不同的条件(当前成绩是否大于已知的最好成绩)而采取不同的操作(将当前成绩作为新的已知最好成绩或者是什么都不做),所以我们在循环结构中还需要嵌套一个选择结构。
// 查找最高成绩模块 int findmax(int* pscores,int count) { // 假设数组中的第一个数为当前最高成绩 int max = pscores[0]; // 循环结构,遍历数组中的每一个数据 for(int i = 1; i < count; ++i ) { // 选择结构:当前成绩是否大于已知最高成绩 if(pscores[i]>max) max = pscores[i]; } return max; }