软件工程实验四
实验目的
利用可重用的链表来改写我们在lab3中的命令行小程序,定义借口,进一步增加代码的复用率。
实验过程
1.在github上创建一个名为se_lab4的仓库,用git命令导入到本地仓库
2.分别创建menu.c linktable.c linktable.h linklist.c linklist.h文件
3.代码如下所示
#include <stdio.h>
#include <stdlib.h>
#include "linklist.h"
#include "linktable.h"
int Help();
int Quit();
int Add();
int Sub();
int Mult();
int Divide();
int Factorial();//阶乘运算
int Fibonaci();//斐波那契数列
#define CMD_MAX_LEN 128
#define DESC_LEN 1024
#define CMD_NUM 10
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*)(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);
pNode = (tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd = "add";
pNode->desc = "Add two integer";
pNode->handler = Add;
AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode);
pNode = (tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd = "subtract";
pNode->desc = "Subtract two integer";
pNode->handler = Sub;
AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode);
pNode = (tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd = "Mult";
pNode->desc = "Mennu Program v1.0";
pNode->handler = Mult;
AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode);
pNode = (tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd = "divide";
pNode->desc = "Divide two integer";
pNode->handler = Divide;
AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode);
pNode = (tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd = "factorial";
pNode->desc = "Do factorial";
pNode->handler = Factorial;
AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode);
pNode = (tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd = "fibonaci";
pNode->desc = "Get the fibonaci NUM";
pNode->handler = Fibonaci;
AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode);
return 0;
}
tLinkTable * head = NULL;
int main ()
{
InitMenuData(&head);
/* cmd line begins */
while (1)
{
char cmd[CMD_MAX_LEN];
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();
}
}
}
int Help()
{
ShowAllCmd(head);
}
int Quit()
{
exit(0);
}
int Add()
{
printf("pelease input two integers:\n");
int temp1,temp2;
scanf("%d%d",&temp1,&temp2);
printf("The result is :%d\n", temp1+temp2);
return 0;
}
int Sub()
{
int temp1,temp2;
printf("please input two integers:\n");
scanf("%d%d", &temp1,&temp2);
printf("The result is :%d\n", temp1-temp2);
return 0;
}
int Mult()
{
printf("pelease input two integers:\n");
int temp1,temp2;
scanf("%d%d",&temp1,&temp2);
printf("The result is :%d\n", temp1*temp2);
return 0;
}
int Divide()
{
printf("pelease input two integers:\n");
int temp1,temp2;
scanf("%d%d",&temp1,&temp2);
printf("The result is :%d\n", temp1/temp2);
return 0;
}
int Factorial()//阶乘运算;
{
printf("pelease input the number of integer:\n");
int count;
scanf("%d", &count);
if(count < 0)
return -1;
int i = 1;
int value = 1;
while(i <= count)
{
value *= i;
++i;
}
printf("The result is:%d\n", value);
return 0;
}
int Fibonaci()//斐波那契数列计算;
{
printf("pelease input the number of integer:\n");
int temp1=1,temp2=1;
int count;
scanf("%d", &count);
if(count < 0)
{
printf("The wrong number.\n");
return 0;
}
else if(count==1||count==2)
{
printf("The result is :1.\n");
return 0;
}
for(int i=3;i<=count;i++)
{
int temp;
temp = temp2;
temp2 += temp1;
temp1 = temp;
}
printf("The result is :%d\n", temp2);
return 0;
}
linktable.c
#ifndef _LINK_TABLE_H_
#define _LINK_TABLE_H_
#define SUCCESS 0
#define FAILURE (-1)
#include <stdio.h>
#include <stdlib.h>
/*
* LinkTable Node Type
*/
typedef struct LinkTableNode
{
struct LinkTableNode *pNext;
}tLinkTableNode;
/*
* LinkTable Type
*/
typedef struct LinkTable
{
tLinkTableNode *pHead;
tLinkTableNode *pTail;
int SumOfNode;
}tLinkTable;
/*
* Create a LinkTable
*/
tLinkTable * CreateLinkTable();
/*
* Delete a LinkTalbe
*/
int DeleteLinkTable(tLinkTable *pLinkTable);
/*
* Add a LinkTableNode to LinkTable
*/
int AddLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode *pNode);
/*
* Delete a LinkTableNode 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_ */
linklist.c
#include <stdio.h>
#include <stdlib.h>
#include "linklist.h"
tDataNode* FindCmd(tLinkTable * head, char* cmd)
{
if (head == NULL || cmd == NULL)
{
return NULL;
}
tDataNode *p = (tDataNode*)GetLinkTableHead(head);
while (p != NULL)
{
if (strcmp(p->cmd, cmd) == 0)
{
return p;
}
p = (tDataNode*)GetNextLinkTableNode(head, (tLinkTableNode*)p);
}
return NULL;
}
/* Show all the cmd in Listlist */
int ShowAllCmd(tLinkTable * head)
{
printf("Menu List:\n");
tDataNode *p = (tDataNode*)GetLinkTableHead(head);
while (p != NULL)
{
printf("%s - %s\n", p->cmd, p->desc);
p = (tDataNode*)GetNextLinkTableNode(head, (tLinkTableNode*)p);
}
return 0;
}
linklist.h
#ifndef _LINK_LIST_H_
#define _LINK_LIST_H_
#include "linktable.h"
/* data struct and its operations */
typedef struct DataNode
{
tLinkTableNode *pNext;
char* cmd;
char* desc;
int (*handler)();
} tDataNode;
/* find a cmd in the linklist and return the data node pointer */
tDataNode * FindCmd(tLinkTable *head, char *cmd);
/* show all cmd in linklist */
int ShowAllCmd(tLinkTable *head);
#endif /*_Link_LIST_H_*/
4.组合编译如下
5执行代码演示如下
实验总结
通过这次实验的进行,了解可重用的链表的通用性,不用重复造轮子,如何设置规范的借口,方便以后的使用,以及对耦合与内聚的把我,受益很多。