第三次作业——(涂江凤、邓洪虹)

                       组员:涂江凤、邓洪虹

  • 题目

          请编写一个能自动生成小学四则运算题目的 “软件”。

          让程序能接受用户输入答案,并判定对错。  

          最后给出总共 对/错 的数量。

  • 需求分析

        - 基本功能

           - 显示每次测试题目数量

           - 用户可以选择测试类型(混合、加、减、乘、除)

           - 用户可以逐个题目解答

           - 显示答案的对错,错误的给出正确答案

           - 统计每次测试答对的题的个数

        - 扩展功能

           -可以出表达式里含有负整数(负整数最小不小于-100)的题目,且负数需要带括号,用户输入的结果不用带括号。

           -用户答题结束以后,程序可以显示用户答题所用的时间

  • 设计

        - 主函数运用了一个for循环来限制测试的次数。

        - 用了9个子函数(测试的5种模式选择、加法、减法、乘法、除法)来实现对测试模式的选择以及选择后的运算。

        - 本软件随机生成负一百到一百以内的整数;

        - 本软件采用菜单的方式,提示比较清楚,用户可随机选择运算;

        - 采用模块化思想,把源文件分成几个模块进行封装。

  • 代码实现

     main.cpp文件

#include<stdio.h>
#include<windows.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include"calc.h"
#include"fun.h"
time_t start_time,end_time;

int count=0;
#define RESULT_SUCCESS 1
#define RESULT_FAILED  0



/*加、减、乘、除混合测试*/
void test_Mix()
{
	int remainder=0;   //初始化余数
	int first=0;     //第一个数
	int second=0;     //第二个数
	int number=1;//控制循环
	//题目数量的限定
	for(number=1;number<=5;number++)
	{
	    srand((unsigned)time(NULL));
	    int third = rand()%100;   // 产生随机数
		remainder = third%4;        //除以四取余
		generate(&first,&second);      //调用产生随机数函数
		switch(remainder)       //模式选择
		{
		case 0:
			{
				show(first,second,'+');        //调用打印题目函数
		        int answer=0;
		        scanf("%d",&answer);
		        int result=0;
				result=(int)calc('+',first,second);
		        int ret=juge(result,answer);      //调用判断函数
				if(ret==RESULT_SUCCESS)
				{
					printf("正确!\n");
					count++;
				}
				else
				{
					printf("错误!\n正确答案是:%d\n",result);
				}
				break;
			}
		case 1:
			{
				show(first,second,'-');           //调用打印题目函数
		        float answer=0;
		        scanf("%d",&answer);
		        float result=0;
				result=calc('-',first,second);
		        int ret=juge(result,answer);        //调用判断函数
				if(ret==RESULT_SUCCESS)
				{
					printf("正确!\n");
					count++;
				}
				else
				{
					printf("错误!\n正确答案是:%d\n",result);
				}
				break;
			}
		case 2:
			{
				show(first,second,'*');        //调用打印题目函数
		        float answer=0;
		        scanf("%d",&answer);
		        float result=0;
				result=calc('*',first,second);
		        int ret=juge(result,answer);           //调用判断结果函数
				if(ret==RESULT_SUCCESS)
				{
					printf("正确!\n");
					count++;
				}
				else
				{
					printf("错误!\n正确答案是:%d\n",result);
				}
				break;
			}
		default:
			{
				show(first,second,'/');         //调用打印题目函数
		        float answer=0;
		        scanf("%f",&answer);
		        float result=0;
				result=calc('/',first,second); 
				if(result==RESULT_FAILED)
				{
					printf("出错了!");
					break;
				}
		        int ret=juge(result,answer); //调用判断函数
				if(ret==RESULT_SUCCESS)
				{
					printf("正确!\n");
					count++;
				}
				else
				{
					printf("错误!\n正确答案是:%0.2f\n",result);   //除法答案保留小数点后两位
				}
				break;
			}
		}
	}
	printf("本次测试共对了%d道题\n",count);
	printf("\n");
	count=0;
}

/*加法测试*/
void test_Add()
{
	int first=0;
	int second=0;
	int number=1;   //控制循环
	for(number=1;number<=5;number++)
	{
		generate(&first,&second);        //调用产生随机数函数
		show(first,second,'+');         //调用打印题目函数
		int answer=0;
		scanf("%d",&answer);
		int result=0;
		result=(int)calc('+',first,second);
	    int ret=juge(result,answer);        //调用判断函数
		if(ret==RESULT_SUCCESS)
		{
			printf("正确!\n");
			count++;
		}
     	else
		{
			printf("错误!\n正确答案是:%d\n",result);
		}
	}
	printf("本次测试共对了%d道题\n",count);
	printf("\n");
	count=0;
}

/*减法测试*/
void test_Subtraction()
{
	int first=0;
	int second=0;
	int number=1;
	for(number=1;number<=5;number++)
	{
		generate(&first,&second);           //调用产生随机数函数
		show(first,second,'-');           //调用打印题目函数
		int answer=0;
		scanf("%d",&answer);
		int result=0;
        result=(int)calc('-',first,second);
	    int ret=juge(result,answer);        //调用判断函数
		if(ret==RESULT_SUCCESS)
		{
			printf("正确!\n");
			count++;
		}
		else
		{
			printf("错误!\n正确答案是:%d\n",result);
		}
	}
	printf("本次测试共对了%d道题\n",count);
	printf("\n");
	count=0;
}

/*乘法测试*/
void test_Multiplication()
{
	int first=0;
	int second=0;
	int number=1;
	for(number=1;number<=5;number++)
	{
		generate(&first,&second);           //调用产生随机数函数
		show(first,second,'*');        //调用打印题目函数
		int answer=0;
		scanf("%d",&answer);
		int result=0;
	    result=(int)calc('*',first,second);
	    int ret=juge(result,answer);          //调用判断函数
		if(ret==RESULT_SUCCESS)
		{
			printf("正确!\n");
			count++;
		}
		else
		{
			printf("错误!\n正确答案是:%d\n",result);
		}
		juge(result,answer);
	}
	printf("本次测试共对了%d道题\n",count);
	printf("\n");
	count=0;
}

/*除法测试*/
void test_Division()
{
	int first=0;
	int second=0;
	int number=1;
	for(number=1;number<=5;number++)
	{
		generate(&first,&second);      //调用产生随机数函数
		show(first,second,'/');          //调用打印题目函数
		float answer=0;
		scanf("%f",&answer);
	    float result=0;
		result=calc('/',first,second);
		if(result==RESULT_FAILED)
		{
			printf("出错了!");
			break;
		}
	    int ret=juge(result,answer);         //调用判断函数
		if(ret==RESULT_SUCCESS)
		{
			printf("正确!\n");
			count++;
		}
		else
		{
			printf("错误!\n正确答案是:%f\n",result);
		}
	}
	printf("本次测试共对了%d道题\n",count);
	printf("\n");
	count=0;
}

/*主函数*/
int  main()
{
	int number=0;    //控制循环
	int first=0;
	int second=0;
	int choose=0;     //接收用户输入选择的序号
	printf("\n您好,欢迎登录小学生四则运算测试系统!\n\n");
	start_time=time(NULL);   //时间记录开始

	//测试循环
	for(number=0;number<=100;number++)
	{
		printf("*******************************************\n");
		printf("提示:每次测试共5题,请输入相应序号:\n\n");
		printf("   1、混合测试     4、乘法测试\n\n");
		printf("   2、加法测试     5、除法测试\n\n");
		printf("   3、减法测试     6、退出测试系统\n");         
		printf("*******************************************\n\n");
		printf("特别提示:除法的计算结果保留小数点后两位!\n");
	    scanf("%d",&choose);
		//模式选择
        switch(choose)
		{
		case 1:
			{
				test_Mix();
				break;
			}
		case 2:
			{
				test_Add();
				break;
			}
		case 3:
			{
				test_Subtraction();
				break;
			}
		case 4:
			{
				test_Multiplication();
				break;
			}
		case 5:
			{
				test_Division();
				break;
			}
		case 6:
			{
	            end_time=time(NULL);      //事件记录结束
	            printf("本次答题您所消耗的时间为:%f秒\n",difftime(end_time,start_time));
				printf("您已退出测试系统!再见!\n\n");
				return 0;
			}
		default:
			{
				printf("\n您的输入有误,请重新输入!\n\n"); 
				break;
			}
		}
	}
    return 0;
}

 

       calc.cpp文件(加、减、乘、除)

#include"calc.h"
double calc(char type,int first,int second)
{
	switch(type)
	{
	case '+':
		{
			/*加法计算*/
			int result = first + second;
			return result;
			break;
		}
	case '-':
		{
			/*减法计算*/
			int result = first - second;
			return result;
			break;
		}
	case '*':
		{
			/*乘法计算*/
			int result = first * second;
			return result;
			break;
		}
	default:
		{
			/*除法计算*/
			if(second==0)
			{
				return RESULT_FAILED;
				break;//如果除数随机为0,则返回错误
			}
			float result = (float)first /(float)second;
			if(result>0)
			{
				result=(double)((int)(result*100+0.5))/100; //结果保留到小数点后两位
			}
			else
			{
				result=(double)((int)(result*100-0.5))/100; //结果保留到小数点后两位
			}
			return result;
			break;
		}
	}
}

 

        calc.h文件

#ifndef _CALC_H
#define _CALC_H
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

double calc(char type,int first,int second);
int test();

#endif 

         fun.c文件

#include"fun.h"
/*产生随机数*/
void generate(int *first,int *second)
{
	srand((unsigned)time(NULL));
	*first = rand()%201-100;       //产生负一百到一百之间的随机数
	*second = rand()%201-100;       //产生负一百到一百之间的随机数
}

/*打印题目,为负数项添加括号*/
void show(int first,int second,char type)
{
	switch(type)
	{
	case'+':
		{
			if(first<0 && second>0)
			{
				printf("(%d) + %d =",first,second);
			}
			else if(first>0 && second<0)
			{
				printf("%d + (%d) =",first,second);
			}
			else if(first<0 && second<0)
			{
				printf("(%d) + (%d) =",first,second);
			}
			else
			{
				printf("%d + %d =",first,second);
			}
			break;
		}
	case'-':
		{
			if(first<0 && second>0)
			{
				printf("(%d) - %d =",first,second);
			}
			else if(first>0 && second<0)
			{
				printf("%d - (%d) =",first,second);
			}
			else if(first<0 && second<0)
			{
				printf("(%d) - (%d) =",first,second);
			}
			else
			{
				printf("%d - %d =",first,second);
			}
			break;
		}
	case'*':
		{
			if(first<0 && second>0)
			{
				printf("(%d) * %d =",first,second);
			}
			else if(first>0 && second<0)
			{
				printf("%d * (%d) =",first,second);
			}
			else if(first<0 && second<0)
			{
				printf("(%d) * (%d) =",first,second);
			}
			else
			{
				printf("%d * %d =",first,second);
			}
			break;
		}
	default:
		{
			if(first<0 && second>0)
			{
				printf("(%d) / %d =",first,second);
			}
			else if(first>0 && second<0)
			{
				printf("%d / (%d) =",first,second);
			}
			else if(first<0 && second<0)
			{
				printf("(%d) / (%d) =",first,second);
			}
			else
			{
				printf("%d / %d =",first,second);
			}
			break;
		}
	}
}

/*判断答案的对错*/
int juge(double result,double answer)
{
	if(result==answer)
	{
		return RESULT_SUCCESS;
	}
	else
	{
		return RESULT_FAILED;
	}
}

         fun.h文件

#ifndef _FUN_H
#define _FUN_H
#include<stdio.h>
#include<time.h>
#include<math.h>
#include<stdlib.h>

#define RESULT_SUCCESS 1
#define RESULT_FAILED  0

void generate(int *first,int *second);  //产生随机数函数声明
void show(int first,int second,char type);  //打印题目函数声明
int juge(double result,double answer);   //判断结果是否正确函数声明

#endif 

 

         test.c文件

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<assert.h>
#include"calc.h"

/*测试函数*/
int test()
{
    assert(3==calc('+',1,2));
    assert(0==calc('+',100,-100));
    assert(0==calc('+',0,0));
    assert(2==calc('+',2,0));

    return 1;
}

 

  • 程序运行截图

        

         改变其中一个值:

        

         除法:

         

        负数加了括号:

       

         答题结束显示时间:

       

  • 两人合作步骤

        1. 先对题目做一个大概的分析,明确需要做什么。

        2. 分别在网上或书上查找相应的资料。

        3. 重新写了代码,并进行规范以及相应的修改。

        4. 对函数进行模块化,将函数进行了封装,并把函数声明与具体实现分别存放在头文件(.h)和源文件(.c)中。

        5. 进行代码复审。

        6. 进行相应的测试,检查加法计算是否有错误。

  • 总结

        1. 在写好代码调试的过程中,出现了“.exe已停止工作”的问题,然后我们反复检查了几遍才发现了问题,scanf(“%d“,&answer)少写了一个&,检查的方法:printf(”部分代码--->1“); printf(”部分代码-->2“); printf(”部分代码-->3“);如果显示了--->1,而没有显示--->2和--->3,则---2出现了错误。

      2. 对如何写测试代码还是不太熟悉,不过理解了它的思想。

      3. 刚开始对scanf的问题很不理解,怎么把scanf拿到内函数外部也不知道,后来经过讨论并询问老师,重写了代码才弄清楚。

  • psp耗时统计

       

步骤

耗时

百分比

理解题目要求和查找资料

2

4.44

需求分析

5

11.12

具体设计

3

6.67

代码规范和函数封装

3

6.67

代码复审

15

33.33

测试

15

33.33

总结

2

                       4.44

posted @ 2015-04-22 12:59  涂江凤  阅读(293)  评论(8编辑  收藏