数据结构课程设计(C语言版)模拟飞机订票系统文档说明
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构课程设计(C语言版)模拟飞机订票系统文档说明
一、问题描述:
试设计一个系统完成对航班的录入,查询,修改,订票,退票操作,航班与客户信息以文件的形式保存。
二、需求分析:
通过此系统可以实现如下功能:
1)录入:可以录入航班情况(数据可以存储在一个数据文件中)。
2)查询:可以查询某个航线的情况(如,输入航班号,查询起降时间,起飞抵达城市,航班票价,票价折扣,确定航班是否满仓);可以输入起飞抵达城市,查询飞机航班情况;3)订票:(订票情况可以存在一个数据文件中,结构自己设定)可以订票,如果该航班已经无票,可以提供相关可选择航班;
4)退票:可退票,退票后修改相关数据文件;客户资料有姓名,证件号,订票数量及航班情况,订单要有编号。
5)修改航班信息:当航班信息改变可以修改航班数据文件
要求:根据以上功能说明,设计航班信息,订票信息的存储结构,设计程序完成功能。
可以建立航班结构体,结构体成员包括航班号、起点站、终点站、飞行时间、预售票总数。
客户结构体成员包括客户姓名、证件号码、订票航班号、订票数额。
三、具体模块划分:
根据需求分析,该程序可分为粗略以下七个模块:
四、代码设计:
该部分包括对数据结构定义的分析,各个主函数的定义分析,关键函数算法的分析。
1、数据结构的定义分析:
struct Flight//定义航班结构体
{
char ID_flight[20]; //航班号
char City_started[20]; //航班起飞城市
char City_landed[20]; //航班抵达城市
char Time_started[10]; //航班起飞时间
char Time_landed[10]; //航班抵达时间
char Price[10]; //航班票价
char Discount[10]; //航班折扣
int flight_num; //航班票额
}airp[n];
struct Guest//定义客户结构体
{
char name[20]; //客户姓名
char ID_guest[20]; //客户证件号
char flight_booking[20]; //客户所定航班
int booking_sv; //客户订单号
int num_booking; //客户所定机票额
}gt[n];
该部分定义了两个结构体数组分别用于存放航班信息、客户信息。
各个数据类型如结构体所示。
说明一:
为什么在航班结构体中票价跟折扣选用字符型而不是浮点型。
因为当选用浮点型时,会出现以下编译错误提示:
忽略后提示出现:
解答:
在CSDN论坛找到以下答案:
用VC ++6.0 编译不通过,最后只好改成字符型代替。
说明二:
为什么选用结构体数组,而不是结构体链表?
当我们使用结构体数组来存储一组信息时,这些信息在内存单元中采用的是顺序存储结构。
当我们要将这些信息写入文件的时候,可对这些信息进行正常的写入读取操作。
而且没有空间的浪费。
当我们采用结构体链表存储时,由于地址是动态分配的,物理位置上没有要求相邻存储。
当对其进行文件的写入与读取时,并不是一件简单的事。
问题一:
当我们把链表中的每个结点作为一个整体块写入文件中时,此时会产生信息的冗余,此冗余就是结构体链表中指向下一个结点的指针所存储的地址。
问题二:
当我们从文件中读取数据重新构造链表的时候,在文件中所存储的指向下个结点的指针中所存储的原来旧有的地址是否会对我们新建的链表造成影响。
假设在文件中存储着多个结点的情况:
第一步:新开辟一个空间,假设这个空间地址为1000,并且作为链表的头结点,在文件中第一组数据中指向下一个结点所存储的指针中的地址为2000,如图所示:
第二步:重新开辟一个空间,地址为1500,令指针q指向其,并且从文件中读取数据。
假设文件中所存储的指针中的地址为3000,如图所示
此时,令P指针所指向的next指针赋值为Q指针所存储的地址,也就是1500。
那么,在头结点存储地址为2000的地方会被重新赋值为1500。
也就是说,这个next指针的值被重写了。
由此可知,在文件中所存储的next指针的值,并不影响在下次读取文件内容进行链表的构造,只能引起文件中所存储数据的冗余。
问题解决:
我们可以分别定义一个结构体链表,令结构体链表中只存在两个指针,其中一个是指向结构体的指针,一个指针作为next指针来使用。
具体实现方式就是定义两个结构体,其中一个是结构体数组,其中一个是结构体链表。
比如:
struct Engineer
{
int num; //工程师编号
int name; //工程师姓名
char sex ; //工程师性别
float salary; //工程师薪水
}
struct link
{
struct Engineer *p
struct link *next
}
具体实现如图所示:
综上所述:结构体链表跟文件之间的存储与读取太麻烦,我还是选择简单的吧!
2.代码设计:
主函数void main()
1、分析:
主函数的功能比较简单,形式比较简洁,主要功能为:调用菜单函数。
程序中的各模块都要用到同一个文件,如果该文件不存在,则该程序就无法正常运行,为了让程序能够方便的回到主函数里,所以就建立了一个菜单函数。
菜单函数的功能是替主函数调用个功能模块函数,因而设计的基本思路很简单,即:用一个输入来接受用户的选择,加以个循环来让输入错误的用户继续输入,直到输入正确为止;用一个switch语句来选择用户所要用到的函数。
2、程序:
参考源代码。
公共函数public function
1.分析:
各功能模块中的分程序中的交错的较多,公共函数使得各功能模块函数显得简洁,使得代码复用性好,实用性强,这是程序的一个特点。
2.程序:
(1)、输入航班信息:void input();
(2)、输出航班信息:void print_plane();
(3)、保存航班信息:void save();
(4)、读入航班信息:void read();
(5)、保存客户信息:void save_gt();
(6)、读入客户信息:void read_gt();
(7)、输出客户信息:void print_gt();
(8)、查询函数:void search_plane();
具体代码参考源程序。
航班、客户基本信息输入模块
1、分析:
航班、客户的基本信息,对它们输入后,要存进原文件,采用fwrite函数就可以实现。
而且以二进制形式进行存储。
在用户输入完成后,程序会询问是否继续输入,这个功能更具人性化,可以省去返回到主函数在进入这个函数的麻烦。
流程图:
2、程序:参考源代码。
航班、客户基本信息输出模块
1、分析:
航班的基本信息,对它们读取后,从写入的文件中读入输出到屏幕上,采用fread函数就可以实现文件的读入。
而且以二进制形式进行读入。
在输出部分采用了定格式输出,将信息逐一输出。
流程图:
2、程序:参考源代码。
航班信息查询模块
1、分析:
基本信息的查询按查询可供选择的方式比较丰富,本模块提供了两种查询方式:按航班号查询,按起飞地点抵达地点查询。
在查询小模块中采用了直接查找的方法。
更多查询方式可以再后续完善。
流程图
2、程序:参考源程序查询模块。
航班信息修改删除模块
1、分析:
这两个模块跟查询模块类似,同样提供两种方式进行修改删除,为了代码的复用性,该两个模块,可以调用查询模块找到相关信息进行相关操作。
流程图:
大致类似查询模块。
2程序:参考源程序修改删除模块。
订票模块
1、分析:
订票模块详细的分了两中订票方式,按航班号订票,按起始抵达地点订票,开始先输入客户的基本信息,然后选择相应的订票方式找到相应的机票,当客户需求的票不满足订票额度时,提示客户重新订票,特别当用户是按起始抵达地点方式订票时,会提示用户确定具体航班号。
当系统没有客户需求的机票时,提供重新选择。
使程序更具人性化。
流程图
2程序:参考订票源程序。
退票模块
1、分析:
退票模块采用订票时随机产生的订单号退票,输入订单号找到相应用户信息,再次输入需要退票的数额,确认都修改客户以及航班信息。
该模块的订单号是由订票模块随机产生的在一定的程度上减少了相关的操作,但是由于是随机产生的并没有检测是否有已有相同的订单号,在以后的优化中有待改进。
流程图:
2、程序:参考源退票源程序。
五、运行与测试:
在第一步编程过程中比较顺利的编写好了各模块,最后整合成了一个完整的程序,但在调试过程中遇到了许多问题。
1、由于粗心导致分号,括号,字母输错的例子很多。
不一一举例,不过这些小错误很快改正。
还有写程序中当调用某个函数时经常忘记头文件包含命令,以及函数声明,导致调试中出现警告。
2、运行中遇到问题。
由于粗心导致输出文件一直增加,程序一直停滞。
输入完一个信息后,当退出时,程序没反应:
结果发现输出的文件N大:
最后查看代码,都是粗心惹祸。
还有一些文件输出冲突的问题,或者输入不正常的问题。
最后经过细心查找,一一解决,从中也得出了细心耐心的重要性。
六、关于程序的改进:
1、由于该程序分模块完成,只有在订票模块中,当有多个航班具有相同的起始点和终点站
时,提供了确认航班信息的选择程序,其他删除修改模块,默认为定位到查找过程中的最后一个航班。
在以后的优化中希望能加以改善。
2、程序并没有对航班的添加删除等相关操作进行加密,使得管理员与用户是同一种入口,
也就是说没有区分开用户跟管理员的具体函数,这个有待改善。
3、在输入用户信息以及航班信息时,没有对输入信息加以控制,这方面,在第二个程序中
有所改进。
4、该程序是在DOS环境下运行,需要多步输入输出处理,希望将程序整合成界面,通过界
面化程序将程序更加人性化。
5、该系统是单机单客户操作,如果嵌入网页,做成B/S多层结构,考虑的问题将更加复杂,
比如涉及到票的冲突,系统资源的冲突等。
七、具体分工:
1、本小组由四名成员组成,其中一名充当队长。
2、队长贯穿整个小软件的整个生命周期,包括需求分析、概要设计、详细设计、运行与测
试,充当领头与决策作用。
3、小组成员认真完成队长分配任务,最后参与各个部分的讨论。
4、初期,队长对整个系统做需求分析,概要分析,将数据结构以及各种数据定义分析清楚,
对整个程序进行鸟瞰,画出各个部分的流程图以及各模块的关系图。
随后,分配小组成员查阅相关图书,参与各个部分的细化讨论,具体细节跟队长讨论。
5、队长分模块给小组成员分配任务,成员在接受任务时,必须向队长汇报自己的不明处,
对自己的该部分充分了解。
各成员在完成任务的过程中如有问题可以查询相关书籍。
同时各小组成员在完成任务中相互交流各自的成果。
如订票系统中:分三大模块:数据的文件存储与读取由一名成员完成,处理模块由两名成员完成,队长完成细化的输入输出部分以及对各个模块的整合。
6、成员定期向队长汇报任务完成情况,如果问题及时讨论解决。
7、队长在整合各个模块时,如有发现数据出错以及各模块交流问题,应跟各模块小组成员
讨论解决。
8、队长对程序进行运行与测试,各小组成员应参与负责的模块测试。
记录测试中出现的错
误,讨论解决方案并对程序进行改进。
9、最后,队长完成程序文档撰写。
另:各小组成员的详细体会参见小组成员报告。