学生成绩管理系统的设计与实现
#include <>
#include <>
#include <>
#define max_size 30 //学生最大容量
#define max_course 6 //课程最大数量
typedef struct
{ //学生的信息
int *grades;
int number; //学号
char *name;
int sum_gardes;
double ave_grade;
} StudentTp;
typedef struct node
{ //链表结点结构体
StudentTp data;
struct node *next;
} LNode, *Node;
void main()
{
//函数声明
void Input_record(char **s, Node h, int &total_course, int &total_student);
void Calculate_total_average(char **s, Node h, int &total_course, int &total_student);
void Calculate_students_total_average(Node h, int &total_course, int &total_student);
void Sort_in_up_order(Node h, int &total_course, int &total_student);
void Sort_in_down_order(Node h, int &total_course, int &total_student);
void Sort_ByNumber(Node h);
void Sort_ByDictionary(Node h);
void Search_ByNumber(Node h, int &number, int &total_course, int &total_student);
void Search_ByName(Node h, char *name, int &total_course, int &total_student);
void Statistic_Analysis(Node h, char **s, int &total_course, int &total_student);
void List_Record(Node h, char **s, int &total_course, int &total_student);
void Write_to_a_file(Node h, char **s, int &total_course, int &total_student);
void Read_from_a_file(char **s, Node h, int &total_course, int &total_student);
int total_student = 0; //用于记录已经录入的学生人数
int total_course = 0; //用于记录已经录入的课程数
//初始化必要的信息
Node h;
h = (Node)malloc(sizeof(LNode));
h->next = NULL; //初始化头结点
int i;
printf("请输入课程数:");
scanf("%d", &total_course); //初始化课程信息
printf("请输入课程名(用空格隔开):");
char **a = (char **)malloc(total_course * sizeof(char *));
for (i = 0; i < total_course; i++)
*(a + i) = (char *)malloc(10);
for (i = 0; i < total_course; i++)
scanf("%s", *(a + i));
//菜单栏用switch-case语句实现
int menu;
do
{
printf("********************学生成绩管理系统********************\n");
printf(" record\n");
printf(" total and average score of every course\n");
printf(" total and average score of every student\n");
printf(" in descending order by total score of every student\n");
printf(" in ascending order by total score of every student\n");
printf(" in ascending order by number\n");
printf(" in dictionary order by name\n");
printf(" by number\n");
printf(" by name\n");
printf(" analysis for every course\n");
printf(" record\n");
printf(" to a file\n");
printf(" from a file\n");
printf("\n");
printf("Please enter your choice:");
scanf("%d", &menu);
printf("********************学生成绩管理系统********************\n");
switch (menu)
{
case 1:
Input_record(a, h, total_course, total_student);
break;
case 2:
if (h->next == NULL)
{
printf("未录入学生信息!\n");
break;
}
else
{
Calculate_total_average(a, h, total_course, total_student);
break;
}
case 3:
if (h->next == NULL)
{
printf("未录入学生信息!\n");
break;
}
else
{
Calculate_students_total_average(h, total_course, total_student);
printf("计算成功!\n\n");
break;
}
case 4:
if (h->next == NULL)
{
printf("未录入学生信息!\n");
break;
}
else
{
Sort_in_down_order(h, total_course, total_student);
int order = 0;
Node p;
for (p = h; p->next; p = p->next)
printf("第%d名:%s,总分为:%d\n", ++order, p->next->data.name, p->next->data.sum_gardes);
printf("\n\n");
break;
}
case 5:
if (h->next == NULL)
{
printf("未录入学生信息!\n");
break;
}
else
{
Sort_in_up_order(h, total_course, total_student);
int order = total_student;
Node p;
for (p = h; p->next; p = p->next)
printf("第%d名:%s,总分为:%d\n", order--, p->next->data.name, p->next->data.sum_gardes);
printf("\n\n");
break;
}
case 6:
if (h->next == NULL)
{
printf("未录入学生信息!\n");
break;
}
else
{
Sort_ByNumber(h);
break;
}
case 7:
if (h->next == NULL)
{
printf("未录入学生信息!\n");
break;
}
else
{
Sort_ByDictionary(h);
break;
}
case 8:
if (h->next == NULL)
{
printf("未录入学生信息!\n");
break;
}
else
{
printf("请输入要查找的学号:");
int number;
scanf("%d", &number);
Search_ByNumber(h, number, total_course, total_student);
break;
}
case 9:
if (h->next == NULL)
{
printf("未录入学生信息!\n");
break;
}
else
{
printf("请输入要查找的姓名:");
char *name = (char *)malloc(10);
scanf("%s", name);
Search_ByName(h, name, total_course, total_student);
free(name);
break;
}
case 10:
if (h->next == NULL)
{
printf("未录入学生信息!\n");
break;
}
else
{
Statistic_Analysis(h, a, total_course, total_student);
break;
}
case 11:
if (h->next == NULL)
{
printf("未录入学生信息!\n");
break;
}
else
{
List_Record(h, a, total_course, total_student);
break;
}
case 12:
Write_to_a_file(h, a, total_course, total_student);
break;
case 13:
Read_from_a_file(a, h, total_course, total_student);
break;
case 0:
break;
}
} while (menu != 0);
free(h);
free(a);
}
void Input_record(char **s, Node h, int &total_course, int &total_student)
{ /*二重指针用于传递课程名,total_course用于传递课程数,total_student用于传递学生总数
这里不是pure C,借用了C++的引用,有类似于全局变量的作用
*/
int n, i;
Node p; //扫描指针,准备用头插法插入结点
Node r; //待插入的结点
p = h;
printf("请输入学生人数:");
scanf("%d", &n); //同时记录学生人数
total_student = total_student + n; //n用于插入结点时记录剩余插入的结点数
printf("请按以下顺序输入学生信息:姓名,学号");
for (i = 0; i < total_course; i++)
printf(",%s", *(s + i));
printf("\n");
while (n)
{
//以下初始化待插入结点的信息
r = (Node)malloc(sizeof(LNode));
r->next = NULL;
r->data.name = (char *)malloc(10);
r->data.grades = (int *)malloc(total_course);
scanf("%s %d", r->data.name, &r->data.number);
for (i = 0; i < total_course; i++)
scanf("%d", &r->data.grades[i]);
//以下插入该结点
if (p == h)
{
p->next = r;
p = r;
}
else
{
h->next = r;
r->next = p;
p = r;
}
n--;
}
printf("录入成功!\n\n");
}
void Calculate_total_average(char **s, Node h, int &total_course, int &total_student)
{ //计算每门课程的总分
Node p; //扫描指针
double *sum = (double *)malloc(total_course * sizeof(double));
int i;
for (i = 0; i < total_course; i++)
sum[i] = 0; //求和数组初始化
for (i = 0; i < total_course; i++)
{ //以下对和数组赋值
p = h;
while (p->next)
{
sum[i] = sum[i] + p->next->data.grades[i];
p = p->next;
}
}
for (i = 0; i < total_course; i++)
{
printf("%s课程的总分为:%\n", *(s + i), sum[i]);
printf("%s课程的平均分为:%8.3lf\n", *(s + i), sum[i] / total_student * 1.0);
}
free(sum);
}
void Calculate_students_total_average(Node h, int &total_course, int &total_student)
{ //计算每个学生的总分和平均分并保存
Node p; //扫描指针
double *sum = (double *)malloc(total_student * sizeof(double));
int i, j;
for (i = 0; i < total_student; i++)
sum[i] = 0; //求和数组初始化
for (i = 0, p = h; i < total_student, p->next; i++, p = p->next)
for (j = 0; j < total_course; j++)
sum[i] = sum[i] + p->next->data.grades[j];
//以下将sum数组的值存入学生的个人信息
for (i = 0, p = h; i < total_student, p->next; i++, p = p->next)
{
p->next->data.sum_gardes = sum[i];
p->next->data.ave_grade = sum[i] / total_course * 1.0;
}
free(sum);
}
void Sort_in_up_order(Node h, int &total_course, int &total_student)
{
Calculate_students_total_average(h, total_course, total_student);
//以下开始升序排序(总分由低到高)
Node p, r, s, pr;
r = h->next;
h->next = NULL; //断开头结点
while (r)
{
s = r; //“摘下”结点r给s
r = r->next;
pr = h;
p = h->next; //初始化主、从动指针
//以下将取下的s结点插入到以head为头结点的链表中
while (p && p->data.sum_gardes < s->data.sum_gardes)
{ //当p->data.sum_gardes第一次大于s->data.sum_gardes时跳出循环
pr = p;
p = p->next;
}
//开始插入
pr->next = s;
s->next = p;
}
}
void Sort_in_down_order(Node h, int &total_course, int &total_student)
{
Calculate_students_total_average(h, total_course, total_student);
//以下开始降序排序(总分由高到低)
Node p, r, s, pr;
r = h->next;
h->next = NULL; //断开头结点
while (r)
{
s = r; //“摘下”结点r给s
r = r->next;
pr = h;
p = h->next; //初始化主、从动指针
//以下将取下的s结点插入到以head为头结点的链表中
while (p && p->data.sum_gardes > s->data.sum_gardes)
{ //当p->data.sum_gardes第一次小于s->data.sum_gardes时跳出循环
pr = p;
p = p->next;
}
//开始插入
pr->next = s;
s->next = p;
}
}
//这两个排序也可以求其中之一然后利用"逆置"算法来求另一个;或者求其中一个,然后倒序输出另外一个
void Sort_ByNumber(Node h)
{ //按学号升序排列
Node p, r, s, pr;
r = h->next;
h->next = NULL; //断开头结点
while (r)
{
s = r; //“摘下”结点r给s
r = r->next;
pr = h;
p = h->next; //初始化主、从动指针
//以下将取下的s结点插入到以head为头结点的链表中
while (p && p->data.number < s->data.number)
{ //当p->第一次大于s->时跳出循环
pr = p;
p = p->next;
}
//开始插入
pr->next = s;
s->next = p;
}
for (p = h; p->next; p = p->next)
printf("姓名:%s 学号:%d 总分:%d\n", p->next->data.name, p->next->data.number, p->next->data.sum_gardes);
printf("\n\n");
}
void Sort_ByDictionary(Node h)
{ //按姓名的字典顺序排列
Node p, r, s, pr;
r = h->next;
h->next = NULL; //断开头结点
while (r)
{
s = r; //“摘下”结点r给s
r = r->next;
pr = h;
p = h->next; //初始化主、从动指针
//以下将取下的s结点插入到以head为头结点的链表中
while (p && strcmp(p->data.name, s->data.name) < 0)
{ //当p->第一次大于s->时跳出循环
pr = p;
p = p->next;
}
//开始插入
pr->next = s;
s->next = p;
}
for (p = h; p->next; p = p->next)
printf("姓名:%s 学号:%d 总分:%d\n", p->next->data.name, p->next->data.number, p->next->data.sum_gardes);
printf("\n\n");
}
void Search_ByNumber(Node h, int &number, int &total_course, int &total_student)
{ //查询的成绩假定是按总分从高到低
Sort_in_down_order(h, total_course, total_student);
Node p;
int i = 0;
for (p = h; p->next; p = p->next)
{
i++;
if (p->next->data.number == number)
{
printf("该学生是第%d名 总分为:%d\n", i, p->next->data.sum_gardes);
printf("\n\n");
break;
}
}
if (i >= total_student)
printf("没有该生的成绩!\n");
printf("\n");
}
void Search_ByName(Node h, char *name, int &total_course, int &total_student)
{ //查询的成绩假定是按总分从高到低
Sort_in_down_order(h, total_course, total_student);
Node p;
int i = 0;
for (p = h; p->next; p = p->next)
{
i++;
if (strcmp(p->next->data.name, name) == 0)
{
printf("该学生是第%d名 总分为:%d\n", i, p->next->data.sum_gardes);
printf("\n\n");
break;
}
}
if (i >= total_student)
printf("没有该生的成绩!\n");
printf("\n");
}
void Statistic_Analysis(Node h, char **s, int &total_course, int &total_student)
{
int i; //i表示第i门课
int A[max_course] = {0}, B[max_course] = {0}, C[max_course] = {0}, D[max_course] = {0}, E[max_course] = {0};
Node p;
for (i = 0; i < total_course; i++)
{
p = h;
while (p->next)
{
if (p->next->data.grades[i] >= 90 && p->next->data.grades[i] <= 100)
A[i]++;
else if (p->next->data.grades[i] >= 80)
B[i]++;
else if (p->next->data.grades[i] >= 70)
C[i]++;
else if (p->next->data.grades[i] >= 60)
D[i]++;
else if (p->next->data.grades[i] < 60 && p->next->data.grades[i] >= 0)
E[i]++;
p = p->next;
}
}
for (i = 0; i < total_course; i++)
printf("%s:优秀%d人,占%5.2lf%% 良好%d人,占%5.2lf%% 中等%d人,占%5.2lf%% 及格%d人,占%5.2lf%% 不及格%d人,占%5.2lf%%\n", *(s + i), A[i], A[i] * 100.0 / total_student, B[i], B[i] * 100.0 / total_student, C[i], C[i] * 100.0 / total_student, D[i], D[i] * 100.0 / total_student, E[i], E[i] * 100.0 / total_student);
printf("\n\n");
}
void List_Record(Node h, char **s, int &total_course, int &total_student)
{
Calculate_students_total_average(h, total_course, total_student);
int i, j;
Node p;
for (i = 0, p = h; i < total_student, p->next; i++, p = p->next)
{
printf("姓名:%s 学号:%d ", p->next->data.name, p->next->data.number);
for (j = 0; j < total_course; j++)
printf("%s:%d分 ", *(s + j), p->next->data.grades[j]);
printf("总分:%d 平均分:%8.3lf\n", p->next->data.sum_gardes, p->next->data.ave_grade);
}
printf("\n\n");
}
void Write_to_a_file(Node h, char **s, int &total_course, int &total_student)
{ //只是在输出学生信息的函数里加了一个打开文件和关闭文件的操作
freopen("Debug\\", "w", stdout);
List_Record(h, s, total_course, total_student);
fclose(stdout);
}
void Read_from_a_file(char **s, Node h, int &total_course, int &total_student)
{ //只是在录入学生信息的函数里加了一个打开文件和关闭文件的操作
freopen("Debug\\", "r", stdin);
Input_record(s, h, total_course, total_student);
fclose(stdout);
}