Download presentation
Presentation is loading. Please wait.
1
C 程序设计实例 1. 问题描述 2. 数据结构 3. 算法分析 4. 参考程序 5. 改进说明
2
实例 :学生成绩处理 1. 问题描述 进行若干个学生、 若干门课程的成绩处理: (1) 计算每门课程平均分和方差;
(2) 计算每个学生总分、 平均分; (3) 按总分对学生由高分到低分排序。
3
(1) 学生人数假定不超过1000人, 课程门数假定不超过30门,分别用符号常量 N、M 存储
2. 数据结构 (1) 学生人数假定不超过1000人, 课程门数假定不超过30门,分别用符号常量 N、M 存储 (2) 实际学生人数及课程门数分别用整型量 n、m 存储 (3) M 门课程的名称用二维字符数组 sname 存储 (4) 学生信息包括:学号(num)、姓名(name)、M门课程成绩,用结构类型 stt 描述,其中 M 门课的成绩用一维数组 score 存储 (5) N 个学生的信息用结构数组 sta 存储
4
(6) 每门课程的平均分、方差用一维实型数组avs1、 svs1 保存
2. 数据结构(续) (6) 每门课程的平均分、方差用一维实型数组avs1、 svs1 保存 (7) 每个学生的总分、 平均分用一维实型数组 total、 avs2 保存,学生平均分的方差用实数变量 svs2 保存 (8) 排序结果采用一个序号数组 sort 间接保存 以上变量均是全局变量,用于在函数间传递数据 (9) 数据输入文件、结果输出文件分别用字符指针变量 ps、pt 与文件指针变量 fps、fpt 描述
5
2. 数据结构(续) (10) 中间变量i、 j、 k:i 用于循环中控制学生, j 用于循环中控制课程,k 对应总分最高的学生序号
(11) 数据输入文件格式:前面存放学生实际人数、 实际课程门数与课程名称 (12) 结果输出文件格式:学生数据及其总分、平均分及名次,课程平均分、方差和学生平均分的方差存放于文件最后
6
3. 算法分析 (1) 程序结构:由若干函数模块组成 主控模块 main() 输入控制模块 input() 键盘输入模块 kinput()
文件输入模块 finput() 每门课程平均分、方差计算模块 asfun() 每个学生的总分、平均分及其方差计算模块 tasfun() 排序模块 sortfun() 输出模块 output()
7
3. 算法分析 (2)数据输入: 学生实际人数 n 课程实际门数 m 原始成绩数据 第一次由键盘输入,并写入磁盘文件 SCORE.DAT
以后数据可直接从上述文件读取
8
3. 算法分析 (3) 方差计算 (4) 总成绩排序 (5) 处理结果 方差 = 数据平方和的平均值减去数据平均值的平方 采用简单选择排序
若方差值大,则表示数据值之间的差别较大;反之,若方差值小,则表示数据值之间的差别较小 (4) 总成绩排序 采用简单选择排序 利用序号数组保存学生名次,无需交换数据 (5) 处理结果 与原始成绩数据合并,写入磁盘文件STUDEN.DAT
9
#include "stdio.h" /* 标准输入输出 */ #include "math.h" /* 标准数学函数*/
4. 参考程序 (1) #include "stdio.h" /* 标准输入输出 */ #include "math.h" /* 标准数学函数*/ #define N 1000 /* 最大学生人数 */ #define M 30 /* 最大课程门数*/ void input (); /* 学生数据输入控制 */ void kinput (); /* 键盘输入学生数据 */ void finput (); /* 文件读入学生数据 */ void asfun (); /* 课程平均及方差计算 */ void tasfun (); /* 学生总分、平均分及方差计算 */ void sortfun (); /* 成绩排序 */ void output (); /* 输出学生数据 */
10
float score[M]; /* 成绩数组 */ } sta[N]; /* 保存学生数据的数组 */
4. 参考程序 (2) /*** 以下为全局变量声明 ***/ int n, /* 学生实际人数 */ m; /* 课程实际门数 */ /* 学生数据结构体 */ struct stt { int num; /* 学号*/ char *name; /* 姓名 */ float score[M]; /* 成绩数组 */ } sta[N]; /* 保存学生数据的数组 */ char sname[M][16]; /* 课程名称数组,名称长度不超过16个字符 */
11
float avs1[M], /* 课程平均分数组 */ svs1[M]; /* 课程方差数组 */
4. 参考程序 (3) /*** 以下为全局变量声明(续) ***/ float avs1[M], /* 课程平均分数组 */ svs1[M]; /* 课程方差数组 */ float total[N], /* 学生总分数组*/ avs2[N], /* 学生平均分数组 */ svs2; /* 学生平均分的方差 */ int sort[N]; /* 排序用的序号数组 */ /* 元素值 = 学生数据在结构体数组 sta 中的下标 */
12
#include <stdio.h> #include <stdlib.h>
4. 参考程序 (4) /*主函数*/ #include <stdio.h> #include <stdlib.h> #include <string.h> void main () { input( ); /* 输入 */ asfun( ); /* 课程计算 */ tasfun( ); /* 学生计算 */ sortfun( ); /* 排序 */ output( ); /* 输出 */ }
13
4. 参考程序 (5) void input( ) { /*获取原始数据的子函数*/ char ch; printf("请选择数据源(K-键盘输入 F-磁盘文件读取): \n"); ch=getch( ); if(ch==‘K’||ch=='k') { /* 键盘输入*/ kinput(); else if(ch=='F'||ch=='f')/*从磁盘文件读取数据*/ finput(); else { printf("数据源选择错误!"); } }
14
4. 参考程序 (6) void kinput( ) { /* 键盘输入原始数据子函数 */ int i, j; char *ps; printf("请输入实际学生人数: "); scanf("%d", &n); printf("请输入实际课程门数: "); scanf("%d", &m); if(n<=0||n>N || m<=0 ||m> M ) { printf("数据无效!"); exit(0); } printf("请输入%d门课程名称: ",m); for(j=0; j<m; j++) scanf("%s", sname[j]);
15
4. 参考程序 (7) 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]); } /* 后续代码:将键盘输入数据写入文件 */
16
4. 参考程序 (8) 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); } /* end kinput() */
17
4. 参考程序 (9) void finput( ) { /*从文件读取原始数据子函数*/ char *ps; FILE *fps; 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); }
18
4. 参考程序 (10) void asfun( ) {/*计算课程平均分、方差子函数*/ int i , 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]; } avs1[j]=t[j]/n; sus1[j]=ts[j]/n- avs1[j]* avs1[j]; }
19
4. 参考程序 (11) 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]; } svs2=ts/n-(ta/n)*(ta/n);
20
4. 参考程序 (12) 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; }
21
4. 参考程序 (13) void output( ) {/*输出数据子函数*/ int i, l, j; int is; 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++)
22
if(sort[l]==i+1) is=l; printf("%8d%12s", sta[is].num, sta[is].name);
4. 参考程序 (14) 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(" 方差 ");
23
4. 参考程序 (15) for(j=0; j<m; j++) printf("%16.2f", sus1[j]); printf("%16.2\n", svs2); 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++) {
24
4. 参考程序 (16) 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(&svs2, 4, 1, fpt); fclose(fpt); }
25
5. 改进说明 (1) 数据输入文件可用记事本直接建立 (2) 程序实现可以不用数组,而用链表 (3) 函数之间数据可改用参数传递
Similar presentations