模块化程序设计实例DOC.docx
《模块化程序设计实例DOC.docx》由会员分享,可在线阅读,更多相关《模块化程序设计实例DOC.docx(17页珍藏版)》请在冰豆网上搜索。
模块化程序设计实例DOC
9.5模块化程序设计实例
《程序设计基础》(基于C语言讲解)石光华编著—北京:
清华大学出版社
下面以设计一个简单的成绩管理软件为例,一步一步地按模块化程序设计方法进行设计。
1.定义问题
设计一个成绩管理软件,其基本功能包括:
输入成绩,成绩加分,计算平均成绩,找出最高分,找出最低分,输出成绩等。
2.确定组成程序的模块
根据成绩管理软件的功能,确定软件的基本模块包括:
输入模块,加分模块,平均分模块,最高分模块,最低分模块,输出模块等。
142程序设计基础
3.绘制程序结构图
成绩管理软件的结构图如图9-5所示。
图9-5成绩管理软件结构图
4.流程图
用流程图确定主程序的逻辑结构,如图9-6所示。
在流程图中,istate的作用是记录是否已经输入成绩。
istate的使用有如下两种
方式。
(1)作为全局变量使用。
此时istate可以在所有模块中改变其值,主程序更简洁,但
可能产生边际效应。
(2)作为主程序的局部变量使用。
此时istate只能在主程序中改变其值。
在主程序
中可以直观地看到其变化,能够防止边际效应。
采用方式
(2)的主程序如下。
#include
#defineSIZE10
voidmain()
{
intiscore[SIZE]={0};
intkey=-1;
intiresult=0;
floatfresult=0;
intistate=0;
printf(″1:
Inputscores;\n″);
第9章模块化程序设计143
图9-6成绩管理软件主程序流程图
printf(″2:
Outputscores;\n″);
printf(″3:
Countforthemaxscore;\n″);
printf(″4:
Countfortheminimumscore;\n″);
printf(″5:
Countforthetotalscore;\n″);
printf(″6:
Countfortheaveragescore;\n″);
printf(″-1:
Exit.\n″);
while
(1)
{
printf(″Pleaseinputyourchoose:
″);
scanf(″%d″,&key);
if(key==-1)
144程序设计基础
break;
switch(key)
{
case1:
istate=input_all_numbers(iscore,SIZE);
break;
case2:
if(istate==0)
printf(″ERROR:
Youmustinputscoresfirst!
\n″);
else
output_all_numbers(iscore,SIZE);
break;
case3:
if(istate==0)
printf(″ERROR:
Youmustinputscoresfirst!
\n″);
else
{
iresult=count_for_max(iscore,SIZE);
printf(″themaxscoreis%d\n″,iresult);
}
break;
case4:
if(istate==0)
printf(″ERROR:
Youmustinputscoresfirst!
\n″);
else
{
iresult=count_for_min(iscore,SIZE);
printf(″theminscoreis%d\n″,iresult);
}
break;
case5:
if(istate==0)
printf(″ERROR:
Youmustinputscoresfirst!
\n″);
else
第9章模块化程序设计145
{
iresult=count_for_total(iscore,SIZE);
printf(″thetotalscoreis%d\n″,iresult);
}
break;
case6:
if(istate==0)
printf(″ERROR:
Youmustinputscoresfirst!
\n″);
else
{
fresult=count_for_average(iscore,SIZE);
printf(″theaveragescoreis%.2f\n″,fresult);
}
break;
default:
printf(″ERROR:
Inputerror,pleaseinputagain!
\n″);
}
}
}
5.编写算法
为程序结构图中每个模块编写算法。
在前面的学习中,已经学过如何加分,计算平均分,以及查找最高、最低分,在这里就不再画出流程图了。
6.审查算法
最后审查整个算法,直到没有任何逻辑错误。
7.编程调试
审查算法后,即可进行编程调试。
【例9-12】成绩管理软件的完整程序。
/*name:
amanagementsystemaboutscores*/
/*creat:
stone,2004/3/8*/
146程序设计基础
/*modify:
stone,2004/3/20*/
/*version:
1.0
#include
#defineSIZE5/*定义成绩个数的符号常量*/
intinput_all_numbers(intiscore[],intisize);
voidoutput_all_numbers(intiscore[],intisize);
intcount_for_max(intiscore[],intisize);
intcount_for_min(intiscore[],intisize);
intcount_for_total(intiscore[],intisize);
floatcount_for_average(intiscore[],intisize);
voidmain()
{
intiscore[SIZE]={0};
intkey=-1;
intiresult=0;
floatfresult=0;
/*用于区分是否已经输入数据的标志,0表示未输入,1表示已经输入*/
intistate=0;
/*主菜单,可以选择完成不同的成绩统计功能*/
printf(″**********************************************\n″);
printf(″Thisisamanagementsystemaboutscores.\n\t\tWELCOME!
\n″);
printf(″**********************************************\n″);
printf(″1:
Inputscores;\n″);
printf(″2:
Outputscores;\n″);
printf(″3:
Countforthemaxscore;\n″);
printf(″4:
Countfortheminimumscore;\n″);
printf(″5:
Countforthetotalscore;\n″);
printf(″6:
Countfortheaveragescore;\n″);
printf(″-1:
Exit.\n″);
while
(1)
{
printf(″Pleaseinputyourchoose:
″);
scanf(″%d″,&key);
/*根据输入选择的不同,分别进行不同的处理*/
第9章模块化程序设计147if(key==-1)
break;
switch(key)
{
case1:
istate=input_all_numbers(iscore,SIZE);
break;
case2:
if(istate==0)
printf(″ERROR:
Youmustinputscoresfirst!
\n″);
else
output_all_numbers(iscore,SIZE);
break;
case3:
if(istate==0)
printf(″ERROR:
Youmustinputscoresfirst!
\n″);
else
{
iresult=count_for_max(iscore,SIZE);
printf(″themaxscoreis%d\n″,iresult);
}
break;
case4:
if(istate==0)
printf(″ERROR:
Youmustinputscoresfirst!
\n″);
else
{
iresult=count_for_min(iscore,SIZE);
printf(″theminscoreis%d\n″,iresult);
}
break;
case5:
if(istate==0)
printf(″ERROR:
Youmustinputscoresfirst!
\n″);
148程序设计基础
else
{
iresult=count_for_total(iscore,SIZE);
printf(″thetotalscoreis%d\n″,iresult);
}
break;
case6:
if(istate==0)
printf(″ERROR:
Youmustinputscoresfirst!
\n″);
else
{
fresult=count_for_average(iscore,SIZE);
printf(″theaveragescoreis%.2f\n″,fresult);
}
break;
default:
printf(″ERROR:
Inputerror,pleaseinputagain!
\n″);
}
}
}
/*功能:
输入学生成绩*/
intinput_all_numbers(intiscore[],intisize)
{
intiindex=0;
printf(″pleaseinput%dscores:
\n″,isize);
for(iindex=0;iindex
{
scanf(″%d″,&iscore[iindex]);
}
return1;
}
/*功能:
输出学生成绩*/
第9章模块化程序设计149voidoutput_all_numbers(intiscore[],intisize)
{
intiindex=0;
for(iindex=0;iindex
{
printf(″iscore[%2d]=%3d\n″,iindex,iscore[iindex]);
}
}
/*功能:
计算最高分*/
intcount_for_max(intiscore[],intisize)
{
intimax=iscore[0];
intiindex=0;
for(iindex=0;iindex
{
if(imaximax=iscore[iindex];
}
returnimax;
}
/*功能:
计算最低分*/
intcount_for_min(intiscore[],intisize)
{
intimin=iscore[0];
intiindex=0;
for(iindex=0;iindex
{
if(imin>iscore[iindex])
imin=iscore[iindex];
}
returnimin;
150程序设计基础
}
/*功能:
计算总分*/
intcount_for_total(intiscore[],intisize)
{
intiindex=0;
intisum=0;
for(iindex=0;iindex
{
isum=isum+iscore[iindex];
}
returnisum;
}
/*功能:
计算平均分*/
floatcount_for_average(intiscore[],intisize)
{
intiindex=0;
floatfaverage=0;
for(iindex=0;iindex
{
faverage=faverage+iscore[iindex];
}
faverage=faverage/isize;
returnfaverage;
}
由于C语言中,常用的输入语句scanf()存在缺陷,在1.0版中,输入成绩时,如
果误按了字母键,则程序会出现异常。
为此,我们给出了一个改进版,通过自定义函
数intgetdigi(inticount)进行输入,从而解决了这个问题,提高了程序的稳定性和健
壮性。
这个主程序能够灵活处理不同的分支情况,可以作为C语言程序的一个基本
框架。
程序设计中不同的风格与经验,对程序的易用性和健壮性影响很大,要设计和编写出
成功的程序,需要更深入的学习,需要丰富的经验。
第9章模块化程序设计151【例9-13】成绩管理软件程序的改进版。
/*name:
amanagementsystemaboutscores*/
/*creat:
stone,2004/3/8*/
/*modify:
stone,2004/3/30*/
/*version:
1.1
1.改进了输入时误按字符导致程序失效的问题
2.采用void型函数,简化主程序
3.采用功能键退出程序,符合常例*/
#include
#include
#defineESC27/*使用功能键控制正常退出*/
#defineSIZE5/*定义成绩个数的符号常量*/
#defineMAXdigit20/*定义数据的最大字符个数*/
intinput_all_score(intiscore[],intisize);
voidoutput_all_score(intiscore[],intisize);
voidcount_for_max(intiscore[],intisize);
voidcount_for_min(intiscore[],intisize);
voidcount_for_total(intiscore[],intisize);
voidcount_for_average(intiscore[],intisize);
intgetdigi(inticount);
voidmain()
{
intiscore[SIZE]={0};
charckey=′a′;
/*用于区分是否已经输入了数据的标志,0表示未输入,1表示已经输入*/
intistate=0;
/*主菜单,可以选择完成不同的成绩统计功能*/
do
{
clrscr();
printf(″**********************************************\n″);
printf(″Thisisamanagementsystemaboutscores.\n\t\tWELCOME!
\n″);
printf(″**********************************************\n″);
152程序设计基础
printf(″1:
Inputscores;\n″);
printf(″2:
Outputscores;\n″);
printf(″3:
Countforthemaxscore;\n″);
printf(″4:
Countfortheminimumscore;\n″);
printf(″5:
Countforthetotalscore;\n″);
printf(″6:
Countfortheaveragescore;\n″);
printf(″Esc:
Exitsystem.\n″);
printf(″Pleaseinputyourchoose(1-6):
\n″);
/*根据输入的选择的不同,分别进行不同的处理*/
ckey=getch();
if(ckey==′1′)
istate=input_all_score(iscore,SIZE);
elseif((istate==0)&&(ckey!
=Esc))
{
printf(″\nERROR:
Youmustinputscoresfirst!
″);
printf(″\nPressakeytocontinue.″);
getch();
}
elseif(ckey==′2′)
output_all_score(iscore,SIZE);
elseif(ckey==′3′)
count_for_max(iscore,SIZE);
elseif(ckey==′4′)
count_for_min(iscore,SIZE);
elseif(ckey==′5′)
count_for_total(iscore,SIZE);
elseif(ckey==′6′)
count_for_average(iscore,SIZE);
}while(ckey!
=Esc);
}
/*功能:
输入学生成绩*/
intinput_all_score(intiscore[],intisize)
第9章模块化程序设计153{
intiindex=0;
printf(″pleaseinput%dscores:
\n″,isize);
for(iindex=0;iindex
{
printf(″\npleaseinputthe%dscores:
″,iindex);
iscore[iindex]=getdigi(3);
}
return1;
}
/*功能:
输出学生成绩*/
voidoutput_all_score(intiscore[],intisize)
{
intiindex=0;
for(iindex=0;iindex
{
printf(″iscore[%2d]=%3d\n″,iindex,iscore[iindex]);
}
getch();
}
/*功能:
计算最高分*/
voidcount_for_max(intiscore[],intisize)
{
intimax=iscore[0];
intiindex=0;
for(iindex=0;iindex
{
if(imaximax=iscore[iindex];
}
printf(″\nThemaxscoreis%d″,imax);
154程序设计基础
getch();
}
/*功能:
计算最低分*/
voidcount_for_min(intiscore[],intisize)
{
intimin=iscore[0];
intiindex=0;
for(iindex=0;iindex
{
if(imin>iscore[iindex])
imin=iscore[iindex];
}
printf(″\nTheminscoreis%d″,imin);
getch();
}
/*功能:
计算总分*/
voidcount_for_total(intiscore[],intisize)
{
intiindex=0;
intisum=0;
for(iindex=0;iindex
{
isum=isum+iscore[iindex];
}
printf(″\nThetotalscoreis%d″,isum);
getch();
}
/*功能:
计算平均分*/
voidcount_for_average(intiscore[],intisize)
{
第9章模块化程序设计155
intiindex=0;
floatfaverage=0;
for(iindex=0;iindex
{
faverage=faverage+iscore[iindex];
}
faverage=faverage/isize;
printf(″\nTheaveragescoreis%.2f″,faverage);
getch();
}
/*function:
输入指定个数的数字,构成一个整形数据,可以用来代替scanf*/
/*name:
getdigi()*/
/*creat:
stone,2004/3/25*/
/*modify:
stone,2004/3/26*/
/*parametric:
inticount,数字个数*/
/*return:
int,整形数字*/
intgetdigi(inticount)
{
intiloop=0;
chardigit_str[MAXdigit]={′0′};
iloop=0;
do
{
digit_str[iloop]=getch();
if(isdigit(digit_str[iloop]))
{
putch(digit_str[iloop]);
iloop++;
}
}
while(iloopreturnatoi(digit_str);
}
156程序设计基础
双语精髓
Themainline
Sinceeachmoduleperformsasinglespecifictask,amainlineroutinemustprovide
themastercontrolthattiesallthemodulestogetherandcoordinatestheiractivity.This
programmainlineshouldshowthemainprocessingfunctions,andtheorderinwhich
theyaretobeperformed.Itshouldalsoshowtheflowofdataandthemajorcontrol
structures.Themainlineshouldalsobeeasytoread,beofmanageablelengthan