实验四:用可重用的链表模块来实现命令行菜单小程序V2.5

来源:互联网 发布:ubuntu 启动器 图标 编辑:程序博客网 时间:2024/06/01 23:27

“软件工程(C编码实践篇)”实验报告
实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
网易云课堂昵称:Arjen0130
《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006
GitHub仓库:https://github.com/Arjen0130/AdvancedSoftwareEngineering.git
实验报告原链接地址:http://note.youdao.com/noteshare?id=34e9c5ee0afe055b2b83b5501c6fcd95&sub=503CCB201F82416FB6780968CA6AE688
1. 实验内容和要求
1.1 实验内容
用可重用的链表模块来实现命令行菜单小程序V2.5
1.2 实验要求
用可重用的链表模块来实现命令行菜单小程序,执行某个命令时调用一个特定的函数作为执行动作;
链表模块的接口设计要足够通用,命令行菜单小程序的功能保持不变;
可以将通用的Linktable模块集成到我们的menu程序中;
接口规范。
2. 实验的思路和具体过程
2.1 实验的思路
看完实验四的相关学习视频以后,初步了解了可重用链表模块的设计方法。依照视频讲解,在制定完成链表模块的各个函数接口以后,就可以用链表模块替换掉实验三中的顺序表接口,从而完成本次实验。
2.2 实验的具体过程
1)使用实验1中创建好的本地仓库,添加lab4文件夹,并在lab4目录下创建、编写相关的头文件以及源文件。期间,根据实际需要,会重用前面实验编写好的相关代码文件;
2)创建、编写相关文件的过程中,完成可重用链表模块的相关代码为主要工作内容;将实验3中的顺序表替换为可重用链表为次主要工作内容;
3)编译通过后,进行测试。待测试通过之后,将步骤1)、2)中完成的头文件和源文件提交到本地仓库;
4)将本地仓库的变化更新到GitHub远端仓库。
3. 关键代码
3.1 main函数关键代码
... ...typedef struct CmdInfo{    char * cmd;    char * desc;    void (*handler)();}tCmdInfo;tLinkTable * pLinkTable = NULL;tDataNode * head = NULL;tCmdInfo cmdInfo[CMD_NUM] ={    {"help", "this is help cmd", help},    {"read", "this is read cmd", read},    {"write", "this is write cmd", write},    {"get", "this is get cmd", get},    {"pull", "this is pull cmd", pull},    {"push", "this is push cmd", push},    {"compare", "this is compare cmd", compare},    {"put", "this is put cmd", put},    {"quit", "this is quit cmd", quit}};/* * Initialize the pLinkTable with the menu command */void InitMenuTable(tLinkTable * pLinkTable);int main(){    pLinkTable = CreateLinkTable();    if(NULL == pLinkTable)    {        printf("CreateLinkTable Error...\n");        exit(1);    }    InitMenuTable(pLinkTable);    head = (tDataNode *)pLinkTable->pHead;    char cCmd[CMD_MAX_LEN];    while(1)    {        printf("Input a cmd > ");        scanf("%s", cCmd);        tDataNode *p = FindCmd(head, cCmd);        if (NULL == p)        {            printf("Undefined command...\n");            continue;        }        printf("%s - %s\n", p->cmd, p->desc);        if(NULL != p->handler)        {            p->handler();        }    }    return 0;}/* * Initialize the pLinkTable with the menu command */void InitMenuTable(tLinkTable * pLinkTable){    for(int i = 0; i < CMD_NUM; i++)    {        tDataNode * pNode = (tDataNode *)malloc(sizeof(tDataNode));        if(NULL == pNode)        {            printf("malloc Error...\n");            exit(1);        }        pNode->cmd = (cmdInfo[i]).cmd;        pNode->desc = (cmdInfo[i]).desc;        pNode->handler = (cmdInfo[i]).handler;        if(1 == AddLinkTableNode(pLinkTable, (tLinkTableNode *) pNode))        {            printf("AddLinkTableNode Error...\n");            exit(1);        }    }}
3.2 可重用链表模块关键代码
/* * Create a LinkTable * return value: If success, return the poiner points to the created LinkTable, otherwise return NULL */tLinkTable * CreateLinkTable(){    tLinkTable * p = (tLinkTable *)malloc(sizeof(tLinkTable));    if(NULL == p)        return NULL;    p->pHead = NULL;    p->pTail = NULL;    p->sumOfNode = 0;    return p;}/* * Delete a LinkTable, and free the memory * return value: Always zero */int DeleteLinkTable(tLinkTable * pLinkTable){    if(NULL == pLinkTable)        return 0;    tLinkTableNode * pNode = pLinkTable->pHead;    tLinkTableNode * pHead = pNode;    while(NULL != pNode)    {        pHead = pHead->pNext;        free(pNode);        pNode = pHead;    }    free(pLinkTable);    return 0;}/* * Add a LinkTableNode to LinkTable * return value: If success, return zero, otherwise return one */int AddLinkTableNode(tLinkTable * pLinkTable, tLinkTableNode * pNode){    if((NULL == pLinkTable) || (NULL == pNode))        return 1;    tLinkTableNode * pHead = pLinkTable->pHead;    tLinkTableNode * pTail = pLinkTable->pTail;    pNode->pNext = NULL;    if(NULL == pHead)    {        pLinkTable->pHead = pLinkTable->pTail = pNode;    }    else    {        pLinkTable->pTail->pNext = pNode;        pLinkTable->pTail = pNode;    }    pLinkTable->sumOfNode += 1;    return 0;}
注:与实验3相比,实验4的其余部分改动很小或基本没有改动。
4. 相关截图
4.1 实验结果截图

注:每一条命令执行后,共打印出来两行提示信息。其中,第一行为命令的描述信息;第二行为命令函数执行后,函数体内printf函数的打印信息。
4.2 关键代码截图

















4.3 操作过程截图
4.3.1 创建的各个头文件和源文件

4.3.2 将工作目录中的文件添加并提交到Git本地仓库

4.3.3 将本地仓库的变化提交到远端仓库



4.4 复现操作截图

5. 实验过程中遇到的疑惑、困难及处理方法
本次实验过程,主要的困难还在于对可重用链表模块相关代码的编写与调试。特别是C语言中与指针相关部分的处理,如果对指针的使用不当,虽然编译、链接都可以通过,但测试过程中很容易发生段错误问题。遇到这种情况时,可以使用GDB调试工具对代码进行调试,在调试过程中可以监视相关变量的值的变化,进而可以判断出程序代码中哪里出现了问题。
6. 实验总结
通过本次实验,学习了可重用链表的实现方法,同时,也初步练习了GDB调试工具的使用。

阅读全文
0 0