一个很简单的小项目,大一的学生作业。我简单介绍一下相关功能和代码之类的吧~
本来题目不强制要求菜单的,我有点强迫症加了菜单。
【1】题目:
一个班40名学生,期末有10门课程成绩,要求计算并输出如下数据:
(1)按每行6人输出每个学生总成绩
(2)按每行5门输出每一科的平均成绩
(3)提供菜单选择按某一科成绩、总成绩进行升序、降序排名输出 (每行6人).
【2】功能代码分析:(需求分析分解)
(1)功能一: 计算并打印学生的总分。
【1】目标:对每个学生的各科成绩进行累加,得出总分,并打印出每个学生的姓名和对应的总分。
【2】详细要求:
1.系统应支持添加学生成绩信息,包括学生的姓名和各科成绩。
2.系统应能够自动计算每个学生的总分。
3.系统应支持打印出所有学生的姓名和对应的总分。
(2)功能二: 打印各科的平均成绩。
【1】目标: 计算每门科目所有学生的总成绩,然后除以学生人数,得出每门科目的平均分,并打印出来。
【2】详细要求:
1.系统应支持统计每门科目的总成绩。
2.系统应能够计算每门科目的平均成绩(总成绩/学生人数)。
3.系统应支持打印出每门科目的名称和对应的平均成绩。
(3)功能三: 按科目成绩排序。
【1】目标: 允许用户选择一个科目,然后根据该科目的成绩对学生进行升序或降序排序,并打印排序后的学生姓名和成绩。
【2】详细要求:
1.系统应支持用户选择想要排序的科目。
2.系统应支持用户选择排序方式(升序或降序)。
3.系统应能够根据所选科目和排序方式对学生进行排序。
4.系统应支持打印出排序后的学生姓名和对应的科目成绩。
(4)功能四: 按总分排序。
【1】目标: 根据学生的总分对学生进行升序或降序排序,并打印排序后的学生姓名和成绩。
【2】详细要求:
1.系统应支持用户选择排序方式(升序或降序)。
2.系统应能够根据学生的总分对学生进行排序。
3.系统应支持打印出排序后的学生姓名、总分以及各科成绩(可选)。
(5)其他考虑
1.用户界面:系统应提供用户友好的界面,便于用户进行操作和查看结果。(我这里做了一个三级的菜单)
2.错误处理:系统应能够妥善处理可能出现的错误,如数据输入错误、文件读取错误等,并给出相应的错误提示。
菜单模块包括以下:
【1】主菜单: 提供按科目成绩排序、按总分排序和退出程序的选项。
【2】科目排序菜单: 提供显示所有科目、选择科目并排序的选项。
【3】总分排序菜单: 提供按总分升序排序和降序排序的选项。
【3】功能代码实现
1.结构体、相关参数介绍:
[1]Student结构体: 用于存储学生的姓名、各科成绩、总分。
这里姓名使用字符串数组存储,各科成绩使用整型数组存储,总分用整型变量存储。
//学生的结构体定义
typedef struct {
char name[20];
int scores[SUBJECT_COUNT];
int totalScore;
} Student;
[2]subjects数组: 存储科目名称的字符串数组,方便在打印和排序时使用科目名称而非索引,使用const关键字定义的。
//添加一个数组来存储科目名称
const char* subjects[SUBJECT_COUNT] = {
"语文", "数学", "英语", "物理", "化学",
"生物", "历史", "地理", "政治", "体育"
};
(1)总分成绩输出:输入学生数据,调用calculateTotalScores函数计算总分,调用printTotalScores函数打印总分。
【1】核心代码:
void calculateTotalScores(Student students[], int count) {
for (int i = 0; i < count; ++i) {
int sum = 0;
for (int j = 0; j < SUBJECT_COUNT; ++j) {
sum += students[i].scores[j];
}
students[i].totalScore = sum;
}
}
void printTotalScores(Student students[], int count) {
printf("学生姓名 总分\n");
for (int i = 0; i < count; ++i) {
printf("%-10s %4d\n", students[i].name, students[i].totalScore);
}
}
【2】运行界面截图: 显示每个学生的姓名和总分。
(2)单科平均成绩输出:输入学生数据,调用printAverageScores函数计算并打印平均分。
【1】核心代码:
void printAverageScores(Student students[], int count) {
float averages[SUBJECT_COUNT] = {0};
for (int i = 0; i < count; ++i) {
for (int j = 0; j < SUBJECT_COUNT; ++j) {
averages[j] += students[i].scores[j];
}
}
printf("各科平均分:\n");
for (int i = 0; i < SUBJECT_COUNT; ++i) {
printf("科目%d: %.2f\n", i + 1, averages[i] / count);
}
}
【2】运行界面截图: 显示每门科目的平均分。
(3)单科升序/降序成绩输出:输入学生数据,显示科目供用户选择,用户输入科目编号和排序方向,调用sortStudentsBySubject函数进行排序,调用printSortedStudents函数打印排序后的学生信息。
【1】核心代码:
void sortStudentsBySubject(Student students[], int count, int subjectIndex, bool ascending) {
for (int i = 0; i < count - 1; ++i) {
for (int j = 0; j < count - i - 1; ++j) {
if (ascending ? students[j].scores[subjectIndex] > students[j + 1].scores[subjectIndex] :
students[j].scores[subjectIndex] < students[j + 1].scores[subjectIndex]) {
Student temp = students[j];
students[j] = students[j + 1];
students[j + 1] = temp;
}
}
}
}
void printSortedStudents(Student students[], int count, int subjectIndex, bool ascending) {
printf("\n按%s成绩%s序排名:\n", subjectIndex >= 0 ? subjects[subjectIndex] : "总分", ascending ? "升序" : "降序");
printf("学生姓名 成绩\n");
for (int i = 0; i < count; ++i) {
// 确保只打印已初始化的学生数据
if (students[i].totalScore != 0) {
int scoreToPrint = subjectIndex >= 0 ? students[i].scores[subjectIndex] : students[i].totalScore;
printf("%-10s %4d\n", students[i].name, scoreToPrint);
}
}
}
【2】运行界面截图: 显示按选定科目排序后的学生信息。
(4)总分升序/降序成绩输出:输入学生数据,用户选择排序方向,调用sortStudentsByTotal函数进行排序,调用printSortedStudents函数打印排序后的学生信息。
【1】核心代码:
void sortStudentsByTotal(Student students[], int count, bool ascending) {
for (int i = 0; i < count - 1; ++i) {
for (int j = 0; j < count - i - 1; ++j) {
if (ascending ? students[j].totalScore < students[j + 1].totalScore :
students[j].totalScore > students[j + 1].totalScore) {
Student temp = students[j];
students[j] = students[j + 1];
students[j + 1] = temp;
}
}
}
}
void printSortedStudents(Student students[], int count, int subjectIndex, bool ascending) {
printf("\n按%s成绩%s序排名:\n", subjectIndex >= 0 ? subjects[subjectIndex] : "总分", ascending ? "升序" : "降序");
printf("学生姓名 成绩\n");
for (int i = 0; i < count; ++i) {
// 确保只打印已初始化的学生数据
if (students[i].totalScore != 0) {
int scoreToPrint = subjectIndex >= 0 ? students[i].scores[subjectIndex] : students[i].totalScore;
printf("%-10s %4d\n", students[i].name, scoreToPrint);
}
}
}
【2】运行界面截图: 显示按总分排序后的学生信息。