收藏 分销(赏)

C面向对象设计计算器程序.doc

上传人:可**** 文档编号:9628163 上传时间:2025-04-01 格式:DOC 页数:14 大小:87.50KB 下载积分:8 金币
下载 相关 举报
C面向对象设计计算器程序.doc_第1页
第1页 / 共14页
C面向对象设计计算器程序.doc_第2页
第2页 / 共14页


点击查看更多>>
资源描述
一. 课程设计题目: 模拟计算器程序 设计内容:设计一个程序来模拟一个简单的手持计算器。程序支持算术运算+、-、*、/、=、以及C(清除)、A(全清除)操作。程序运行时,显示一个窗口,等待用户输入,用户可以从键盘输入要计算的表达式,输入的表达式显示在窗口中,用户键入’=’ 符号后,窗口显示出结果。选作内容如果用户输入的表达式不合法,可以判别出来并给出相应的错误提示。测试数据程序输入不少于5种不同的表达式进行测试。 二.问题的分析 此程序设计主要运用了栈,利用栈后进先出的原理,建立两个栈,操作数栈和操作符栈,先将数据和运算符分别压入这两个栈,判断栈内和栈外运算符的优先级,依据运算符的优先级判断是应再次压入运算符,还是将数据和运算符弹出栈,在栈外进行运算,再将所得的结果压入栈,继续进行与计算,直至运算结束。 例如;计算5/2+1-2*3= 操作数2入操作数栈, 2 运算符”/”入运算符栈, 操作数5入操作数栈 5 / 数字栈 运算符栈 。 运算符“+”入运算符栈顶 比较后,将2,5出栈运算, 并将结果入数字栈 2.5 数字栈 字符栈 运算符“+”入字符栈,操作 1 数1入数字栈 2.5 + 数字栈 字符栈 运算符“—”入运算符栈顶比较后,将 1, 2.5出栈运算,并将结果压入操作 数栈 3.5 — 运算符“—”入运算符栈 数字栈 字符栈 操作数2入操作数栈,运算符“*” 入运算符栈顶比较后压入运算符栈 3 将操作数3压入操作数栈 2 * 3.5 — 数字栈 字符栈 当扫描到=号时,操作数3和2出栈 运算符*出栈,进行运算,运算结果入 操作数栈 6 3.5 — 数字栈 字符栈 操作数6和2出栈,运算符“—” 出栈,进行运算,运算结果入操作数 栈 6 3.5 — 数字栈 字符栈 运算符栈空,操作数栈中运算为运算 —2.5 结果 数字栈 字符栈 分析: 设置两个栈,运算数栈和运算符栈,然后,自左向右扫描表达式,遇操作数进操作数栈,遇 操作符栈则与操作符栈顶运算符比较:若当前操作符大于操作符栈顶,则当前操作符进入操作符栈;若当前操作符小于等于运算符栈顶,次栈顶出栈,同时操作数栈顶也出栈,形成一个运算,并将运算的结果压入数字栈。 流程图 开始 初始化数字栈和字符栈 读入字符c 是否为“=”号 Y N N 是否为运算符 Y 字符栈是否为空 Y N C入数字栈 Y 是否比字符栈顶优先级高 N C入字符栈 数字栈顶元素和次栈顶元素 出栈,运算符栈顶出栈, 运算结果入数字栈 结束 三.算法的设计 1、 创建一个calculator类,将计算器需要用到的函数都封装起来,形成一个整体。 2、 设计成员函数及数据。 首先定义两个私有的结构体save1和save2分别用来存放数字和运算符,在结构体内定义整型的栈顶元素top,和存放数据及运算符的数组double n[MAX]和char n[MAX]。 定义了一个空的构造函数calculator()。 函数bool stack1empty(save1 s),bool stack2empty(save2 s)分别判断数字栈和字符栈是否为空,若栈顶为-1则空则返回1表示真,否则返回0表示假。 函数void push1(save1 &s,double num);,void push2(save2 &s,char op);分别将数字和字符压入栈。若所存储的内容已经数组的最大限度,则显示“栈已满”,否则将数字和字符压入栈顶。 函数void pop1(save1 &s,double &num),void pop2(save2 &s,char &op)分别是将栈内的数字和字符弹栈,存储在num和op中。首先判断栈是否为空,若空则显示“栈为空”,否则将栈顶元素分别赋值给num和op。 函数int in(char op),int out(char op)分别判断栈内和栈外运算符的优先级。 在栈内,“+”“—”返回2,“*”“/”返回4,在栈外“+”“—”返回1,“*”“/”返回3,当遇到“+” 或“—”和“*”或“/”同时存在时,“*”“/”的优先级高于“+”“—”,首选“*”“/”运算。当遇到同级运算符时在时,先进行栈内运算。通过返回值的大小选择进行在哪里的哪种运算。 函数void count(double a,char op,double b)是用来进行计算的,并将计算的结果压入栈。以便下一次的运算。 函数void cal ()是最主要的操作函数。首先提示输入表达式,并在表达式之后加上=,然后输入表达式。分别清空存放数字和字符的栈。总体用一个while语句,以“=”结束。由于是用char定义的表达式expression[MAX],所以要将里面的数字提取出来,转化成int或float类型,利用库函数isdigit()查找,若读入的字符为数字,则继续判断下一个字符,直到下个字符不是数字或者不是小数点,即可保证该操作数是完整的小数,然后将该数入操作数栈。库函数atof()将char类型进行转换。当栈内和栈外同时都有运算符时,利用int in(char op) 和 int out(char op)函数根据其返回值的大小判断运算符的优先级,判断是将栈外的运算符压入栈还是将站内的数据及运算符弹出栈进行运算。若为后者,运算完后再将所得的结果压入栈顶,再次进行判断,直至栈顶为空,运算结束。 主函数void main(),首先提示此程序设计者的信息。然后进行正式的计算环节,将整个主函数分为part1 和part2两部分,运用goto语句使程序在执行的流程可以跳转到part1部分,进行多次运算。定义calculator mycal,进行运算。运算结束提示是否继续进行运算,输入选择y(是) n(否) A(退出) 利用while语句,当输入A时结束运算。当输入“y”时,运用system("cls")对前面的运算进行全清除,然后利用goto语句跳转到part1再次进行计算。当输入“n”时停止运算,输出“谢谢使用!”程序运行结束。 类:calculator 数据:struct save1 struct save1 函数: calculator(){}; bool stack1empty(save1 s); bool stack2empty(save2 s); void push1(save1 &s,double num); void push2(save2 &s,char op); void pop1(save1 &s,double &num); void pop2(save2 &s,char &op); int in(char op); int out(char op); void count(double a,char op,double b); void cal(); 系统类图 基类的数据成员和函数成员描述 属性和方法定义 类名 成员类别 类型 成员名 描述 calculator 属性 struct Save1 存储数字 Struct Save2 存储运算符 Bool stack1empty(save1s) 判断数字栈是否为空 Bool stack2empty(save2s) 判断运算符栈是否为空 void push1(save1&s,doublenum) 将数据压入数字栈 void push2(save2 &s,char op) 将运算符压入运算符栈 void pop1(save1&s,double&num) 将栈顶的数据元素取出,存放在num中 void int int void void pop2(save2 &s,char &op) in(char op) out(char op) count(double a,char op,double b) cal() 将栈顶的运算符取出,存放在op中 在栈内优先级的判断 栈外优先级的判断 进行计算并将所得的结果压入栈顶 主要进行运算的函数 用户手册 程序运行时,首先显示此程序设计者的信息。 提示欢迎使用计算机请输入表达式(输完之后请加=),然后输入所要进行计算的表达式,进行计算。计算结束后提示:继续计算吗?,输入y表示同意继续计算,输入n表示结束计算,并显示谢谢使用!输入A时退出,选择你所需的形式,进行计算。 (四) 上机调试过程 (1) 刚开始只能进行两个数字的运算,不能进行多个数字的计算,想到用for循环解决输入数字上的问题,但只能进行一种运算,达不到多重运算的要求。 (2)想到在用for循环解决次问题,但改来改去都弄不好,最后经老师提示,运用栈的知识解决问题。 (3)开始对栈一点都不了解,全部程序都需要重新写,完全没有一点头绪,把课本关于栈的部分看了好多遍,和同学讨论,大概知道栈是什么样的了,开始写我的程序了。 (4)本来只是考虑到建立一个数字栈的,但这样运算符的优先级不能进行,得不出正确的结果,经同学提示,建立两个栈,一个存储数字,另一个存放运算符,判断运算符的优先级以后,将数字和运算符弹出栈,进行计算,把计算的结果压入栈,以便下一次运算。 (5)解决了多个多个数和多个运算符计算的问题,又想到了可不可以进行多次运算,当想结束时,按指定的键,结束运算,想到了用goto语句进行跳转,达到循环计算的目的。 说明:此程序清除的功能还不能实现,只能进行全清除,修改了好长时间也未能找到一个好方法解决。 (五) 运行实例 选择继续运算,跳转到part1部分。 经验与体会 此次c++课程设计,在指导教师的精心教导下,我们学会了如何用C++编写一个简单的应用程序。首先要对程序的设计要求有一个比较明确的认识,然后系统分析与系统设计,最后是代码设计与调试。程序实现上,设计了简单的查询界面,将各个功能集中出来按照程序编写原则,便于查询。根据C++课程所学的概念、理论和方法,按照C++程序设计的基本步骤,设计出一个适当规模的程序;进一步加深对C++语言的理解和掌握。理论联系实际,加深和巩固所学的理论知识,提高实践能力和计算机的综合运用能力。我们编写程序的过程是辛苦与快乐的,程序的编写原则很重要,只要我们在编程,就必须不断改进,才能更好提高编程能力。 课程设计是培养学生综合运用所学知识、发现、提出、分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程.随着科学技术发展的日新日异,C++已经成为当今计算机应用中空前活跃的领域, 在生活和学习中可以说得是无处不在。因此作为二十一世纪的大学来说掌握C++软件开发技术是十分重要的。 此次课程设计使我们将理论教学中涉及到的知识点贯穿起来,对不同的数据类型、程序控制结构、数据结构作一比较和总结,结合设计题目进行综合性应用,对所学知识达到融会贯通的程度。 通过课程设计,使我们在各方面的能力应该得到锻炼,不仅进一步巩固、加深学生所学专业课程《C++语言教程》的基本理论知识,理论联系实际,进一步培养学生综合分析问题,解决问题的能力。 而且全面考核我们所掌握的基本理论知识及其实际业务能力,从而达到提高学生素质的最终目的。并且利用所学知识,开发小型应用系统,掌握运用C++语言编写调试应用系统程序,训练独立开发应用系统,进行数据处理的综合能力。还使我们懂得了对于给定的设计题目,如何进行分析,理清思路,并给出相应的数学模型。 同时也使我们掌握自顶而下的设计方法,将大问题进行模块化,领会结构化程序设计的方法。熟练掌握C++语言的基本语法,灵活运用各种数据类型。进一步掌握在集成环境下如何调试程序(单步调试,设置断点、观察表达式,分块调试)和修改程序。 这次课程设计历时二周,通过这次设计让我对C++有了更新的认识,认识到了它的实际应用价值,可以及大的减少工作量,节省人力物力,同时也让我认识发现到自己再学习上的存在的不足,再以后的生活学习中要多加练习编程,力求改变自己的不足。课程设计学习让我学到了很多,学会了用所学习的知识去解决实际问题,一开始拿到题目,根本就不知道要从什么地方下手,感觉写这个也不行写那个不行,但经过时间的磨练以及和同学之间的交流开始有点头绪,脑海中有个大概,但还是无法全部写出来,只能实现一部分功能,而且在写程序时遇到了很多问题,程序出错自己无法修改,后来经过学长的指导和同学以及指导老师的帮助大部分功能都可以实现,自己再慢慢摸索,程序终于写出来了,这期间感觉以前好多不懂的,通过这次的学习都可以一一解决,但发现自己也有很多的不足,很多以前学过的知识点都不记得了,而且无法将它们联系在一起,除了课本上的知识还有好多跟本课程有关的知识点都不懂,所以通过这次的学习,我知道自己不仅仅要把课本上的东西学好,还要了解相关的东西,让自己的知识面更广,同时我也更深刻的认识到了任何事都不可能一个人独立完成,同学和老师的帮助是非常重要的。 (六) 参考资料 [1] 郑莉 等编著《C++语言程序设计(第三版)》北京:清华大学出版社 [2] 郑莉 等编著《C++语言程序设计(第三版)学生用书》北京: 清华大学出版社 [3] 刘振安 等编著《C++程序设计课程设计》 机械工业出版社 [4] 吴乃陵 等编著《C++程序设计》北京:高等教育出版社 [5] 李春葆 等编著《C++程序设计学习与上机实验指导》 北京:清华大学出版社 [6] 范辉 等编著《Visual C++6.0程序设计简明教程》 高等教育出版社 [7] 李龙澍《C++程序设计实训教程》北京:清华大学出版社 [8] 洪国胜 等编著 《C++ Builder程序设计轻松上手》北京:清华大学出版社 [9] 宁正元《数据结构(c语言)》 南京:东南大学出版社。2000年6月第1版 [10] 严蔚敏等 《数据结构(c语言版)》 北京:清华大学出版社,1997年4月第1版。 [11] 胡学钢等《数据结构算法设计指导》北京:清华大学出版社,1999年 第1版。 源程序: #include <stdlib.h> #include<iostream.h> #include<ctype.h> # define MAX 1000 class calculator { private: struct save1 //存储数字 { double n[MAX]; int top; } stack1; struct save2 //存储运算符 { char n[MAX]; int top; } stack2; public: calculator(){}; //空的构造函数 bool stack1empty(save1 s); bool stack2empty(save2 s); void push1(save1 &s,double num); void push2(save2 &s,char op); void pop1(save1 &s,double &num); void pop2(save2 &s,char &op); int in(char op); int out(char op); void count(double a,char op,double b); void cal(); }; bool calculator::stack1empty(save1 s) //判断数字栈是否为空 { if(s.top==-1) return 1; else return 0; } bool calculator::stack2empty(save2 s)//判断运算符栈是否为空 { if(s.top==-1) return 1; else return 0; } void calculator::push1(save1 &s,double num)//将数据压入数字栈 { if(s.top==MAX-1) {cout<<"栈已满 "; } else { s.top++; s.n[s.top]=num; } } void calculator::push2(save2 &s,char op)//将运算符压入运算符栈 { if(s.top==MAX-1) {cout<<"栈已满"; } else { s.top++; s.n[s.top]=op; } } void calculator::pop1(save1 &s,double &num)//将栈顶的数据元素取出,存放在num中 { if(s.top==-1) cout<<"栈为空"<<endl; else { num=s.n[s.top]; s.top--; } } void calculator::pop2(save2 &s,char &op)//将栈顶的运算符取出,存放在op中 { if(s.top==-1) cout<<"栈为空"<<endl; else { op=s.n[s.top]; s.top--; } } int calculator::in(char op)//在栈内优先级的判断 { if(op=='-'||op=='+') return 2; else if(op=='*'||op=='/') return 4; else return -1; } int calculator::out(char op)//早栈外优先级的判断 { if(op=='-'||op=='+') return 1; else if(op=='*'||op=='/') return 3; else return -1; } void calculator::count(double a,char op,double b)//进行计算并将所得的结果压入栈顶 { double sum; switch(op) { case '+':sum=a+b;break; case '-':sum=a-b;break; case '*':sum=a*b;break; case '/':sum=a/b;break; default:break; } push1(stack1,sum); } void calculator::cal(void) { int i=0,j; double a,b,c; char expression[MAX],operate,temp[20]; cout<<"请输入表达式(输完之后请加=):"; cin>>expression; stack1.top=-1;//清空数字栈 stack2.top=-1;//清空运算符栈 while(expression[i]!='=')//以=号结尾 { if(isdigit(expression[i]))/*若读入的字符为数字,则继续判断下一个字符,直到下个字符不是数字或者不是小数点,即可保证该操作数是完整的小数,然后将该数入操作数栈*/ { j=0; while(isdigit(expression[i])||expression[i] =='.') { temp[j++]=expression[i]; i++; } temp[j]='\0'; c=atof(temp);//char类型进行转换 push1(stack1,c); } else { if(expression[i]=='-'||expression[i] =='+'||expression[i]=='*'||expression[i] =='/')//若读入的字符为运算符的情况 { if(in(stack2.n[stack2.top])<out(expression [i])||stack2empty(stack2))//读入的运算符与运算符栈顶元素相比,并进行相应的操作 { push2(stack2,expression[i]); i++; } else { pop1(stack1,a); pop1(stack1,b); pop2(stack2,operate); count(b,operate,a);//先进后出原则 } } } } while(stack2.top!=-1)//读入结束后,继续进行操作,直到运算符栈为空 { pop1(stack1,a); pop1(stack1,b); pop2(stack2,operate); count(b,operate,a); } cout<<stack1.n[stack1.top]<<endl; } void main() { cout<<"\t****************************************\n"; cout<<"\t 模拟计算器程序 \n"; cout<<endl; cout<<" \t**** 制作人:陈露 \n"; cout<<" \t**** 指导老师:徐静 \n"; cout<<" \t**** 专业班级:08网工(1)班 \n"; cout<<" \t**** 制作时间:2009年6月19日 \n"; cout<<" \t*****************************************\n"; cout<<endl; part1: cout<<"----------欢迎使用本计算器--------"<<endl; calculator mycal; mycal.cal(); cout<<"继续计算吗?"<<endl; cout<<"y(是) n(否) A(退出)"<<endl; char choice; cout<<"请输入你的选择:"; cin>>choice; while( choice!='A'){ if(choice=='y') {system("cls");//进行全清除 goto part1;}//goto语句跳转到part1再次进行计算 else { cout<<"谢谢使用!"<<endl; break; } } }
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 考试专区 > 中考

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服