📃 基于C语言的学生试卷分数统计程序设计及实现
🧈 前言
最近有个朋友找我帮做C语言作业,话不多说,直接上代码,一定注意看清要求是否差不多。
🥪 程序要求
-
程序运行时,首先必须接收总评成绩的计算比例,针对该课程,平时成绩和期末考试成绩所占的比例分别为20%和80%。
-
接收若干同学的平时成绩和期末考试成绩,计算出总评成绩。
-
输出所有学号、平时成绩、期末卷面成绩和总评成绩,输出各分数段的分数分布情况。
-
画出各分数段的直方图。
-
计算平时成绩、期末成绩和总评成绩的平均分和标准差,以及期末考试卷面的及格率、最高分和最低分等。
这个作业是给了部分程序代码的,我看了下,实现的时候就避免使用实例代码额外的方法,就类似于只使用结构体数组存储这种。注释得也比较清楚,就不分析了。
🍤 代码
#include "stdio.h"
#include "string.h"
#include "conio.h"
#include "math.h"#define FLT_MIN 1.175494351e-38F
#define FLT_MAX 3.402823466e+38F
#define MAX_NUM 34 // 最大学生人数typedef struct student
{int number; // 学号float score[3]; // 平时、期末、总评成绩
} STUDENT;int accept_data(STUDENT stu[], int grade_count[], int stu_count); // 学生数据输入 + 成绩计算 + 数据存储
void show_stu_data(STUDENT stu[], int grade_count[], int stu_count); // 所有学生信息显示
void draw(int grade_count[], int grade_count_length, int stu_count); // 直方图绘制
void caculate(float *score_min, float *score_max, float *pass, float ave[], float f[], STUDENT stu[], int stu_count); // 及格率 & 平均分 & 标准差计算
void show_data(float score_min, float score_max, float pass, float ave[], float f[]); // 平时成绩、期末成绩、总评成绩平均值&标准差显示int accept_data(STUDENT stu[], int grade_count[], int stu_count = 0)
/*
学生数据输入 + 成绩计算 + 数据存储
:param stu[]: 学生结构体数组
:param grade_count[]: 学生总评成绩分布数组
:param stu_count: 当前学生总数, 默认为0
:return stu_count: 当前学生总数
*/
{int a1, a2;printf("\n请输入计算总评成绩时使用平时成绩与期末成绩的比例, 用整数表示: ");scanf("%d%d", &a1, &a2);while (stu_count < MAX_NUM){printf("请输入学号:");scanf("%d", &stu[stu_count].number);if (stu[stu_count].number == -1) // 序号—1跳出循环{return stu_count;}printf("请输入学生的平时成绩和期末成绩:");bool flag = true;while (flag){ // 重复读入两个数,正确为止scanf("%f%f", &stu[stu_count].score[0], &stu[stu_count].score[1]);if (stu[stu_count].score[0] <= 100 && stu[stu_count].score[0] >= 0 &&stu[stu_count].score[1] <= 100 && stu[stu_count].score[1] >= 0)flag = false; // 输入数据合理elseprintf("\n错误数据, 请再次输入学生的平时成绩和期末成绩:");}stu[stu_count].score[2] = 1.0 * a1 / 100 * stu[stu_count].score[0] + 1.0 * a2 / 100 * stu[stu_count].score[1];// 学生分布计数int temp = int(stu[stu_count].score[2] / 10);grade_count[temp]++;stu_count++;}return stu_count;
}void show_stu_data(STUDENT stu[], int grade_count[], int stu_count)
/*
输出所有学生信息
:param stu[]: 学生结构体数组
:param grade_count[]: 学生总评成绩分布数组
:param stu_count: 当前学生总数
:return stu_count: 当前学生总数
*/
{printf("\n-------------学生成绩信息-------------\n");for (int i = 0; i < stu_count; i++){printf("%4d ", stu[i].number);for (int j = 0; j < 3; j++)printf("%4.2f ", stu[i].score[j]);printf("\n");}printf("\n-----------------成绩分布状况-----------------\n");for (int i = 0; i < 10; i++){printf("%d ", grade_count[i]);}printf("\n");
}void draw(int grade_count[], int grade_count_length, int stu_count)
/*
直方图绘制
:param grade_count[]: 学生总评成绩分布数组
:param grade_count_length: 分数段类型数
:return: null
*/
{int i, j;const int width_length = 4; // x 段长const int high_length = 2; // y 段长const int width = 44; // x 长度const int high = 22; // y 长度char screen[high + high_length][width + width_length]; // 画布 包含标记// 画布初始化for (i = 0; i < high + high_length; i++){for (j = 0; j < width + width_length; j++){screen[i][j] = 0;}}// 画布数据标准化printf("\n-------------------模拟直方图-----------------\n");for (i = 0; i < grade_count_length; i++) {grade_count[i] = (int)(float(high) * grade_count[i] / stu_count);}// X&Y轴for (i = 0; i < width; i++){screen[high + high_length - 1][i] = '-';}for (i = 1; i < high + high_length; i++){screen[i][0] = '|';}screen[high + high_length - 1][width + width_length - 1] = 'X';screen[0][0] = 'Y';screen[1][0] = '^';screen[high + high_length - 1][width] = '>';// 柱形for (i = 0; i < grade_count_length; i++){for (j = grade_count[i]; j > 0; j--){screen[high + high_length - j - 1][(i + 1) * 4] = '*';}}// 绘图for (i = 0; i < high + high_length; i++){for (j = 0; j < width + width_length; j++)if (screen[i][j] != 0)printf("%c", screen[i][j]);elseprintf(" ");printf("\n");}printf(" 0 10 20 30 40 50 60 70 80 90 100\n");
}void caculate(float *score_min, float *score_max, float *pass, float ave[], float f[], STUDENT stu[], int stu_count)
/*
及格率 & 平均分 & 标准差计算
:param *score_min: 卷面成绩最低分
:param *score_max: 卷面成绩最高分
:param *pass: 及格率
:param ave[]: 平时成绩、期末成绩和总评成绩 平均分
:param f[]: 平时成绩、期末成绩和总评成绩 标准差
:param stu[]: 学生结构体数组
:param stu_count: 当前学生总数
:return: null
*/
{for (int i = 0; i < stu_count; i++){if ((stu[i].score[1]) > *score_max) // 若高于最高分,更新最高分*score_max = stu[i].score[1];if ((stu[i].score[1]) < *score_min) // 若低于最低分,更新最低分*score_min = stu[i].score[1];if (stu[i].score[1] >= 60)(*pass)++;}*pass = (*pass) / stu_count * 100.0; // 及格率for (int i = 0; i < 3; i++) // 平均分{float sum = 0;for (int j = 0; j < stu_count; j++){sum += stu[j].score[i];}ave[i] = sum / stu_count;}for (int i = 0; i < 3; i++) // 标准差{double sum = 0;for (int j = 0; j < stu_count; j++){sum += pow(double(stu[j].score[i] - ave[0]), 2.0);}f[i] = float(sqrt(sum / stu_count));}
}void show_data(float score_min, float score_max, float pass, float ave[], float f[])
/*
平时成绩、期末成绩、总评成绩平均值&标准差显示
:param score_min: 卷面成绩最低分
:param score_max: 卷面成绩最高分
:param pass: 及格率
:param ave[]: 平时成绩、期末成绩和总评成绩 平均分
:param f[]: 平时成绩、期末成绩和总评成绩 标准差
:return: null
*/
{char str1[3][22] = {"平时成绩平均分", "期末成绩平均分", "总评成绩平均分"};char str2[3][22] = {"平时成绩标准差", "期末成绩标准差", "总评成绩标准差"};printf("\n及格率=%6.2f 最低分=%6.2f 最高分=%6.2f\n", pass, score_min, score_max);for (int j = 0; j < 3; j++)printf("\n%s = %6.2f %s = %6.2f\n", str1[j], ave[j], str2[j], f[j]);
}int main()
{int stu_count = 0; // 当前学生人数int grade_count_length = 11; // 分数段类型数int grade_count[11] = {0}; // 总评成绩分布float score_min = FLT_MAX; // 卷面成绩最小值float score_max = FLT_MIN; // 卷面成绩最大值float pass = 0.0; // 及格率float ave[3] = {0.0}; // 平时成绩、期末成绩和总评成绩 平均值float f[3] = {0.0}; // 平时成绩、期末成绩和总评成绩 标准差STUDENT stu[MAX_NUM];stu_count = accept_data(stu, grade_count, stu_count); // 学生信息输入show_stu_data(stu, grade_count, stu_count); // 学生信息显示draw(grade_count, grade_count_length, stu_count); // 成绩分布直方图绘制caculate(&score_min, &score_max, &pass, ave, f, stu, stu_count); // 所有成绩及格率、最高分、最低分计算show_data(score_min, score_max, pass, ave, f); // 期末成绩的最高分、最低分以及平时期末和总评成绩的平均分和标准差显示return 0;
}
🍡 测试结果
🥯 题外话
最近不是chatGPT比较火吗,我就把要求拿上去试了一下,给出的结果基本一致,以下是它给出的结果。
-
chatGPT给的代码
#include <stdio.h> #include <stdlib.h> #include <math.h>#define NUM_STUDENTS 3 // 定义学生数量 #define SCORE_LEVELS 10 // 定义分数段数量typedef struct student { // 定义学生结构体char id[10]; // 学号float score_regular; // 平时成绩float score_final; // 期末成绩float score_total; // 总评成绩 } Student;// 函数声明 void get_proportions(float *regular_proportion, float *final_proportion); // 获取成绩计算比例 void input_scores(Student *students); // 输入学生成绩 void calculate_total_scores(Student *students, float regular_proportion, float final_proportion); // 计算学生总评成绩 void print_students(Student *students); // 输出学生成绩 void print_score_distribution(Student *students); // 输出分数分布情况 void draw_histogram(Student *students); // 画出各分数段的直方图 void calculate_statistics(Student *students); // 计算各种统计信息int main(void) {float regular_proportion, final_proportion; // 定义平时成绩和期末成绩所占比例// 获取成绩计算比例get_proportions(®ular_proportion, &final_proportion);Student students[NUM_STUDENTS]; // 定义学生数组// 输入学生成绩input_scores(students);// 计算学生总评成绩calculate_total_scores(students, regular_proportion, final_proportion);// 输出学生成绩print_students(students);// 输出分数分布情况print_score_distribution(students);// 画出各分数段的直方图draw_histogram(students);// 计算各种统计信息calculate_statistics(students);return 0; }// 获取成绩计算比例 void get_proportions(float *regular_proportion, float *final_proportion) {// 平时成绩所占比例为20%*regular_proportion = 0.2;// 期末成绩所占比例为80%*final_proportion = 0.8; }// 输入学生成绩 void input_scores(Student *students) {for (int i = 0; i < NUM_STUDENTS; i++){printf("请输入第%d个学生的学号、平时成绩和期末成绩:\n", i + 1);scanf("%s%f%f", students[i].id, &students[i].score_regular, &students[i].score_final);} }// 计算学生总评成绩 void calculate_total_scores(Student *students, float regular_proportion, float final_proportion) {for (int i = 0; i < NUM_STUDENTS; i++){// 总评成绩 = 平时成绩 * 平时成绩所占比例 + 期末成绩 * 期末成绩所占比例students[i].score_total = students[i].score_regular * regular_proportion + students[i].score_final * final_proportion;} }// 输出学生成绩 void print_students(Student *students) {printf("学号\t平时成绩\t期末卷面成绩\t总评成绩\n");for (int i = 0; i < NUM_STUDENTS; i++){printf("%s\t%.1f\t\t%.1f\t\t%.1f\n", students[i].id, students[i].score_regular, students[i].score_final, students[i].score_total);} }// 输出分数分布情况 void print_score_distribution(Student *students) {int distribution[SCORE_LEVELS] = {0}; // 定义分数分布数组,并将所有元素初始化为0// 统计分数分布for (int i = 0; i < NUM_STUDENTS; i++){int score = (int)students[i].score_total / 10; // 计算分数所属的分数段distribution[score]++; // 将对应分数段的值加1}printf("分数段\t人数\n");for (int i = 0; i < SCORE_LEVELS; i++){printf("%d-%d\t%d\n", i * 10, i * 10 + 9, distribution[i]);} }// 画出各分数段的直方图 void draw_histogram(Student *students) {int distribution[SCORE_LEVELS] = {0}; // 定义分数分布数组,并将所有元素初始化为0// 统计分数分布for (int i = 0; i < NUM_STUDENTS; i++){int score = (int)students[i].score_total / 10; // 计算分数所属的分数段distribution[score]++; // 将对应分数段的值加1}// 画出直方图for (int i = 0; i < SCORE_LEVELS; i++){printf("%d-%d: ", i * 10, i * 10 + 9);for (int j = 0; j < distribution[i]; j++){putchar('*');}putchar('\n');} }// 计算各种统计信息 void calculate_statistics(Student *students) {float sum_regular = 0, sum_final = 0, sum_total = 0; // 定义平时成绩、期末成绩和总评成绩的总和float square_sum_regular = 0, square_sum_final = 0, square_sum_total = 0; // 定义平时成绩、期末成绩和总评成绩的平方和float pass_count = 0; // 定义及格人数float max_regular = 0, max_final = 0, max_total = 0; // 定义平时成绩、期末成绩和总评成绩的最大值float min_regular = 100, min_final = 100, min_total = 100; // 定义平时成绩、期末成绩和总评成绩的最小值for (int i = 0; i < NUM_STUDENTS; i++){// 统计平时成绩、期末成绩和总评成绩的总和和平方和sum_regular += students[i].score_regular;square_sum_regular += students[i].score_regular * students[i].score_regular;sum_final += students[i].score_final;square_sum_final += students[i].score_final * students[i].score_final;sum_total += students[i].score_total;square_sum_total += students[i].score_total * students[i].score_total;// 统计及格人数if (students[i].score_final >= 60){pass_count++;}// 更新平时成绩、期末成绩和总评成绩的最大值if (students[i].score_regular > max_regular){max_regular = students[i].score_regular;}if (students[i].score_final > max_final){max_final = students[i].score_final;}if (students[i].score_total > max_total){max_total = students[i].score_total;}// 更新平时成绩、期末成绩和总评成绩的最小值if (students[i].score_regular < min_regular){min_regular = students[i].score_regular;}if (students[i].score_final < min_final){min_final = students[i].score_final;}if (students[i].score_total < min_total){min_total = students[i].score_total;}}// 计算平时成绩、期末成绩和总评成绩的平均分float average_regular = sum_regular / NUM_STUDENTS;float average_final = sum_final / NUM_STUDENTS;float average_total = sum_total / NUM_STUDENTS;// 计算平时成绩、期末成绩和总评成绩的标准差float std_dev_regular = sqrt((square_sum_regular - sum_regular * sum_regular / NUM_STUDENTS) / (NUM_STUDENTS - 1));float std_dev_final = sqrt((square_sum_final - sum_final * sum_final / NUM_STUDENTS) / (NUM_STUDENTS - 1));float std_dev_total = sqrt((square_sum_total - sum_total * sum_total / NUM_STUDENTS) / (NUM_STUDENTS - 1));// 计算期末考试卷面的及格率float pass_rate = pass_count / NUM_STUDENTS;// 输出统计信息printf("平时成绩的平均分:%.1f\n", average_regular);printf("平时成绩的标准差:%.1f\n", std_dev_regular);printf("平时成绩的最大值:%.1f\n", max_regular);printf("平时成绩的最小值:%.1f\n", min_regular);printf("期末成绩的平均分:%.1f\n", average_final);printf("期末成绩的标准差:%.1f\n", std_dev_final);printf("期末成绩的最大值:%.1f\n", max_final);printf("期末成绩的最小值:%.1f\n", min_final);printf("总评成绩的平均分:%.1f\n", average_total);printf("总评成绩的标准差:%.1f\n", std_dev_total);printf("总评成绩的最大值:%.1f\n", max_total);printf("总评成绩的最小值:%.1f\n", min_total);printf("期末考试卷面的及格率:%.1f%%\n", pass_rate * 100); }
-
运行结果
-
个人评价
从结果来看,chatGPT效果确实很惊人,注释也很清楚,好多基础内容都可以交给它做,嘿嘿~~ 不过不知道后续还会持续免费试用不。