C++计算器程序课程设计_第1页
C++计算器程序课程设计_第2页
C++计算器程序课程设计_第3页
C++计算器程序课程设计_第4页
C++计算器程序课程设计_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、荆楚理工学院课程设计成果 学院: 计算机工程学院 班 级: 14计算机科学与技术<2>班 学生姓名: 杨悦 学 号: 2014404010215 设计地点(单位): 设计题目: 模拟计算器程序 完成日期: 2016 年 6 月 30 日 指导教师评语: _成绩(五级记分制): 教师签名: 目 录1 设计任务11.1设计目的11.2设计内容11.3设计指标或者要求12 设计过程12.1程序功能12.2程序流程图33软件运行或者测试结果44 软件设计过程中遇到的问题以及解决办法65 总结6参考文献6附录(程序源代码)71 设计任务1.1设计目的运用所学C+知识,完成模拟计算器程序,通过

2、实践加强对所学知识的理解和巩固。1.2设计内容设计一个程序来模拟一个简单的手持计算器。程序支持幂运算、算术运算+、-、*、/、=、以及Black(清除)、Esc(全清除)等操作。1.3设计指标或者要求程序运行时,显示一个窗口,等待用户输入,用户可以从键盘输入要计算的表达式,输入的表达式显示在窗口中,用户键入“=” 符号回车后,窗口显示出结果。2 设计过程通过对微软附件计算器软件进行调研、分析,研究,使用。我们了解到了作为一个计算器所应该的一些简单功能,我们知道了怎样使编写的计算器程序向微软附件计算器靠拢。其中计算器软件的主要功能是: 1)可以进行加减乘除四则运算2)可以实现科学计算器

3、的部分计算功能3)可以进行清零运算 4)可以进行退格键运算 5)可以进行连续计算2.1程序功能void menu();/位于calculate函数后面的菜单函数声明void guide();/位于主函数后面的指导函数的声明double D_Operate(double x,char op,double y)/双目运算符的运算定义double S_Operate(char op,double x)/前缀单目运算符的运算定义char Precede(char op1,char op2) /判断符号的优先级 op1在返回的结果符的左边 op2在右边/用于判定运算符的优先级 以决定

4、是把运算符压栈 还是把栈内的运算符弹出来进行计算int match(string s)/栈结构的括号匹配检测函数class NUMstack/运算数栈 void start()/初始化栈清空栈顶指针置底 for(int i=0;i<1000;i+) numi=0; top=0; class OPERstack/运算符栈 public: char oper1000; int top; void start()/初始化函数栈清空栈底放一"="用于判定算式结束 oper0='=' for(int i=1;i<1000;i+) operi=NULL; t

5、op=1;/栈顶指针置于栈底的上一位 void calculate(string equation)/算式计算函数(关键函数) NUMstack number;/定义运算数栈变量number OPERstack oper;/定义运算符栈变量oper number.start(); oper.start();/把两个栈初始化number.numnumber.top=tt;/运算结果压回原来yuan1在栈内的位置 number.lift();/提升指针 temp1=oper.getTop(); rep=Precede(temp1,temp2);/再判优先级rep=Precede(temp1,tem

6、p2);/双目运算符的计算if(number.num0=ceil(number.num0) cout<<equation<<number.num0<<endl; else cout<<equation<<fixed<<setprecision(8)<<number.num0<<endl;/输出结果控制精度8位小数 /调试时检查运算结束后站内情况的代码段void menu()/菜单函数 cin>>go_on;/可以循环进行算式计算运行程序2.2程序流程图进入界面,输入第一个操作数输入“=”

7、键,输出运算结果选择计算算式选择,进行运算根据所选功能,选择下一个操作数显示运算结果3软件运行或者测试结果进入界面输入“1”,查看说明按任意键,返回界面,并输入“2”输入算式“(2+3)*10/2=”输入“y”后,继续输入算式“(1+2/3=”4 软件设计过程中遇到的问题以及解决办法经过大约一个星期的设计,计算器基本完毕。在本次课程设计中困难遇到不少,比如如何对输入的一个字符数组中的单个字符进行整型运算、如何能循环菜单、如何倒叙输出等。由于设计时间较短,所以该计算器还有很多不尽如人意的地方,比如功能不够完善、函数不够完整等多方面问题。在这次系统开发的过程中,我深深体会到了做一个系统,首先要进行

8、需求分析的重要性,也了解到了制作一个软件的不易。5 总结通过本次课程设计学到了很多东西,对于c+对象的含义有了进一步的认识。学习不能只是停留在表面,此次课程设计为以后的学习积累了经验,设计不比编写容易,只有一个好的规划才能写出好的程序。不过也通过本次发现了自己的不足之处。总是:本次课程设计受益匪浅,动手能力大大增强。参考文献1李素若.C+面向对象程序设计.北京:中国水利水电出版社,2013.2郑莉,傅仕星编,C+面向对象程序设计,清华大学出版社,2003年9.3谭浩强编,C+面向对象程序设计,清华大学出版社,2005年7月.4李师贤等译,C+精髓,机械工业出版社,2002年8月.5Davis

9、Chapman,学用Visual c+ 6.0,清华大学出版社,2001年7月出版6郑莉,傅仕星编,C+语言面向对象程序设计习题与实验指导,清华大学出版社,2003年9月.附录(程序源代码)#include<iostream>#include<cmath>#include<string>#include<iomanip>using namespace std;void menu();/位于calculate函数后面的菜单函数声明void guide();/位于主函数后面的指导函数的声明double D_Operate(doub

10、le x,char op,double y)/双目运算符的运算定义 double a;/计算结果 switch(op) 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)/前缀单

11、目运算符的运算定义 double a;/计算结果 switch(op) case's': a=sin(x);break; case'c': a=cos(x);break; case't': a=tan(x);break; case'l': a=log10(x);break;/以10为底的对数 case'n': a=log(x);break;/以e(2.718281828)为底的对数 case'_': a=-x;break;/取负用下划线代替负号 定义为一元运算 return a;char Prece

12、de(char op1,char op2) /判断符号的优先级 op1在返回的结果符的左边 op2在右边/用于判定运算符的优先级 以决定是把运算符压栈 还是把栈内的运算符弹出来进行计算 if(op1='+'|op1='-')&&(op2='+'|op2='-'|op2=')'|op2='=')| (op1='*'|op1='/')&&(op2='+'|op2='-'|op2='*'|op2

13、='/'|op2=')'|op2='=') |(op1=''&&(op2='+'|op2='-'|op2='*'|op2='/'|op2=')'|op2='='|op2='s'|op2='c'|op2='t'|op2='_'|op2='l'|op2='n') |(op1='_'|op1='s'|

14、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 '>'/上述情况下 栈顶运算

15、符优先级高于待定运算符 需弹栈 if(op1='('&&op2=')')|(op1='='&&op2='=') return '=' else return '<'int illegal_char(string s,int i)/非法输入字符判定函数 int j=0; while(j<i) if(sj>='0'&&sj<='9') j+; else if(sj='+'|sj=

16、9;-'|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'&

17、&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; /以上都是标准的数字字符和运算符 如若存在其他形式的字符 则是非法输入 else cout<<"程序终止,

18、存在非法的字符输入!"<<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-; /把与右括号匹配的左括号弹掉 el

19、se cout<<"括号输入有误"<<endl; return 0;/多了右括号 括号失陪 返回非法 /pop'(' i+; if (top!=0) cout<<"括号输入有误"<<endl; return 0;/多了左括号 括号失陪 返回非法 return 1;/返回合法class NUMstack/运算数栈 public: double num1000; int top; void start()/初始化栈清空栈顶指针置底 for(int i=0;i<1000;i+) numi=0

20、; top=0; void push(char a)/因为有多位数的运算因此不能一压栈就提升栈顶指针 numtop=numtop*10+(a-'0');/把字符转成数因为每次入栈之前要乘10 所以初始化要清0 double pop() top-; double number=numtop; numtop=0; return number; /弹栈函数 弹掉栈顶元素 栈顶归0 top指针下降 double getTop()/取栈顶元素但不必弹栈 return numtop-1; void lift()/提升top指针的函数 top+;class OPERstack/运算符栈 pu

21、blic: char oper1000; int top; void start()/初始化函数栈清空栈底放一"="用于判定算式结束 oper0='=' for(int i=1;i<1000;i+) operi=NULL; top=1;/栈顶指针置于栈底的上一位 void push(char a) opertop=a; top+;/与数字栈不同一压栈就可以提升指针 char pop() top-; char op=opertop; opertop=NULL; return op;/弹出计算符 用于计算 char getTop() return oper

22、top-1;/取栈顶符号 但不弹栈 可用于判定优先级 ; void calculate(string equation)/算式计算函数(关键函数) NUMstack number;/定义运算数栈变量number OPERstack oper;/定义运算符栈变量oper number.start(); oper.start();/把两个栈初始化 int i=0,len=0,k; char p,sig; double yuan1,yuan2; while(equationi!='0') len+; i+; /计算等式长度len if(equationlen-1!='=

23、9;) cout<<"输入有误没有输入终止符号-等号“=”"<<endl; return;/检测有没有结束符等号"=" int le; le=illegal_char(equation,len-1); if(le=0) return;/有非法字符 不进行后续计算 le=match(equation); if(le=0) return;/括号匹配非法 不进行后续计算 for(i=0;i<len;i+)/初步确定合法后开始计算算式 if(equationi='!')/阶乘是后缀单目运算符单独进行计算 yuan1=

24、number.pop();/弹出栈顶元素做阶乘 if (yuan1=0) number.numnumber.top=0;/0的阶乘为0 压结果入栈 number.lift(); else number.numnumber.top=1; for(k=1;k<=yuan1;k+)/阶乘循环 number.numnumber.top=k*number.numnumber.top; number.lift();/结果入站 else if(equationi>='0'&&equationi<='9') number.push(equati

25、oni);/压数字字符入栈 if(equationi+1<'0'|equationi+1>'9')&&equationi+1!='.') number.lift();/当整个多位运算数读取完毕后,运算数栈栈顶指针才能提升 else if(equationi='p') number.numnumber.top=3.1415926536;/pi值即 圆周率 要压入数字栈 number.lift(); i+;/pi是两个字符所以要移动扫描算式的指针往后跳一个 else if(equationi='e&

26、#39;) number.numnumber.top=2.718281828459;/e 自然对数底数 压入运算数栈 number.lift(); else if(equationi='.')/小数压栈代码 int x=1; while(equationi+x>='0'&&equationi+x<='9') number.numnumber.top+=(equationi+x-'0')/pow(10,x);/第x位小数入栈 x+; x-; number.lift(); i=i+x; else if(eq

27、uationi='(') 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开头

28、所以要分情况讨论 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

29、; p=Precede(temp1,temp2); if(p='<') oper.push(temp2);/栈顶符优先级较低现在待定的运算符就可以入栈了 if(p='>'|p='=') char rep=p;/当栈顶符优先级不低于待入栈的符号 则运算符栈不停地弹栈 /进行运算直到低于待入栈符号为止 rep用于记录比较结果 要多次进行判断 while(rep='>'|p='=')&&(oper.top-1>0) sig=oper.pop(); yuan1=number.pop(

30、); yuan2=number.getTop();/靠前的一个运算数只要取得不要弹出来 if(sig='/'&&yuan1=0)/yuan1是双目运算符后面的第二运算元 cout<<"计算时出错!出现了除数为0的情况!"<<endl; return; if(sig=''&&yuan2<0&&yuan1>0&&yuan1<1&&(static_cast <int>(1/yuan1)%2=0) /对负数开偶次根号的

31、限制 cout<<"计算时出错!出现了负数开偶次根号的情况!"<<endl; 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();

32、 rep=Precede(temp1,temp2);/再判优先级 else number.num(number.top)-1=D_Operate(yuan2,sig,yuan1); temp1=oper.getTop(); rep=Precede(temp1,temp2);/双目运算符的计算 if(equationi=')')/如果栈外符是右括号要把与之匹配的左括号弹出栈外 oper.pop(); else if(equationi='l'&&equationi+1='o') oper.push('l');/代表l

33、og的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(equationi='l'&&equa

34、tioni+1='n') i+; /对于不止一个字符的运算符 sin log ln等等 要移动扫描算式的指针 往后跳一个或两个 if(number.num0=ceil(number.num0) cout<<equation<<number.num0<<endl; else cout<<equation<<fixed<<setprecision(8)<<number.num0<<endl;/输出结果控制精度8位小数 /调试时检查运算结束后站内情况的代码段void menu()/菜单函数

35、 cout<<"实数型科学算式计算器"<<endl; cout<<"(荆楚理工学院215 杨悦)"<<endl; cout<<endl; cout<<"欢迎使用o(_)o !"<<endl; cout<<"请选择你需要的功能:(0,1或者2)"<<endl; cout<<"-"<<endl; cout<<"1.使用说明"<<

36、;endl; cout<<"2.计算算式"<<endl; cout<<"0.退出程序"<<endl; cout<<"-"<<endl; cout<<"你的选择是:" int choice; cin>>choice; switch(choice) case 0:return; case 1:guide();break; case 2: system("cls"); char go_on='y' string equation; while(go_on='y') cout<<endl<<endl<<"请输入算式,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论