停车场管理系统课程设计总结免取卡停车场管理

  华 北 科 技 学 院 课程设计说明书 专 业: xxxxx 课程名称: 数据结构课程设计 班级: xxxx 姓 名: xxx 学号: xxxxxx 设计题目: 停车场管理系统 设计时间: 2012-2-27 至 2012-3-9 评 语:_________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ 评阅成绩:____________评阅教师:____________ 一、 设计题目与要求 停车场管理系统 设停车场只有一个可停放几辆车的狭长通道, 且只有一个大门可供汽车进出, 汽车在停车场内按车辆的先后顺序依次排列, 若车站内已停满汽车, 则后来的汽车只能在门外的通道上等停, 一旦停车场内有车开走, 则排在同道上的第一辆车即可进入, 当停车内某辆车要离开时, 由于停车场是狭长的通道, 在它之后开入的车辆必须先退出车站不能从便道上开走, 试设计这样一个停车场模拟管理程序。 二、 概要设计 程序包括以下几个模块(包括其功能及程序实现思路与方法) 1、 成批车辆入站时信息的记录。 该功能则是将成批车辆入站, 并且记录下信息。 已知车场为一个开口的狭长通道, 所以信息采用栈来记录。 因为针对的是成批车辆, 则在输入信息的时候采用循环输入, 以输入特殊字符为结束符号。 在程序设计的时候, 除了 要完成循环, 还要完成特殊字符的判断及车场是否已经停满的判断。 2、 单辆车辆入站时车站的记录。 单辆车辆入站的实现思路与方法与成批入站的相差无几, 主要区别在于车辆车不需要循环。 3、 在车站已满的情况下, 将车辆停在通道里。 车站有固定容量, 当车站停满车后, 车辆先放置在通道中。 通道是一个两头开口的狭长通道, 而且当车站有空位时, 通道中第一辆车要进入车站, 则是先进先出的原则, 所以采用队列的形式记录通道内车辆的信息。 4、 能显示出当前车站及通道内车辆的信息。 车站及通道内车辆的信息显示, 使管理者更方便的查看车站内车辆情况。程序设计时采用循环遍历输出, 将车辆信息显示出来。 5、 车辆出站的同时, 通道里第一辆车能进车站。 由于车站是狭长单开口的, 所以当其中一辆车要出站时, 必须将其后面的车先移出来, 车出站后, 再把移出来的车按先前的顺序放回去, 在把通道里第一辆车放在车站最后一个位置。 由上可知, 要把成批的车辆移出来再按顺序移进去, 符合先进后出的原则, 设计时需要建立一个临时栈, 将这些车先放入临时栈中, 待所要车出站后, 再把车从临时栈里出来, 进入到车场的栈中去。 6、 能设置车场的容量。 根据不同实际情况, 车场实际容量也不一样, 所以这个函数能使程序适用 三、 算法设计 存储结构设计: 运用三个结构体, 分别是车辆信息结构体, 栈的结构体,队列的结构体。 因为车辆信息, 栈和队列都包含了 很多信息, 所以用结构体绑定。 此外栈和队列的信息中还包含了车辆信息, 运用结构体, 可以明确的表示出信息的出处。 1. 几个小函数。 停车管理系统 车辆成批入站 单辆车入站 车辆出站 显示车辆信息 设置车场 (1) InitStack(Stack *s) 初始化一个Stack类型的, 叫做s的栈。 (2) InitQueue(Queue *Q) 初始化一个Queue类型的, 叫做Q的队列。 (3) Push(Stack *s, Car x) 将car类型的x中的数据放到stack类型的栈s里。 其中用if语句先判断栈是否已满。 (4) Pop(Stack *s, Car *px) 将栈s里的数据放到px的指针中。 其中先用if语句判断栈是否是空的。 需要提一句的是, 当栈非空的时候, 栈顶位置先移向上一个, 然后把先前位置的数据给px。 代码中用*px=s-data[s-top+1]表示, 很方便。 (5) DeleteQueue(Queue *Q, Car *x) 将队列Q中某个位置的数据删除,即把该数据给x, 然后下移一个位置。 2、 主函数。 这个程序中的主函数比较简单, 在排除一些可能导致的错误之后, 初始化栈和队列, 调用菜单函数carmenu() 。 4、 菜单函数 菜单函数比较简单, 就是在输出提示语句后, 用switch语句选择。 选择的system(color e)将显示界面的字改成黄色 栈的空间为空 是 否 输出 “失败!” 退出 队列的空间为空 是 空 输出 初始化栈 失败! 初始化队列 跳出菜单 退出 退出 内容为几个功能模块, 分别为相应的函数。 6、 I ni tCarpark() 成批车辆入站函数 循环输入方法如下, 每输入一个信息, 将其与结束符号作对比, 如果不是结束符号, 则再次输入。 7、 I nsertCar() 单辆车入站函数 信息输入方式与InitCarpark() 函数相同, 只是把循环略去。 8、 ExitCar(void) 车辆出站函数 定义好循环变量, 临时变量, 将开关标志flag==0后。 程序会先判断车场是否为空。 在车场非空的条件下, 根据提示输入要退出车辆的车牌号, 然后开始循环,将输入车牌号与车场内的车辆的车牌号从第一辆开始对比。 如果找到相同的, 把位置i赋给position, 并将开关标志flag==1。 如果完成循环, 都没有找到, 则flag依然是0, 将会输出提示语句“车辆为找到”。 如果flag==1, 则建立一个临时栈,将该位置以后的车辆从最后一辆依次放入临时栈中。 当该位置的信息删除后, 再将临时栈里的车辆再依次放回。 并且把通道里第一辆车放入车场内。 流程图如下。 输入车辆信息, 以/ /结束 scanf(%s%s,pnum,pname) 当输入数字不为 / 时 将输入数字复制在 pcar.num 将输入字符串复制在Push(SCar,pcar)==-1 是 否 车站已满, 已进入通道! getch() scanf InsertQueue(QCar,pcar) (%s %s ==-1 是 否 pnum, 停入通道失败! 退出 pname) 显示菜单 9、 ShowCar() 显示车辆信息函数 显示信息的函数原理都大致相同, 即循环输出语句。 循环输出前, 先对栈和队列是否非空的情况进行判断, 避免因为栈或队列的空导致的问题。 10、 SetCar() 设置车场容量函数 这个函数比较简单, 输入所要改变的数据之后, 进行循环。 并把值赋给循环后的n。 在循环中加入一个开关变量做标志。 以此来判断是否编辑成功。 栈为空 是 否 请输入车牌号 scanf(%s,pnum) i=0; iSCar-top+1 输入数字与 i 位置处车辆车牌号相等 是 否 记下 flag=1 i, 并 是 否 将 flag 初始化栈 s =1 i=SCar-top;iposition 车辆 未找到 将车场中 i 后面的数据放入 x 将 x 中的数据放入栈 s 中 显示 菜单 将 i 位置的数据放入另外一个 x 中 s 栈非空 将 s 中的数据放入 x 将 x 中的数据放入车场中 队列非空 是 否 提取第一个数据 输出退出成功; 将这个数据放入 显示菜单 车场中 车场为空 显示菜单 四、 运行结果和调试分析 1、 程序开始的时候, 出现菜单界面, 如果输入菜单选项以外的数字, 则出现车场为空。 2、 菜单界面会自动跳出, 然后选择1, 车辆成批入站。 程序一开始不会显示输入数字, 我觉得显示出来比较清晰。 输入车辆信息,“车牌号(空格) 司机姓名”。 然后输入“/(空格) /” 表示输入结束。 原来的特殊符号为“*” 但是“*” 不如“/” 输入方便, 所以改了。 3、 成批输入结束后, 选择4显示车辆信息。 因为车场未满, 所以没有显示通道内的信息。 可以在此加入通道显示通道里的显示。 4、 选择2, 单辆车入站, 只需要输入信息再选择4查看, 刚才输入的车辆信息已经在车场里了。 5、 现在测试设置车场的函数。 选择5之后, 输入一个小于当前车辆数(4)的数, 比如2, 则出现提示语句错误。 重新编辑, 为了测试通道的作用, 则将最大容量改成4, 4为合理数据, 所以提示语句编辑成功。 6、 然后选择2进行单辆车入站, 测试通道作用。 提示“车站已满, 已进入通道!” 然后选择4显示信息, 发现车辆已停入通道。 7、 车辆出站, 选择3, 输入一个不属于已知车辆信息的信息(ahe1006), 会提示“车辆未找到”, 于是重新选择3, 输入一辆在车场内的车辆信息(ahe1002), 显示 “退出成功”, 然后选择4查看, 发现ahe1002已经退出, 而通道内的车 (ahe1005)已经进入车场。 这个程序还有要改进的地方, 比如车辆退出成功后自动跳出显示车辆的信息的函数, 可以让程序使用者更直观的判断车辆是否退出成功。 五、 总结体会 通过数据结构课程设计, 明显感觉到比之前数据结构的大实验要更难, 要求掌握的只是点也更多, 更扎实。 做完设计后, 有以下几点收获: 1、 结构体的优点。免取卡停车场管理系统方案 这次程序中, 运用到很多结构体。停车场管理系统课程设计总结 在我看来, 结构体像一根绳子, 把有关的信息都捆绑在一起, 贴上一个标签, 哪里要用到这些信息, 就把标签名字输入, 这些信息就跟着到了 。 其中感触最深的是车辆信息的结构体设计。 车辆信息包括车牌号和司机姓名。 几乎在所有的函数中都用到了 。 并且栈和队列的结构体设计中, 巧妙的把车结构体放进去了, 这样无论是栈还是队列, 想要找到其中车辆的信息, 就方便很多。 这个程序是个小型应用程序, 如果需要更大的信息量, 比如加车型, 入站时间, 收费统计等与车绑定在一起的信息, 就更能显示出单独把车辆信息设计成结构体的优越性。 2、 对栈和队列的更深层次的理解。 以前做实验, 都是栈和队列分开来应用,这次根据题目要求, 充分利用了 栈和队列各自的特性, 讲其放在一起, 又互相弥补了 对方的不足, 使程序更加方便。 而且在这个程序中, 几乎每个函数都先预计了 栈空栈满, 队列空队列满的情况, 保证程序的正常运行。 掌握每种线性结构的优点, 在以后的程序设计中运用起来也更得心应手。 我也通过这次课程设计知道了, 数据结构中的知识点一定要通过实践, 才能更好的记住。 3、 临时栈的设计。 最初接触到程序的代码, 觉得临时栈的设计是这个程序的一大亮点。 临时栈用在了车辆出站的设计中, 假设要出站车辆为A, 这个临时栈出色的完成了A后面车辆的临时储存和再次入车站的任务。另外在临时栈的设计过程中, 还运用了两个小函数(pop和push) 作为第三方, 这在以前的试验中都是没有遇到过的。 我觉得第三方的运用使整个出站函数更加明朗简洁化。 因为每辆车都包含了 大量信息, 在信息交换替代过程中, 容易出现大的偏差。 第三方像一个临时站点, 把所用信息先存入进去, 等栈或队列准备就绪后, 再把信息存入, 有条有理, 易理解。 4、 将菜单单独做一个函数。 这次可能设计算是一个小型应用软件, 不像以前的实验。 将菜单单独做成一个函数, 可以在任意函数中进行调用, 就是说, 每完成一个功能, 都会将菜单显示出来, 给了使用者重新选择功能的机会。 程序应用起来会更加便利。 5、 小函数的调用。 这个程序的函数调用十分灵活, 纵观大函数, 在选择语句, 循环语句中都有小函数的身影。 我觉得这是一个新颖的设计思路。 当某种运作方式需要重复的时候, 可以将这个功能做成一个小函数, 重复使用的时候只需要调用该函数就可以了 。 在这个程序中的小函数只是几行简单的代码, 如果不用小函数, 直接将代码添加进去也不是不可以, 只不过这样一来, 整个代码就显得冗长, 没有做到简洁明了 。 而且若是需要重复的功能代码比较长, 小函数的优势就很明显了。 6、 将成批车辆和单辆车入站做成两个函数。 光看代码, 前者不过在后者的基础上加了 个循环, 看似简单, 作用却很大。 如果没有成批入站的设计, 那么输入一辆车的信息后想要再输入信息, 就要不停的在菜单界面和输入信息界面转换, 显示繁琐。 如果没有单辆入站的设计, 那么想单辆入站的时候, 每输入一个信息就要写一遍结束语句的特殊符号, 使用起来不人性化。 如此一个程序, 运行的时候肯定有很多问题的。 其中最令人困惑的是在车辆出站这个函数运行的时候, 在输入车牌号后, 直接跳出了程序。 解决这个问题的时候, 我学到了 很多方法(以下方法名都是我归纳的, 若有不当之处, 请见谅)。 1、 逐步分割法。 因为输入车牌号后就会跳出程序, 而代码中没有标志性语句, 所以很难判断, 是哪一句代码, 即程序运行到哪一步出的问题。 所以在老师的指导下, 在不同位置插入内容不同的输出语句, 比如: printf( “aaaaaa”)。 这些输出语句把代码一点一点分割开来, 运行程序的时候, 显示出多少输出语句就表明程序运行到哪里。 问题就比较容易找到了。 2、 输出检测法。 通过上述方法虽然解决了程序运行顺利与否的问题, 但是运行结果依然有问题, 即我输入任何以停车辆的车牌号, 都是退出车场内最后一辆车, 我以为是循环的问题, 可能没有通过循环对比就直接退出了 最后一辆车。 所以同学建议我在循环结束的地方加了一个输出循环变量i的值, 运行结 果表明循环是完成了 的, 只是退出的仍然是最后一辆。 虽然这个方法没有解决问题, 但是我觉得这个同学的思路有让我学习的地方。 输出循环变量可以很有效的检测到循环是否完成, 在以后的程序设计中很有帮助。 3、 文图解说法。 我对着代码看很久, 还是不明白问题出在哪里, 然后请教老师。 老师根据代码的顺序和要求, 将栈用图的形式画出来, 无论是车场栈还是临时栈都得到了 很好的体现, 才发现是某个小函数中将临时栈的名字写成了 车场栈的名字, 导致程序运行结果不对。 我觉得把图画出来了 以后, 原来很抽象的代码立马变得清晰了 , 然后根据程序设计思路, 很轻易的就发现问题所在。 实在是一个很好的方法。 4、 函数替代法。这个方法是我在和同学交流课程设计的时候总结出来的,原来的函数是gets()。 就是输入一串字符串, 可以把回车当成字符。 只要调用了 这个函数的大函数都不能运行, 直接跳出了程序。 我们上网查了 资料, 核对了 头文件及应用范围, 都显示没有问题。 我就想反正都是输入一串字符, 不如用scanf( “%s”) 语句, 换用之后, 问题就解决了, 虽然不知道为什么用原始的函数不可以, 好在问题还是解决了。 数据结构课程设计是在《数据结构B》 和《C语言》 的基础上, 实践性强的一门课。 这两个礼拜的上机, 从确定课题, 查找代码, 调试程序, 理解代码,停车场管理系统程序 写报告。 实在是受益匪浅, 为我以后程序设计方面奠定了 理论和实践的基础。