前言
本文在链表前篇之数组的基础上写的一个简易的学生管理系统。
本着练手感的目的去写的一个代码,并不是很完美,代码仅供参考。
话不多说,先放源码
一、代码
代码如下(示例):
/*
*作者: LiZhenhao
*项目:学生成绩管理系统
*功能:记录、插入、排序、删除
*时间:2021年10月16日17:04:36
*
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//#define N 6 //学生最多6个人
//int stu_sum; //记录学生人数
typedef struct Student {
int num; /*学号*/
char name[15]; /*姓名*/
int c_grade; /*C语言成绩*/
int m_grade; /*数学成绩*/
int e_grade; /*英语成绩*/
int aver; /*平均分*/
int rank; /*名次*/
} student_t;
typedef struct Arr {
student_t *pBase; //存储的是数组第一个元素的地址
int len; //数组所能容纳的最大元素的个数
int cnt; //当前数组有效的个数
}array_t;
/* 函数声明 */
array_t* init_arr(array_t *pArr, int length); //给学生数组开辟内存空间
void Menu1(); //菜单1
void Menu2(array_t *pArr ); //菜单2
void InputRecored(array_t *pArr ); //记录学生成绩
void DisplayRecord(array_t *pArr ); //显示学生成绩
void InsertRecorde(array_t *pArr ); //插入数据
void ShowData(array_t *pArr); //只显示数据
void Sort_Arr(array_t *pArr); //排序
void Delete_Arr(array_t *pArr); //删除某个位置的学生信息
int main(void) {
int number; //选择数
array_t *p_array;
init_arr(p_array, 6); //初始化,开辟学生数组长度为6的动态内存,cnt有效学生个数为0,学生数组长度为6
Menu1(); //执行函数
printf("请选择你要用的功能(0-5):");
scanf("%d", &number);
printf("\n");
if ( 1 == number ) { //非0即1
printf("请输入要记录的学生人数:");
scanf("%d", &p_array->cnt); //输入有效学生个数
} else if (!number) {
number = 0;
} else {
printf("你尚未输入数据!!! \n请输入要记录的学生人数:");
scanf("%d", &p_array->cnt);
printf("\n");
number = 1;
}
switch (number) {
case 1:
system("cls");
InputRecored(p_array);
break;
case 0:
exit(0);
break;
default:
break;
}
return 0;
}
//初始化数组,给数组开辟动态内存空间
array_t* init_arr(array_t *pArr, int length) {
(pArr) = (array_t*)malloc( 1 * sizeof(array_t) );
(pArr)->pBase = (student_t*)malloc( sizeof(student_t) * length );
if ( (NULL == pArr) && (NULL == (pArr)->pBase) ) {
printf("创建动态内存失败!!!");
exit(-1); //终止整个程序
} else {
(pArr)->len = length;
(pArr)->cnt = 0;
}
return pArr;
}
/* 菜单1 */
void Menu1() {
printf(" 学生成绩管理系统 \n");
printf(" *********************菜单*********************\n");
printf(" * *\n");
printf(" * 1 输入记录 2 展示记录 *\n");
printf(" * 3 插入数据 4 成绩排序 *\n");
printf(" * 5 删除数据 0 退出系统 *\n");
printf(" * *\n");
printf(" *********************************************** \n");
}
/* 菜单2 */
void Menu2(array_t *pArr ) {
int i;
Menu1();
printf("请输入选项0-5:");
scanf("%d", &i);
printf("\n");
switch(i) {
case 0:
exit(0);
break;
case 1:
system("cls");
InputRecored(pArr);
break;
case 2:
system("cls");
DisplayRecord(pArr);
break;
case 3:
system("cls");
InsertRecorde(pArr);
break;
case 4:
system("cls");
Sort_Arr(pArr);
break;
case 5:
system("cls");
Delete_Arr(pArr);
break;
default:
break;
}
}
/* 输入成绩 */
void InputRecored(array_t *pArr ){
int i, j;
// system("cls");
printf(" 输入学生信息 \n");
printf("*****************************************************\n");
printf("\n");
printf("数据录入格式提示:\n");
printf("1.数据内容:学号、姓名、c语言成绩、数学成绩、英语成绩\n");
printf("2.数据间以空格做间隔,最后回车录入数据结束\n");
printf("\n");
for(i = 0; i < pArr->cnt; i++) {
printf("请输入第%d个学生的数据:",i+1);
scanf("%d", &(pArr->pBase + i)->num);
scanf("%s", (pArr->pBase + i)->name);
scanf("%d", &(pArr->pBase + i)->c_grade);
scanf("%d", &(pArr->pBase + i)->m_grade);
scanf("%d", &(pArr->pBase + i)->e_grade);
}
printf("\n");
printf("数据录入完成!\n");
printf("\n");
printf("1查看录入的信息 2返回主菜单 0退出:");
scanf("%d",&j);
switch(j)
{
case 1: //输入1:显示数据
printf("\n");
DisplayRecord(pArr);
break;
case 2: //输入2:显示子菜单
system("cls");
Menu2(pArr);
break;
case 0: //输入0:退出
exit(0);
break;
}
}
//显示数据
void DisplayRecord(array_t *pArr ){
int i,j;
system("cls");
printf(" 显示学生成绩 \n");
printf("************************************************************************\n");
printf(" 学号 姓名 c语言成绩 数学成绩 英语成绩\n");
for( i = 0; i < pArr->cnt; i++){
printf("\t%d\t%s\t%d\t\t%d\t\t%d\n", (pArr->pBase + i)->num, (pArr->pBase + i)->name, (pArr->pBase + i)->c_grade, (pArr->pBase + i)->m_grade, (pArr->pBase + i)->
e_grade);
}
printf("\n");
printf("1返回主菜单 0退出:");
scanf("%d",&j);
switch(j) {
case 1:
system("cls");
Menu2(pArr);
break;
case 0:
exit(0);
break;
default:
break;
}
}
//只显示数据
void ShowData(array_t *pArr) {
int i;
printf(" 已经录入的学生成绩 \n");
printf("************************************************************************\n");
printf(" 学号 姓名 c语言成绩 数学成绩 英语成绩\n");
for( i = 0; i < pArr->cnt; i++){
printf("\t%d\t%s\t%d\t\t%d\t\t%d\n", (pArr->pBase + i)->num, (pArr->pBase + i)->name, (pArr->pBase + i)->c_grade, (pArr->pBase + i)->m_grade, (pArr->pBase + i)->
e_grade);
}
printf("\n");
}
//在某个学号前面插入学生信息
void InsertRecorde(array_t *pArr ) {
int i, j, pos, m = pArr->cnt; ///* m是记录当前移动的位置 */
ShowData(pArr);
printf("请输入你插入的学生信息(学号、姓名、C语言成绩、数学成绩、英语成绩):\n");
printf("tip:以空格分别输入\n");
student_t new_stu; //定义一个新插入学生的结构体变量
scanf("%d",&new_stu.num);
scanf("%s",new_stu.name);
scanf("%d",&new_stu.c_grade);
scanf("%d",&new_stu.m_grade);
scanf("%d",&new_stu.e_grade);
pos = new_stu.num -1;
for( i = 0; i < (pArr->cnt - pos); i++ ) { //假如有5个学生,n = 5,插入3号位置,需要循环三次
*(pArr->pBase + m) = *(pArr->pBase + (m - 1) );
(pArr->pBase + m)->num++;
m--;
}
*(pArr->pBase + pos) = new_stu; //在用户想插入位置补充进新学生的信息
pArr->cnt++; //插入一名学生信息后,学生数组里的有效个数cnt加1
printf("\n");
printf("数据插入成功!\n");
printf("\n");
printf("1查看录入的信息 2返回主菜单 0退出:");
scanf("%d",&j);
switch(j) {
case 1: //输入1:显示数据
printf("\n");
DisplayRecord(pArr);
break;
case 2: //输入2:显示子菜单
system("cls");
Menu2(pArr);
break;
case 0: //输入0:退出
exit(0);
break;
}
}
//平均成绩排序
void Sort_Arr(array_t *pArr) {
int i, j;
student_t temp;
for( i = 0; i < pArr->cnt; i++) {
(pArr->pBase + i)->aver = ( (pArr->pBase + i)->c_grade + (pArr->pBase + i)->m_grade + (pArr->pBase + i)->e_grade ) / 3;
}
//先选出第一个最大的数,然后"沉底"
for( j = 0; j < (pArr->cnt - 1); j++) { //如果数组长度是6的话,那么外循环需要"沉底"5次
for( i = 0; i < ( (pArr->cnt - 1) - j); i++ ) { //第一次"沉底"需要比较5次
if( (pArr->pBase + i)->aver < (pArr->pBase + (i + 1) )->aver ) {
temp = *(pArr->pBase + i);
*( pArr->pBase + i) = *(pArr->pBase + (i + 1) );
*( pArr->pBase + (i + 1) ) = temp;
}
}
}
int k;
printf("\n");
printf("数据排序成功!\n");
printf(" 排序后的学生成绩 \n");
printf("************************************************************************\n");
printf("排名 学号 姓名 c语言成绩 数学成绩 英语成绩 平均成绩\n");
for( i = 0; i < pArr->cnt; i++) {
(pArr->pBase + i)->rank = i+1;
}
for( i = 0; i < pArr->cnt; i++){
printf("%d\t%d\t%s\t%d\t\t%d\t\t%d\t\t\t%d\n", (pArr->pBase + i)->rank, (pArr->pBase + i)->num,
(pArr->pBase + i)->name, (pArr->pBase + i)->c_grade, (pArr->pBase + i)->m_grade, (pArr->pBase + i)->e_grade, (pArr->pBase + i)->aver);
}
printf("\n");
printf("\n");
printf("1返回主菜单 0退出:");
scanf("%d",&k);
switch(k) {
case 1: //输入2:显示子菜单
system("cls");
Menu2(pArr);
break;
case 0: //输入0:退出
exit(0);
break;
}
return ;
}
void Delete_Arr(array_t *pArr) {
ShowData(pArr);
printf("请输入你想要删除哪个位置的学生信息:");
int i, j, pos, m; /* m 表示记录数组的当前的位置,先设为pos*/
scanf("%d", &pos);
printf("\n");
m = pos;
for ( i = 0; i < (pArr->cnt - pos); i++ ) {
*(pArr->pBase + (m -1)) = *(pArr->pBase + m);
(pArr->pBase + m)->num--;
m++;
}
pArr->cnt--;
printf("\n");
printf("数据删除成功!\n");
ShowData(pArr);
printf("\n");
printf("1查看录入的信息 2返回主菜单 0退出:");
scanf("%d",&j);
switch(j) {
case 1: //输入1:显示数据
printf("\n");
DisplayRecord(pArr);
break;
case 2: //输入2:显示子菜单
system("cls");
Menu2(pArr);
break;
case 0: //输入0:退出
exit(0);
break;
}
}
二、展示结果
1.主界面
2.输入记录
3.插入数据
4.删除数据
这里有点小bug,学号没有自动对齐。
5.成绩排序
总结
总体来说,写代码是一件既是痛苦又是快乐的事。
痛苦的是有时候一个小bug让你纠结很久,被人打断思路,又很难滤清思路。快乐的是你能得到很多你意想不到的收获,比如说,代码的规范,思路更加清晰,知识被填补等等。但这些收获是建立在你坚持努力把代码打出来。