课程设计四则运算1.docx
《课程设计四则运算1.docx》由会员分享,可在线阅读,更多相关《课程设计四则运算1.docx(32页珍藏版)》请在冰点文库上搜索。
课程设计四则运算1
淮北师范大学
《数据结构设计实验报告》
题目——四则运算练习软件
班级:
09非师
设计者:
曹严严
指导老师:
张震
时间:
2011/04/13---2011/04/14
目录
1程序设计的内容和相关的要求-----------------------------------
2程序总的功能说明----------------------------------------------
3程序的模块的说明----------------------------------------------
4程序设计的流程图----------------------------------------------
5程序的操作说明及运行结果-------------------------------------
6源程序的清单--------------------------------------------------
7心得体会------------------------------------------------------
1程序设计的内容和相关的要求
课程设计的目的:
数据结构课程设计是计算机学院重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决实际问题的机会。
●进一步巩固和复习数据结构的基础知识。
●培养学生结构化程序、模块化程序设计的方法和能力。
●提高学生调试程序的技巧和软件设计的能力。
●提高学生分析问题、解决问题以及综合利用C语言进行程序设计的能力。
●了解软件的编制过程。
实现的任务:
编写一个100以内的四则运算练习软件。
设计内容:
1.随机产生两个<100的整数(运算结果也要在100内),可以选择要练习的运算+,-*,/,调用+,-,*,/四个运算函数实现运算。
2.+,-,*,/混合运算(用栈的原理实现)
设计要求:
1.不同的功能使用不同的函数实现(模块化),对每个函数的功能和调用接口要注释清楚。
对程序其它部分也进行必要的注释。
2.对系统进行功能模块分析、画出总流程图和各模块流程图。
3.用户界面要求使用方便、简洁明了、美观大方、格式统一。
所有功能可以反复使用,最好使用菜单。
4.通过命令行相应选项能直接进入某个相应菜单选项的功能模块。
5.所有程序需调试通过。
2程序总的功能说明:
本程序主要功能是进行数学算式运算练习,能够进行简单算式练习、混合算式运算,也能进行双向运算练习(自己模拟训练)。
3程序各模块的功能说明:
(1)界面显示函数:
enu();显示主菜单界面
show();显示子界面双向练习菜单
(2)执行练习的功能函数:
main_1();简单练习函数
main_2();混合运算函数
main_3();双向运算练习函数
(3)窗体和背景设置函数
调用System(“colornA”)(其中n表示从0到9任意一个数字;A表示任意取一个A,B,C,D,E,F中的一个字符)函数来实现不同窗体前景和背景色彩的设置
4程序设计的流程图:
5程序操作说明书及结果
在vc++6.0环境中运行本程序,先进行编译,然后再进行链接,在进行执行将会出现显示界面。
按照显示界面上显示的提示从键盘上输入数字,就可以实现相应的功能。
6源程序清单
#include
#include
#include//对内存操作的头文件
#include
#include
#include
#include//#include是在调用字符函数时,在源文件中包含的头文件。
ctype"中c为字符型char的缩写,type为类型。
#include//操作时间有关的函数的头文件
#defineMAX_LEN1024
#defineEXP_LEN4
intright=0,wrong=0;
intv;
voidadd()
{
inta,b,c;
a=rand()%100;//rand()函数,生成范围1-1000;
b=100-a;
b=rand()%b;
printf("请回答:
%d+%d=",a,b);
scanf("%d",&c);
if(a+b!
=c){printf("回答错误\n");wrong++;}
else{printf("回答正确\n");right++;}
}
voidminu()
{
inta,b,c;
a=rand()%100;/*随机产生1个100以内的整数,并赋值给a。
srand()函数是随机数发生器的初始化函数,
还缺少
#include
#include
两个头文件,
intx,a;//表示初始化整数x和a
srand(time(0));//表示随机数产生初始化
a=(int)(rand()%100);//表示调用rand()函数产生100以内整数并赋值给a*/
b=rand()%a;
printf("请回答:
%d-%d=",a,b);
scanf("%d",&c);
if(a-b!
=c){printf("回答错误\n");wrong++;}
else{printf("回答正确\n");right++;}
}
voidmul()
{
inta,b,c;
a=rand()%11;
b=(rand()%100)/(a+1);
printf("请回答:
%d*%d=",a,b);
scanf("%d",&c);
if(a*b!
=c){printf("回答错误\n");wrong++;}
else{printf("回答正确\n");right++;}
}
voiddi()
{
inta,b,c;
a=rand()%100;
b=rand()%100+1;
printf("请回答:
%d/%d=",a,b);
scanf("%d",&c);
if(a/b!
=c){printf("回答错误\n");wrong++;}
else{printf("回答正确\n");right++;}
}
voidmain_1()
{
system("pause");
system("cls");
intchoise,con=0;
system("color2A");
printf("\n\n\t\t简单四则运算程序\n");
system("pause");
system("cls");
while
(1)
{
printf("\n\n\t\t请选择:
\n加(输入1)\n减(输入2)\n乘(输入3)\n除(输入4)\n");
if(con==0)scanf("%d",&choise);
switch(choise)
{
case1:
add();break;
case2:
minu();break;
case3:
mul();break;
case4:
di();break;
}
printf("请问您想继续进行这个运算还是重新选择其他运算还是退出?
\n继续(输入1),重新(输入2),退出(输入3)");
scanf("%d",&con);
if(con==1)con=1;
if(con==2)con=0;
if(con==3)break;
}
system("pause");
}
constchar*OPERATOR="+-*/";
typedefstruct{
intn[100];
inttop;
}stack;//定义栈的基本结构
voidinits(stack*s)
{
s->top=-1;
}//栈的初始化
intpush(stack*s,inte)//将e入栈
{
s->top++;
s->n[s->top]=e;
return1;
}
intpop(stack*s)//将栈顶元素出栈,存到e中
{
inte;
e=s->n[s->top];
s->top--;
returne;
}
intGetTop(stack*s)//取栈顶元素
{
inte;
e=s->n[s->top];
returne;
}
charS2[MAX_LEN],Exp[MAX_LEN*2];/*S1保存数字或运算结果,S2保存操作符,Exp为输入的表达式
*T1为栈S1的顶指针,T2为栈S2的顶指针,p为扫描Exp的位置
*/
intS1[MAX_LEN],T1,T2,p;
intisCorrect;/*检查生成的表达式是否合理*/
intnumber[EXP_LEN],bracket[EXP_LEN];/*number为随机生成的表达式的操作数,oper为运算符,bracket为括号数组(0表示没有括号,-1表示左括号,1表示右括号)*/
charoper[EXP_LEN-1];
charreply[MAX_LEN*2];/*用户答案*/
intN=5;/*题目数量,默认为5道题*/
intGetPriority(charc)/*获得运算符的优先级*/
{
if(c=='+'||c=='-')
return1;
else
return2;
}
intGetNum()/*将字符转换成int*/
{
intr=0;
while(isdigit(Exp[p]))
{
r=r*10+Exp[p]-'0';
p=p+1;
}
returnr;
}
voidCalc(charop)/*从栈顶取出两个数字,进行op对应的操作*/
{
inta=S1[T1-2];intb=S1[T1-1];
if(op=='+')
a+=b;
elseif(op=='-')
{
a-=b;
if(a<0)/*如果中间结果出现负数,认为不合法*/
isCorrect=0;
}
elseif(op=='*')
a*=b;
else
{
if(b==0||a%b!
=0)/*如果中间结果出现无法整除或除数为0,认为不合法*/
isCorrect=0;
if(b!
=0)
a/=b;
}
S1[T1-2]=a;/*将计算结果压入S1操作数栈中,并更新栈顶指针*/
T1=T1-1;
}
voidPush(charop)/*操作符入栈*/
{
if(op==')')/*优先计算括号内的表达式*/
{
while(S2[T2-1]!
='(')
{
T2=T2-1;
Calc(S2[T2]);
}
T2=T2-1;
}
elseif(op=='(')/*左括号直接入栈*/
{
S2[T2]=op;
T2=T2+1;
}
else
{
while(T2>0&&S2[T2-1]!
='('&&GetPriority(S2[T2-1])>=GetPriority(op))/*先计算优先级高的表达式*/
{
T2=T2-1;
Calc(S2[T2]);
}
S2[T2]=op;/*将op压入S2操作符栈中,并更新栈顶指针*/
T2=T2+1;
}
}
intProcessExp()/*计算表达式的值*/
{
T1=T2=p=0;/*清空栈,将扫描指针复位*/
while(Exp[p]!
='\0')
{
if(isdigit(Exp[p]))/*如果是数值,入S1栈*/
{
S1[T1]=GetNum();
T1=T1+1;
--p;
}
else/*反之是运算符,入S2栈*/
{
Push(Exp[p]);
}
p=p+1;
}
while(T2>0)/*取出S2中剩余操作符,进行运算*/
{
T2=T2-1;
Calc(S2[T2]);
}
returnS1[0];
}
intGenerateExp()/*生成合法的表达式(中间结果没有负数,分数和小数等)*/
{
inti,j,k,w,ret,digit[16];
while(true)/*一直循环直到随机到一个合法的表达式*/
{
isCorrect=1;
for(i=0;inumber[i]=rand()%30+1;
for(i=0;ioper[i]=OPERATOR[rand()%4];
j=-1;
memset(bracket,0,sizeof(bracket));/*随机括号的位置*/
while(true)
{
i=j+1;
if(EXP_LEN-1-i<=0)
break;
j=rand()%(EXP_LEN-1-i)+i;
bracket[j]=-1;
i=j+1;
j=rand()%(EXP_LEN-i)+i;
bracket[j]=1;
}
memset(Exp,0,sizeof(Exp));/*构造生成的表达式*/
j=0;
for(i=0;i{
if(bracket[i]==-1)
{
Exp[j]='(';
j=j+1;
}
k=0;
while(number[i]>0)
{
digit[k]=number[i]%10;
number[i]/=10;
k++;
}
for(w=k-1;w>=0;w--)
{
Exp[j]=digit[w]+'0';
j=j+1;
}
if(bracket[i]==1)
{
Exp[j]=')';
j=j+1;
}
Exp[j]=oper[i];
j++;
}
ret=ProcessExp();/*计算表达式的结果*/
if(isCorrect)/*如果合法,退出*/
break;
}
returnret;
}
voidoperate()
{intj,k,i,ans=0,rep=0,correctNum=0;
charc;
printf("请输入您要做题的数量:
");
scanf("%d",&k);
for(i=1;i<=k;i++)
{
ans=GenerateExp();
if(ans<101&&ans>-1)
{
{
{printf("%s=\n",Exp);
printf("答案:
");}
while((c=getchar())=='\n'||c=='')/*忽略用户无意输入的空格和回车*/
;
ungetc(c,stdin);/*将最后的合法字符放回输入缓冲区*/
gets(reply);/*读取用户答案*/
rep=0;}
{for(j=0;reply[j];j++)/*将用户的答案转化为数字*/
{
if(!
isdigit(reply[j]))
break;
rep=rep*10+reply[j]-'0';
}
if(reply[j])/*若发现用户输入中有字母,退出*/
return;
if(reply[j]||rep!
=ans)/*与标准答案不一致*/
{printf("很抱歉,回答错误!
\n");wrong++;}
elseif(rep==ans)/*回答正确*/
{
printf("恭喜您,回答正确!
\n");right++;
}
}
}
elsei--;
}
}
voidmain_2()
{
intchoise,con=0;
system("cls");
printf("\n\n\t\t混合运算练习界面\n");
system("pause");
system("cls");
while
(1)
{
printf("\n\n\t\t请选择:
\n继续(输入1)\n退出(输入2)\n");
if(con==0)scanf("%d",&choise);
switch(choise)
{
case1:
operate();break;
case2:
;break;
}
printf("请问您想继续进行这个运算还是重新选择其他运算还是退出程序?
\n继续(输入1),重头再来(输入2)\n,退出(输入3)\n");
scanf("%d",&con);
if(con==1)con=1;
if(con==2)con=0;
if(con==3)break;
}
system("pause");
}
charOP[7]={'+','-','*','/','(',')','#'};//运算符数组
charLEVEL[7][7]={'>','>','<','<','<','>','>',
'>','>','<','<','<','>','>','>','>','>','>','<','>','>','>','>','>','>','<','>','>',
'<','<','<','<','<','=','','>','>','>','>','','>','>','<','<','<','<','<','','='};//用二维数组定义运算符优先级
intIn(charc)
{
switch(c)
{
case'+':
case'-':
case'*':
case'/':
case'(':
case')':
case'#':
return1;
}
return0;
}//判断c是否在运算符数组中
charPrecede(charc1,charc2)
{
inti,j;
for(intk=0;k<7;k++)
if(c1==OP[k]){i=k;break;}//判断c1为何种运算符
for(k=0;k<7;k++)
if(c2==OP[k]){j=k;break;}//判断c2为何种运算符
returnLEVEL[i][j];
}//判断两个运算符的优先级
intoparate(intf1,charc,intf2)
{
switch(c)
{
case'+':
returnf1+f2;
case'-':
returnf1-f2;
case'*':
returnf1*f2;
case'/':
returnf1/f2;
}
return0;
}//计算f1和f2
intEve(stack*OPTR,stack*OPND)
{
charc;
inti,temp;
intt,x,theta;
charn[20];//定义一个数组临时存储待转换字符
charc1='#';
push(OPTR,(int)c1);
c=getchar();
intl,r;
i=0;
while(c!
='='||(int)GetTop(OPTR)!
=(int)('#'))
{
if(c=='=')
{
c=c-26;
}//将'='转换为'#'进行处理
if(theta=='/'&&r==0)
{
while(c!
='\n')
{
c=getchar();
}
printf("Error!
\n");
break;
}//除数为0处理
if(!
In(c))
{
n[i]=c;
i++;
c=getchar();//如果获取的是不是运算符,则暂存于一个数组中,继续获取下一字符
continue;
}
if(In(c))
{
if(n[0]!
='\0')
{
i=0;
t=(int)atof(n);//将数组中的字符串转换为float型数据
push(OPND,t);
memset(n,'\0',strlen(n));//清空数组,待下次获取v
}
temp=(int)GetTop(OPTR);
switch(Precede((char)temp,c))
{
case'<':
push(OPTR,(int)c);
c=getchar();
break;
case'=':
x=pop(OPTR);
c=getchar();
break;
case'>':
theta=pop(OPTR);
r=pop(OPND);
l=pop(OPND);
if(theta=='/'&&r==0)
{
v=1;
break;
}