- (꒪ꇴ꒪ ),hello我是祐言
- 博客主页:C语言基础,Linux基础,软件配置领域博主🌍
- 快上🚘,一起学习!
- 送给读者的一句鸡汤🤔:
- 集中起来的意志可以击穿顽石!
- 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏
一个基础功能完善的学生成绩管理系统必须要实现对学生信息的管理和处理,包括初始化学生信息、计算平均成绩、修改成绩、查看学生信息、排序学生信息和筛选查看学生成绩等功能。它可以帮助用户管理学生的成绩信息,并根据不同的需求进行排序和筛选,方便了学生成绩的管理和分析。
那么我们要实现的目标也就有了:
- 首先定义学生信息的结构体,并包含姓名、学号、年龄和语文、数学、英语成绩等信息。
- 提供学生信息的初始化函数,通过随机生成学生的姓名、学号、年龄和成绩来初始化学生信息。
- 实现计算学生平均成绩的函数,根据语文、数学和英语成绩计算平均成绩,并根据平均成绩给学生等级评定(ABCDE)。
- 提供修改学生成绩的函数,可以根据用户输入的选项修改学生的语文、数学或英语成绩,并重新计算平均成绩和等级评定。
- 实现查看学生信息的函数,可以打印所有学生的姓名、学号、年龄、语文、数学、英语成绩、平均成绩和等级评定。
- 提供根据学生姓名查找并打印学生信息的函数,用户可以输入姓名来查看特定学生的详细信息。
- 实现学生信息排序的函数,可以根据姓名、年龄、平均成绩、语文、数学或英语成绩进行排序,并打印排序后的学生信息。
- 添加筛选查看成绩高于指定阈值的学生信息的函数,用户可以输入一个分数阈值,程序会打印所有满足条件的学生信息。
功能展示:
什么,你问我为啥没有标注?
那我只能说自己认真看hhh~
学知识不要嫌累!
完整代码如下:
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <stdbool.h>
// 学生信息结构体
struct student
{
char name[20]; //姓名
int num; //学号
short age; //年龄
struct scores
{
float chinese; //语文
float math; //数学
float english; //英语
float average; //平均成绩
}score;
char grade; //等级评定: ABCDE
};
// 获取随机年龄
int rand_age(void)
{
int tmp;
while( ( tmp=rand()%24) < 19 ) //随机数范围0~23, 小于19的不取
/* empty */;
return tmp;
}
// 初始化
void student_init(struct student stu[10], int n)
{
//准备是个名字
char *tmp_name[10] = {"赵", "钱", "孙", "李", "王", "张", "陈", "杨", "吴", "苏"};
srand(time(NULL)); //播撒随机种子
for (int i=0; i<n; i++)
{
strcpy(stu[i].name, tmp_name[i]); //赋值名字
stu[i].num = 23050+i; //学号
stu[i].age = rand_age();
// 随机给定一些成绩
stu[i].score.chinese = rand() % 56 + 45; //随机45~100
stu[i].score.math = rand() % 56 + 45; //45~100
stu[i].score.english = rand() % 56 + 45; //45~100
stu[i].score.average = 0; //初始化平均成绩0
stu[i].grade = 'E'; //初始化等级为E
}
}
// 打印所有学生信息
void show_student(struct student stu[10], int n)
{
char *line = "---------------------------------------------------------------------------------";
char *print_table[] = {"姓 名", "学 号", "年 龄", "语 文", "数 学", "英 语", "平 均", "等 级"};
int tab_pad = 12; // 填充表头间的空隙
printf("%s\n", line);
printf("%*s%*s%*s%*s%*s%*s%*s%*s\n",
tab_pad,print_table[0], tab_pad,print_table[1], tab_pad,print_table[2], tab_pad,print_table[3],
tab_pad,print_table[4], tab_pad,print_table[5], tab_pad,print_table[6], tab_pad,print_table[7]);
for (int i=0; i<n; i++)
{
printf("%10s%11d%10hd%10.1f%10.1f%10.1f%10.1f%9c\n",
stu[i].name, stu[i].num, stu[i].age,
stu[i].score.chinese,
stu[i].score.math,
stu[i].score.english,
stu[i].score.average,
stu[i].grade);
}
printf("%s\n", line);
}
// 计算平均成绩
void average_stu(struct student stu[10], int n)
{
for (int i=0; i<n; i++)
{
stu[i].score.average = (stu[i].score.chinese + stu[i].score.math + stu[i].score.english)/3;
if( (int)(stu[i].score.average) >= 90)
stu[i].grade = 'A';
else if( (int)(stu[i].score.average) >= 80)
stu[i].grade = 'B';
else if( (int)(stu[i].score.average) >= 70)
stu[i].grade = 'C';
else if( (int)(stu[i].score.average) >= 60)
stu[i].grade = 'D';
else
stu[i].grade = 'E';
}
}
// 修改学生的成绩
void change_score(struct student *stu)
{
printf("请输入你要修改的成绩(0语文, 1数学, 2英语, 其他输入表示暂不修改)\n");
int n;
scanf("%d", &n);
switch(n)
{
case 0:
scanf("%f", &stu->score.chinese);
break; //-> . 的优先级比&高,所以此处取的是chinese成员的地址
case 1:
scanf("%f", &stu->score.math);
break; //-> . 的优先级比&高,所以此处取的是math成员的地址
case 2:
scanf("%f", &stu->score.english);
break; //-> . 的优先级比&高,所以此处取的是english成员的地址
default:
printf("暂不修改\n");
}
// 平均分和等级应该重新评定
stu->score.average = (stu->score.chinese + stu->score.math + stu->score.english)/3;
if( (int)(stu->score.average) >= 90)
stu->grade = 'A';
else if( (int)(stu->score.average) >= 80)
stu->grade = 'B';
else if( (int)(stu->score.average) >= 70)
stu->grade = 'C';
else if( (int)(stu->score.average) >= 60)
stu->grade = 'D';
else
stu->grade = 'E';
}
// 打印一个学生信息
void print_info(struct student *stu)
{
char *line = "---------------------------------------------------------------------------------";
char *print_table[] = {"姓 名", "学 号", "年 龄", "语 文", "数 学", "英 语", "平 均", "等 级"};
int tab_pad = 12; // 填充表头间的空隙
printf("%s\n", line);
printf("%*s%*s%*s%*s%*s%*s%*s%*s\n",
tab_pad,print_table[0], tab_pad,print_table[1], tab_pad,print_table[2], tab_pad,print_table[3],
tab_pad,print_table[4], tab_pad,print_table[5], tab_pad,print_table[6], tab_pad,print_table[7]);
printf("%10s%11d%10hd%10.1f%10.1f%10.1f%10.1f%9c\n",
stu->name, stu->num, stu->age,
stu->score.chinese,stu->score.math,
stu->score.english, stu->score.average,stu->grade);
printf("%s\n", line);
}
// task 表示要对该学生做的某种信息处理(打印该生信息,修改成绩)
void find_student(struct student stu[10], int n, char *cmp_name, void (*task)(struct student *stu) )
{
if (cmp_name == NULL)
return;
for (int i=0; i<n; i++)
{
if ( !strcmp ( stu[i].name , cmp_name) )
{
task( &stu[i] );
break;
}
}
}
// 按照名字排序
bool compare_name(struct student *s1, struct student *s2)
{
return strcmp(s1->name, s2->name) >= 0 ? true : false;
}
// 按照年龄排序
bool compare_age(struct student *s1, struct student *s2)
{
return s1->age >= s2->age ? true : false;
}
// 按照平均分排序
bool compare_average(struct student *s1, struct student *s2)
{
return s1->score.average <= s2->score.average ? true : false;
}
// 按照语文分排序
bool compare_chinese(struct student *s1, struct student *s2)
{
return s1->score.chinese <= s2->score.chinese ? true : false;
}
// 按照数学分排序
bool compare_math(struct student *s1, struct student *s2)
{
return s1->score.math <= s2->score.math ? true : false;
}
// 按照英语分排序
bool compare_english(struct student *s1, struct student *s2)
{
return s1->score.english <= s2->score.english ? true : false;
}
// 排序(名字,成绩,等级)
// cmp 由自己实现的比较方式
void sort(struct student stu[10], int n, bool (*cmp)(struct student*, struct student*) )
{
for (int i=0; i<n; i++) //比较多少轮
{
for (int j=0; j<n-i-1; j++) //每轮多少次
{
if ( cmp(&stu[j], &stu[j+1] ) ) //通过传进来的参数来比较
{
struct student tmp = stu[j];
stu[j] = stu[j+1];
stu[j+1] = tmp;
}
}
}
}
// 筛选查看xx分数以上的学生
void filter_students(struct student stu[10], int n, float threshold)
{
char *line = "---------------------------------------------------------------------------------";
char *print_table[] = {"姓 名", "学 号", "年 龄", "语 文", "数 学", "英 语", "平 均", "等 级"};
int tab_pad = 12; // 填充表头间的空隙
printf("%s\n", line);
printf("%*s%*s%*s%*s%*s%*s%*s%*s\n",
tab_pad,print_table[0], tab_pad,print_table[1], tab_pad,print_table[2], tab_pad,print_table[3],
tab_pad,print_table[4], tab_pad,print_table[5], tab_pad,print_table[6], tab_pad,print_table[7]);
for (int i = 0; i < n; i++)
{
if (stu[i].score.average > threshold)
{
printf("%10s%11d%10hd%10.1f%10.1f%10.1f%10.1f%9c\n",
stu[i].name, stu[i].num, stu[i].age,
stu[i].score.chinese,
stu[i].score.math,
stu[i].score.english,
stu[i].score.average,
stu[i].grade);
}
}
printf("%s\n", line);
}
int main(int argc, char *argv[])
{
struct student stu[10];
// bzero( stu, sizeof(stu) ); //把stu所代表的内存清零
student_init(stu, 10);
printf("\n\n 平均成绩统计表\n");
average_stu(stu, 10);
show_student(stu, 10);
printf("\n\n 张同学成绩表\n");
find_student(stu, 10, "张", print_info);//查看张的成绩
printf("\n\n 修改陈同学成绩\n");
find_student(stu, 10, "陈", change_score);//修改陈的成绩
printf("\n\n 均分排序表\n");
sort(stu, 10, compare_average);
show_student(stu, 10);
// sort(stu, 10, compare_chinese);
// show_student(stu, 10);
// sort(stu, 10, compare_math);
printf("\n\n 筛选成绩表\n");
filter_students(stu, 10, 60);
// 写成一个选择的菜单
// 函数指针数组
// 把所有排序比较的方法存到该数组汇总
bool (*cmp[6])(struct student*, struct student*) = {compare_name, compare_age, compare_average,
compare_chinese, compare_math, compare_english};
int cmp_tmp = 0; //定义默认为姓名排序
while(1)
{
printf("输入你想要的排序(0.姓名 1.年龄 2.平均分 3.语文分 4.数学分 5.英语分):\n");
scanf("%d", &cmp_tmp);
switch (cmp_tmp)
{
case 0: sort( stu, 10, cmp[cmp_tmp] ); break;
case 1: sort( stu, 10, cmp[cmp_tmp] ); break;
case 2: sort( stu, 10, cmp[cmp_tmp] ); break;
case 3: sort( stu, 10, cmp[cmp_tmp] ); break;
case 4: sort( stu, 10, cmp[cmp_tmp] ); break;
case 5: sort( stu, 10, cmp[cmp_tmp] ); break;
default:
printf("超出选择范围\n");
}
show_student(stu, 10);
break;
}
return 0;
}
📢写在最后
- 今天的分享就到这啦~
- 觉得博主写的还不错的烦劳
一键三连喔
~ - 🎉感谢关注🎉