第 14章 C语言程序设计实例第 14章 C语言程序设计实例实例一 成绩处理程序实例二 电子词典程序第 14章 C语言程序设计实例实例一 成绩处理程序
1,问题描述进行若干个学生,若干门课程的成绩处理,要求计算:
(1) 每门课程的平均分和方差 。
(2) 每个学生的总分,平均分及方差 。
(3) 按总分对学生由高分到低分排序。
第 14章 C语言程序设计实例
2,数据说明
(1) 学生人数假定不超过 1000人,课程门数假定不超过
30门,分别用符号常量 N,M描述 。
(2) 实际学生人数,实际课程门数分别用整型量 n,m描述 。
(3) M门课程名称用二维字符数组 sname描述 。
(4) 学生数据考虑学号 num,姓名 name,M门课程成绩,
用结构体 stt描述 。 M门课程成绩用一维数组 score描述 。 N
个学生数据用结构体数组 sta描述 。
第 14章 C语言程序设计实例
(5) 每门课程的平均分和方差分别用一维实型数组
avs1,sus1描述 。
(6) 每个学生的总分,平均分及方差分别用一维实型数组 total,avs2和实型量 sus2描述 。
(7) 排序结果引入一序号数组 sort保存 。
以上变量定义为全局变量,同时利用这些变量在函数之间传递数据 。
(8) 数据源文件,处理结果文件分别用字符指针变量 ps,pt与文件指针变量 fps,fpt描述 。
第 14章 C语言程序设计实例
(9) 引入中间整型变量 i,j,k,i用于循环中控制学生,j用于循环中控制课程,k对应总分最高的学生序号 。
(10) 数据源文件前面存放学生实际学生人数,实际课程门数与课程名称;处理结果文件中学生数据增加总分,平均分及名次,课程的平均分和方差,学生的平均分和方差存放于文件的最后 。
第 14章 C语言程序设计实例
3,算法分析
(1) 整个程序由主控模块 main( ),输入模块
input( ),每门课程的平均分和方差计算模块 asfun
( ),每个学生的总分平均分及方差计算模块 tasfun
( ),排序模块 sortfun( ),输出模块 output( ) 六个模块组成 。 各模块之间顺序执行 。
(2) 实际学生人数 n,实际课程门数 m,原始成绩数据由键盘输入或从磁盘数据文件读取 。
第 14章 C语言程序设计实例
(3) 原始成绩数据由键盘输入时,将送磁盘文件
SCORE.DAT保存 。
(4) 方差计算公式为数据平方和的平均值减去数据平均值的平方 。
方差大,表示数据相互之间差别较大;方差小,表示数据相互之间差别较小 。
(5) 排序采用选择排序方法,利用序号数组保存学生名次,无需交换数据 。
(6) 处理结果与原始成绩数据合并后用另一磁盘文件 STUDEN.DAT保存。
第 14章 C语言程序设计实例
4,参考程序
# include ″stdio.h″
# include ″math.h″
# define N 1000
# define M 30
void input( ) ;
void asfun( ) ;
void tasfun( ) ;
void sortfun( ) ;
void output( );
第 14章 C语言程序设计实例
int n,m;
struct stt
{int num;
char *name;
float score[ M] ;
}sta[ N] ;
char sname[ M] [ 16] ;
float avs1[ M],svs1[ M] ;
float total[ N],avs2[ N],svs2;
int sort[ N]; [KH*2D]
第 14章 C语言程序设计实例
main( ) /*主控函数 */
{clrscr( ) ;
input( ) ;
asfun( ) ;
tasfun( ) ;
sortfun( ) ;
output( ) ;
}
第 14章 C语言程序设计实例
void input( ) /*获取数据 */
{char ch;
int i,j;
char *ps;
FILE *fps;
printf( ″请选择数据源 ( K-键盘输入 F-磁盘文件读取 ),\n″) ;
ch=getch( ) ;
if( ch==′K′||ch==′k′) /*键盘输入 */
{printf( ″请输入实际学生人数,″) ;
scanf( ″%d″,&n) ;
printf( ″请输入实际课程门数,″) ;
scanf( ″%d″,&m) ;
第 14章 C语言程序设计实例
if( n<=0||n>1000 ||m<=0 ||m>30)
{printf( ″数据无效 ! ″) ;
exit( 0) ;
}
printf( ″请输入 %d门课程名称,″,m) ;
for( j=0; j<m; j++)
scanf( ″%s″,sname[ j]) ;
for( i=0; i<n; i++)
{printf( ″请输入第 %d个学生学号,姓名,%d门课程成绩,″,i+1,m) ;
scanf( ″%d%s″,&sta[ i],num,sta[ i],name) ;
for( j=0; j<m; j++)
scanf( ″%f″,&sta[ i],score[ j]);
}
第 14章 C语言程序设计实例
ps=″SCORE.DAT″; /*送磁盘文件保存 */
if(( fps=fopen( ps,″wb″)) = =NULL)
{printf( ″文件建立错误 ! ″) ;
exit( 0) ;
}
fwrite( &n,2,1,fps) ;
fwrite( &m,2,1,fps) ;
fwrite( sname,16,m,fps) ;
fwrite( sta,sizeof( struct stt),n,fps) ;
fclose( fps) ;
}
第 14章 C语言程序设计实例
else if( ch==′F′||ch==′f′) /*从磁盘文件读取数据 */
{printf( ″请输入数据文件名,″) ;
scanf( ″%s″,ps) ;
if(( fps=fopen( ps,″rb″)) ==NULL)
{printf( ″文件打开错误 ! ″) ;
exit( 0) ;
}
fread( &n,2,1,fps) ;
fread( &m,2,1,fps) ;
fread( sname,16,m,fps) ;
fread( sta,sizeof( struct stt),n,fps) ;
fclose( fps) ;
}
第 14章 C语言程序设计实例
else
{printf( ″数据源选择错误 ! ″) ;
exit( 0) ;
}
}
void asfun( ) /*计算每门课程的平均分和方差 */
{int j;
float t[ M],ts[ M] ;
for( j=0; j<m; j++)
{t[ j] =0; ts[ j] =0;
for( i=0; i<n; i++)
{t[ j] +=sta [ i],score[ j] ;
ts[ j] +=sta [ i],score[ j] *sta[ i],score[ j] ;
}
第 14章 C语言程序设计实例
avs1[ j] =t[ j] /n;
sus1[ j] =ts[ j] /n- avs1[ j] * avs1[ j] ;
}
}
void tasfun( ) /*计算每个学生的总分,平均分和方差 */
{int i,j;
float ta=0,ts=0;
for( i=0; i<n; i++)
{total[ i] =0;
for( j=0; j<m; j++)
total[ i] +=sta[ i],score[ j] ;
avs2[ i] =total[ i] /n;
ta+=avs2[ i] ; ts+=avs2[ i] *avs2[ i] ;
}
第 14章 C语言程序设计实例
sus2=ts/n-( ta/n) *( ta/n) ;
}
void sortfun( ) /*按总分排序 */
{int i,j,k;
for( i=0; i<n; i++)
{k=i;
for( j=i+1; j<m; j++)
if( total[ j] >total[ k]) k=j;
sort[ i] =k+1;
}
}
第 14章 C语言程序设计实例
void output( ) /*输出数据 */
{int i,l,j;
int is;
clrscr( ) ; /*输出数据送屏幕 */
printf( ″%d个学生 %d门课程成绩数据如下,\n″) ;
printf( ″ 学号 姓名 ″) ;
for( j=0; j<m; j++)
printf( ″%16s″,sname[ j]) ;
printf( ″| 总分 平均分 名次 \n″) ;
for( i=0; i<n; i++)
{for( l=0; l<n; l++)
第 14章 C语言程序设计实例
if( sort[ l] ==i+1) is=l;
printf( ″%8d%12s″,sta[ is],num,sta[ is],name) ;
for( j=0; j<m; j++)
printf( ″%16.2f″,sta[ is],score[ j]) ;
printf( ″| %8.2f%8.2f%6d\n″,total[ is],avs2[ is],sort[ is] );
}
printf( ″ 课程平均分 ″) ;
for( j=0; j<m; j++)
printf( ″%16.2f″,avs1[ j]) ;
printf( ″\n″) ;
printf( ″ 方差 ″);
第 14章 C语言程序设计实例
for( j=0; j<m; j++)
printf( ″%16.2f″,sus1[ j]) ;
printf( ″%16.2\n″,sus2) ;
pt=″STUDENT.DAT″; /*输出数据送磁盘 */
if(( fpt=fopen( pt,″wb″)) ==NULL)
{printf( ″文件建立错误 ! ″) ;
exit( 0) ;
}
fwrite( &n,2,1,fpt) ;
fwrite( &m,2,1,fpt) ;
fwrite( sname,16,m,fpt) ;
for( i=0; i<n; i++)
第 14章 C语言程序设计实例
{ fwrite( &sta[ i],sizeof( struct stt),1,fpt) ;
fwrite( &total[ i],4,1,fpt) ;
fwrite( &avs2[ i],4,1,fpt) ;
fwrite( &sort[ i],2,1,fpt) ;
}
fwrite( avs1,4,m,fpt) ;
fwrite( &sus2,4,1,fpt) ;
fclose( fpt) ;
}
第 14章 C语言程序设计实例
5,几点说明
(1) 数据源文件可用字处理软件直接建立 。
(2) 程序的实现可以不用数组,而用链表 。
(3) 函数之间数据可改用参数传递 。
(4) 处理结果还可考虑打印输出 。
(5) 流程图请读者画出 。
(6) 所做的数据与算法分析可转化成本程序的简单技术文档。
第 14章 C语言程序设计实例实例二 电子词典程序
1.
在计算机中建立有限规模的电子英汉词典 ( 文件 ),利用程序实现电子英汉词典的查找与增,删,
改等维护 。
第 14章 C语言程序设计实例
2.
(1) 对单词和释义字符串长度的限定分别为不超过 20
个与 40个字符,词条数限定为不超过 1000条 。
(2) 单词数组 words,字符串数组 。 释义数组 expls,
字符串数组 。 词典中词条总数 len,整型变量 。
(3) 标志变量 flag,在主函数中为 0则执行菜单,为 1
则退出程序;在进入词典操作命令后,为 1则继续执行同一命令,为 0则退回到菜单 。
以上变量定义为全局变量。
第 14章 C语言程序设计实例
(4) 命令序号 num,整型 。 在 main( ) 函数中用于散转执行对应操作 。
(5) 一维字符数组 ( 字符串 ) word在 lookup( ) 函数中为待查单词,在 insert( ) 函数中为 r待插入单词,在 delete
( ) 函数中为待删除单词,在 modify( ) 函数中为待修改单词,在 display( ) 函数中为待显示单词 。
(6) 一维字符数组 ( 字符串 ) expl为待插入释义或待改成的释义 。
(7) 在 search1( ) 和 search2( ) 中,正整数 l,查找下限,形参;正整数 r,查找上限,形参;正整数 m,中点位置,计算得到 。
第 14章 C语言程序设计实例
3,算法分析
(1) 执行该程序要求在磁盘上有一个词典文件,可使用任何中文编辑软件生成 。 其内容是每行对应一个词条,每词条包括用若干空格符分开两个字符串,前一个是单词字符串 ( 英文 ),后一个是释义字符串
( 中文 ),使用分号作为多个释义的分隔符 ( 无空格 ) 。 事实上,即使该文件内无一词条,也可用本程序在线生成所需词典,但必须有一个已存在的合乎上述格式的,哪怕是空白的文件 。
第 14章 C语言程序设计实例
(2) 采用菜单工作方式 。 在一个操作命令执行之后,程序询问是否继续执行该命令 。 如输入 y或 Y,
则重复同一操作,不退回到菜单;如输入其它信息,
则回到菜单等待另一次选择 。 仅当选择退出操作时,
程序会询问是否将修改后的词典存盘,并根据用户的选择存盘或不存盘退出 。
第 14章 C语言程序设计实例
(3) 除主函数之外,程序包含其它 11 个函数:
input( file),从文件 file中读入词典各词条的单词和释义分别到字串数组 words和 expls中 。 对每个字符串长度进行检查,发现非法长度后会显示出错信息并退出程序 。
menu( ),显示控制菜单 。
lookup( ),查询一个单词的释义 。
insert( ),在词典中适当位置插入一个给定词条的单词和释义 。
delete( ),从词典中删去一个词条的单词和释义 。
modify( ),修改词典中给定单词的释义 。
display( ),显示词典中在给定单词前后的部分词条的单词和释义。
第 14章 C语言程序设计实例
quit( ),在询问是否要存盘之后退出程序 。
search1( l,r,word),在单词数组 words的 1~r位置中查找给定单词 word的位置 。 查到,返回该位置;查不到返回 -1。 分别由 lookup( ),delete( ),modify( ) 和
display( ) 调用 。
search2( 1,r,word),在单词数组 words的 1~r位置中查找给定单词 word的插入位置 。 查到,返回该位置;查不到,不必插入,返回 -1。 分别由 insert( ) 和 display( )
调用 。
continue( ),询问用户是否继续执行词典的操作 。
除了退出,查询,插入,删除,修改,显示均调用该函数 。
第 14章 C语言程序设计实例
4,参考程序
# include ″stdio.h″
# include ″string.h″
# define MAXLEN 1000
# define STRLEN1 20
# define STRLEN2 40
void menu( ) ;
void input( ) ;
void lookup( ) ;
void insert( ) ;
void delete( ) ;
void modify( ) ;
void display( ) ;
void quit( );
第 14章 C语言程序设计实例
int search1( ) ;
int search2( ) ;
void continue( ) ;
char *words[ MAXLEN],*expls[ MAXLEN] ;
int len,flag=0; [KH*2D]
main( ) /*主控函数 */
{char *file;
int num;
printf( ″请输入词典文件名,\n″) ;
scanf( ″%s″,file) ;
input( file) ;
while( ! flag)
{menu( );
第 14章 C语言程序设计实例
scanf( ″%d″,&num) ;
switch( num)
{case 1,lookup( ) ; break;
case 2,insert( ) ; break;
case 3,delete( ) ; break;
case 4,modify( ) ; break;
case 5,display( ) ; break;
case 6,qiut( file) ; break;
default,printf( ″选择错,按任一键返回菜单 ! ″) ; getch( ) ;
}
}}
第 14章 C语言程序设计实例
void input( file) /*读取词典 */
char file[ ] ;
{int i;
FILLE *fp;
char str[ STRLEN1] ;
if(( fp=fopen( file,″r″)) ==NULL)
{printf( ″不能打开文件 %s! ″,file) ;
exit( 0) ;
}
i=0;
fscanf( fp,″%s″,str) ;
while(! feof( fp))
第 14章 C语言程序设计实例
{strcpy( words[ i],str) ;
fscanf( fp,″%s″,expls[ i++]) ;
fscanf( fp,″%s″,str) ;
}
len=i;
fclose( fp) ;
}
void menu( ) /*菜单 */
{clrscr( ) ;
printf( ″电子词典程序 \n″) ;
printf( ″\n\n1-单词查询 \n″) ;
printf( ″2-增加词条 \n″);
第 14章 C语言程序设计实例
printf( ″3-删除词条 \n″) ;
printf( ″4-修改词条 \n″) ;
printf( ″5-显示词条 \n″) ;
printf( ″6-退出 \n\n\n″) ;
printf( ″\n\n请选择 ( 1~6) \n″) ;
}
void lookup( ) /*查找单词释义 */
{char word[ STRLEN1] ;
int i;
flag=1;
while( flag)
{printf( ″请输入查询单词,″) ;
scanf( ″%s″,word) ;
i=search1( 0,len-1,word);
第 14章 C语言程序设计实例
if( i==-1)
printf( ″无此单词 ! \n″) ;
else
printf( ″%s\n″,expls[ i]) ;
continue( ) ;
}}
void insert( ) /*插入 */
{char word[ STRLEN1],expl[ STRLEN2] ;
int i,j;
flag=1;
while( flag)
{printf( ″请输入待插入的单词和释义,″) ;
scanf( ″%s%s″,word,expl);
第 14章 C语言程序设计实例
i=search2( 0,len,word) ;
if( i==-1)
printf( ″已有此单词 ! \n″) ;
else
{for( j=len; j>i; j--)
{strcpy( words[ j],words[ j-1]) ;
strcpy( expls[ j],expls[ j-1]) ;
}
strcpy( words[ i],word) ;
strcpy( expls[ i],expls) ;
len++;
}
第 14章 C语言程序设计实例
continue( ) ;
}}
void delete( ) /*删除 */
{char word[ STRLEN1] ;
int i,j;
flag=1;
while( flag)
{printf( ″请输入待删除的单词,″) ;
scanf( ″%s″,word) ;
i=search1( 0,len-1,word) ;
if( i==-1)
printf( ″无此单词! \n″);
第 14章 C语言程序设计实例
else
{for( j=i; j<len-1; j++)
{strcpy( words[ j],words[ j+1]) ;
strcpy( expls[ j],expls[ j+1]) ;
}
len--;
}
continue( ) ;
}}
void modify( ) /*修改 */
{char word[ STRLEN1],expl[ STRLEN2] ;
int i;
flag=1;
第 14章 C语言程序设计实例
while( flag)
{printf( ″请输入待修改的单词,″) ;
scanf( ″%s″,word) ;
i=search1( 0,len-1,word) ;
if( i==-1)
printf( ″无此单词 ! \n″) ;
else
{printf( ″输入新释义,″) ;
scanf( ″%s″,expl) ;
strcpy( expls[ i],expl) ;
}
continue( ) ;
}}
第 14章 C语言程序设计实例
void quit( file) /*退出 */
char file[ ] ;
{int i;
FILE *fp;
char ch;
printf( ″是否存入词典 ( Y/N)? ″) ;
ch=getch( ) ;
if( ch==′Y′‖ ch==′y′)
{if(( fp=fopen( file,″w″)) ==NULL)
{printf( ″不能打开文件 %s! \n″,file) ;
exit( 0) ;
}
第 14章 C语言程序设计实例
for( i=0; i<len; i++)
fprintf( fp,″%-20s%-40s\n″,words[ i],expls[ i]) ;
fclose( fp) ;
}
flag=1;
}
void display( ) /*显示 */
{int i,i1,i2;
char word[ STRLEN1] ;
flag=1;
while( flag)
{printf( ″请输入待显示的单词,″) ;
scanf( ″%s″,word) ;
i=search1( 0,len-1,word);
第 14章 C语言程序设计实例
if( i= =-1)
i=search2( 0,len,word) ;
i1=i>=8? i-8,0;
i2=i<=len-8? i+8,len-1;
for( i=i1; i<=i2; i++)
printf( ″%-20s%-40s\n″,words[ i],expls[ i]) ;
continue( ) ;
}}
int search1( 1,r,word) /*查找单词位置 */
int l,r;
char word[ ] ;
{int m;
第 14章 C语言程序设计实例
while( l<=r)
{m=( l+r) /2;
if( strcmp( word,words[ m]) = =0)
return m;
else if( strcmp( word,words[ m]) >0)
l=m+1;
else r=m-1;
}
return( -1) ;
}
int search2( l,r,word) /*查找插入位置 */
int l,r;
char word;
第 14章 C语言程序设计实例
{int m;
while( l<r)
{m=( l+r) /2;
if( strcmp( word,words[ m]) = =0)
return( -1) ;
else if( strcmp( word,words[ m]) >0)
l=m+1;
else r=m;
}
return ( l);
第 14章 C语言程序设计实例
}
void continue( ) /*重复执行操作 */
{char ch;
printf( ″继续执行吗 ( Y/N)? ″) ;
ch=getch( ) ;
if( ch==′Y′‖ ch=′y′)
flag=1;
else
flag=0;
}
第 14章 C语言程序设计实例
5,说明
(1) 如果需增加单词及释义字串长度,应修改源程序中有关参数 。
(2) 对单词除了释义外,还可增加发音,同义词,反义词等考虑 。
(3) 流程图,简单技术文档亦请读者给出 。
(4) 延伸考虑电子新华字典程序。