C语言——静态学生成绩系统从0到1实现


前言

不足之处,请多指教。
该程序不涉及文件读写,没有用链表,主要运用以下知识点:

  • 结构体
  • 函数封装

一、程序介绍

设计一款基础的学生成绩管理系统,实现包括以下功能:

  • 显示帮助菜单
  • 成绩录入
  • 计算学生平均分
  • 列出成绩表
  • 按平均成绩由高到低排序
  • 清屏
  • 退出系统
    在这里插入图片描述

二、面向结果

在具体实现之前,先思考程序整个的执行流程是怎样的,首先是弹出帮助菜单,菜单中包含需求功能,菜单前面有唯一的编号,提示用户选择,用户通过输入编号进行相应的操作;操作结束后,继续提示用户选择,从而进行不同的操作,循环这一过程,直到用户选择退出操作,整个程序停止。
在这里插入图片描述

三、程序实现

1. 搭建框架

1.1 思路

根据面向结果,在用户选择退出之前,规范输入时,需要一直进行选择提示->键入指令->用户操作这一循环,所以用while(1)搭配switch case来实现这一循环,当用户输入选择后,scanf接收这一选择,程序根据不同的选择来进行相应的case下的功能,选择什么指令,就让它走对应的功能。在程序刚开始运行的时候,要让菜单显示出来。

  • 打印菜单
  • 提示输入
  • 用户键入
  • switch case匹配

1.2 实现顺序

#include <stdio.h>							//1

void Init_Menu()							//10
{
    printf("*************************************\n");
    printf("  * 学生成绩管理系统————帮助菜单  *\n");
    printf("*************************************\n");
    printf("  *        H = 显示帮助菜单       *\n");
    printf("  *        T = 成绩录入           *\n");
    printf("  *        A = 计算学生平均学分   *\n");
    printf("  *        L = 列出成绩表         *\n");
    printf("  *        P = 成绩排序(高->低)   *\n");
    printf("  *        S = 学号查询学生成绩   *\n");
    printf("  *        C = 清屏               *\n");
    printf("  *        Q = 退出系统           *\n");
    printf("*************************************\n");
}

int main(int argc, char const *argv[])		//2
{
    char input;//接受输入的菜单具体命令		//8
    Init_Menu();//初始化菜单					//9
    while (1)								//3
    {
        printf("请输入指令= ");//提醒用户输入	//4
        scanf("%c", &input);//接收输入传给input  //5
        getchar();//吸收掉换行符					//6
        //当输入Q指令,跳出循环,程序结束
        if (input == 'Q')						//11
        {
            printf("已退出\n");
            break;
        }
        
        switch (input)							//7
        {
            case 'H':
                printf("执行H功能");//以后替换为相应功能函数
                break;
            case 'T':
                printf("执行T功能");//以后替换为相应功能函数
                break;
            case 'A':
                printf("");
                break;
            case 'L':
                printf("");
                break;
            case 'P':
                printf("");
                break;
            case 'S':
                printf("");
                break;
            case 'C':
                printf("");
                break;
            default:
                printf("输出格式错误,请重新输入!\n");
                break;
        }
    }     
    return 0;
}

1.3 测试

在这里插入图片描述
测试结束,到这里我们就实现了代码的基本雏形。

2. 类型定义

2.1 思路

首先,系统是用来存放,显示,处理学生信息的,而学生的信息包括学号 语文成绩 数学成绩 英语成绩 平均分这四个部分,所以要用到结构体数组来定义学生信息,每一个结构体数组成员存放一个学生信息。num会在后面说明。

2.2 实现

typedef struct Student			//12
{
    int xuehao;//学生学号
    float chinese;//语文成绩
    float math;//数学成绩
    float english;//英语成绩
    float avg;//平均分
}Student;

int num;		//全局变量,用来接收用户输入的人数
int main(int argc, char const *argv[])
{
    char input;//接受输入的菜单具体命令
    Student stu[4];					//13
    Init_Menu();//初始化菜单

3. 函数实现

首先,先实现添加学生信息功能,然后通过查看学生信息功能,测试添加功能是否正确

3.1 添加学生信息——Add_Score()

3.1.1 思路

首先,请用户输入学生人数,通过人数将决定后面你输入多少个学生信息,所以这里想到用for循环实现,人数是几就让用户循环输入几次。然后在每次循环的过程中,用户每次输入信息时,都能够自动生成学号(1,2,3…),这里想到通过对循环变量加1实现这一操作。在传参时,要改变结构体成员的内容,所以是地址传递, 而数组名即首地址,所以实参传入数组名,形参用同类型的数组接收即可。形参数组名取得该首地址之后,也就等于有了实在的数组。实际上形参和实参为同一数组,因此当形参数组发生变化时,实参数组也随之变化

3.1.2 实现
case 'T':
     	Add_Score(stu);			//14
        break;
void Add_Score(Student stu[])		//15
{
   						//16	好吧,这里没有东西
    printf("请输入学生人数:");//17
    scanf("%d", &num);          //18
    printf("请输入%d名学生的三门课成绩(成绩用\\t符间隔):\n", num); //19
    printf("%s\t%s\t%s\t%s\n", "学号", "语文", "数学", "外语");	//20
    
    for (int i = 0; i < num; i++)			//21
    {
   		 //学号从1开始生成,所以i+1
        stu[i].xuehao = i+1;		//22
        //每次输入信息前,显示学号			
        printf("%d", stu[i].xuehao);		//23
        //接收用户输入
        scanf("%f %f %f", &stu[i].chinese, 	//24
                          &stu[i].math, 
                          &stu[i].english);
     	//吸收换行符                     
        getchar();						//25
    }
}
3.1.3 测试

在这里插入图片描述

3.2 查看学生信息——Print_Score()

3.2.1 思路

首先,我们需要判断系统里是否有学生信息,如果没有,则提示用户成绩为空,请先使用命令T录入学生成绩,如果有则输出学生成绩,num设为全局变量后,默认值为0,当用户进行添加操作后,num值发生改变,可通过num是否为0判断系统里有无信息。
输出信息时,通过循环,将成员信息输出。

3.2.2 实现
case 'L':
        Print_Score(stu);   //查看   26
        break;
void Print_Score(Student stu[])		//27
{
    // 先判断系统是否为空,如果人数为0,则代表一个信息都没有		28
    if (num == 0)
    {
        printf("成绩为空,请先使用命令T录入学生成绩。\n");
        return;
    }
    
    printf("学生成绩如下:\n");		//29
    printf("%s\t%s\t%s\t%s\t%s\n", "学号", "语文", "数学", "外语", "平均分");//30
    //当学号不为0时,一直输出学生信息
    for (int i = 0;i < num; i++)		//31
    {
        printf("%d\t%.1f\t%.1f\t%.1f\t%.1f\n",  stu[i].xuehao, 
                                                stu[i].chinese, 
                                                stu[i].math, 
                                                stu[i].english, 
                                                stu[i].avg);
    }    
}
3.2.3 测试

在这里插入图片描述

3.3 计算平均分——Average_Score()

3.3.1 思路

首先,在计算之前,依然要判断结构体数组中是否存有信息,操作同上。
然后遍历学生信息,将每一个数组成员的成绩相加,然后除3得到平均数,就可以计算出每个学生的平均数。

3.3.2 实现
case 'A':
        Average_Score(stu);//计算平均分		32
        break;
// 计算平均数
void Average_Score(Student stu[]) 		//33
{
    // 先判断系统是否为空,如果学号为0,则代表一个信息都没有
    if (num == 0)		//34
    {
        printf("成绩为空,请先使用命令T录入学生成绩。\n");
        return;
    }
        // 计算平均分
    for (int i = 0; i < num; i++)		//35
    {
        stu[i].avg = (stu[i].chinese + stu[i].math + stu[i].english) / 3;
    }
    printf("平均分已计算,请使用命令L查看.\n");		//36
}
3.3.3 测试

在这里插入图片描述

3.4 根据平均分排序——Sort_Score()

3.4.1 思路

首先,依旧是判断系统信息是否为空,操作同上。
在进行排序时,如果需要互换位置,不需要挨个互换变结构体组成员的属性,而只需将数组成员的首地址进行互换,就可以达到内容互换的效果,进而实现互换位置结构体数组成员名即首地址。在进行交换时,通过选择排序思路来实现交换。

3.4.2 实现
 case 'A':
         Average_Score(stu);//计算平均分	37
         break;
// 根据平均分进行排序	
void Sort_Score(Student stu[])		//38
{
    // 先判断系统是否为空,如果学号为0,则代表一个信息都没有		39
    if (num == 0)
    {
        printf("成绩为空,请先使用命令T录入学生成绩。\n");
        return;
    }

    // 排序
    Student temp_stu;	//临时变量		40
    // 外层for循环控制循环轮数
    for (int i = 0; i < num - 1; i++)		//41
    {
        // 内层for循环控制每一轮的数还要与后面几个数比较
        for (int j = i + 1; j < num; j++)	//42
        {
            if (stu[i].avg < stu[j].avg)		//43
            {
            // 结构体数组成员名即收地址,
                temp_stu = stu[i];			//44
                stu[i] = stu[j];			//45
                stu[j] = temp_stu;    		//46
            } 
        }  
    }
    printf("完成排序,请使用命令L查看\n");		//47
}
3.4.3 测试

在这里插入图片描述

3.5 学号查询——Search_Number()

3.5.1 思路
  • 判断系统信息是否为空
  • 提示用户输入查询学号
  • 根据学号遍历整个信息
  • 输出查找到的信息
  • 没有找到提示用户
3.5.2 实现
 case 'S':
         Search_Number(stu); // 通过学号查询		48
         break;
// 根据学号查询
void Search_Number(Student stu[])		//49
{
    // 先判断系统是否为空,如果学号为0,则代表一个信息都没有		50
    if (num == 0)
    {
        printf("成绩为空,请先使用命令T录入学生成绩。\n");
        return;
    }

    int temp;   //接收查询的学号			51
    printf("请输入要查询的学生学号:\n");		//52
    scanf("%d", &temp);		//53
    getchar();//吸收换行
    // 遍历学生信息,找到和学号匹配的信息
    for (int i = 0; i < num; i++)		//54
    {
        if (temp == stu[i].xuehao)		//55
        {
            printf("%s\t%s\t%s\t%s\t%s\n", "学号", "语文", "数学", "外语", "平均分");	//56
            printf("%d\t%.1f\t%.1f\t%.1f\t%.1f\n",  stu[i].xuehao, //57
                                                    stu[i].chinese, 
                                                    stu[i].math, 
                                                    stu[i].english, 
                                                    stu[i].avg);
        }
        else		//58
        {
			printf("没有此人!\n");
		}   
    }
}
3.5.3 测试

在这里插入图片描述

3.6 清屏

引入头文件#include <stdlib.h>

case 'C':
        system("clear");	//	清屏		//59
        break;

到此,所有功能都已实现。

四、全部代码

#include <stdio.h>
#include <stdlib.h>

// 学生信息结构体
typedef struct Student     
{
    int xuehao;//学生学号
    float chinese;//语文成绩
    float math;//数学成绩
    float english;//英语成绩
    float avg;//平均分
}Student;

int num;//全局变量num,用来接收用户输入的学生个数

// 提示菜单
void Init_Menu()  
{
    printf("*************************************\n");
    printf("  * 学生成绩管理系统————帮助菜单  *\n");
    printf("*************************************\n");
    printf("  *        H = 显示帮助菜单       *\n");
    printf("  *        T = 成绩录入           *\n");
    printf("  *        A = 计算学生平均学分   *\n");
    printf("  *        L = 列出成绩表         *\n");
    printf("  *        P = 成绩排序(高->低)   *\n");
    printf("  *        S = 学号查询学生成绩   *\n");
    printf("  *        C = 清屏               *\n");
    printf("  *        Q = 退出系统           *\n");
    printf("*************************************\n");
}
// 添加
void Add_Score(Student stu[])		
{					
    printf("请输入学生人数:");
    scanf("%d", &num);          
    printf("请输入%d名学生的三门课成绩(成绩用\\t符间隔):\n", num); 
    printf("%s\t%s\t%s\t%s\n", "学号", "语文", "数学", "外语");	
    
    for (int i = 0; i < num; i++)			
    {
   		 //学号从1开始生成,所以i+1
        stu[i].xuehao = i+1;		
        //每次输入信息前,显示学号			
        printf("%d", stu[i].xuehao);		
        //接收用户输入
        scanf("%f %f %f", &stu[i].chinese, 	
                          &stu[i].math, 
                          &stu[i].english);
     	//吸收换行符                     
        getchar();						
    }
}
// 查看
void Print_Score(Student stu[])
{
    // 先判断系统是否为空,如果学号为0,则代表一个信息都没有
    if (num == 0)
    {
        printf("成绩为空,请先使用命令T录入学生成绩。\n");
        return;
    }
    
    printf("学生成绩如下:\n");
    printf("%s\t%s\t%s\t%s\t%s\n", "学号", "语文", "数学", "外语", "平均分");
    //当学号不为0时,一直输出学生信息
    for (int i = 0; i < num; i++)
    {
        printf("%d\t%.1f\t%.1f\t%.1f\t%.1f\n",  stu[i].xuehao, 
                                                stu[i].chinese, 
                                                stu[i].math, 
                                                stu[i].english, 
                                                stu[i].avg);
    }    
}

// 计算平均数
void Average_Score(Student stu[])
{
    // 先判断系统是否为空,如果学号为0,则代表一个信息都没有
    if (num == 0)
    {
        printf("成绩为空,请先使用命令T录入学生成绩。\n");
        return;
    }
        // 计算平均分
    for (int i = 0; i < num; i++)
    {
        stu[i].avg = (stu[i].chinese + stu[i].math + stu[i].english) / 3;
    }
    printf("平均分已计算,请使用命令L查看.\n");
}

// 根据平均分进行排序
void Sort_Score(Student stu[])
{
    // 先判断系统是否为空,如果学号为0,则代表一个信息都没有
    if (num == 0)
    {
        printf("成绩为空,请先使用命令T录入学生成绩。\n");
        return;
    }

    // 排序
    Student temp_stu;
    // 外层for循环控制循环轮数
    for (int i = 0; i < num - 1; i++)
    {
        // 内层for循环控制每一轮的数还要与后面几个数比较
        for (int j = i + 1; j < num; j++)
        {
            if (stu[i].avg < stu[j].avg)
            {
            // 结构体数组成员名即收地址,
                temp_stu = stu[i];
                stu[i] = stu[j];
                stu[j] = temp_stu;
               
            } 
        }  
    }
    printf("完成排序,请使用命令L查看\n");
}

// 根据学号查询
void Search_Number(Student stu[])
{
    // 先判断系统是否为空,如果学号为0,则代表一个信息都没有
    if (num == 0)
    {
        printf("成绩为空,请先使用命令T录入学生成绩。\n");
        return;
    }

    int temp;   //接收查询的学号
    printf("请输入要查询的学生学号:\n");
    scanf("%d", &temp);
    getchar();//吸收换行
    // 遍历学生信息,找到和学号匹配的信息
    for (int i = 0; i < num; i++)
    {
        if (temp == stu[i].xuehao)
        {
            printf("%s\t%s\t%s\t%s\t%s\n", "学号", "语文", "数学", "外语", "平均分");
            printf("%d\t%.1f\t%.1f\t%.1f\t%.1f\n",  stu[i].xuehao, 
                                                    stu[i].chinese, 
                                                    stu[i].math, 
                                                    stu[i].english, 
                                                    stu[i].avg);
        }
        else
        {
			printf("没有此人!\n");
		}      
    }
}

int main(int argc, char const *argv[])
{
    char input;//接受输入的菜单具体命令
    // 定义结构体数组       
    Student stu[4];   
    
    Init_Menu();//初始化菜单
    while (1)
    {
        printf("请输入指令= ");//提醒用户输入
        scanf("%c", &input);//接收输入传给input
        getchar();//吸收掉换行符
        // 退出
        if (input == 'Q')
        {
            printf("已退出\n");
            break;
        }
        
        switch (input)
        {
            case 'H':
                Init_Menu();;
                break;
            case 'T':
                Add_Score(stu);     //添加
                break;
            case 'A':
                Average_Score(stu);//计算平均分
                break;
            case 'L':
                Print_Score(stu);   //查看
                break;
            case 'P':
                Sort_Score(stu);    //根据平均分排序
                break;
            case 'S':
                Search_Number(stu); // 通过学号查询
                break;
            case 'C':
                system("clear");    //清屏
                break;
            default:
                printf("输出格式错误,请重新输入!\n");
                break;
        }
    }
    
        
    return 0;
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值