# 成绩记录簿思路讲解
首先对需求进行分析,基本功能要求了最基本的增删查操作,同时拓展功能要求了对文件的io操作,那么针对前者的三项基本操作,我们考虑链表和数组对这些操作的优缺点。
链表:没有现成的数据结构,需要自行编写这一类数据结构并定义合适的组织方式。但是当组织好这类数据结构之后,后续的增添、删除、查询相对方便,而且在数据写入文件时只需要用到类似查询的操作来逐个将数据写入文件中,实现起来难度较低。难点在于如何组织这类数据结构。
数组:有现成的数据结构支撑后续代码的编写,起点相对较高,在增添和查询以及文件操作都非常容易实现,且拥有与链表类似的时间复杂度;但是在删除操作上,我们要知道,如果删除的元素在数组的中间,那么非常容易破坏组织起来的结构,如果要保持这种结构的完整性需要以时间为代价进行修复,也就是说如果删除数组中间的元素,那么处在这个数组元素后面的元素都要往前移动一个单位,这个操作所花费的时间复杂度是O(n)。
那么了解完二者之间的优缺点,很明显在不考虑时间复杂度的情况下,数组的实现难度是相对较低的;但是在数据量十分庞大的时候,明显链表的组织方式更为合理。因此我们考虑采用链表的这一类数据结构来存储数据。
链表的基础原理我不在这里过多赘述,针对我这个代码,我们要了解的就是
链表的每个结点需要包含什么
怎么采用链表实现要求的删除功能
首先第一个问题,分析题目的内容,可以看到是以每个学生为基本单位进行操作的,因此可以把一个学生看作是一个对象Student(重点不在于这个学生对象,而在于怎么有效的清晰的组织这个链表),那么一个结点就代表一个学生,里面包含了一个学生应该具备的基本信息;同时为了方便后续统计,还需要一个计数器count,来统计目前已经存在于系统内的学生个数;除开这些记录特别信息的元素外,还需要一个指向下一个结点的指针next,以将这些无序存放的结点通过一根无形的线串连起来。如此,一个链表就组织好了。
针对实现层面的操作,以下只作简述,只要具备实现这些功能的思路,那么照猫画虎地编写出自己的代码也只是时间问题。
增添操作:
一个结点存储一个学生单位,那么首先需要获取整个学生信息列表里,指向最后一个结点的那个指针,我们暂且记为latest,但是获取到的这个指针latest并不是能直接使用的,我们还需要创建一个新的结点temp,并将获取到的结点指针,也就是latest,把它的next指针重定向为刚刚创建的结点temp,那么这个新创建的结点temp就是记录了空内容的“新学生”了,将用户的输入逐步填入这个temp指针里,存放学生信息的相应部分,再更新最后一个结点的值,使其指向刚才创建的新结点temp,也就是最后latest已经不是最后一个结点了,而是新创建的temp,我们需要把latest的值更改为temp。如此,这个增添操作就完成了。
删除操作:
删除操作要求用户输入合适的学号信息或是姓名信息,然后根据学号与姓名的特征进行区分用户输入的到底是学号还是姓名。获取信息列表的第一个结点的指针,从第一个指针依据其next指针是否为NULL来逐个排查其next指针指向的学生信息是否与用户要找的那个学生一致,换言之,就是我目前处在第n个学生的位置,但我是用第n+1个学生的信息来与用户输入做对比,而不是拿第n个学生的信息来作比较,这么做的目的后面会谈到。那么,一旦我发现二者信息匹配上了,就说明我已经找到了要删除的这个学生。怎么删除呢?很简单,因为我们是利用第n个学生来访问第n+1个学生的信息,也就是说我们目前是处在第n个学生的位置的,我们要删除的是第n+1个学生,因为我们是比较的第n+1个学生的信息和用户输入的信息,第n+1个学生才是需要删除的,我们只要将第n个学生的next指针修改,修改成第n+1个学生的next指针,那么修改完之后第n个学生后面指向的就是第n+2个学生了,第n+1个学生已经被丢弃在了内存中,如此一来,信息列表里就已经没有了与用户输入相匹配的学生了(前提是没有学生的学号或是姓名重复),也就相当于完成了删除操作。
查询单个学生:
查询操作与删除操作十分相似,只是删除操作在遇到信息匹配的学生后停下,并将这个学生删除,但查询操作不需要删除,只要将这个信息打印到屏幕上即可。
查询课程:
查询单个学生是拿其姓名或是学号来比较,查询课程则是根据课程号来比较,其中并没有多大的差异。
文件写入:
相当于从第一个结点开始逐个打印这个结点包含的信息,只是这个打印的目标从屏幕变成了文件。在此需要一个辅助数组buf,我们将一个学生一个学生的把信息存入文件中,其难点在于如何操作文件,以及将buf数组的信息写入到文件,根据代码自行理会即可,没有什么可以深入讲解的。
文件读入:
从文件中读取信息对文件的组织形式有十分严格的要求,文件内容必须规范、标准,以便程序能正确读取。
这里的文件规范是上一步文件写入挂钩的,每一个学生的信息以换行符\n分隔,这样读入时按行读入即可一次读入一个学生的信息。获取到一行,也就是一个学生的信息后,每个独立的信息块以空格进行分隔,因此逐个读取这一行的字符,遇到空格就切换下一个数据块,否则当作这个信息块的一部分内容。举例说明此段:
使用fgets函数读取到的内容为
10020309 defoggre 2 10001 66 2
读第一个字符为'1',不是空白符(空格、换行符、制表符\t),那么就存入Student类型的临时变量temp的sid域内,再读取下一个字符,为'0',同样存入temp的sid内,此时sid里面的内容是'10',重复该步骤,直到遇到第一个空白符,即制表符'\t',此时程序知道读完sid的内容了,它会略过这个空白符,直到遇到下一个非空白符的字符,该例中是字母'd',那么这个'd'会依照程序所写,存入到temp的name域内,再次重复直到遇到"defoggre"后面的空白符'\t',略过空白符,当它再遇到第一个非空白符的字符时(本例中是'2'),他会把这个'2'按数据类型存入temp的ac_credit域内,这个域的含义是表示已经获得的学分,因此这是一个整型数据,'2'是一个char字符,因此若直接将'2'存入ac_credit中会是得到'2'的ASCII码的值50,而非我们所想要的数字2,因此需要作基础的数值转换,将'2'减去0的ASCII码(为48)。后面的操作与前面类似,重复直到遇到读取的这一行的最后一个字符,通常是'\n',这一行的读入便结束了,这一个学生的信息便已经完整的读取并存入到了结点中。
【C语言期末/实践/大作业】成绩管理系统
版权申诉
5星 · 超过95%的资源 173 浏览量
2022-06-27
17:48:01
上传
评论
收藏 7KB ZIP 举报
Zemoey
- 粉丝: 6
- 资源: 5
最新资源
- 课程设计-基于SpringBoot + Mybatis+python爬虫NBA球员数据爬取可视化+源代码+文档+sql+效果图
- 软件品质管理系列二项目策划规范.doc
- 基于TensorFlow+PyQt+GUI的酒店评论情感分析,支持分析本地数据文件和网络爬取数据分析+源代码+文档说明+安装教程
- 软件定义无线电中的模拟电路测试技术.pptx
- 软件开发协议(作为技术开发合同附件).doc
- 软件开发和咨询行业技术趋势分析.pptx
- 软件测试题详解及答案.doc
- 软件漏洞生命周期管理策略.pptx
- 毕业设计-基于Python实现的的简易气温爬虫,可以爬取全国各市的近7日气温数据
- 软件系统测试报告(实用版).doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
前往页