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

 

posted @ 2017-10-14 11:17  一叶知秋,人生几何  阅读(313)  评论(0编辑  收藏  举报