软件工程实验7

实验报告7

网易云课堂昵称:哪来的妖精

网易云课堂《软件工程(C编码实践篇)》MOOC课程作业:http://mooc.study.163.com/learn/USTC-1000002006

github   https://github.com/littlewulei/Software-Engineering-Lab.git

实验要求

为menu子系统设计接口,并写用户范例代码来实现原来的功能;

使用make和make clean来编译程序和清理自动生成的文件;

使menu子系统支持带参数的复杂命令,并在用户范例代码中自定义一个带参数的复杂命令;

实验步骤

创建lab7文件夹。创建Makefile文件如下:

CC_PTHREAD_FLAGS   =-lpthread
CC_FLAGS           =-c
CC_OUTPUT_FLAGS    =-o
CC                 =gcc
RM                 =rm
RM_FLAGS           =-f
TARGET=test
OBJS=linktable.o menu.o test.o
all: $(OBJS)
    $(CC) $(CC_OUTPUT_FLAGS) $(TARGET) $(OBJS)

.c.o:
    $(CC) $(CC_FLAGS) $<

clean:
    $(RM) $(RM_FLAGS) $(OBJS) $(TARGET) *.bak

需要注意的是Makefile 需要用Tab缩进,空格不行。

linktable.h代码如下:

#ifndef _LINK_TABLE_H_
#define _LINK_TABLE_H_
#include <pthread.h>
#define SUCCESS 0
#define FAILURE (-1)
/*
 * LinkTable Node Type
 */
typedef struct LinkTableNode tLinkTableNode;
/*
 * LinkTable Type
 */
typedef struct LinkTable tLinkTable;
/*
 * Create a LinkTable
 */
tLinkTable * CreateLinkTable();
/*
 * Delete a LinkTable
 */
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);
/*
 * Search a LinkTableNode from LinkTable
 * int Conditon(tLinkTableNode * pNode);
 */
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void * args), void * args);
/*
 * get LinkTableHead
 */
tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable);
/*
 * get next LinkTableNode
 */
tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode);
#endif /* _LINK_TABLE_H_ */

linktable.c文件如下:

#include<stdio.h>
#include<stdlib.h>
#include"linktable.h"
typedef struct LinkTableNode
{
    struct LinkTableNode * pNext;
}tLinkTableNode;
typedef struct LinkTable{
    tLinkTableNode *pHead;
    tLinkTableNode *pTail;
    int            SumOfNode;
    pthread_mutex_t mutex;
}tLinkTable;
/*
 * Create a LinkTable
 */
tLinkTable * CreateLinkTable()
{
    tLinkTable * pLinkTable = (tLinkTable *)malloc(sizeof(tLinkTable));
    if(pLinkTable == NULL)
    {
        return NULL;
    }
    pLinkTable->pHead = NULL;
    pLinkTable->pTail = NULL;
    pLinkTable->SumOfNode = 0;
    pthread_mutex_init(&(pLinkTable->mutex), NULL);
    return pLinkTable;
}
/*
 * Delete a LinkTable
 */
int DeleteLinkTable(tLinkTable *pLinkTable)
{
    if(pLinkTable == NULL)
    {
        return FAILURE;
    }
    while(pLinkTable->pHead != NULL)
    {
        tLinkTableNode * p = pLinkTable->pHead;
        pthread_mutex_lock(&(pLinkTable->mutex));
        pLinkTable->pHead = pLinkTable->pHead->pNext;
        pLinkTable->SumOfNode -= 1 ;
        pthread_mutex_unlock(&(pLinkTable->mutex));
        free(p);
    }
    pLinkTable->pHead = NULL;
    pLinkTable->pTail = NULL;
    pLinkTable->SumOfNode = 0;
    pthread_mutex_destroy(&(pLinkTable->mutex));
    free(pLinkTable);
    return SUCCESS;
}
/*
 * Add a LinkTableNode to LinkTable
 */
int AddLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode)
{
    if(pLinkTable == NULL || pNode == NULL)
    {
        return FAILURE;
    }
    pNode->pNext = NULL;
    pthread_mutex_lock(&(pLinkTable->mutex));
    if(pLinkTable->pHead == NULL)
    {
        pLinkTable->pHead = pNode;
    }
    if(pLinkTable->pTail == NULL)
    {
        pLinkTable->pTail = pNode;
    }
    else
    {
        pLinkTable->pTail->pNext = pNode;
        pLinkTable->pTail = pNode;
    }
    pLinkTable->SumOfNode += 1 ;
    pthread_mutex_unlock(&(pLinkTable->mutex));
    return SUCCESS;
}
/*
 * Delete a LinkTableNode from LinkTable
 */
int DelLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode)
{
    if(pLinkTable == NULL || pNode == NULL)
    {
        return FAILURE;
    }
    pthread_mutex_lock(&(pLinkTable->mutex));
    if(pLinkTable->pHead == pNode)
    {
        pLinkTable->pHead = pLinkTable->pHead->pNext;
        pLinkTable->SumOfNode -= 1 ;
        if(pLinkTable->SumOfNode == 0)
        {
            pLinkTable->pTail = NULL;
        }
        pthread_mutex_unlock(&(pLinkTable->mutex));
        return SUCCESS;
    }
    tLinkTableNode * pTempNode = pLinkTable->pHead;
    while(pTempNode != NULL)
    {
        if(pTempNode->pNext == pNode)
        {
            pTempNode->pNext = pTempNode->pNext->pNext;
            pLinkTable->SumOfNode -= 1 ;
            if(pLinkTable->SumOfNode == 0)
            {
                pLinkTable->pTail = NULL;
            }
            pthread_mutex_unlock(&(pLinkTable->mutex));
            return SUCCESS;
        }
        pTempNode = pTempNode->pNext;
    }
    pthread_mutex_unlock(&(pLinkTable->mutex));
    return FAILURE;
}
/*
 * Search a LinkTableNode from LinkTable
 * int Conditon(tLinkTableNode * pNode);
 */
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void * args), void * args)
{
    if(pLinkTable == NULL || Conditon == NULL)
    {
        return NULL;
    }
    tLinkTableNode * pNode = pLinkTable->pHead;
    while(pNode != NULL)
    {
        if(Conditon(pNode, args) == SUCCESS)
        {
            return pNode;
        }
        pNode = pNode->pNext;
    }
    return NULL;
}
/*
 * get LinkTableHead
 */
tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable)
{
    if(pLinkTable == NULL)
    {
        return NULL;
    }
    return pLinkTable->pHead;
}
/*
 * get next LinkTableNode
 */
tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode)
{
    if(pLinkTable == NULL || pNode == NULL)
    {
        return NULL;
    }
    tLinkTableNode * pTempNode = pLinkTable->pHead;
    while(pTempNode != NULL)
    {
        if(pTempNode == pNode)
        {
            return pTempNode->pNext;
        }
        pTempNode = pTempNode->pNext;
    }
    return NULL;
}

menu.h :

#ifndef _MENU_H
#define _MENU_H

int MenuConfig(char * cmd, char * desc, void (*handler)(int argc, char *argv[]));

int ExecuteMenu();

#endif

menu.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linktable.h"
#include "menu.h"
#define CMD_MAX_LEN 128
#define CMD_MAX_ARGV_LEN 128
#define DESC_LEN    1024
#define CMD_NUM     10

tLinkTable * head = NULL;
void Help(int argc, char *argv[]);

/* data struct and its operations */

typedef struct DataNode
{
    tLinkTableNode * pNext;
    char*   cmd;
    char*   desc;
    void    (*handler)(int argc, char *argv[]);
} tDataNode;

int SearchCondition(tLinkTableNode * pLinkTableNode, void * args)
{
    char * cmd = (char*) args;
    tDataNode * pNode = (tDataNode *)pLinkTableNode;
    if(strcmp(pNode->cmd, cmd) == 0)
    {
        return  SUCCESS;
    }
    return FAILURE;
}

/* find a cmd in the linklist and return the datanode pointer */
tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
    return  (tDataNode*)SearchLinkTableNode(head, SearchCondition, (void *)cmd);
}

/* show all cmd in listlist */
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 MenuConfig(char * cmd, char * desc, void (*handler)(int argc, char *argv[]))
{
    tDataNode* pNode = NULL;
    if (head == NULL)
    {
        head = CreateLinkTable();
        pNode = (tDataNode*)malloc(sizeof(tDataNode));
        pNode->cmd = "help";
        pNode->desc = "Menu List:";
        pNode->handler = Help;
        AddLinkTableNode(head, (tLinkTableNode *)pNode);
    }
    pNode = (tDataNode*)malloc(sizeof(tDataNode));
    pNode->cmd = cmd;
    pNode->desc = desc;
    pNode->handler = handler;
    AddLinkTableNode(head, (tLinkTableNode *)pNode);
}

int ExecuteMenu()
{
    while(1)
    {
        int argc = 0;
        char *argv[CMD_MAX_ARGV_LEN];
        char cmd[CMD_MAX_LEN];
        char *pcmd = NULL;
        printf("Input a cmd number > ");
        pcmd = fgets(cmd, CMD_MAX_LEN, stdin);
        if (pcmd == NULL)
        {
            continue;
        }
        pcmd = strtok(pcmd, " ");
        while (pcmd != NULL && argc < CMD_MAX_ARGV_LEN)
        {
            argv[argc] = pcmd;
            argc++;
            pcmd = strtok(NULL, " ");
        }
        if (argc == 1)
        {
            int len = strlen(argv[0]);
            *(argv[0] + len - 1) = ‘\0‘;
        }

        tDataNode *p = FindCmd(head, argv[0]);
        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(argc, argv);
        }
    }
}
void Help(int argc, char *argv[])
{
    ShowAllCmd(head);
}

test.c :

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include "menu.h"

void Quit(int argc, char *argv[]);
void Version(int argc, char *argv[]);

void Quit(int argc, char *argv[])
{
    exit(0);
}

void Version(int argc, char *argv[])
{
    printf("version7.0\n");
}

void Date(int argc, char *argv[])
{

    system("date");
}

int Add(int argc, char* argv[])
{
    int i,r;
    if(argc != 3)
    {
        printf("warning input 2 numbers\n");
        return 0;
    }
    r=atoi(argv[1])+atoi(argv[2]);
    printf("result is %d\n",r);
    return 0;
}

int Sub(int argc, char* argv[])
{
    int i,r;
    if(argc !=3)
    {
        printf("warning input 2 numbers\n");
        return 0;
    }
    r=atoi(argv[1])-atoi(argv[2]);
    printf("result is %d\n",r);
    return 0;
}

int Mul(int argc, char* argv[])
{
    int i,r;
    if(argc !=3)
    {
        printf("warning input 2 numbers\n");
        return 0;
    }
    r=atoi(argv[1])*atoi(argv[2]);
    printf("result is %d\n",r);
    return 0;
}

int Divi(int argc, char* argv[])
{
    int i;
    float r;
    if(argc !=3)
    {
        printf("warning input 2 numbers\n");
        return 0;
    }
    r=((float)atoi(argv[1]))/atoi(argv[2]);
    printf("result is %.2f\n",r);
    return 0;
}

int main(int argc,char* argv[])
{
    MenuConfig("version","XXX1.0(Menu program v7.0 inside)",NULL);
    MenuConfig("quit","Quit from XXX",Quit);
    MenuConfig("date","Show the date",Date);
    MenuConfig("add","return sum of the two numbers", Add);
    MenuConfig("sub","return difference of the two numbers", Sub);
    MenuConfig("mul","return product of the two numbers", Mul);
    MenuConfig("divi","return quotient of the two numbers", Divi);
    ExecuteMenu();
}

运行截图

上传GitHub

实验总结

这次实验彻底将menu小程序编写成为一个可重用的小程序供其他程序使用,实现了代码的可重用性,并且学会了使用Makefile 编译代码。

时间: 2024-10-14 23:38:14

软件工程实验7的相关文章

软件工程实验一--编程随机生成30个四则运算,算数包括100以内的整数和真分数。

软件工程实验一: ——编程随机生成30个四则运算,算数包括100以内的整数和真分数. 实验思路:先利用rand()函数随机生成两个算数,包括100以内的整数和真分数,生成100以内的整数,用rand()%100,为了避免在除法运算中除数不能为零,所以运算符右边的整数直接用1+rand()%99:在随机生成真分数时,我先生成两个整数,来充当分子和分母,同样分母不能为零,用1+rand()%99.加减乘除四则运算有整数与整数之间的运算,分数与分数之间的运算,整数和分数之间的运算,分数和整数之间的运算

软件工程实验一 复利计算——单元测试

对复利计算器进行单元测试 一.实验历次题目要求 1.客户说:帮我开发一个复利计算软件. 2.如果按照单利计算,本息又是多少呢? 3.假如30年之后要筹措到300万元的养老金,平均的年回报率是3%,那么,现在必须投入的本金是多少呢? 4.利率这么低,复利计算收益都这么厉害了,如果拿100万元去买年报酬率10%的股票,若一切顺利,过多长时间,100万元就变成200万元呢? 5.如果我希望在十年内将100万元变成200万元,应该找到报酬率在多少的投资工具来帮助我达成目标?如果想在5年后本金翻倍,报酬率

软件工程实验一 复利计算(第三次实验实验总结)

主题内容:复利计算器的第三次改进 追加题目: 4.利率这么低,复利计算收益都这么厉害了,如果拿100万元去买年报酬率10%的股票,若一切顺利,过多长时间,100万元就变成200万元呢? 5.如果我希望在十年内将100万元变成200万元,应该找到报酬率在多少的投资工具来帮助我达成目标?如果想在5年后本金翻倍,报酬率就应至少为多少才行呢? 附加题:6.如果每年都将积蓄的3万元进行投资,每年都能获得3%的回报,然后将这些本利之和连同年金再投入新一轮的投资,那么,30年后资产总值将变为多少?如果换成每月

软件工程 实验二 结对编程(第二阶段)

一.实验目标: 1)体验敏捷开发中的两人合作. 2)进一步提高个人编程技巧与实践. 二 .实验内容: 1)根据以下问题描述,练习结对编程(pair programming)实践: 2)两个学生组合,每人使用一台计算机,二人共同编码,完成实验要求. 3)针对课题查阅相关资料,加深对课题的理解: 4)在结对编程工作期间,两人的角色至少切换 4 次: 5)实验过程中合作编程两人互相探讨后采用开发平台和技术,语言工具,准备实验开展工作: 6)做好试验记录和分析工作. 三.实验过程 (一)问题描述 生命游

软件工程实验一 复利计算

本次编写复利计算我使用了Java编写,有两项功能,一是根据本金计算复利终值,二是根据复利终值计算所需的本金,此时我利用了两条公式 输入本金求终值:S = P * Math.pow(1.0 + i, n) 即  复利终值=本金*(1+利率)^利率获取时间 输入终值求本金:P = S * Math.pow(1.0 + i, -n)即 所需本金=复利终值*(1+利率)^(-利率获取时间) 在Java中运行结果如下: 1.输入本金求终值 2.输入终值求本金 首先在第一个输入框内输入1.2来选择计算方向,

软件工程实验一

题目一: 删除排序数组中的重复数字 描述: 给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度. 不要使用额外的数组空间,必须在原地没有额外空间的条件下完成. 给出数组A =[1,1,2],你的函数应该返回长度2,此时A=[1,2] public class Solution { /** * @param A: a array of integers * @return : return an integer */ public int removeD

软件工程实验1

删除排序数组中的重复数字 给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度. 不要使用额外的数组空间,必须在原地没有额外空间的条件下完成. public class Solution { /** * @param A: a array of integers * @return : return an integer */ public int removeDuplicates(int[] nums) { // write your code her

软件工程实验一 复利计算——观赏其他团队工程

我评论的: 05 卢琪 http://www.cnblogs.com/xiseven/p/5392425.html 06 邹育萍 http://www.cnblogs.com/zou779596337/p/5392381.html 08 周诗琦 http://www.cnblogs.com/sr1zsq/p/5393497.html 25 陈庆祥 http://www.cnblogs.com/qing8/p/5392804.html#3408933

软件工程实验课

今天我更加深刻理解这么绘制图形和使用绘图软件,感谢老师的耐心指导,以及小伙伴的帮助.我们小组一起讨论这么绘制图形,和几张难懂的图形该怎么绘制.我们有细致的分工,每个人都指导自己该完成什么内容,并且在完成自己的任务后帮助需要帮助的伙伴.这就是团结吧. 看着大家全身心投入到项目中的样子,自己都被感动了.我今天也完成了自己的任务,就是完成两个用例图,一个顺序图和两个用例规约.编写用例规约主要是合同管理用例规约和租金管理用例规约.很高兴自己按时完成任务. 原文地址:https://www.cnblogs