C语言学生信息管理系统包括以下几个功能:
1、学生成绩的录入
2、学生成绩的浏览
3、学生成绩的查询
4、学生成绩的删除
5、学生成绩的排序(这是进阶功能,实现起来也最复杂)
6、学生成绩的分析
程序主要实现思路是依靠链表,数组,指针,结构体等相关知识,其中的核心是对链表的操作。
①:使用单链表作为程序核心,单链表的每个结点储存一个学生的基本信息
②:创建一个函数类 ;主要包含以下功能的函数:创建链表,创建结点,插入结点,打印链表,删除结点等
③:创建一个功能类;主要包含主菜单功能显示以实现用户自主选择功能,操作函数
为了使代码看起来更为简洁明了,我将实现链表功能的函数类放入student.h的头文件中,主函数中只留有main函数
首先需要完成对功能菜单栏的设计,为此,我创建了一个menu函数,为了使界面看起来更美观,可以加入一些符号
void menu(void)
{
printf("\t\t||--------------------------------------------------------------------------------||\n");
printf("\t\t|| ****************【学生管理系统】*************** ||\n");
printf("\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||* 6.学生成绩分析 ||\n");
printf("\t\t||* 0.退出程序 ||\n");
printf("\t\t||--------------------------------------------------------------------------------||\n");
}
main函数的构建则依赖于while的无限循环,用来让用户不断选择功能直到其按0退出
while循环内再嵌套一个switch函数来判断用户输入的数字以跳转到相应的功能
int main(void)
{
menu();
while (1)
{
int choice;
printf("请选择功能菜单(0-6): ");
scanf("%d", &choice);
switch (choice)
{
case 1:
{
printf("-----------------【学生成绩录入】----------------------\n");
break;
}
case 2:
{
printf("-----------------【学生成绩浏览】----------------------\n");
break;
}
case 3:
{
printf("-----------------【学生成绩查询】----------------------\n");
break;
}
case 4:
{
printf("-----------------【学生成绩删除】----------------------\n");
break;
}
case 5:
{
printf("-----------------【学生成绩排序】----------------------\n");
break;
}
case 6:
{
printf("-----------------【学生成绩分析】----------------------\n");
printf("该系统提供学生成绩方差来帮助分析学生成绩\n");
break;
}
default:
{
printf("谢谢使用^_^!\n");
system("pause");
exit(0);
break;
}
}
}
return 0;
}
以上就是主函数的整体框架,接下来要做的就是编写函数类,再往主函数里填充。
头文件里主要包含函数类
首先我们需要完成对链表的构建,为此我们先创建一个学生信息结构体来表示一个学生的姓名、学号和语文、英语、数学、物理四颗成绩
struct grade
{
int Chinese;
int English;
int Math;
int physical;
};
struct student //学生信息结构体
{
char name[20];
int number;
struct grade grade;
};
接下来就是编写链表的有关函数了
struct Node //单个链表结点
{
struct student data;
struct student* next;
};
struct Node* Creatlist(void) //创建链表
{
struct Node* HeadNode = (struct Node*)malloc(sizeof(struct Node)); //创建一个头结点,头结点表示此链表
HeadNode->next = NULL;
return HeadNode;
}
struct Node* CreatNode(struct student data) //创建结点
{
struct Node* NewNode = (struct Node*)malloc(sizeof(struct Node));
NewNode->data = data; //数据域
NewNode->next = NULL; //指针域
return NewNode;
}
链表结点的插入方法有很多种,像头插法,尾插法等,为了简便,这里采用头插法。
void InsertNode(struct Node* HeadNode, struct student data)
{
struct Node* NewNode = CreatNode(data); //创建一个新结点来插入
NewNode->next = HeadNode->next; //该结点的指针域指向头结点的下一个结点
HeadNode->next = NewNode; //头结点的指针域指向该结点
return;
}
可以依据多种根据来删除结点,这里我们指定学号来删除结点
void deleteNode(struct Node* HeadNode, int num) //删除结点(根据指定学号删除)
{
struct Node* postNode = HeadNode->next;
struct Node* postNodebefore = HeadNode;
if (postNode == Null)
printf("系统暂无任何学生信息,无法进行删除\n");
else
while (postNode->data.number != num)
{
postNodebefore = postNode;
postNode = postNode->next;
if (postNode == Null)
{
printf("系统中无该学生信息,无法进行删除\n");
return;
}
}
postNodebefore->next = postNode->next;
free(postNode);
}
void printList(struct Node* HeadNode) //打印链表
{
struct Node* pMove;
pMove = HeadNode->next;
if (pMove == NULL)
printf("无学生信息\n");
else
{
printf("学号\t姓名\t语文\t英语\t数学\t物理\n");
while (pMove != NULL)
{
printf("%d %s %d %d %d %d", pMove->data.number, pMove->data.name, pMove->data.grade.Chinese, pMove->data.grade.English, pMove->data.grade.Math, pMove->data.grade.physical);
pMove = pMove->next;
}
printf("\n");
}
void searchNode(struct Node* HeadNode, int number) //根据学生学号来查询学生成绩
{
struct Node* pMove = HeadNode->next;
if (pMove == NULL)
printf("无学生信息\n");
else
{
while (pMove != NULL)
{
if (number == pMove->data.number)
{
printf("学号\t姓名\t语文\t英语\t数学\t物理\n");
printf("%d %s %d %d %d %d", pMove->data.number, pMove->data.name, pMove->data.grade.Chinese, pMove->data.grade.English, pMove->data.grade.Math, pMove->data.grade.physical);
break;
}
pMove = pMove->next;
}
printf("\n");
}
}
由此,链表类函数已经全部构建完毕,函数的作用使一个个功能独立封装,在调用时直接引用函数即可,可是程序变得简单易读,也是写程序变得更有条理。
接下来,就是与主函数的整合了
#include
#include
#include
#include"student.h"
//主函数
int main (void)
{
menu();//打印界面
//声明变量
struct student newstudent;
int choice , month;
struct Node*List=Creatlist();
while (1)
{
printf("请选择功能菜单(0-6):");
scanf("%d", &choice);
switch (choice)
{
case 1:
{
printf("-----------------【学生成绩录入】----------------------\n");
printf("请输入学生的学号和姓名:\n");
fflush(stdin);//字符串输入之前清空缓冲区
scanf("%d%s", &newstudent.number, newstudent.name);
printf("请输入学生的成绩(语文/英语/数学/物理):");
scanf("%d%d%d%d", &newstudent.grade.Chinese, &newstudent.grade.English, &newstudent.grade.Math, &newstudent.grade.physical);
InsertNode(List, newstudent); //数据存入结点中
}break;
case 2:
{
printf("-----------------【学生成绩浏览】----------------------\n");
printList(List);
}break;
case 3:
{
printf("-----------------【学生成绩查询】----------------------\n");
int search_number;
printf("请输入您想要查询的学号:");
scanf("%d", &search_number);
searchNode(List, search_number);//根据学号打印出学生成绩
}break;
case 4:
{
system("CLS");
printf("-----------------【学生成绩删除】----------------------\n");
int delete_number;
printf("请输入要删除学生的学号:");
scanf("%d", &delete_number);
deleteNode(List,delete_number);//根据学生学号删除
printf("%d号学生已删除\n",delete_number);
}break;
case 5:
{
system("CLS");
printf("-----------------【学生成绩排序】----------------------\n");
}break;
case 0:
{
system("CLS");
printf("谢谢使用^_^!\n");
system("pause");
exit(0);
}break;
default:
{
system("CLS");
printf("选择错误,请重新输入0.0\n");
}break;
}
}
system("pause");
return 0;
}
#include
#include
//功能菜单
void menu(void)
{
printf("\t\t||--------------------------------------------------------------------------------||\n");
printf("\t\t|| ****************【学生管理系统】*************** ||\n");
printf("\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("\t\t||--------------------------------------------------------------------------------||\n");
}
struct grade
{
int Chinese;
int English;
int Math;
int physical;
};
struct student //学生信息结构体
{
char name[20];
int number;
struct grade grade;
};
struct Node //单个链表结点
{
struct student data;
struct student* next;
};
struct Node* Creatlist(void) //创建链表
{
struct Node* HeadNode = (struct Node*)malloc(sizeof(struct Node)); //创建一个头结点,头结点表示此链表
HeadNode->next = NULL;
return HeadNode;
}
struct Node* CreatNode(struct student data) //创建结点
{
struct Node* NewNode = (struct Node*)malloc(sizeof(struct Node));
NewNode->data = data; //数据域
NewNode->next = NULL; //指针域
return NewNode;
}
void InsertNode(struct Node* HeadNode, struct student data)
{
struct Node* NewNode = CreatNode(data); //创建一个新结点来插入
NewNode->next = HeadNode->next; //该结点的指针域指向头结点的下一个结点
HeadNode->next = NewNode; //头结点的指针域指向该结点
return;
}
void deleteNode(struct Node* HeadNode, int num) //删除结点(根据指定学号删除)
{
struct Node* postNode = HeadNode->next;
struct Node* postNodebefore = HeadNode;
if (postNode == Null)
printf("系统暂无任何学生信息,无法进行删除\n");
else
while (postNode->data.number != num)
{
postNodebefore = postNode;
postNode = postNode->next;
if (postNode == Null)
{
printf("系统中无该学生信息,无法进行删除\n");
return;
}
}
postNodebefore->next = postNode->next;
free(postNode);
}
void printList(struct Node* HeadNode) //打印链表
{
struct Node* pMove;
pMove = HeadNode->next;
if (pMove == NULL)
printf("无学生信息\n");
else
{
printf("学号\t姓名\t语文\t英语\t数学\t物理\n");
while (pMove != NULL)
{
printf("%d %s %d %d %d %d", pMove->data.number, pMove->data.name, pMove->data.grade.Chinese, pMove->data.grade.English, pMove->data.grade.Math, pMove->data.grade.physical);
pMove = pMove->next;
}
printf("\n");
}
}
void searchNode(struct Node* HeadNode, int number) //根据学生学号来查询学生成绩
{
struct Node* pMove = HeadNode->next;
if (pMove == NULL)
printf("无学生信息\n");
else
{
while (pMove != NULL)
{
if (number == pMove->data.number)
{
printf("学号\t姓名\t语文\t英语\t数学\t物理\n");
printf("%d %s %d %d %d %d", pMove->data.number, pMove->data.name, pMove->data.grade.Chinese, pMove->data.grade.English, pMove->data.grade.Math, pMove->data.grade.physical);
break;
}
pMove = pMove->next;
}
printf("\n");
}
}
!!!注:排序函数的构建由于所学有限,可以将录入的学生成绩储存在一个数组中,对数组中元素进行排序是很简单的
项目的构建最先需要设想好程序应当实现的功能在进行编写,把需要多次调用的功能用函数封装起来,使程序更简单,主函数和头文件的分类也更方便他人阅读。
成绩管理系统使较为简单的一个项目,比较适合大一新生上手锻炼实践,需要对链表,指针有足够的熟悉。