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的一个很好前期学习铺垫,循序渐进。