学生成绩统计系统
所使用的知识较少所以实现的功能比较简单,处理的学生信息也不全面学习了结构体和文件处理后将会有一个更完善更实用的学生信息管理系统一、项目实现
1.系统分析设计:
(1)程序功能模块:
根据系统要求,系统主模块应包含显示主菜单模块、录入学生成绩模块、显示学生成绩模块、统计高于平均分模块、统计最高分和最低分模块、统计各分段人数模块,每个模块都定义为一个功能相对独立的函数*显示主菜单模块,函数名 MainMenu();
*录入学生成绩模块,函数名 InputScore(long num[], int score[]);
*显示学生成绩模块,函数名 DisplayScore(long num[], int score[], int n);
*统计高于平均分模块,函数名 AboveAvgScore(long num[], int score[], int n);
*统计最高分和最低分模块,函数名 MaxMinScore(long num[], int score[], int n);
*统计各分段人数模块,函数名 GradeScore(int score[], int n);
(2)定义数据结构。
要实现学生成绩统计,首先要考虑的问题就是学生学号、成绩的存储。那么设计一位数组 num[]、set_score[]来存储学生学号与成绩,并在一开始设置了一个符号常量MAXSTU,用于定义数组最大长度,即最多学生人数。假设学生不超过30人,则MAXSTU代表30在本项目中,除主菜单显示函数MainMenu()外,其他函数都使用数组set_score[]。本例中将该数组定义为局部变量,利用形参和实参的数据传递,实现对学生成绩数组的访问。在主函数中定义stu_count,存放学生的实际人数。
2.各个模块设计
(1)主界面设计。
采用printf()函数实现主界面设计,并使用system("cls")清屏,此函数原型在"stdlib.h"头文件中。本模块通过main()调用。void MainMenu()
{
system("cls");
printf("\n\t\t 学生成绩统计系统 \n");
printf("\n\t\t==================================\n");
printf("\t\t 1.录入学生成绩 \n");
printf("\t\t 2.显示学生成绩 \n");
printf("\t\t 3.显示高于平均分名单 \n");
printf("\t\t 4.显示最高分和最低分的名单 \n");
printf("\t\t 5.统计各分数段人数 \n");
printf("\t\t 0.退出 \n");
printf("\n\t\t==================================\n");
printf("\n\t\t 请输入您的选择: ");
}
效果如图:
(2)录入学生成绩模块。
本模块是从键盘输入学生学号和成绩,当输入成绩为负数时结束。本模块函数有2个,长整型num用来存放学生学号;整型数组score,存放学生的成绩。函数的返回值i为学生的总数。int InputScore(long num[], int score[])
{
int i = -1;
system("cls");
do
{
i++;
printf("\n\t\t 请输入学号 成绩 (输入-1 退出)");
scanf_s("%ld%d", &num[i], &score[i]);
} while (num[i] > 0 && score[i] >= 0);
return i;
}
效果(包括输入)如图:
(3)显示学生信息模块。
本模块函数参数有3个,长整型数组num,存放学生学号;整型数组score,存放学生成绩;整型变量n,存放学生总数。函数无返回值。void DisplayScore(long num[], int score[], int n)
{
int i;
system("cls");
printf("\n\t\t 学生成绩如下:");
printf("\n\t\t===============================\n");
printf("\n\t\t 学生号 成绩");
printf("\n\t\t-------------------------------\n");
for (i = 0; i < n; i++)
{
printf("\n\t\t %ld %d", num[i], score[i]);
}
}
效果如图:
(4)显示高于平均分的名单模块。
先计算平均分,并显示高于平均分的名单。本模块函数参数有3个,长整型数组num,存放学生序号;整型数组score存放学生成绩;整型变量n,存放学生总数。函数无返回值。模块中平均值变量用变量average存放,声明为float类型。void AboveAvgScore(long num[], int score[], int n)
{
int i, sum = 0;
int count = 0;
float average;
system("cls");
for (i = 0; i < n; i++)
{
sum = sum + score[i];
}
average = (float)sum / n;
printf("\n\t\t平均分为:%.2f\n", average);
printf("\n\t\t--------------------------------\n");
printf("\n\t\t高于平均分:\n\t\t学号 成绩");
printf("\n\t\t--------------------------------\n");
for (i = 0; i < n; i++)
{
if ((float)score[i] > average)
{
printf("\n\t\t%ld %d", num[i], score[i]);
count++;
}
}
printf("\n\t\t高于平均分的人数:%d\n", count);
}
效果如图:
(5)显示最高分最低分名单模块。
本模块函数参数有3个,整型数组num,存放学生学号;整型数组score,存放学生成绩;整型变量n,存放学生总数。函数无返回值。将最高分成绩存于变量max中,学号存于max_num中,将最低分成绩存于变量min中,学好存于min_num中。void MaxMinScore(long num[], int score[], int n)
{
int i, max, min;
long max_num, min_num;
system("cls");
max = min = score[0];
max_num = min_num = num[0];
for (i = 1; i < n; i++)
{
if (score[i] > max)
{
max = score[i]; max_num = num[i];
}
if (score[i] < min)
{
min = score[i]; min_num = num[i];
}
}
printf("\n\t\t最高分学号: %ld,分数: %d", max_num, max);
printf("\n\t\t最低分学号: %ld,分数: %d", min_num, min);
}
效果如图:
(6)统计各分数段人数模块。
本模块函数参数有2个,整型数组score,存放学生成绩;整型变量n,存放学生总数。函数无返回值。void GradeScore(int score[], int n)
{
int i;
int grade_90 = 0;
int grade_80 = 0;
int grade_70 = 0;
int grade_60 = 0;
int grade0_59 = 0;
system("cls");
for (i = 0; i < n; i++)
{
switch (score[i] / 10)
{
case 10:
case 9:grade_90++; break;
case 8:grade_80++; break;
case 7:grade_70++; break;
case 6:grade_60++; break;
default:grade0_59++; break;
}
}
printf("\n\t\t 90分以下的人数为: %d", grade_90);
printf("\n\t\t 80--90分的人数为: %d", grade_80);
printf("\n\t\t 70--80分的人数为: %d", grade_70);
printf("\n\t\t 60--70分的人数为: %d", grade_60);
printf("\n\t\t 不及格的人数为 : %d", grade0_59);
}
效果如图:
(7)主函数。
主要是通过循环语句,结合switch语句完成主菜单的功能调用。void main()
{
int set_score[MAXSTU]; //定义一维数组,存放学生某门课程的成绩
long num[MAXSTU]; //定义一维数组,存放学生学生学号
int stu_count = 0; //存放学生实际人数
int choose; //定义整型变量,存放主菜单选择序号
while (1)
{
MainMenu();//调用显示菜单主函数
printf("\n\t\t 请选择主菜单序号(0--5):");
scanf_s("%d", &choose);
switch (choose)
{
case 1:stu_count = InputScore(num, set_score); break;//调用录入成绩
case 2:DisplayScore(num, set_score, stu_count); break;//调用显示成绩
case 3:AboveAvgScore(num, set_score, stu_count); break;//调用显示高低分
case 4:MaxMinScore(num, set_score, stu_count); break;//调用显示最高低分
case 5:GradeScore(set_score, stu_count); break;//调用统计各分段
case 0:return; //退出
default:printf("\n\t\t 输入无效,请重新选择!\n");
}
printf("\n\n\t\t 按任意键返回主菜单");
_getch();
}
}
除了每个函数模块以外还要注意函数声明,函数声明和头文件的引用如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define MAXSTU 30 //最大学生人数
//------函数原型声明------
void MainMenu(); //主菜单函数声明
int InputScore(long num[], int score[]); //录入学生成绩
void DisplayScore(long num[], int score[], int n); //显示学生成绩
void AboveAvgScore(long num[], int score[], int n); //显示高于平均分名单
void MaxMinScore(long num[], int score[], int n);
void GradeScore(int score[], int n);
总结:
(1)在实际开发中,当编写由许多函数组成的程序时,一般情况下先编写主函数,对于尚未编写的被调函数,先使用空函数占位,以后再使用编写好的函数代替它。(2)声明一维形参数组时,方括号内可以不给出数组长度
(3)在被调函数中改变形参数组元素时,实参数组元素值也会随之改变