课程设计————学生信息管理系统(包含历代思路和代码)

课程设计————学生管理系统(包含历代思路和代码)

一.前言

学生信息管理系统是我第一个独立完成的比较长的代码,也算是花费了一些心血,这个系统是我一点点把它从几百行的代码逐渐优化到上千行,功能从简单到复杂。在这里我把个人思路分享给你们,但愿能给你们带来一些帮助。git

相比较上一篇博客(学生管理系统)而言,这一篇,主要讲的是我逐步优化的思路和过程。以及在那篇博客后,继续进行的优化。github

二.学生管理系统1.0版

1. 实现功能

  • 简单的密码验证
  • 学生信息的录入(链表的建立)
  • 学生信息的增.删.改.查
  • 按照平均分排序输出

2. 函数框架

int main(void)
{
	int a;
	struct student *pHead;
	show1(); 
	while(1)
	{
		system("cls");//清屏
		show2();//界面
		fflush(stdin);
		scanf("%d",&a);
		switch(a)
		{
			case 1:pHead=input();break;//输入 
			case 2:output(pHead);break;//输出 
			case 3:increase(pHead);break;//增长 
			case 4:strike_out(pHead);break;//删除
			case 5:chang(pHead);break;//修改 
			case 6:inquiry(pHead);break;//查询 
			case 7:sore(pHead);break;//排序 
			case 0:exit(0);break;
			default :printf("输入有误请从新输入\n");break; 
		}
		printf("按任意键进行下一步操做\n");
		getch();
	}
}

3. 函数调用关系图

这里写图片描述

4. 部分功能函数

  1. 链表的建立输出和增删改查
    这一部分你们能够参考我以前的博客(链表及其简单应用),里面有较详细的说明
  2. 链表的排序
    这一部分在我以前的博客(链表及其简单应用)中也有写到,里面介绍了两种排序,链表的冒泡排序和插入排序。相比较而言,其实插入排序更加简单一点,多是由于冒泡排序是我接触的第一个排序吧,因此个人代码中几乎都是用冒泡来进行排序的
  3. 密码的输入显示 *
void show1()
{
	char cipher[20]={"123456"},a[20],t;//cioher 表示密码
	int i,j;
	printf("欢迎进入学生信息管理系统\n");
	for(i=0;i<3;i++)
	{
		printf("请输入管理员密码:");	
		for(j=0;a[j-1]!=13;j++)//输入时回车时,中止录入密码
		{
			a[j]=getch();//getch接受键盘输入字符,不显示到屏幕上
			if(a[j]==8&&j>0)//若是输入的是删除键
			{
				printf("\b \b");//用\b和空格覆盖前面的*
				j-=2;//删除数组中的字符
			}		
			else if(j>=0)
				printf("*");
			else //防止删除提示语句
				printf(" ");
		}
		printf("\n");
		a[j-1]='\0';	
		if(strcmp(cipher,a)==0)
	 		return;
	}
	printf("三次输入错误!!!退出系统\n");
	Sleep(150);
	exit(1);
}

5. 源代码

代码地址web

学生信息管理2.0版

这个版中,刚刚学习了文件的相关操做,因此将文件的操做加入到其中。数组

1. 新增功能

  1. 从文件中录入数据
  2. 能够选择多种顺序输出
  3. 将学生信息保存到文件中
  4. 使用多文件保存不一样功能的函数

2. 函数框架

int main(void)
{
	struct student *pHead;
	int flag;
	show1();//登陆界面 
	pHead=startup();//信息的录入 
	save_3(pHead);//保存到缓存文件中 
	while(1)
	{
		system("cls");
		show3();
		fflush(stdin);
		scanf("%d",&flag);
		switch(flag)
		{
			case 1:increase(pHead);break;//增长 
			case 2:strike_out(pHead);break;//删除 
			case 3:chang(pHead);break;//修改 
			case 4:inquiry(pHead);break;//查询
			case 5:save_3(pHead);
				   output(pHead);
				   pHead=finput(1);break;//输出
			case 6:
			   	   save_3(pHead);
				   save(pHead);
				   pHead=finput(1);break;//保存 
			case 0:exit(0);break;
			default :printf("输入有误请从新输入\n");break; 
		}
		printf("按任意键进行下一步操做\n");
		getch();
	}	
}

3. 函数调用关系图

这里写图片描述

4. 部分功能函数

  1. 文件的读
struct student *finput(int a)//文件录入 a控制是否须要输入文件名 
{
	
	FILE *fp;
	struct student *pHead=NULL,*pEnd,*pNew;
	int sum=0,i,j,num;
	char filename[100]=N; 
	if(a==2)
	{
		printf("请输入文件路径及文件名:"); 
		fflush(stdin); 
		gets(filename);
	}
	iCound=0;
	pEnd=pHead=(struct student *)malloc(sizeof(struct student));
	fp=fopen(filename,"rt+");
	if(fp==NULL)
	{
		printf("不能打开文件");
		exit(1); 
	}
	while(1)
	{
		sum=0;
		pNew=(struct student *)malloc(sizeof(struct student));
		fscanf(fp,"%s %s %s",pNew->name,pNew->num,pNew->classes);
		fscanf(fp,"%s %s %s",pNew->score[0],pNew->score[1],pNew->score[2]); 
		for(i=0;i<3;i++)//字符串转换为整数 
		{	
		 	num=0;
			for(j=0;pNew->score[i][j];j++)
				num=num*10+pNew->score[i][j]-'0';	
			sum=sum+num;	
		}	
		pNew->aver=sum*1.0/3;
		if(feof(fp))
			break;
		pEnd->next=pNew;
		pEnd=pNew;
		iCound++;
	}
	pEnd->next=NULL;
	fclose(fp);
	return pHead;
}
  1. 文件的写
void save_3(struct student *pHead)
{
	FILE *fp;
	char filename[100]= N;  
	fp=fopen(filename,"wt");
	if(fp==NULL)
	{
		printf("不能打开文件");
		exit(1); 
	}
	pHead=pHead->next;
	while(pHead)
	{
		fprintf(fp,"%s %s %s ",pHead->name,pHead->num,pHead->classes);
		fprintf(fp,"%s %s %s\n",pHead->score[0],pHead->score[1],pHead->score[2]);
		pHead=pHead->next;
	}
	fclose(fp);
}
  1. 使用参数屡次调用排序函数
void output_2(struct student *pHead,int a)//a控制排序依据 //方式2输出 
{
	int i,j,flag;
	struct student *pj_1,*pj,*pj_h;
	for(i=0;i<iCound-1;i++)
		for(j=0,pj=pHead,flag=0;j<iCound-i-1;j++) 
		{
			if(flag==0)
			{
				pj_1=pj;
				pj=pj->next;
				pj_h=pj->next;
			}
			if(flag==1)
			{
				pj_1=pj_1->next;
				pj_h=pj->next;
			}	
			flag=0;
			if(a==2&&(pj->aver)<(pj_h->aver))
			{
				exchange(pj,pj_h,pj_1);
				flag=1;	
			}
			else if(a==3&&strcmp(pj->num,pj_h->num)==1)	
			{
				exchange(pj,pj_h,pj_1);
				flag=1;	
			}
			else if(a==4&&strcmp(pj->classes,pj_h->classes)==1)
			{
				exchange(pj,pj_h,pj_1);
				flag=1;
			}
			else if(a==5&&strcmp(pj->name,pj_h->name)==1)
			{
				exchange(pj,pj_h,pj_1);
				flag=1;
			}
		}
	output_t(pHead);		
}

5. 源代码

这个代码中我使用的是cfree建立工程文件的方法
其余编译器不知道是否能够正常运行。
若是要运行查看结果,推荐使用c free
代码地址缓存

学生信息管理3.0版

这个版本具体能够看个人上一篇博客。数据结构

1. 新增功能

  1. 位运算对密码的加密
  2. 分为三个登陆端,学生,教师,管理员

2.源代码

这个代码中我使用的是cfree建立工程文件的方法
其余编译器不知道是否能够正常运行。
若是要运行查看结果,推荐使用c free
代码地址框架

学生信息管理4.0版

1. 新增功能

  1. 从管理一个班变为管理五个班
  2. 对学生信息的数据结构进行改进,将保存成绩从二维数组改成链表,即十字链表。(老师加的要求)

2. 函数框架

这里写图片描述

3. 函数调用关系图

这里写图片描述

4. 部分功能函数

  1. 学生信息结构节点的定义
struct score//分数 
{
	char date[20];
	int No;
	struct score *next;
};
struct student
{
	int No; //排名 
	char name[20];//姓名 
	char num[20];//学号 
	char classes[20];//班级 
	struct score *ScorepHead;//分数 
	double aver;//平均分
	struct student *next;//指针域 
}; 
struct student *StupHead[6]; //5个班的头节点 
int iCound[6];//5个班的节点数量
  1. 学生信息链表的建立(文件读入)
struct student *Finput(char filename[]) 
{
	
	FILE *fp;
	struct student *pHead=NULL,*pEnd,*pNew;
	int sum=0,i,j,num;
	iCound[filename[5]-'0'-1]=0;
	pEnd=pHead=(struct student *)malloc(sizeof(struct student));
	fp=fopen(filename,"rt");
	if(fp==NULL)
	{
		printf("不能打开文件");
		exit(1); 
	}
	char a[20];//暂存信息 
	fscanf(fp,"%s",a);
	
	int temp[Classnum]={0};//暂存科目数量 
	while(!feof(fp))
	{
		sum=0;
		pNew=(struct student *)malloc(sizeof(struct student));
		strcpy(pNew->name,a);
		fscanf(fp,"%s %s",pNew->num,pNew->classes);
		
				
		struct score *spEnd,*spNew,*spt; //录入科目成绩 
		pNew->ScorepHead=spEnd=(struct score *)malloc(sizeof(struct score));
		while(1)
		{
			spNew=(struct score *)malloc(sizeof(struct score));
			fscanf(fp,"%s",a);
			if(a[0]<'0'||a[0]>'9'||feof(fp))
				break;
			strcpy(spNew->date,a);
			spEnd->next=spNew;
			spEnd=spNew;	
		}
		spEnd->next=NULL;
		int k;
		for(k=0,spt=pNew->ScorepHead->next;spt!=NULL;spt=spt->next,k++)//字符串转整数 
		{	
			for(j=0,num=0;spt->date[j];j++)
				num=num*10+spt->date[j]-'0';	
			sum=sum+num;
			temp[k]++;	
		} 
		pNew->aver=sum/k;	
			
		iCound[filename[5]-'0'-1]++;
		pEnd->next=pNew;
		pEnd=pNew;
	}
	for(i=0;i<Classnum;i++)
			subject[filename[5]-'0'-1][i]=temp[i]; 
	pEnd->next=NULL;
	fclose(fp);
	return pHead;
}

5. 源代码

这个代码中我使用的是cfree建立工程文件的方法
其余编译器不知道是否能够正常运行。
若是要运行查看结果,推荐使用c free
代码地址svg

后续能够进行的优化

1.梳理函数调用关系,让代码更加清晰简洁

2.使用MFc或者Esay_x制做图形化界面。