学生成绩管理实习报告.docx
《学生成绩管理实习报告.docx》由会员分享,可在线阅读,更多相关《学生成绩管理实习报告.docx(17页珍藏版)》请在冰豆网上搜索。
学生成绩管理实习报告
计算机实习报告
●选题任务:
学生成绩管理
主要功能
(1)能按学期、按班级完成对学生成绩的录入、修改
(2)能按班级统计学生的成绩,求学生的总分及平均分,并能根据学生的平均成绩进行排序
(3)能查询学生成绩,不及格科目及学生名单
(4)能按班级输出学生的成绩单
(5)能将输入的数据以文件的形式存盘
(6)能将原来已经存盘的文件读入内存,进行管理
能实现以上基本功能,界面友好、清晰
●设计思想:
要想用C语言模拟数据库表文件进行对文件的增删改操作,我首先想到用链表存储结构。
因为如果采用数组存储结构或采用顺序表存储结构,在删除和增加新的数据时需要移动插入点后面的所有数据记录,当所存储的数据相当多而且要增加或删除的数据不在存储的结尾的话,将需要大量的时间进行数据的挪动,这需要计算机进行大量的运算并耗时较久,对日后繁多的数据进行增删修改维护时带来极大的不便。
相反采用链表存储结构,每次增删操作只需要修改节点指针的指向即可,不管存了多少数据都不需要挪动任何数据,既方便又快捷,而且易于实现和快速操作。
要想库表存放的每个学生数据项包括:
学号,姓名,性别,年龄和奖学金等内容,我想到建立一个名为student的结构,里面相对应的设以下变量:
num(学号),name(姓名),sex(性别),age(年龄),prize(奖学金),score(成绩)。
增加和删除只要修改被操作节点的指针指向即可实现,修改节点数据也只需要把该节点存放的内容调出来,然后重新输入,覆盖之前的内容再存回去即可实现。
具体的程序代码和实现过程如下:
1.我选用的链表存储结构是:
单链表动态分配存储结构,以及考虑到将要进行的操作,头文件及存储结构体如下:
#include"stdio.h"
#include"iostream.h"
#include"malloc.h"
#include"iomanip.h"/*为使用控制符setw提供头文件*/
#include"string.h"
#defineNULL0
#defineLENsizeof(structstudent)
structstudent{/*建立一个学生数据的结构体*/
longnum;
charname[20];
charsex[4];
intage;
floatscore;
intprize;
structstudent*next;
};
2.我建立的调用函数如下:
structstudent*creat(void)/*定义建立新表的函数,此函数带回一个指向链表头节点的指针*/
structstudent*del(structstudent*head,longnum)/*按指定的学号删除对应的记录数据*/
structstudent*insert(structstudent*head,structstudent*stud)/*增加新的记录数据*/
structstudent*modify(structstudent*head)/*修改已有的记录数据*/
voidlocate_num(structstudent*head,longnum)/*依指定的学号进行查询*/
voidlocate_name(structstudent*head,charname[20])/*依指定的姓名进行查询*/
voidprint(structstudent*head)/*输出记录数据*/
voidexchange(structstudent*p1,structstudent*p2)/*交换两节点间的记录数据*/
structstudent*sort_num(structstudent*head,intk)/*按学号升序排列*/
structstudent*sort_name(structstudent*head,intk)/*按姓名升序排列*/
structstudent*sort_age(structstudent*head,intk)/*按年龄升序排列*/
structstudent*sort_score(structstudent*head,intk)/*按成绩升序排列*/
structstudent*sort_prize(structstudent*head,intk)/*按获奖情况升序排列*/
voidsave(structstudent*head,intk)/*保存输入的所有记录数据*/
voidopen_file(structstudent*head,intk)/*打开已保存的所有记录数据*/
voidmain()
●程序框图:
1.我的主函数main()的程序框图如下:
2.①连接的是各排序输出函数,流程图如下所示:
而每一种排序输出的流程图如下(已默认排序——学号排序为例,其余同):
3.②连接的是删除节点数据的函数:
思路大体如下:
从p指向的第一个节点开始,检查该节点中的num值是否等于输入的要求删除的那个学号。
如果相等就将该节点删除,如不相等,就将p后移一个节点,再如此进行下去,直到遇到表尾为止。
4.③连接的是插入节点数据的函数,流程图如下所示:
5.④连接的是查询已有记录的函数,流程图如下所示:
而所被调用的locatenum()和locatename()函数的流程图如下所示:
以学号查询locatenum()为例,locatename()同
6.⑤连接的是修改节点数据的函数,流程图如下所示:
7.⑥连接的是打开文件的函数,流程图如下:
8.⑦连接的是保存文件的函数,流程图如下:
●对程序进行调试,其调试结果如下:
首先,界面应该显示相关的管理界面,例如:
选择操作1,按提示输入学生信息,例如:
如果想退出,则学号输入0,界面显示:
若选择操作1,则界面显示如下:
按需要选择操作,如果选1,则界面显示:
按需要选择操作,如果选6,则界面显示:
如果想退出系统,则界面显示:
●总结:
1.问题及解决方法:
我实验的主要问题有两个方面:
首先是对链表的插入操作。
对链表的插入是将一个节点插入到一个已有的链表中。
为了能正确插入,必须解决两个问题:
怎样找到插入的位置;
怎样实现插入。
我是这样做的:
先用指针变量p0指向待插入的节点,p1指向第一个节点。
将p0->num与p1->num相比较,如果p0->num>p1->num,则待插入的节点不应插在p1所指的节点之前。
此时将p1后移,并使p2指向刚才p1所指的节点。
再将p1->num与p0->num比。
如果仍然是p0->num大,则应使p1继续后移,直到p0->nump<=p1->num为止。
这时将p0所指的节点插到p1所指节点之前。
但是如果p1所指的已是表尾节点,则p1不再后移。
如果p0->num比所有节点的num都大,则应将p0所指的节点插到链表表尾。
如果插入的位置既不在第一个节点之前,又不在表尾节点之后,则将p0的值赋给p2->next,使p2->next指向待插入的节点,然后将p1的值赋给p0->next,使得p0->next指向p1指向的变量。
这时,在第一个节点和第二个节点之间已插入了一个新节点。
如果插入位置为第一个节点之前(即p1等于head时),则将p0赋给head,将p1赋给p0->next.如果要插到表尾之后,应将p0赋给p1->next,NULL赋给p0->next.
其次是在main函数调用insert()时出现死循环,最后究其原因在于:
stu是有一个固定地址的结构体变量。
第一次把stu节点插入到链表中。
第二次再用它来插入到第二个节点,就把第一次节点的数据冲掉了。
实际上并没有开辟两个节点。
为了解决这个问题,必须在每插入一个节点是新开辟一个内存区。
此后能删除多个节点直到输入要删的学号为0,能插入多个节点直到输入要插入的学号为0。
2.总结:
回顾五天的实验时间,我觉得还是时间太少不够用,迫于时间紧迫和掌握的知识有限,而不能在实验结束前更好的完成自己的程序,但我没有打算实验结束后就停止对程序的完成,我决定在往后的日子里,我将会运用自己不断学到的新知识来使我的设计更加智能和人性化。
●参考资料:
C程序设计(第二版)清华大学出版社谭浩强著
数据结构(C语言版)清华大学出版社严薇敏吴伟民著
二〇〇六年
九月十四日