咖啡机《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006
新创建一个目录lab4完成实验。
// 防止重复定义
#ifndef _LINK_TABLE_H_
#define _LINK_TABLE_H_
#define SUCCESS 0
#define FAILURE (-1)
// LinkTable Node Type
typedef struct LinkTableNode
{
struct LinkTableNode * pNext;
} tLinkTableNode;
// LinkTable Type
typedef struct LinkTable
{
tLinkTableNode *pHead;
tLinkTableNode *pTail;
int SumOfNode;
} tLinkTable;
// Interface
// Create a LinkTable
tLinkTable * CreateLinkTable();
// Delete
int DeleteLinkTable(tLinkTable *pLinkTable);
// Add a Node to LinkTable
int AddLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode * pNode);
// Delete a Node from LinkTable
int DelLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode * pNode);
// Get LinkTableHead
tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable);
// Get next LinkTableNode
tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode * pNode);
#endif // !_LINK_TABLE_H_
#include <stdio.h>
#include <stdlib.h>
#include "linkable.h"
// Create a LinkTable
tLinkTable * CreateLinkTable()
{
tLinkTable *pTable = (tLinkTable*)malloc(sizeof(tLinkTable));
pTable->pHead = NULL;
pTable->pTail = NULL;
pTable->SumOfNode = 0;
return pTable;
}
// Delete
int DeleteLinkTable(tLinkTable *pLinkTable)
{
free(pLinkTable);
return 0;
}
// Add a Node to LinkTable
int AddLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode * pNode)
{
if (pLinkTable == NULL)
{
printf("The table is empty!\n");
exit(0);
}
if (pNode == NULL)
{
printf("The node is empty!\n");
return 0;
}
if (pLinkTable->pHead == NULL)
{
pLinkTable->pHead = pNode;
pLinkTable->pTail = pNode;
pLinkTable->pTail->pNext = NULL;
pLinkTable->SumOfNode = 1;
}
else
{
pLinkTable->pTail->pNext = pNode;
pLinkTable->pTail = pNode;
pLinkTable->pTail->pNext = NULL;
pLinkTable->SumOfNode++;
}
return 0;
}
// Get LinkTableHead
tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable)
{
if (pLinkTable == NULL)
{
printf("The table is empty!\n");
exit(0);
}
return pLinkTable->pHead;
}
// Get next LinkTableNode
tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode * pNode)
{
if (pLinkTable == NULL)
{
printf("The table is empty!\n");
exit(0);
}
if (pNode == NULL)
{
printf("The node is empty!\n");
exit(0);
}
return pNode->pNext;
}
int main ()
{
InitMenuData(&head);
info();
printf("Plesea input a command:\n");
while(1)
{
char cmd[CMD_MAX_LEN];
printf(">>>");
scanf("%s",cmd);
tDataNode *p = FindCmd(head,cmd);
if (p == NULL)
{
printf("Error: Wrong command!\n");
printf("Type 'info' for available commands.\n");
continue;
}
printf("%s - %s\n", p->cmd, p->desc);
if (p->handler != NULL)
{
p->handler();
}
}
return 0;
}
集成在menu.c中的linktable:
#define CMD_MAX_LEN 128
#define DESC_LEN 1024
#define CMD_NUM 20
//定义命令结构体
typedef struct DataNode
{
tLinkTableNode *pNext;
char* cmd; //commands
char* desc; //Descriptions of commands
int (*handler)();
struct DataNode *next;
}tDataNode;
//从链表头部开始寻找指定命令
tDataNode *FindCmd(tLinkTable *head, char *cmd)
{
tDataNode* pNode=(tDataNode*)GetLinkTableHead(head);
while(pNode != NULL)
{
if(strcmp(pNode->cmd,cmd) == 0)
{
return pNode;
}
pNode=(tDataNode*)GetNextLinkTableNode(head,(tLinkTableNode*)pNode);
}
return NULL;
}
//显示所有指令
int ShowAllCmd(tLinkTable* head)
{
tDataNode *pNode=(tDataNode*)GetLinkTableHead(head);
while(pNode !=NULL)
{
printf("%s - %s\n",pNode->cmd,pNode->desc);
pNode =(tDataNode*)GetNextLinkTableNode(head,(tLinkTableNode*)pNode);
}
return 0;
}
//初始化命令菜单
int InitMenuData(tLinkTable ** ppLinkTable)
{
*ppLinkTable=CreateLinkTable();
tDataNode* pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="info";
pNode->desc="Command Informations";
pNode->handler=info;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="quit";
pNode->desc="close this program";
pNode->handler=quit;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="plus";
pNode->desc="result of a + b";
pNode->handler=plus;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="minus";
pNode->desc="result of a - b";
pNode->handler=minus;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="multiply";
pNode->desc="result of a * b";
pNode->handler=multiply;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="divide";
pNode->desc="result of a / b";
pNode->handler=divide;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="power";
pNode->desc="result of a ^ b";
pNode->handler=power;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="square";
pNode->desc="result of the square root of a";
pNode->handler=square;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="factorial";
pNode->desc="result of a!";
pNode->handler=factorial;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="absolute";
pNode->desc="result of |a|";
pNode->handler=absolute;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
return 0;
}
tLinkTable* head=NULL;
菜单命令包括以下9种:
- 介绍命令信息info()
- 加法运算plus()
- 减法运算minus()
- 乘法运算multiply()
- 除法运算divide()
- 幂运算power()
- 平方根运算square()
- 阶乘运算factorial()
- 绝对值运算absolute()
- 退出quit()
限制于报告篇幅,以上命令的具体实现代码就不在文中贴出,烦请移步github工程中查看。
https://github.com/973301529/se/tree/master/lab4
本次实验在上次实验的基础上更进一步,对可重用的链表模块来实现命令行菜单小程序进行实验,更加熟悉了链表的相关知识,并学习了链表模块的接口设计,初步了解了接口设计。在此次实验中,也感受到了自己在链表设计中的不足,以后的学习中会更加注重链表的学习。