C++计算器程序课程设计.docx
- 文档编号:29067121
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:25
- 大小:99.87KB
C++计算器程序课程设计.docx
《C++计算器程序课程设计.docx》由会员分享,可在线阅读,更多相关《C++计算器程序课程设计.docx(25页珍藏版)》请在冰豆网上搜索。
C++计算器程序课程设计
荆楚理工学院
课程设计成果
学院:
计算机工程学院班级:
14计算机科学与技术<2>班
学生姓名:
杨悦学号:
*************
设计地点(单位):
设计题目:
模拟计算器程序
完成日期:
2016年6月30日
指导教师评语:
______________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
成绩(五级记分制):
教师签名:
1设计任务
1.1设计目的
运用所学C++知识,完成模拟计算器程序,通过实践加强对所学知识的理解和巩固。
1.2设计内容
设计一个程序来模拟一个简单的手持计算器。
程序支持幂运算、算术运算+、-、*、/、=、以及Black(清除)、Esc(全清除)等操作。
1.3设计指标或者要求
程序运行时,显示一个窗口,等待用户输入,用户可以从键盘输入要计算的表达式,输入的表达式显示在窗口中,用户键入“=”符号回车后,窗口显示出结果。
2设计过程
通过对微软附件计算器软件进行调研、分析,研究,使用。
我们了解到了作为一个计算器所应该的一些简单功能,我们知道了怎样使编写的计算器程序向微软附件计算器靠拢。
其中计算器软件的主要功能是:
1)可以进行加减乘除四则运算
2)可以实现科学计算器的部分计算功能
3)可以进行清零运算
4)可以进行退格键运算
5)可以进行连续计算
2.1程序功能
voidmenu();//位于calculate函数后面的菜单函数声明
voidguide();//位于主函数后面的指导函数的声明
doubleD_Operate(doublex,charop,doubley)//双目运算符的运算定义
doubleS_Operate(charop,doublex)//前缀单目运算符的运算定义
charPrecede(charop1,charop2)//判断符号的优先级op1在返回的结果符的左边op2在右边
//用于判定运算符的优先级以决定是把运算符压栈还是把栈内的运算符弹出来进行计算
intmatch(strings)//栈结构的括号匹配检测函数
classNUMstack//运算数栈
voidstart()//初始化栈清空栈顶指针置底
{
for(inti=0;i<1000;i++)
num[i]=0;
top=0;
}
classOPERstack//运算符栈
{
public:
charoper[1000];
inttop;
voidstart()//初始化函数栈清空栈底放一"="用于判定算式结束
{
oper[0]='=';
for(inti=1;i<1000;i++)
oper[i]=NULL;
top=1;//栈顶指针置于栈底的上一位
}
voidcalculate(stringequation)//算式计算函数(关键函数)
{
NUMstacknumber;//定义运算数栈变量number
OPERstackoper;//定义运算符栈变量oper
number.start();
oper.start();//把两个栈初始化
number.num[number.top]=tt;//运算结果压回原来yuan1在栈内的位置
number.lift();//提升指针
temp1=oper.getTop();
rep=Precede(temp1,temp2);//再判优先级
rep=Precede(temp1,temp2);//双目运算符的计算
if(number.num[0]==ceil(number.num[0]))
cout< else {cout< //调试时检查运算结束后站内情况的代码段 voidmenu()//菜单函数 cin>>go_on;//可以循环进行算式计算 2.2程序流程图 3软件运行或者测试结果 进入界面 输入“1”,查看说明 按任意键,返回界面,并输入“2” 输入算式“(2+3)*10/2=” 输入“y”后,继续输入算式“(1+2/3=” 4软件设计过程中遇到的问题以及解决办法 经过大约一个星期的设计,计算器基本完毕。 在本次课程设计中困难遇到不少,比如如何对输入的一个字符数组中的单个字符进行整型运算、如何能循环菜单、如何倒叙输出等。 由于设计时间较短,所以该计算器还有很多不尽如人意的地方,比如功能不够完善、函数不够完整等多方面问题。 在这次系统开发的过程中,我深深体会到了做一个系统,首先要进行需求分析的重要性,也了解到了制作一个软件的不易。 5总结 通过本次课程设计学到了很多东西,对于c++对象的含义有了进一步的认识。 学习不能只是停留在表面,此次课程设计为以后的学习积累了经验,设计不比编写容易,只有一个好的规划才能写出好的程序。 不过也通过本次发现了自己的不足之处。 总是: 本次课程设计受益匪浅,动手能力大大增强。 参考文献 [1]李素若.《C++面向对象程序设计》.北京: 中国水利水电出版社,2013. [2]郑莉,傅仕星编,《C++面向对象程序设计》,清华大学出版社,2003年9. [3]谭浩强编,《C++面向对象程序设计》,清华大学出版社,2005年7月. [4]李师贤等译,《C++精髓》,机械工业出版社,2002年8月. [5]DavisChapman,《学用Visual c++ 6.0》,清华大学出版社,2001年7月出版 [6]郑莉,傅仕星编,C++语言面向对象程序设计习题与实验指导,清华大学出版社,2003年9月. 附录(程序源代码) #include #include #include #include usingnamespacestd; voidmenu();//位于calculate函数后面的菜单函数声明 voidguide();//位于主函数后面的指导函数的声明 doubleD_Operate(doublex,charop,doubley)//双目运算符的运算定义 { doublea;//计算结果 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进行运算因此不定义取模运算 returna; } doubleS_Operate(charop,doublex)//前缀单目运算符的运算定义 { doublea;//计算结果 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;//取负用下划线代替负号定义为一元运算 } returna; } charPrecede(charop1,charop2)//判断符号的优先级op1在返回的结果符的左边op2在右边 //用于判定运算符的优先级以决定是把运算符压栈还是把栈内的运算符弹出来进行计算 { if(((op1=='+'||op1=='-')&&(op2=='+'||op2=='-'||op2==')'||op2=='='))||\ ((op1=='*'||op1=='/')&&(op2=='+'||op2=='-'||op2=='*'||op2=='/'||op2==')'||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'<'; } intillegal_char(strings,inti)//非法输入字符判定函数 { intj=0; while(j { if(s[j]>='0'&&s[j]<='9') j++; elseif(s[j]=='+'||s[j]=='-'||s[j]=='*'||s[j]=='/'||s[j]=='.'||s[j]=='('||s[j]==')'||s[j]=='^'||s[j]=='! '||s[j]=='e'||s[j]=='_') j++; elseif((s[j]=='p'&&s[j+1]=='i')||(s[j]=='l'&&s[j+1]=='n')) j+=2; elseif((s[j]=='s'&&s[j+1]=='i'&&s[j+2]=='n')||(s[j]=='c'&&s[j+1]=='o'&&s[j+2]=='s')||(s[j]=='t'&&s[j+1]=='a'&&s[j+2]=='n')||(s[j]=='l'&&s[j+1]=='o'&&s[j+2]=='g')) j+=3; //以上都是标准的数字字符和运算符如若存在其他形式的字符则是非法输入 else { cout<<"程序终止,存在非法的字符输入"< return0; } } return1;//没有非法字符返回1否则返回0 } intmatch(strings)//栈结构的括号匹配检测函数 { inti=0,top=0; charstack[50]; while(s[i]! ='\0') { if(s[i]=='(') { stack[top]=s[i]; top++; } //push左括号压入栈内 if(s[i]==')') if(stack[top-1]=='(') { inta=i+1; stack[top-1]=NULL; top--; }//把与右括号匹配的左括号弹掉 else { cout<<"括号输入有误"< return0;//多了右括号括号失陪返回非法 }//pop'(' i++; } if(top! =0) { cout<<"括号输入有误"< return0;//多了左括号括号失陪返回非法 } return1;//返回合法 } classNUMstack//运算数栈 { public: doublenum[1000]; inttop; voidstart()//初始化栈清空栈顶指针置底 { for(inti=0;i<1000;i++) num[i]=0; top=0; } voidpush(chara)//因为有多位数的运算因此不能一压栈就提升栈顶指针 { num[top]=num[top]*10+(a-'0');//把字符转成数因为每次入栈之前要乘10所以初始化要清0 } doublepop() { top--; doublenumber=num[top]; num[top]=0; returnnumber; }//弹栈函数弹掉栈顶元素栈顶归0top指针下降 doublegetTop()//取栈顶元素但不必弹栈 {returnnum[top-1];} voidlift()//提升top指针的函数 {top++;} }; classOPERstack//运算符栈 { public: charoper[1000]; inttop; voidstart()//初始化函数栈清空栈底放一"="用于判定算式结束 { oper[0]='='; for(inti=1;i<1000;i++) oper[i]=NULL; top=1;//栈顶指针置于栈底的上一位 } voidpush(chara) { oper[top]=a; top++;//与数字栈不同一压栈就可以提升指针 } charpop() { top--; charop=oper[top]; oper[top]=NULL; returnop;//弹出计算符用于计算 } chargetTop() { returnoper[top-1];//取栈顶符号但不弹栈可用于判定优先级 } }; voidcalculate(stringequation)//算式计算函数(关键函数) { NUMstacknumber;//定义运算数栈变量number OPERstackoper;//定义运算符栈变量oper number.start(); oper.start();//把两个栈初始化 inti=0,len=0,k; charp,sig; doubleyuan1,yuan2; while(equation[i]! ='\0') { len++; i++; }//计算等式长度len if(equation[len-1]! ='=') { cout<<"输入有误没有输入终止符号--等号“=”"< return;//检测有没有结束符等号"=" } intle; le=illegal_char(equation,len-1); if(le==0) return;//有非法字符不进行后续计算 le=match(equation); if(le==0) return;//括号匹配非法不进行后续计算 for(i=0;i { if(equation[i]=='! ')//阶乘是后缀单目运算符单独进行计算 { yuan1=number.pop();//弹出栈顶元素做阶乘 if(yuan1==0) { number.num[number.top]=0;//0的阶乘为0压结果入栈 number.lift(); } else { number.num[number.top]=1; for(k=1;k<=yuan1;k++)//阶乘循环 number.num[number.top]=k*number.num[number.top]; number.lift();//结果入站 } } elseif(equation[i]>='0'&&equation[i]<='9') { number.push(equation[i]);//压数字字符入栈 if((equation[i+1]<'0'||equation[i+1]>'9')&&equation[i+1]! ='.') number.lift();//当整个多位运算数读取完毕后,运算数栈栈顶指针才能提升 } elseif(equation[i]=='p') { number.num[number.top]=3.1415926536;//pi值即π圆周率要压入数字栈 number.lift(); i++;//pi是两个字符所以要移动扫描算式的指针往后跳一个 } elseif(equation[i]=='e') { number.num[number.top]=2.718281828459;//e自然对数底数压入运算数栈 number.lift(); } elseif(equation[i]=='.')//小数压栈代码 { intx=1; while(equation[i+x]>='0'&&equation[i+x]<='9') { number.num[number.top]+=((equation[i+x]-'0')/pow(10,x));//第x位小数入栈 x++; } x--; number.lift(); i=i+x; } elseif(equation[i]=='(') { oper.push(equation[i]);//左括号无条件压栈 } else//数阶乘左括号判断完毕后其他运算符的分类讨论 { if(oper.top==1)//运算符栈为空运算符可以无条件入栈 { if(equation[i]=='l'&&equation[i+1]=='o') oper.push('l'); elseif(equation[i]=='l'&&equation[i+1]=='n') oper.push('n');//因为log和ln都是小写字母l开头所以要分情况讨论 else oper.push(equation[i]); } else//运算符栈不为空则要进行优先级判断 { chartemp1=oper.getTop();//取出栈顶符号 chartemp2;//待入栈符号 if(equation[i]=='l'&&equation[i+1]=='o') temp2='l'; elseif(equation[i]=='l'&&equation[i+1]=='n') temp2='n';//log与ln的再次讨论 else temp2=equation[i]; p=Precede(temp1,temp2); if(p=='<') oper.push(temp2);//栈顶符优先级较低现在待定的运算符就可以入栈了 if(p=='>'||p=='=') { charrep=p;//当栈顶符优先级不低于待入栈的符号则运算符栈不停地弹栈 //进行运算直到低于待入栈符号为止rep用于记录比较结果要多次进行判断 while((rep=='>'||p=='=')&&(oper.top-1>0)) { sig=oper.pop(); yuan1=number.pop(); yuan2=number.getTop();//靠前的一个运算数只要取得不要弹出来 if(sig=='/'&&yuan1==0)//yuan1是双目运算符后面的第二运算元 { cout<<"计算时出错! ! 出现了除数为0的情况! ! "< return; } if(sig=='^'&&yuan2<0&&yuan1>0&&yuan1<1&&(static_cast //对负数开偶次根号的限制 { cout<<"计算时出错! ! 出现了负数开偶次根号的情况! ! "< return; } if(sig=='_'||sig=='s'||sig=='c'||sig=='t'||sig=='l'||sig=='n')//若为前缀单目运算符 { doublett; tt=S_Operate(sig,yuan1); number.num[number.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=Precede(temp1,temp2);//双目运算符的计算 } } if(equation[i]==')')//如果栈外符是右括号要把与之匹配的左括号弹出栈外 oper.pop(); elseif(equation[i]=='l'&&equation[i+1]=='o') oper.push('l');//代表log的l elseif((equation[i]=='l')&&(equation[i+1]=='n')) oper.push('n');//代表ln的n else oper.push(equation[i]); } } if(equation[i]=='s'||equation[i]=='c'||equation[i]=='t'||(equation[i]=='l'&&equation[i+1]=='o')) i=i+2; if(equation[i]=='l'&&equation[i+1]=='n') i++; //对于不止一个字符的运算符sinlogln等等要移动扫描算式的指针往后跳一个或两个 } } if(number.num[0]==ceil(number.num[0])) cout< else {cout<
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 计算器 程序 课程设计