学生管理系统代码

学生管理系统代码

好好看,好好学,知识点的部分看不懂就多查。

内容很多,仔细看。

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#define M 100
#define N 10

//定义学生相关信息结构体
typedef struct stu
{
    char sn[13];
    char name[9];
    char sex;
    float corse[N];
} stu;

//知识点:函数声明的使用情况:自主创建(定义)的函数在主函数后面的时候,需要在主函数前面声明;如果是在主函数前面的话,不需要声明。了解一下C语言的是如何扫描和编译代码的
//数据初略分析函数
int   maxs(stu a[], int n, int ii);
int   mins(stu a[], int n, int ii);
float ave(stu a[], int n, int ii);
int   sum(stu a[], int n, int ii);
void  sorts(stu a[], int n, int ii); //从小到大排序,采用的是选择排序

//学生数据分析(新增)
void total_scores(stu a[], int n, float* total);
float max_student_score(float total[], int n);
float min_student_score(float total[], int n);
float average_student_score(float total[], int n);

//整体的插入与删除
void  outdata(stu a[], int n);
stu   indata(stu a[], int n);
int   inalldata(stu a[]);

//数据的插入,删除,统计,查找
void  counts(stu a[], int n, int m[], int ii);
int   ins(stu a[], int n, int pos, stu x);
int   del(stu a[], int n, int pos);
int   lookfor(stu a[], int n, int x, int ii);

//文件的打开与修改
int   opendata(stu a[]);
int   writedata(stu a[], int n);

int dataflag;	//是否有数据
int fileflag;	//数据改动过

int main()
{
    //知识点:stu是结构体的变量名,类似于int的使用方式,注意有typeof和没有的区别,顺便理解一下typeof的作用
    stu a[M];
    int n;
    //代码规范:赋值等号左右留空格
    n = interface(a); //进入46行
    //代码规范:逗号后面加空格
    seebye(a, n);
    return 0;
}


//主要的功能区,所有的功能实现都是靠这个函数调用
int interface(stu a[])
{
    stu s;                      //s是student
    int m[5], n, ii;            //m数组用来统计班级优良情况,n是总人数,ii是科目
    int sel, pos, sn;           //sel是select,sn是按科目分数查找的学生的序号,pos是用于删除数据和插入数据时指明位置的变量
    int x, t;                   //x是对应的查找函数时,输入的科目分数,t是排序是承接学生信息的暂时变量
    int maxdata, mindata, sumdata;
    float avedata;
    float total[M] = { 0 };
    char ch;
    //代码规范:赋值等号左右留空格
    dataflag = 0;
    //代码规范:赋值等号左右留空格
    fileflag = 0;

    do
    {
        //代码规范:赋值等号左右留空格
        sel = menu();  //进入menu函数,输出菜单
        if (sel == 1 || sel == 2 || sel == 3 || sel == 4 || sel == 5 || sel == 8 || sel == 11)
        {
        ls:
            printf("\n请选择一门课程\n");
            printf("-------------\n");
            printf("   1: 数学\n   2:物理\n   3: 英语\n   4: 思政\n   5: 编程\n");
            printf("-------------");
            printf("\n选择哪一门课程:");
            scanf("%d", &ii);
            if (ii < 1 || ii>5)
            {
                printf("课程号错误,请重新输入!\n");
                goto ls;
            }
            printf("\n");
        }
        //知识点:用过C语言代码做到对文件的修改
        if (sel == 0)
        {
            //代码技巧:通过这种变量传承的方式,判断是否执行(这个地方的传参往往就是代表true,false,用变量来承接的话,更加可控
            if (fileflag)
            {
                printf("文件改动过,还没保存,需要保存吗?\n回答Y或者y: ");
                fflush(stdin);
                scanf("%c", &ch);
                //知识点:writedata()修改文件内容,和python里面的write函数,但是在C语言里面的自己写函数才能达到更好的效果
                if (ch == 'Y' || ch == 'y') writedata(a, n);//跳转到291行
            }
            break;
        }
        else if (sel == 1)
        {
            maxdata = maxs(a, n, ii - 1); //跳转到maxs函数,输出该科目的最大值
            printf("最大数:%d\n", maxdata);
        }
        else if (sel == 2)
        {
            mindata = mins(a, n, ii - 1); //跳转到mins函数,输出该科目的最小值
            printf("最小数:%d\n", mindata);
        }
        else if (sel == 3)
        {
            avedata = ave(a, n, ii - 1); //跳转到ave函数,输出该科目的平均值
            printf("平均数:%.2f\n", avedata);
        }
        else if (sel == 4)
        {
            sumdata = sum(a, n, ii - 1); //跳转到sum函数,输出该科目的总共分数
            printf("总和:%d\n", sumdata);
        }
        else if (sel == 5)  //对数据排序
        {
            sorts(a, n, ii - 1);       //跳转到sorts函数,从小到大排序该科目的分数
            outdata(a, n);
        }
        else if (sel == 6)
        {
            outdata(a, n);      //输出数据
        }
        else if (sel == 7)
        {
            n = inalldata(a);   //创建班级数据
            outdata(a, n);
        }
        else if (sel == 8)
        {
            counts(a, n, m, ii - 1);    //返回一个数组,统计学习情况,跳转到479行
            printf("-----------------\n");
            printf("   优秀人数: %d\n   良好人数: %d\n   一般人数: %d\n   及格人数: %d\n   不及格数: %d\n", m[0], m[1], m[2], m[3], m[4]);
            printf("-----------------\n");
        }
        else if (sel == 9) //插入数据
        {
        l2:
            if (n >= M)
                printf("\n成绩表已满,不能再插入了!");
            else
            {
                printf("请输入要插入的位置:");
                scanf("%d", &pos);
                if (pos < 1 || pos > n)
                {
                    printf("位置输入有错,请重新输入!");
                    goto l2;
                }
            l5:
                printf("请输入要插入的值:");
                s = indata(a, n);   //通过indata函数创建要插入的数据
                n = ins(a, n, pos, s);  //插入数据,跳转到
                printf("插入结果:");
                outdata(a, n);
            }
        }
        else if (sel == 10)
        {
        l3:
            printf("请输入要删除的位置:");
            scanf("%d", &pos);
            if (pos < 1 || pos > n)
            {
                printf("位置输入有错,请重新输入!");
                goto l3;
            }
            n = del(a, n, pos);  //删除元素,返回删除后班级人数的长度
            if (n == 0)
            {
                printf("\n成绩表被清空!");
                dataflag = 0;
            }
            else
            {
                printf("删除结果:");
                outdata(a, n);
            }
        }
        else if (sel == 11)
        {
        l4:
            printf("请输入要查找的值:");
            scanf("%d", &x);
            if (x < 0 || x > 100)
            {
                printf("输入值有错,请重新输入!\n");
                goto l4;
            }
            sn = lookfor(a, n, x, ii - 1);  //查找逻辑是按照课程的分数来找到对应的人的序号
            if (sn == 0) printf("要查找的数据不存在!\n");
            else printf("该数据序号为%d\n", sn);
        }
        else if (sel == 12)
        {
        l6:
            n = opendata(a);
            if (n == 0)
            {
                printf("文件不存在,请创建数据!\n");
                goto l6;
            }
            else
                outdata(a, n);
            dataflag = 1;
        }
        else if (sel == 13)
        {
            writedata(a, n);
            printf("数据保存成功!\n");
        }
        else if (sel == 14)
        {
            total_scores(a, n, total);
            float max_score = max_student_score(total, n);
            float min_score = min_student_score(total, n);
            float avg_score = average_student_score(total, n);

            printf("最高分数:%.2f\n", max_score);
            printf("最低分数:%.2f\n", min_score);
            printf("平均分数:%.2f\n", avg_score);
        }

        printf("\n按任意键继续!");
        fflush(stdin);
        getchar();
    } while (1);
    return n;
}


//页面显示的菜单栏部分
int menu()
{
    int dd;  //用于承接 输入选择菜单栏的数字
    printf("\n\n 班级成绩管理系统");
    while (1)
    {
    ll2:
        system("cls");

        printf("\n     功能选择\n");
        printf("  ---------------\n");
        printf(" |  1  求最大数  |\n");
        printf(" |  2  求最小数  |\n");
        printf(" |  3  求平均数  |\n");
        printf(" |  4  数据求和  |\n");
        printf(" |  5  数据排序  |\n");
        printf(" |  6  输出数据  |\n");
        printf(" |  7  创建数据  |\n");
        printf(" |  8  统计数据  |\n");
        printf(" |  9  插入数据  |\n");
        printf(" |  10 删除数据  |\n");
        printf(" |  11 查找数据  |\n");
        printf(" |  12 获取数据  |\n");
        printf(" |  13 保存数据  |\n");
        printf(" |  14 学生数据  |\n");
        printf(" |  0  退出系统  |\n");
        printf("  ---------------\n");
        printf(" 请选择一个功能:");

        scanf("%d", &dd);
        //代码规范:在if条件语句里面,每个符号中间都要留空格
        if (dd < 0 || dd > 15)
        {
            printf("\n选择有错,请重新选择!\n");
            printf("\n按任意键继续!");
            //代码解释:清楚缓冲区(缓冲区称为stdin),也就是所谓的清缓存
            fflush(stdin);
            //代码技巧:这里用的getchar()会自动给到dd变量,至于为什么可以百度(核心在于getchar函数返回的是int型变量),然后继续做while循环
            getchar();
        }
        else if (dd == 0 || dd == 7 || dd == 12 || dataflag == 1) break;
        else
        {
            printf("\n无数据,请选择创建数据!");
            printf("\n按任意键继续!");
            fflush(stdin);
            getchar();
        }
    }
    return dd;
}


// 打开文件
int opendata(stu a[])
{
    FILE* fp;
    int n = 0;
    fp = fopen("score.dat", "rb");
    if (!fp) return 0;
    fseek(fp, 0, SEEK_END);
    n = ftell(fp) / sizeof(struct stu);
    fseek(fp, 0, SEEK_SET);
    fread(a, sizeof(stu), n, fp);
    fclose(fp);
    dataflag = 1;
    return n;
}


// 纯纯的对文件的操作,看不懂就百度吧,我也没怎么学过
int writedata(stu a[], int n)
{
    FILE* fp;
    fp = fopen("score.dat", "wb+");
    if (!fp) return 0;
    fwrite(a, sizeof(stu), n, fp);
    fclose(fp);
    fileflag = 0;
    return 1;
}


//求最大值函数,就是遍历数组,然后去最大值就好了,没什么技术含量
int maxs(stu a[], int n, int ii)
{
    int i;
    int max;
    //注意代码规范
    max = a[0].corse[ii];
    for (i = 1; i < n; i++)
        if (a[i].corse[ii] > max)
            max = a[i].corse[ii];
    return max;
}


//求最小值函数
int mins(stu a[], int n, int ii)
{
    int i;
    //注意代码规范和命名,直接语义化命名是最好的
    int min;
    min = a[0].corse[ii];
    for (i = 1; i < n; i++)
        if (a[i].corse[ii] < min)
            min = a[i].corse[ii];
    return min;
}


//求平均值函数
float ave(stu a[], int n, int ii)
{
    int i;
    int aveg;
    aveg = 0;
    for (i = 1; i < n; i++)
        aveg = aveg + a[i].corse[ii];
    return aveg / (float)n;
}


//求和函数
int sum(stu a[], int n, int ii)
{
    int i;
    int sum;
    sum = 0;
    for (i = 1; i < n; i++)
        sum = sum + a[i].corse[ii];
    return sum;
}


//排序函数,采用的是选择排序,还有很多排序方法,你们搞数据的,排序的算法估计得了如指掌
void sorts(stu a[], int n, int ii)
{
    int i, j, k;
    int m;
    stu t;
    for (i = 0; i < n; i++)
    {
        k = i;
        m = a[i].corse[ii];
        for (j = i + 1; j < n; j++)
        {
            if (m < a[j].corse[ii])
            {
                k = j;
                m = a[j].corse[ii];
            }
        }
        t = a[i];
        a[i] = a[k];
        a[k] = t;
    }
    fileflag = 1;
}


//输出修改的数据
void outdata(stu a[], int n)
{
    int i;
    printf("\n                            数据显示!\n");
    printf("%10s%10s%6s%6s%6s%6s%6s%6s\n", "姓名", "学号", "性别", "数学", "物理", "英语", "思政", "编程");
    for (i = 0; i < 30; i++) printf("---");
    printf("\n");
    for (i = 0; i < n; i++)
        if (a[i].sex == '1')
            printf("%10s%10s%6s%6.1f%6.1f%6.1f%6.1f%6.1f\n", a[i].name, a[i].sn, "男 ", a[i].corse[0], a[i].corse[1], a[i].corse[2], a[i].corse[3], a[i].corse[4]);
        else
            printf("%10s%10s%6s%6.1f%6.1f%6.1f%6.1f%6.1f\n", a[i].name, a[i].sn, "女 ", a[i].corse[0], a[i].corse[1], a[i].corse[2], a[i].corse[3], a[i].corse[4]);
    for (i = 0; i < 30; i++) printf("---");
    printf("\n");
}


// 个人信息的输入,包括姓名,学号,性别,学科成绩
stu indata(stu a[], int n)
{
    stu s;
    printf("\n姓名:");
    fflush(stdin);
    scanf("%s", s.name);
    printf("学号:");
    fflush(stdin);
    scanf("%s", s.sn);
le1:
    printf("性别:(1:男,2:女)");
    fflush(stdin);
    scanf("%c", &s.sex);
    if (s.sex != '1' && s.sex != '2')
    {
        printf("输入有错,请输入1或者2\n");
        //知识点:goto语句是为了方便编译器执行的跳转,是一种避免异常的一种有效方式,避免运用大量的循环造成代码运行时间的增多(你明年学了数据结构就会懂)类似python里面的try语句
        goto le1;
    }
le2:
    printf("数学:");
    fflush(stdin);
    scanf("%f", &s.corse[0]);
    if (s.corse[0] < 0 || s.corse[0] > 100)
    {
        printf("输入有错!重新输入!\n");
        goto le2;
    }
le3:
    printf("物理:");
    fflush(stdin);
    scanf("%f", &s.corse[1]);
    if (s.corse[1] < 0 || s.corse[1] > 100)
    {
        printf("输入有错!重新输入!\n");
        goto le3;
    }
le4:
    printf("英语:");
    fflush(stdin);
    scanf("%f", &s.corse[2]);
    if (s.corse[2] < 0 || s.corse[2] > 100)
    {
        printf("输入有错!重新输入!\n");
        goto le4;
    }
le5:
    printf("思政:");
    fflush(stdin);
    scanf("%f", &s.corse[3]);
    if (s.corse[3] < 0 || s.corse[3] > 100)
    {
        printf("输入有错!重新输入!\n");
        goto le5;
    }
le6:
    printf("编程:");
    fflush(stdin);
    scanf("%f", &s.corse[4]);
    if (s.corse[4] < 0 || s.corse[4] > 100)
    {
        printf("输入有错!重新输入!\n");
        goto le6;
    }
    fileflag = 1;
    dataflag = 1;
    return s;
}


//班级整体人数的输入
int inalldata(stu a[])
{
    int n, i;
    stu s;
    printf("班级数据输入!\n");
l1:
    printf("请输入班级人数:");
    scanf("%d", &n);
//在做项目的时候,学会加入这种输入值的判断,这样会提升代码的复用性(也就是你的代码别人可以轻松使用)
    if (n < 2 || n > M)
    {
        printf("输入有错,请重新输入!");
        goto l1;
    }
    for (i = 0; i < n; i++)
    {
        printf("\n学生%d数据输入!", i + 1);
        s = indata(a, n);//进行对每个学生的具体信息输入
        a[i] = s;
    }
    fileflag = 1;
    dataflag = 1;
    return n;
}


//班级分数优良差统计
void counts(stu a[], int n, int m[], int ii)
{
    int i;
    //初始化数组列表,让其元素为0,这里不使用m[n] = {0},是因为这个方法必须是在定义 m 数组的时候使用,而不是后期赋值的时候使用。
    for (i = 0; i < 5; i++)
        m[i] = 0;
    //遍历班级学生分数情况,统计
    for (i = 0; i < n; i++)
    {
        if (a[i].corse[ii] >= 90 && a[i].corse[ii] <= 100)    m[0]++;
        else if (a[i].corse[ii] >= 80 && a[i].corse[ii] < 90) m[1]++;
        else if (a[i].corse[ii] >= 70 && a[i].corse[ii] < 80) m[2]++;
        else if (a[i].corse[ii] >= 60 && a[i].corse[ii] < 70) m[3]++;
        else if (a[i].corse[ii] >= 0 && a[i].corse[ii] < 60)  m[4]++;
    }
}


//指定位置插入元素数据。这个地方好好想想,以后在数据机构里面很常见
int ins(stu a[], int n, int pos, stu x)
{
    int i;
    //代码解释:将pos后面的元素全部后移一个单位,此时pos位为空
    for (i = n - 1; i >= pos; i--)
        a[i + 1] = a[i];
    //将x(新建立的数据)插入pos位置
    a[pos] = x;
    fileflag = 1;
    //细节:插入元素后,数组长度会增 1
    return n + 1;

}


//删除元素,和上面的插入一样,只不过是反的而已,好好想一下,数据结构里面经常见到这两种操作
int del(stu a[], int n, int pos)
{
    int i;
    for (i = pos - 1; i < n; i++)
        a[i] = a[i + 1];
    fileflag = 1;
    return n - 1;

}


//根据学科分数查找学生的序号
int lookfor(stu a[], int n, int x, int ii)
{
    int i, flag;
    flag = 0;
    for (i = 0; i < n; i++)
    {
        if (a[i].corse[ii] == x)
        {
            flag = 1;
            break;
        }
    }
    if (flag) return i + 1;
    else return 0;
}


//退出程序
void seebye(stu a[], int n)
{
    if (n == 0)
        printf("\n无数据!\n");
    else
        outdata(a, n);
    printf("\n\n\n谢谢使用,再见!\n\n\n\n");
    fflush(stdin);
    getchar();
}


// 实现新函数

//统计一个学生的所有分数
void total_scores(stu a[], int n, float* total)
{
    for (int i = 0; i < n; i++)
    {
        float sum = 0;
        for (int j = 0; j < N; j++)
        {
            sum += a[i].corse[j];
        }
        total[i] = sum;
    }
}
//下面的三个函数,都是通过循环遍历得到的,也称为迭代

//找寻所有学生当中分最高的
float max_student_score(float total[], int n)
{
    float max = total[0];
    for (int i = 1; i < n; i++)
    {
        if (total[i] > max)
        {
            max = total[i];
        }
    }
    return max;
}

//找寻所有学生当中分最低的
float min_student_score(float total[], int n)
{
    float min = total[0];
    for (int i = 1; i < n; i++)
    {
        if (total[i] < min)
        {
            min = total[i];
        }
    }
    return min;
}

//求整体学生的平均分
float average_student_score(float total[], int n)
{
    float sum = 0;
    for (int i = 0; i < n; i++)
    {
        sum += total[i];
    }
    return sum / n;
}



//学会代码规范
//  像"< > ? / \ || && "这种符号之间,两边放入变量的时候,打空格;
//  对于定义变量的时候,逗号和变量之间打空格,int i, j, k;
//  变量的命名最好采用语义化命名,比如 学生------stu 这种的;
//  不要写成代码shi山,读起来很痛苦

看完了之后是不是不那么的凯凯心心了😂😂😂

学代码是这样的,努力看吧❤️

相关推荐
科技资讯早知道2 分钟前
java计算机毕设课设—坦克大战游戏
java·开发语言·游戏·毕业设计·课程设计·毕设
白拾13 分钟前
使用Conda管理python环境的指南
开发语言·python·conda
从0至138 分钟前
力扣刷题 | 两数之和
c语言·开发语言
总裁余(余登武)39 分钟前
算法竞赛(Python)-万变中的不变“随机算法”
开发语言·python·算法
NormalConfidence_Man40 分钟前
C++新特性汇总
开发语言·c++
一个闪现必杀技1 小时前
Python练习2
开发语言·python
有梦想的咕噜1 小时前
target_link_libraries()
开发语言
liu_chunhai1 小时前
设计模式(3)builder
java·开发语言·设计模式
姜学迁1 小时前
Rust-枚举
开发语言·后端·rust
冷白白1 小时前
【C++】C++对象初探及友元
c语言·开发语言·c++·算法