软件工程课程实验报告:实验五
实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
咖啡机《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006
新创建一个目录lab5完成实验。
然后将lab5-1.tar.gz中的代码(即解压后lab5.1/目录下的源文件)直接放到lab5/目录下继续完成后面的实验内容。
一、实验要求
- 给lab5-1.tar.gz找bug,quit命令无法运行的bug
- 利用callback函数参数使Linktable的查询接口更加通用
- 注意接口的信息隐藏
- 及时提交代码以防丢失
二、实验过程
1. 创建lab5文件夹,将lab5-1.tar.gz解压至文件夹下
2. 编译代码并执行,发现quit()
命令无法正确执行
3. 从程序的主入口入手,进行代码审查
- menu.c中的
main()
函数及InitMenuData(tLinkTable ** ppLinktable)
函数
int InitMenuData(tLinkTable ** ppLinktable)
{*ppLinktable = CreateLinkTable();tDataNode* pNode = (tDataNode*)malloc(sizeof(tDataNode));pNode->cmd = "help";pNode->desc = "Menu List:";pNode->handler = Help;AddLinkTableNode(*ppLinktable,(tLinkTableNode *)pNode);pNode = (tDataNode*)malloc(sizeof(tDataNode));pNode->cmd = "version";pNode->desc = "Menu Program V1.0";pNode->handler = NULL; AddLinkTableNode(*ppLinktable,(tLinkTableNode *)pNode);pNode = (tDataNode*)malloc(sizeof(tDataNode));pNode->cmd = "quit";pNode->desc = "Quit from Menu Program V1.0";pNode->handler = Quit; AddLinkTableNode(*ppLinktable,(tLinkTableNode *)pNode);return 0;
}/* menu program */tLinkTable * head = NULL;int main()
{InitMenuData(&head); /* cmd line begins */while(1){printf("Input a cmd number > ");scanf("%s", cmd);tDataNode *p = FindCmd(head, cmd);if( p == NULL){printf("This is a wrong cmd!\n ");continue;}printf("%s - %s\n", p->cmd, p->desc); if(p->handler != NULL) { p->handler();}}
}
可以看到,在main()
中,先初始化命令链表,InitMenuData(tLinkTable ** ppLinktable)
将quit命令的cmd和desc属性赋值。按照main()
的正常运行过程,输入quit,程序的输出应为”Quit from Menu Program v1.0”。
main()
中初始化命令链表之后,便是一个用来等待用户输入命令、并进行相关处理的循环体。在循环中,注意到输入的cmd通过FindCmd()
函数查找命令链表对应的结点p,p不为空时输出结点,p为空时提示错误”This is a Wrong cmd”,这恰与我们目前程序quit的输出相同。因此,错误可能来源于FindCmd()
函数。
- menu.c中的FindCmd()
和 SearchCondition()
函数
int SearchCondition(tLinkTableNode * pLinkTableNode)
{tDataNode * pNode = (tDataNode *)pLinkTableNode;if(strcmp(pNode->cmd, cmd) == 0){
return SUCCESS; }
return FAILURE;
}/* find a cmd in the linklist and return the datanode pointer */
tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
return (tDataNode*)SearchLinkTableNode(head,SearchCondition);
}
在FindCmd()
中可以看到,调用了linktable.c中的SearchLinkTableNode()
函数,其代码如下:
/** Search a LinkTableNode from LinkTable* int Conditon(tLinkTableNode * pNode);*/
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode))
{if(pLinkTable == NULL || Conditon == NULL){return NULL;}tLinkTableNode * pNode = pLinkTable->pHead;while(pNode != pLinkTable->pTail){ if(Conditon(pNode) == SUCCESS){return pNode; }pNode = pNode->pNext;}return NULL;
}
函数中的循环体循环条件while(pNode != pLinkTable->pTail)
使得函数在到达命令链表尾部时,无法退出循环,无法访问最后一个结点。在这个程序中,最后一个结点就是quit命令。因此作以下修改(见代码中注释):
/** Search a LinkTableNode from LinkTable* int Conditon(tLinkTableNode * pNode);*/
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode))
{if(pLinkTable == NULL || Conditon == NULL){return NULL;}tLinkTableNode * pNode = pLinkTable->pHead;//更改循环体条件,当链表结点不为空,便可继续遍历链表寻找命令while(pNode != NULL){ if(Conditon(pNode) == SUCCESS){return pNode; }pNode = pNode->pNext;}return NULL;
}
3. 再次编译运行,发现bug消失
4. 解决数据结构的通用型
- menu.c中
将全局变量cmd[CMD_MAX_LEN]放入main()
函数内
int main()
{InitMenuData(&head);//降低模块间的耦合char cmd[CMD_MAX_LEN]; /* cmd line begins */while(1){printf("Input a cmd number > ");scanf("%s", cmd);tDataNode *p = FindCmd(head, cmd);if( p == NULL){printf("This is a wrong cmd!\n ");continue;}printf("%s - %s\n", p->cmd, p->desc); if(p->handler != NULL) { p->handler();}}
}
修改SearchCondition()
的参数,传入cmd变量。
int SearchCondition(tLinkTableNode * pLinkTableNode,void * args)
{char *cmd = (char *)args;tDataNode * pNode = (tDataNode *)pLinkTableNode;if(strcmp(pNode->cmd, cmd) == 0){return SUCCESS; }return FAILURE;
}
修改FindCmd()
函数:
/* find a cmd in the linklist and return the datanode pointer */
tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
return (tDataNode*)SearchLinkTableNode(head, SearchCondition, (void *) cmd);
}
在linktable.c中修改SearchLinkTableNode()
函数:
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void *args), void * args)
{if(pLinkTable == NULL || Conditon == NULL){return NULL;}tLinkTableNode * pNode = pLinkTable->pHead;while(pNode != NULL){if(Conditon(pNode, args) == SUCCESS){return pNode;}pNode = pNode->pNext;}return NULL;
}
5. 隐藏重要数据结构实现
- linktable.h中
在linktable.h接只提供结构体类型的声明,将结构体类型的定义放在linktable.c中。
/** LinkTable Node Type*/
typedef struct LinkTableNode tLinkTableNode;/** LinkTable Type*/
typedef struct LinkTable tLinkTable;
6. 编译运行
7. 将代码同步到github
Github地址:https://github.com/973301529/se/tree/master/lab5
三、实验总结
通过本次实验,软件开发过程中需要具备模块化思想,掌握了接口函数的作用。对于callback函数进行了简单的实践,体会到了它的优势。
软件工程课程实验报告:实验五相关推荐
- html表单实验结论,web前端开发技术实验报告-实验五
1.长 春 大 学 20 15 2016学年第 二 学期Web前端开发技术 课程实 验 报 告学 院: 计算机科学技术专 业: 软件工程 班 级: 软件14402 学 号: 姓 名: 王 悦 任课教师 ...
- 计算机网络课程设计综合实验,计算机网络课程设计报告实验报告
计算机网络课程设计报告实验报告 (21页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 24.9 积分 中南大学课程设计报告课程:计算机网络课程设计 题目: ...
- Web前端开发技术课程实验报告实验3:Vue路由实验
实验代码:实验3第2题实验参考.rar-互联网文档类资源-CSDN下载 Web前端开发技术课程实验报告 实验3:Vue路由实验 姓名:_ __ _ ___ ___ 班级:_ _ _ ___ _ _ ...
- java程序设计教程实验报告_java程序设计课程--实验报告-实验13.doc
java程序设计课程--实验报告-实验13.doc 还剩 12页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保! 内容要点: ...
- 0145129实验报告(五)
20145129实验报告(五) 实验目的 TCP方式进行网络通讯,实现服务器与客户端. 客户端与服务器连接,并实现数据交互. 实验内容 (一)实现服务器 本次试验,小组中我做服务器. 我将加密算法新建 ...
- 区块链技术与应用实验报告(实验五)
文章目录 区块链技术与应用实验报告(实验五) 关于作者 作者介绍 一.实验目的 二.实验原理简介 三.实验环境 四.实验步骤 1.解压缩即可完成安装. 2. 生成快捷方式 3.修改 bitcoin-q ...
- c语言程序设计第五版实验报告九,C语言程序设计实验报告-实验九.doc
C语言程序设计实验报告-实验九.doc 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会出现我们的网址水印. 3 ...
- 实训报告html前端开发,web前端开发技术实验报告 实验三.doc
web前端开发技术实验报告 实验三.doc (5页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 11.90 积分 长 春 大 学 20 15 - 20 ...
- c语言实验题水仙花数5359,《C语言程序设计》实验报告(实验1-12).doc
<C语言程序设计>实验报告(实验1-12).doc 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会 ...
- 大学计算机张青答案,《大学计算机Ⅰ》实验报告实验一1
<大学计算机Ⅰ>实验报告实验一1 (4页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 广东金融学院实验报告课程名称:大学计算机I ...
最新文章
- ASP.NET 的数据绑定,DataList,Repeater 的绑定示例
- python_day10_并发编程
- 2019年Java程序设计讲课笔记目录
- python3 抽象基类 abc.abstractmethod
- 非标准硬件控制之增加系统API
- 第十篇、微信小程序-view组件
- Google Gson API 介绍与使用
- 你说你会用Companion object?恐怕不是!
- linux 光盘本地yum源,小凡带你搭建本地的光盘yum源
- NOIP2017题解
- cpda数据分析师证书含金量高吗
- 从IOE看云行业的潜力
- 思维的误区:忽视沉默的大多数
- 基于CANoe的ECU Bootloader刷写软件
- python打造最全画地图,可视化数据
- 机器学习: 贝叶斯算法的应用
- python 实现获取与下载网页中图片的四种方案
- 我的python爬虫自学之路
- Python五分钟教你制作一个太阳
- Iframe嵌入页面大小边框和调整
热门文章
- Windows XP优化指南
- 横渡办公室里的银河:一座名为企业智慧屏的桥
- OpenLayers 6 实现仿Echarts风格的动态迁徙图/航班图
- 2019仿笔趣阁小说网站源码(PC版+手机版+APP+采集器+教程)下载
- 基于PyQt5实时曲线绘制源代码和串口调试助手源代码带文件保存加载十六进制显示Python两个工程的源代码
- 史上最简单的Map转List的方式
- xmind2020激活教程_思维导图软件XMind 2020 v10.2.1中文版的官网下载、安装与序列号注册文件激活教程-推荐实用小软件
-亦是美网络...
- 服务器性能测试 iometer 测试io
- 夏普SHARP MX-3508N 一体机驱动
- gson读取json字符串_用Gson解析json文件