项目概述
这个学生成绩管理系统项目采用了C语言编写,实现学生成绩的录入、显示、计算平均分、排序、查询以及清屏等功能。
学生成绩管理系统分为三个主要部分:头文件、实现文件和主程序。头文件中定义了常量、数据结构和函数原型。实现文件包含了所有功能模块的具体实现,包括录入成绩、列出成绩、计算平均分、排序、查询和清屏。主程序通过一个循环不断等待用户输入的命令,并根据用户的输入调用相应的函数。这个循环结构类似于轮询,但更准确地说,它是一个基于用户输入的命令处理循环。
项目架构
1. 头文件 option.h
- 功能:定义常量、数据结构和函数原型。
- 常量:
STU
:定义学生数量的最大值为10。SUB
:定义科目数量为3。
- 数据结构:
Student
:定义学生结构体,包含学号、各科成绩和平均成绩。
- 函数原型:声明各个功能模块的函数。
#ifndef OPTION_H
#define OPTION_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STU 10 // 定义学生数量的最大值
#define SUB 3 // 定义科目数量
// 定义学生结构体
typedef struct {
int id; // 学号
float scores[SUB]; // 各科成绩
float average; // 平均成绩
} Student;
void Type();
void List();
void Average();
void Sort();
void Search();
void Clear();
void Help();
#endif // OPTION_H
2. 实现文件 option.c
- 功能:实现各个功能模块的具体逻辑。
- 全局变量:
Student students[STU]
:定义学生数组。int n
:记录学生数量。
- 函数实现:
Type()
:录入学生成绩。List()
:列出学生成绩。Average()
:计算学生成绩平均分。Sort()
:按平均成绩由高到低排序。Search()
:按学号查询学生成绩。Clear()
:清屏。Help()
:显示帮助菜单。
#include "option.h"
Student students[STU]; // 定义学生数组
int n = 0; // 学生数量
//录入学生成绩
void Type() {
int i;
if (n != 0) {
printf("成绩已存在\n");
return;
}
printf("请输入学生人数: ");
scanf("%d", &n);
for (i= 0; i < n; i++) {
printf("请输入成绩\n学号 语文 数学 英语: ");
scanf("%d %f %f %f", &students[i].id,
&students[i].scores[0],
&students[i].scores[1], &students[i].scores[2]);
}
printf("录入学生成绩操作完成\n");
}
//列出学生成绩
void List() {
int i;
if (n == 0) {
printf("成绩表为空!请先使用命令 T 录入学生成绩\n");
return;
}
printf("学号 语文 数学 英语 平均分\n");
for (i = 0; i < n; i++) {
printf("%-8d%-8.1f%-8.1f%-8.1f%-8.1f\n", students[i].id,
students[i].scores[0], students[i].scores[1],
students[i].scores[2], students[i].average);
}
}
//计算学生成绩平均分
void Average() {
int i;
if (n == 0) {
printf("成绩表为空!请先使用命令 T 录入学生成绩\n");
return;
}
for (i = 0; i < n; i++) {
students[i].average = (students[i].scores[0] +
students[i].scores[1] + students[i].scores[2]) / SUB;
}
printf("平均分已计算。请使用命令L查看。\n");
}
//按平均成绩由高到低排序
void Sort() {
int i,j;
if (n == 0) {
printf("成绩表为空!请先使用命令 T 录入学生成绩\n");
return;
}
for (i = 0; i < n - 1; i++) {
for (j = 0; j < n - i - 1; ++j) {
if (students[j].average < students[j + 1].average) {
Student temp = students[j];
students[j] = students[j + 1];
students[j + 1] = temp;
}
}
}
printf("完成排序。请使用命令L查看。\n");
}
//按学号查询学生成绩
void Search() {
int i;
if (n == 0) {
printf("成绩表为空!请先使用命令 T 录入学生成绩\n");
return;
}
int id;
printf("输入要查询的学生学号: ");
scanf("%d", &id);
printf("学号 语文 数学 英语 平均分\n");
for (i = 0; i < n; i++) {
if (students[i].id == id) {
printf("%-8d%-8.1f%-8.1f%-8.1f%-8.1f\n",
students[i].id, students[i].scores[0], students[i].scores[1],
students[i].scores[2], students[i].average);
return;
} }
printf("未找到学号为 %d 的学生成绩。\n", id);
}
//清屏
void Clear() {
system("clear");
}
//帮助
void Help() {
printf("*****************************************\n");
printf("* 学生成绩管理系统--帮助菜单 *\n");
printf("*****************************************\n");
printf("*\tH = 显示帮助菜单\t\t*\n");
printf("*\tT = 成绩录入\t\t\t*\n");
printf("*\tA = 计算学生平均分\t\t*\n");
printf("*\tL = 列出成绩表\t\t\t*\n");
printf("*\tP = 按平均成绩由高到低排序\t*\n");
printf("*\tS = 按学号查询学生成绩\t\t*\n");
printf("*\tC = 清屏\t\t\t*\n");
printf("*\tQ = 退出系统\t\t\t*\n");
printf("*****************************************\n");
printf("* Copyright <C> 2024.00.00 By name *\n");
printf("*****************************************\n");
}
3. 主程序 main.c
- 功能:主程序入口,处理用户命令,调用相应功能模块。
- 实现:
- 显示帮助菜单。
- 循环接受用户输入命令,并调用对应的功能模块。
- 支持命令包括录入成绩、列出成绩表、计算平均分、排序、查询、清屏和退出系统
#include "option.h"
int main() {
Help();
char command; // 声明变量用于存储用户输入的命令
do {
printf("\n请输入命令= ");
scanf(" %c", &command); // 获取用户输入的命令
switch (command) {
case 'T': Type(); break; // 录入成绩
case 'L': List(); break; // 列出成绩表
case 'A': Average(); break; // 计算平均分
case 'P': Sort(); break; // 按平均分排序
case 'S': Search(); break; // 按学号查询
case 'C': Clear(); break; // 清屏
case 'H': Help(); break; // 显示帮助菜单
case 'Q': break; // 退出循环
default:
printf("无效命令,请重新输入(帮助菜单 H)\n");
}
} while (command != 'Q');
printf("系统已退出\n");
return 0;
}
4. Makefile
# 指定编译器
CC = gcc
# 指定目标文件
OBJS = main.o option.o
# 编译选项,-c 表示编译但不链接,-Wall 表示启用所有警告
CFLAGS = -c -Wall
# 指定生成的可执行文件的名称
TARGET = xs
# 链接目标文件生成可执行文件
$(TARGET): $(OBJS)
$(CC) $^ -o $@ # $^ 表示所有的依赖文件,$@ 表示目标文件
# 指定如何从 .c 文件生成 .o 文件
%.o: %.c
$(CC) $(CFLAGS) $< -o $@ # $< 表示第一个依赖文件,$@ 表示目标文件
# 声明伪目标
.PHONY: clean
# 定义清理目标,删除所有的 .o 文件和可执行文件
clean:
$(RM) *.o $(TARGET)