1.题目要求
作为教师,考试以后对试卷进行分析和研究是必须做的一项工作,假定某学校要求老师在考试之后填写的一个表格,并要求教师根据考试分数分布情况画出直方图。下面就来解决这个实际问题。
2.题目分析
- 程序运行时,首先必须接收总评成绩的计算比例,因为针对不同的课程,平时成绩和期末考试成绩所占的比例可能不同。
- 接收若干同学的平时成绩和期末考试成绩,计算出总评成绩,总评成绩的计算方法是“平时成绩所占比例×平时成绩+期末成绩所占比例×期末成绩”。
- 根据考试成绩计算分数段的分布情况,画出直方图。
- 计算平时成绩、期末成绩和总评成绩的平均分和标准差,以及期末考试卷面的及格率、最高分和最低分等。
由于针对一个学生有3个有关成绩的数据,因此最简单的方法就是使用结构体数组。第1列为学生的学号,第2列为学生的平时成绩,第3列为学生的期末成绩,第4列为学生的总评成绩。
3.文件说明
main.c//主要的函数调用 function.c//函数执行 function.h//整个程序的头文件
4.函数说明
int accept_date(STUDENT stu[],int grade[] ,int size_t);//输入数据 void show_data(STUDENT stu[],int sum,int grade[]);//输出所有的学生学号,成绩 void count(int* max,int* min,double* pass,double ave[],double f[],STUDENT stu[],int sum);//计算期末考试成绩及格率、最高分最低分以及平时、期末和总评成绩的平均分和标准差 void show_data2(int max,int min,double pass,double ave[],double f[]);//显示期末考试成绩及格率、最高分最低分以及平时、期末和总评成绩的平均分和标准差 void draw(int grade[]);//画出频率分布直方图
5.程序编写
5.1 fuction.h
#ifndef TEXT5_7_FUNCTION_H #define TEXT5_7_FUNCTION_H #endif //TEXT5_7_FUNCTION_H #include<stdio.h> #include <math.h> #include <string.h> #include <conio.h> typedef struct student//定义一个结构体变量 { int number;//定义学号 int source[3];//定义期中、期末、总评成绩 }STUDENT; typedef enum { False, True } FLAG;//枚举定义
5.2 main.c
#include "function.h" int accept_date(STUDENT stu[],int grade[] ,int size_t);//输入数据 void show_data(STUDENT stu[],int sum,int grade[]);//输出所有的学生学号,成绩 void count(int* max,int* min,double* pass,double ave[],double f[],STUDENT stu[],int sum);//计算期末考试成绩及格率、最高分最低分以及平时、期末和总评成绩的平均分和标准差 void show_data2(int max,int min,double pass,double ave[],double f[]);//显示期末考试成绩及格率、最高分最低分以及平时、期末和总评成绩的平均分和标准差 void draw(int grade[]);//画出频率分布直方图 int main() { int sum = 0,max = 0,min = 0;//初始化数据 double pass = 0; int SIZE = 0; printf("请输入学生人数\n"); scanf("%d",&SIZE); int grade[11] = {0}; STUDENT stu[SIZE]; double ave[SIZE],f[SIZE]; sum = accept_date(stu,grade,SIZE);//输入数据 show_data(stu,sum,grade);//输出所有的学生学号,成绩 count(&max,&min,&pass,ave,f,stu,sum);//计算期末考试成绩及格率、最高分最低分以及平时、期末和总评成绩的平均分和标准差 show_data2(max ,min,pass,ave,f );//显示期末考试成绩及格率、最高分最低分以及平时、期末和总评成绩的平均分和标准差 draw(grade);//画出直方图 return 0; }
5.3 fuction.c
#include "function.h" int accept_date(STUDENT stu[],int grade[],int size_t)//输入数据声明 { int i = 0,sum = 0,temp = 0,a1 = 0,a2 = 0; FLAG flag; printf("请输入期中期末占总评成绩的百分比,用整数表示\n"); scanf("%d %d",&a1,&a2); while(i<size_t){ printf("请输入学号:\n"); scanf("%d",&stu[i].number); if(stu[i].number==-1) { sum = i; break;//sum记录的是输入的人数 } printf("请输入平时成绩和期末成绩:\n"); flag = True; while(flag==True)//重复读取成绩,直到正确为止 { scanf("%d %d",&stu[i].source[0],&stu[i].source[1]); if(stu[i].source[0]<=100&&stu[i].source[0]>=0&&stu[i].source[1]<=100&&stu[i].source[1]>=0)//输入成绩合理,停止循环 { flag = False; } else//输入成绩不合理,重新输入 { printf("输入错误,请重新输入。\n"); } } temp = (int)(1.0*a1/100*stu[i].source[0]+1.0*a2/100*stu[i].source[1]);//计算总评成绩 stu[i].source[2] = temp; temp = stu[i].source[1]/10; //分数分段 if(temp==10) { grade[10]++; } else { grade[temp+1]++; } i++; } return sum; } void show_data(STUDENT stu[],int sum,int grade[])//输出成绩 { for (int i = 0; i < sum; ++i) { printf("%d",stu[i].number);//输出学号 for (int j = 0; j < 3; ++j) { printf("%d",stu[i].source[j]);//输出期中期末总评 printf("\n"); } } for (int i = 0; i < 10; ++i) { printf("%d\n",grade[i]); } } void count(int* max,int* min,double* pass,double ave[],double f[],STUDENT stu[],int sum) { int i = 0, j = 0, p_sum = 0; int total[3]; double temp = 0; *max = *min = stu[0].source[1];//最大最小值初始化 if(stu[0].source[1]>=60) { p_sum++; } for ( i = 1; i < sum; ++i) { if(stu[i].source[1]>*max) { *max = stu[i].source[1];//若高于最高分,将其覆盖 } if(stu[i].source[1]<*min) { *min = stu[i].source[1];//若低于最低分,将其覆盖 } if(stu[i].source[1]>=60) { p_sum++;//计算及格的人数 } } *pass = (1.0*p_sum/sum)*100;//计算及格率 for ( i = 0; i <= 2; ++i) { total[i] = 0; } for (j = 0; j < 3; j++) { for (int i = 0; i < sum; ++i) { total[j] = total[j] + stu[i].source[j]; } } for ( j = 0; j < 3; ++j) { ave[j] = total[j]/sum; } for (j = 0; j < 3; j++)//计算标准差 { f[j] = 0; for (i = 0; i < sum; i++) { temp = stu[i].source[j] - ave[j]; f[j] = f[j] + temp*temp; } f[j] = sqrt(fabs(f[j])/sum); } } void show_data2(int max,int min,double pass,double ave[],double f[]) { int j = 0; char str1[3][20] = {"平时成绩平均分","期末成绩平均分","总评成绩平均分"}; char str2[3][20] = {"平时成绩标准差","期末成绩标准差","总评成绩标准差"}; printf("及格率:%f 最高分:%d 最低分:%d\n",pass,max,min);//输出期末及格率,最高分,最低分 for (int i = 0; i < 3; ++i) { printf("%s = %f %s = %f\n",str1[i],ave[i],str2[i],f[i]);//循环输出平时期末总评成绩的平均分和标准差 } } void draw(int grade[]) { int max = 0,k = 0, temp = 0, x = 0; char screen[22][24]; printf("模拟直方图\n"); for (int i = 1; i <= 10; ++i) { if(grade[i]>max) { max = grade[i]; } } for (int i = 1; i <= 10; ++i) { grade[i]=(int)(20.0*grade[i]/max+0.5);//计算显示星号个数 } for (int i = 0; i <= 21; i++)//现将所有点清零 { for (int j = 0; j <= 42; j++) { screen[i][j] = 0; } } //画x轴 for (int i = 0; i < 41; ++i) { screen[21][i] = '_'; } screen[21][41] = 'x'; //画y轴 screen[0][0] = 'y'; for (int i = 1; i <= 21;i++) { screen[i][0] = '|'; } k = 1; for (x = 1; x <= 10; x++,k=k+4) { temp = grade[x]; if(temp!=0) { for (int i =1 ; i <= temp; i++) { for (int j = 1; j <= 4; j++) { screen[20-i+1][j+k] = '*'; } } } } for (int i = 0; i <= 21; i++) { for (int j = 0;j <=41; j++) { if(screen[i][j]!=0) { printf("%c",screen[i][j]); } else { printf(" "); } printf("\n"); } printf("0 10 20 30 40 50 60 70 80 90 100\n"); } getch(); }
6 主要C语言知识点
- 函数
- 多维数组
- 指针
- 结构体
- 循环