《C++计算器程序课程设计(共18页).doc》由会员分享,可在线阅读,更多相关《C++计算器程序课程设计(共18页).doc(18页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上荆楚理工学院课程设计成果 学院: 计算机工程学院 班 级: 14计算机科学与技术班 学生姓名: 杨悦 学 号: 15 设计地点(单位): 设计题目: 模拟计算器程序 完成日期: 2016 年 6 月 30 日 指导教师评语: _成绩(五级记分制): 教师签名: 专心-专注-专业 目 录1 设计任务1.1设计目的运用所学C+知识,完成模拟计算器程序,通过实践加强对所学知识的理解和巩固。1.2设计内容设计一个程序来模拟一个简单的手持计算器。程序支持幂运算、算术运算+、-、*、/、=、以及Black(清除)、Esc(全清除)等操作。1.3设计指标或者要求程序运行时,显示一个
2、窗口,等待用户输入,用户可以从键盘输入要计算的表达式,输入的表达式显示在窗口中,用户键入“=” 符号回车后,窗口显示出结果。2 设计过程通过对微软附件计算器软件进行调研、分析,研究,使用。我们了解到了作为一个计算器所应该的一些简单功能,我们知道了怎样使编写的计算器程序向微软附件计算器靠拢。其中计算器软件的主要功能是:1)可以进行加减乘除四则运算2)可以实现科学计算器的部分计算功能3)可以进行清零运算4)可以进行退格键运算5)可以进行连续计算2.1程序功能void menu();/位于calculate函数后面的菜单函数声明void guide();/位于主函数后面的指导函数的声明double
3、D_Operate(double x,char op,double y)/双目运算符的运算定义double S_Operate(char op,double x)/前缀单目运算符的运算定义char Precede(char op1,char op2) /判断符号的优先级 op1在返回的结果符的左边 op2在右边/用于判定运算符的优先级 以决定是把运算符压栈 还是把栈内的运算符弹出来进行计算int match(string s)/栈结构的括号匹配检测函数class NUMstack/运算数栈 void start()/初始化栈清空栈顶指针置底 for(int i=0;i1000;i+) numi
4、=0; top=0; class OPERstack/运算符栈 public: char oper1000; int top; void start()/初始化函数栈清空栈底放一=用于判定算式结束 oper0=; for(int i=1;i1000;i+) operi=NULL; top=1;/栈顶指针置于栈底的上一位 void calculate(string equation)/算式计算函数(关键函数) NUMstack number;/定义运算数栈变量number OPERstack oper;/定义运算符栈变量oper number.start(); oper.start();/把两个
5、栈初始化number.numnumber.top=tt;/运算结果压回原来yuan1在栈内的位置 number.lift();/提升指针 temp1=oper.getTop(); rep=Precede(temp1,temp2);/再判优先级rep=Precede(temp1,temp2);/双目运算符的计算if(number.num0=ceil(number.num0) coutequationnumber.num0endl; else coutequationfixedsetprecision(8)number.num0go_on;/可以循环进行算式计算运行程序2.2程序流程图进入界面,输
6、入第一个操作数输入“=”键,输出运算结果选择计算算式选择,进行运算根据所选功能,选择下一个操作数显示运算结果3软件运行或者测试结果进入界面输入“1”,查看说明按任意键,返回界面,并输入“2”输入算式“(2+3)*10/2=”输入“y”后,继续输入算式“(1+2/3=”4 软件设计过程中遇到的问题以及解决办法经过大约一个星期的设计,计算器基本完毕。在本次课程设计中困难遇到不少,比如如何对输入的一个字符数组中的单个字符进行整型运算、如何能循环菜单、如何倒叙输出等。由于设计时间较短,所以该计算器还有很多不尽如人意的地方,比如功能不够完善、函数不够完整等多方面问题。在这次系统开发的过程中,我深深体会到
7、了做一个系统,首先要进行需求分析的重要性,也了解到了制作一个软件的不易。5 总结通过本次课程设计学到了很多东西,对于c+对象的含义有了进一步的认识。学习不能只是停留在表面,此次课程设计为以后的学习积累了经验,设计不比编写容易,只有一个好的规划才能写出好的程序。不过也通过本次发现了自己的不足之处。总是:本次课程设计受益匪浅,动手能力大大增强。参考文献1李素若.C+面向对象程序设计.北京:中国水利水电出版社,2013.2郑莉,傅仕星编,C+面向对象程序设计,清华大学出版社,2003年9.3谭浩强编,C+面向对象程序设计,清华大学出版社,2005年7月.4李师贤等译,C+精髓,机械工业出版社,200
8、2年8月.5Davis Chapman,学用Visualc+6.0,清华大学出版社,2001年7月出版6郑莉,傅仕星编,C+语言面向对象程序设计习题与实验指导,清华大学出版社,2003年9月.附录(程序源代码)#include#include#include#includeusing namespace std;void menu();/位于calculate函数后面的菜单函数声明void guide();/位于主函数后面的指导函数的声明double D_Operate(double x,char op,double y)/双目运算符的运算定义 double a;/计算结果 switch(op
9、) case+: a=x+y;break; case-: a=x-y;break; case*: a=x*y;break; case/: a=x/y;break; case: a=pow(x,y);break;/幂运算包括乘方和开方 /因为都是利用double进行运算 因此不定义取模运算 return a;double S_Operate(char op,double x)/前缀单目运算符的运算定义 double a;/计算结果 switch(op) cases: a=sin(x);break; casec: a=cos(x);break; caset: a=tan(x);break; cas
10、el: a=log10(x);break;/以10为底的对数 casen: a=log(x);break;/以e(2.)为底的对数 case_: a=-x;break;/取负用下划线代替负号 定义为一元运算 return a;char Precede(char op1,char op2) /判断符号的优先级 op1在返回的结果符的左边 op2在右边/用于判定运算符的优先级 以决定是把运算符压栈 还是把栈内的运算符弹出来进行计算 if(op1=+|op1=-)&(op2=+|op2=-|op2=)|op2=)| (op1=*|op1=/)&(op2=+|op2=-|op2=*|op2=/|op2
11、=)|op2=) |(op1=&(op2=+|op2=-|op2=*|op2=/|op2=)|op2=|op2=s|op2=c|op2=t|op2=_|op2=l|op2=n) |(op1=_|op1=s|op1=c|op1=t|op1=l|op1=n)&(op2=+|op2=-|op2=*|op2=/|op2=)|op2=|op2=s|op2=c|op2=t|op2=_|op2=l|op2=n) return ;/上述情况下 栈顶运算符优先级高于待定运算符 需弹栈 if(op1=(&op2=)|(op1=&op2=) return =; else return ;int illegal_ch
12、ar(string s,int i)/非法输入字符判定函数 int j=0; while(j=0&sj=9) j+; else if(sj=+|sj=-|sj=*|sj=/|sj=.|sj=(|sj=)|sj=|sj=!|sj=e|sj=_) j+; else if(sj=p&sj+1=i)|(sj=l&sj+1=n) j+=2; else if(sj=s&sj+1=i&sj+2=n)|(sj=c&sj+1=o&sj+2=s)|(sj=t&sj+1=a&sj+2=n)|(sj=l&sj+1=o&sj+2=g) j+=3; /以上都是标准的数字字符和运算符 如若存在其他形式的字符 则是非法输入
13、else cout程序终止,存在非法的字符输入!endl; return 0; return 1;/没有非法字符 返回1 否则返回0int match(string s)/栈结构的括号匹配检测函数 int i=0,top=0; char stack50; while(si!=0) if(si=() stacktop=si; top+; /push 左括号压入栈内 if(si=) if(stacktop-1=() int a=i+1; stacktop-1=NULL; top-; /把与右括号匹配的左括号弹掉 else cout括号输入有误endl; return 0;/多了右括号 括号失陪 返
14、回非法 /pop( i+; if (top!=0) cout括号输入有误endl; return 0;/多了左括号 括号失陪 返回非法 return 1;/返回合法class NUMstack/运算数栈 public: double num1000; int top; void start()/初始化栈清空栈顶指针置底 for(int i=0;i1000;i+) numi=0; top=0; void push(char a)/因为有多位数的运算因此不能一压栈就提升栈顶指针 numtop=numtop*10+(a-0);/把字符转成数因为每次入栈之前要乘10 所以初始化要清0 double p
15、op() top-; double number=numtop; numtop=0; return number; /弹栈函数 弹掉栈顶元素 栈顶归0 top指针下降 double getTop()/取栈顶元素但不必弹栈 return numtop-1; void lift()/提升top指针的函数 top+;class OPERstack/运算符栈 public: char oper1000; int top; void start()/初始化函数栈清空栈底放一=用于判定算式结束 oper0=; for(int i=1;i1000;i+) operi=NULL; top=1;/栈顶指针置于栈
16、底的上一位 void push(char a) opertop=a; top+;/与数字栈不同一压栈就可以提升指针 char pop() top-; char op=opertop; opertop=NULL; return op;/弹出计算符 用于计算 char getTop() return opertop-1;/取栈顶符号 但不弹栈 可用于判定优先级 ; void calculate(string equation)/算式计算函数(关键函数) NUMstack number;/定义运算数栈变量number OPERstack oper;/定义运算符栈变量oper number.start
17、(); oper.start();/把两个栈初始化 int i=0,len=0,k; char p,sig; double yuan1,yuan2; while(equationi!=0) len+; i+; /计算等式长度len if(equationlen-1!=) cout输入有误没有输入终止符号-等号“=”endl; return;/检测有没有结束符等号= int le; le=illegal_char(equation,len-1); if(le=0) return;/有非法字符 不进行后续计算 le=match(equation); if(le=0) return;/括号匹配非法
18、不进行后续计算 for(i=0;ilen;i+)/初步确定合法后开始计算算式 if(equationi=!)/阶乘是后缀单目运算符单独进行计算 yuan1=number.pop();/弹出栈顶元素做阶乘 if (yuan1=0) number.numnumber.top=0;/0的阶乘为0 压结果入栈 number.lift(); else number.numnumber.top=1; for(k=1;k=0&equationi=9) number.push(equationi);/压数字字符入栈 if(equationi+19)&equationi+1!=.) number.lift();
19、/当整个多位运算数读取完毕后,运算数栈栈顶指针才能提升 else if(equationi=p) number.numnumber.top=3.;/pi值即 圆周率 要压入数字栈 number.lift(); i+;/pi是两个字符所以要移动扫描算式的指针往后跳一个 else if(equationi=e) number.numnumber.top=2.9;/e 自然对数底数 压入运算数栈 number.lift(); else if(equationi=.)/小数压栈代码 int x=1; while(equationi+x=0&equationi+x=9) number.numnumber
20、.top+=(equationi+x-0)/pow(10,x);/第x位小数入栈 x+; x-; number.lift(); i=i+x; else if(equationi=() oper.push(equationi);/左括号无条件压栈 else/数 阶乘左括号判断完毕后其他运算符的分类讨论 if(oper.top=1)/运算符栈为空运算符可以无条件入栈 if(equationi=l&equationi+1=o) oper.push(l); else if(equationi=l&equationi+1=n) oper.push(n);/因为log和ln都是小写字母l开头所以要分情况讨
21、论 else oper.push(equationi); else/运算符栈不为空则要进行优先级判断 char temp1=oper.getTop();/取出栈顶符号 char temp2;/待入栈符号 if(equationi=l&equationi+1=o) temp2=l; else if(equationi=l&equationi+1=n) temp2=n;/log与ln的再次讨论 else temp2=equationi; p=Precede(temp1,temp2); if(p=|p=) char rep=p;/当栈顶符优先级不低于待入栈的符号 则运算符栈不停地弹栈 /进行运算直到
22、低于待入栈符号为止 rep用于记录比较结果 要多次进行判断 while(rep=|p=)&(oper.top-10) sig=oper.pop(); yuan1=number.pop(); yuan2=number.getTop();/靠前的一个运算数只要取得不要弹出来 if(sig=/&yuan1=0)/yuan1是双目运算符后面的第二运算元 cout计算时出错!出现了除数为0的情况!endl; return; if(sig=&yuan20&yuan11&(static_cast (1/yuan1)%2=0) /对负数开偶次根号的限制 cout计算时出错!出现了负数开偶次根号的情况!endl
23、; return; if(sig=_|sig=s|sig=c|sig=t|sig=l|sig=n)/若为前缀单目运算符 double tt; tt=S_Operate(sig,yuan1); number.numnumber.top=tt;/运算结果压回原来yuan1在栈内的位置 number.lift();/提升指针 temp1=oper.getTop(); rep=Precede(temp1,temp2);/再判优先级 else number.num(number.top)-1=D_Operate(yuan2,sig,yuan1); temp1=oper.getTop(); rep=Pre
24、cede(temp1,temp2);/双目运算符的计算 if(equationi=)/如果栈外符是右括号要把与之匹配的左括号弹出栈外 oper.pop(); else if(equationi=l&equationi+1=o) oper.push(l);/代表log的l else if(equationi=l)&(equationi+1=n) oper.push(n);/代表ln的n else oper.push(equationi); if(equationi=s|equationi=c|equationi=t|(equationi=l&equationi+1=o) i=i+2; if(eq
25、uationi=l&equationi+1=n) i+; /对于不止一个字符的运算符 sin log ln等等 要移动扫描算式的指针 往后跳一个或两个 if(number.num0=ceil(number.num0) coutequationnumber.num0endl; else coutequationfixedsetprecision(8)number.num0endl;/输出结果控制精度8位小数 /调试时检查运算结束后站内情况的代码段void menu()/菜单函数 cout实数型科学算式计算器endl; cout(荆楚理工学院215 杨悦)endl; coutendl; cout欢
26、迎使用o(_)o !endl; cout请选择你需要的功能:(0,1或者2)endl; cout-endl; cout1.使用说明endl; cout2.计算算式endl; cout0.退出程序endl; cout-endl; coutchoice; switch(choice) case 0:return; case 1:guide();break; case 2: system(cls); char go_on=y; string equation; while(go_on=y) coutendlendl请输入算式,以=(等号)结束:equation; calculate(equation
27、); coutgo_on;/可以循环进行算式计算 system(cls); menu(); void main() menu();void guide()/输入规则介绍说明书 system(cls); cout使用说明:endl; cout输入算式时,请按照下列规则输入:endl; cout1.四则运算+加 -减 *乘 /除按常规输入,负号用下划线(_)代替,注意将其与减号区别;可用括号()界定优先级endl; cout2.幂:幂运算如下乘方输入xy(x的y次方)如236就是23的6次方;开方也这样输入如81(1/4)或者810.25表示81开4次方endl; cout3.!阶乘:6!表示1*
28、2*3*4*5*6;(1+3)!表示4的阶乘,结果是24;1+3!表示1再加上3做阶乘的结果,是7endl; cout4.pi代表圆周率,即3.,本计算器利用弧度进行三角函数计算;计算正弦请输入sin,余弦输入cos,正切输入tan;sin(pi/2)就是二分之弧度对应的正弦值(注意一定要打括号)其他依此类推;endl; cout5.计算以10为底的对数请输入log,如log1000=3,计算以e(2.)为底的自然对数请输入ln,如lne4=4,注意指数的输入要规范,如lne4=4,但是(lne)4=1,计算算式的对数要在对数符号后面把算式括起来,如ln(3+6*9),计算以其他数为底的对数可利用对数换底公式,如以2为底,16的对数可输入ln16/ln2或者log16/log2结果都是4endl; cout6.可直接输入e和pi做数值计算endl; cout7.本计算器的括号只有小括号();不接受中括号 和大括号 ,且算式一定要以等号(=)结束endl; system(pause); system(cls); menu();