lab4实验报告
一.实验步骤
- 编写linktable.h头文件。定义链表的数据结构和方法
- 编写linktable.c文件,实现定义的方法
- 讲链表的数据结构引入到数据节点中,修改linklist.h中数据节点的结构。
- 修改menu.c文件。

二、实验代码
1.linklist.h
#include "linktable.h" /* data struct */ typedef struct DataNode { LinkListNode* next; char* cmd; char* desc; void(*handler)(); } tDataNode; /* find the cmd from the linklist, return NULL or the DataNode pointer */ tDataNode* FindCmd(tDataNode* head, char* cmd); /* show all cmd */ int ShowAllCmd(LinkList* head);
2.linklist.c
#include "linklist.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "linktable.h" int ShowAllCmd(LinkList* head) { tDataNode* p = (tDataNode*)getLinkListHead(head); printf("======Menu List======"); while(p != NULL) { printf("%s -- %s\n", p->cmd, p->desc); p = (tDataNode*)getNextLinkListNode(head, (LinkListNode*)p); } printf("=====Menu End=====\n"); return 1; }
3.linktable.h
#ifndef _LINK_LIST_H_ #define _LINK_LIST_H_ typedef struct LinkListNode { struct LinkListNode *pNext; } LinkListNode; typedef struct LinkList { LinkListNode *head; LinkListNode *tail; int size; } LinkList; /*create a new linklist*/ LinkList* createLinkList(); /*destroy the existed linklist*/ int destroyLinkList(LinkList *pLinkList); /*add a node to a linklist*/ int addLinkListNode(LinkList *pLinkList, LinkListNode *pLinkListNode); /*remove a node from the linklist*/ int delLinkListNode(LinkList *pLinkList, LinkListNode *pLinkListNode); /*get the head of the linklist*/ LinkListNode* getLinkListHead(const LinkList *pLinkList); /*get next node of the parameter node*/ LinkListNode* getNextLinkListNode(const LinkList *pLinkList, const LinkListNode *pLinkListNode); #endif
4.linktable.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "linktable.h" /*create a new linklist*/ LinkList* createLinkList() { LinkList *p_list=(LinkList*)malloc(sizeof(LinkList*)); if(p_list==NULL) { printf("CREATE LINKLIST ERROR!\n"); exit(0); } else { p_list->head=NULL; p_list->tail=NULL; p_list->size=0; return p_list; } } /*destroy the existed linklist*/ int destroyLinkList(LinkList *pLinkList) { if(pLinkList==NULL) { printf("destory fails. linklist is not exsit!\n"); exit(0); } while(pLinkList->head != NULL) { LinkListNode *p=pLinkList->head; pLinkList->head = pLinkList->head->pNext; free(p); pLinkList->size -= 1; } pLinkList->tail = NULL; free(pLinkList); return 1; } /*add a node to a linklist*/ int addLinkListNode(LinkList *pLinkList, LinkListNode *pLinkListNode) { if(pLinkListNode == NULL){ printf("add linklist node ERROR!\n"); exit(0); } if(pLinkList->head == NULL) { pLinkList->head = pLinkListNode; pLinkList->tail = pLinkListNode; } else { pLinkList->tail->pNext = pLinkListNode; pLinkList->tail = pLinkListNode; pLinkList->tail->pNext = NULL; } pLinkList->size += 1; return 1; } /*remove a node from the linklist*/ int delLinkListNode(LinkList *pLinkList, LinkListNode *pLinkListNode) { if (pLinkList == NULL || pLinkListNode == NULL) { return 0; } if (pLinkList->head == pLinkListNode) { pLinkList->head = pLinkList->head->pNext; pLinkList->size -= 1; if (pLinkList->size == 0) { pLinkList->tail = NULL; } return 1; } LinkListNode* ptr = pLinkList->head; while (ptr != NULL) { if (ptr->pNext == pLinkListNode) { ptr->pNext = ptr->pNext->pNext; pLinkList->size -= 1; if (pLinkList->size == 0) { pLinkList->tail = NULL; } return 1; } ptr = ptr->pNext; } return 0; } /*get the head of the linklist*/ LinkListNode* getLinkListHead(const LinkList *pLinkList) { if (pLinkList == NULL || pLinkList->head == NULL) { return NULL; } return pLinkList->head; } /*get next node of the parameter node*/ LinkListNode* getNextLinkListNode(const LinkList *pLinkList, const LinkListNode *pLinkListNode) { if (pLinkList == NULL || pLinkListNode == NULL) { return NULL; } LinkListNode* ptr = pLinkList->head; while (ptr != NULL) { if (ptr == pLinkListNode) { return ptr->pNext; } ptr = ptr->pNext; } return NULL; }
5.menu.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linklist.h"
#include "linktable.h"
/* CMD functions */
void Help();
void Quit();
void CmdAdd();
void CmdSub();
void CmdMul();
void CmdDiv();
/* normal functions */
int init_menu();
tDataNode* search_cmd(LinkList* head, char* cmd);
int getAdd(int a, int b);
int getSub(int a, int b);
int getMul(int a, int b);
float getDiv(float a, float b);
#define CMD_MAX_LEN 128
#define DESC_LEN 1024
#define CMD_NUM 10
LinkList* head = NULL;
/* menu program */
int main()
{
/* cmd line begins */
init_menu(&head);
char cmd[CMD_MAX_LEN];
while (1)
{
printf("Input a cmd (input help for cmd help): ");
scanf("%s", cmd);
tDataNode* p = search_cmd(head, cmd);
if (p == NULL)
{
printf("This is wrong cmd!\n");
ShowAllCmd(head);
continue;
}
printf("%s -- %s\n", p->cmd, p->desc);
if (p->handler != NULL)
{
p->handler();
}
}
return 0;
}
/* CMD functions */
void Help()
{
ShowAllCmd(head);
}
void Quit()
{
exit(0);
}
void CmdAdd()
{
int a;
int b;
printf("Input a and b:");
scanf("%d %d", &a, &b);
printf("%d + %d = %d\n", a, b, getAdd(a, b));
}
void CmdSub()
{
int a;
int b;
printf("Input a and b:");
scanf("%d %d", &a, &b);
printf("%d - %d = %d\n", a, b, getSub(a, b));
}
void CmdMul()
{
int a;
int b;
printf("Input a and b:");
scanf("%d %d", &a, &b);
printf("%d * %d = %d\n", a, b, getMul(a, b));
}
void CmdDiv()
{
int a;
int b;
printf("Input a and b:");
scanf("%d %d", &a, &b);
printf("%d / %d = %lf\n", a, b, getDiv(a, b));
}
/* normal functions */
int init_menu(LinkList** pp_table)
{
*pp_table = createLinkList();
tDataNode* node = (tDataNode*)malloc(sizeof(tDataNode));
node->cmd = "help";
node->desc = "you can see help list.";
node->handler = Help;
addLinkListNode(*pp_table, (LinkListNode*)node);
node = (tDataNode*)malloc(sizeof(tDataNode));
node->cmd = "version";
node->desc = "menu program v2.0";
node->handler = NULL;
addLinkListNode(*pp_table, (LinkListNode*)node);
node = (tDataNode*)malloc(sizeof(tDataNode));
node->cmd = "quit";
node->desc = "you quit the menu program.";
node->handler = Quit;
addLinkListNode(*pp_table, (LinkListNode*)node);
node = (tDataNode*)malloc(sizeof(tDataNode));
node->cmd = "add";
node->desc = "a + b";
node->handler = CmdAdd;
addLinkListNode(*pp_table, (LinkListNode*)node);
node = (tDataNode*)malloc(sizeof(tDataNode));
node->cmd = "sub";
node->desc = "a - b";
node->handler = CmdSub;
addLinkListNode(*pp_table, (LinkListNode*)node);
node = (tDataNode*)malloc(sizeof(tDataNode));
node->cmd = "mul";
node->desc = "a * b";
node->handler = CmdMul;
addLinkListNode(*pp_table, (LinkListNode*)node);
node = (tDataNode*)malloc(sizeof(tDataNode));
node->cmd = "div";
node->desc = "a / b";
node->handler = CmdDiv;
addLinkListNode(*pp_table, (LinkListNode*)node);
return 0;
}
tDataNode* search_cmd(LinkList* linklist, char* cmd)
{
tDataNode* ptr_node = (tDataNode*)getLinkListHead(linklist);
while (ptr_node != NULL)
{
if (strcmp(ptr_node->cmd, cmd) == 0)
{
return ptr_node;
}
ptr_node = (tDataNode*)getNextLinkListNode(linklist, (LinkListNode*)ptr_node);
}
return NULL;
}
int getAdd(int a, int b)
{
return a + b;
}
int getSub(int a, int b)
{
return a - b;
}
int getMul(int a, int b)
{
return a * b;
}
float getDiv(float a, float b)
{
return a / b;
}
三、实验关键代码截图
1、链表的操作函数




2,、show memu cmd

四、git 提交


git路径:https://git.coding.net/SA17225233/project.git
五、实验结果

六、实验心得
链表是c语言中的一个难点,链表存储对于数组的优点有以下几点:
1.数组需要提前分配,不能够动态分配,不够灵活,而链表可以很灵活,在需要时候再分配内存;
2.数组需要内存是连续的,这要会导致内存利用率不高,链表恰恰相反。
学习链表需要有很好结构体和指针基础上,lab3就是为实验4的一个很好前期学习铺垫,循序渐进。

浙公网安备 33010602011771号