基于C语言的学生试卷分数统计程序设计及实现

📃 基于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; // 输入数据合理
            else
                printf("\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]);
            else
                printf(" ");
        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(&regular_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效果确实很惊人,注释也很清楚,好多基础内容都可以交给它做,嘿嘿~~ 不过不知道后续还会持续免费试用不。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值