北邮程序设计实验 简易计算器Word格式文档下载.docx
《北邮程序设计实验 简易计算器Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《北邮程序设计实验 简易计算器Word格式文档下载.docx(9页珍藏版)》请在冰豆网上搜索。
本课题主要内容是设计并实现一个与Windows自带标准型计算器相似的计算器,在完成基本要求的基础上添加一些更全面地计算功能,比如括号的实现,达到多次试验计算结果正确、无明显bug出现的目的。
使用的开发平台是MFC,采用的工具是VC++6.0。
1.2系统的主要功能
功能列表
数字按钮
0~9的数字键入
四则运算
加减乘除的二元运算的实现
一元简单运算
正弦、余弦、正切、正负号的功能
退格、清零
在对已有运算或者数字进行退格或清零
多层括号
实现多层括号的优先级运算
2.系统设计
2.1系统总体框架
Y
N
循环连续运算
设计思想:
自己先参看了Windows自带的标准型计算器,发现Windows中的编辑框是双行显示,一开始进行双行显示无疑增大了难度,所有自己决定先单行显示。
然后编辑框中参数类型可以是double也可以是Cstring,自己发现网上众多代码都是CString,这种类型方便显示和字符、数字的键入,但自己为了与网上那些代码区分,决定用double类型,这样在键入数字的时候就会复杂一些。
在完成基本功能(四则运算和简单一元运算后),自己又添加了括号优先级功能。
2.2系统详细设计
[1]模块划分图及描述
各个模块中包含着相应的操作,比如一元运算模块包括了三角和倒数等运算,但是每一个模块中各个函数实现的原理大致相同
[2]类关系图及描述
本课题并无复杂的类关系继承,只是MFC自己封装的一些类,然后在其中写消息处理函数。
[3]程序流程图及描述
该计算器具有连续运算的功能,运算后的结果可以作为下次运算的输入继续参与运算,而且如果判断有左括号输入,则调用结构体来保留现场,继续参与运算。
[4]存储结构、内存分配
在括号功能实现中需要采用一定的结构整体保留括号内的内容,自己采用了结构体,并且结构体通过结构指针构成一个链,这样就可以实现多层括号的功能。
2.3关键算法分析
由于课题中引入了很多起到标志位作用的标识符,在算法分析之前先对各个标志符号进行简单介绍。
flag:
为了让系统知道已按过加-除/清零/开根号/求百分比/倒数/等号按钮
d:
为了让系统知道已按过小数点"
."
按钮,调整为向编辑框输入小数点后的值
a1,a2,a3,a4:
为了让系统知道已分别按过了加/减/乘/除按钮,使系统做相应的运算
a:
为了让系统知道已按过按钮加-除按钮,实现连续运算
backz:
为退格时取整用,backbl为退格时乘倍率时用
f:
为负数时实现退格
wei:
控制输入编辑框的位数不超过9位
算法1:
数字输入函数
[1]算法功能:
当点击相应的数字按钮,让编辑框中显示添加相应的数字(0~9)
[2]算法基本思想:
用UpdataData函数实现编辑框中内容和double类型的互传,分多种情况将数字合理地添加到编辑框中。
[3]代码逻辑:
(令点击的数字为x,伪代码如下)
if(d=1和flag=0和wei<
9)dotbl自乘0.1;
m_strResult+=dotbl*x;
wei自加;
1backbl自乘10;
//实现小数点之后的数字输入
if(flag=0andd=0)or(flag=1)m_strResult=x;
wei+=1;
//按下清零/加-除按钮后编辑框的值为x
if(flag=0andd=0andwei<
9)m_strResult=m_strResult*10+x;
wei+=1;
//小数点之前对于数字的连续输入
以上内容通过标志符号的识别来判断输入数字属于哪种情况,然后按不同情况进行数字的添加处理。
算法2:
一元运算符号函数
[1]算法功能:
实现对编辑框中已有数字的一元运算,比如取倒数、求正弦、余弦、正切值[2]算法基本思想:
调用Cmath函数库中数学操作符号,对已有的double类型的数直接进行函数操作。
[3]代码逻辑:
(伪代码如下)
三角运算以正弦为例:
(系统默认把操作数当成角度值)
m_strResult=sin(m_strResult除以180乘以pi)//先将其转化成弧度值,然后直接调用函数
m_strResult=(int)(m_strResult乘以10^7)除以10^7//这样可以控制正弦值输出为7位有效数字
flag=1,wei=0;
d=0;
dotbl=1;
//运算之后对相应的标志符号重置,flag表示已按过一元运算符号按钮,算出结果后wei和d自然重置为0,小数点倍率dotbl重置为1。
算法3:
二元四则运算函数
实现数值的加减乘除四则运算,并可以进行连续的运算
[2]算法基本思想:
分成两种情况如果之前已进行过四则运算操作,则当再次点击四则运算符号的时候,相当于点击了等号直接计算出之前的值,并将相应四则运算符标志位置为有效。
第二种情况就是第一次进行四则运算,只需要保留相应数据并将相应四则运算标志位置为有效即可。
(伪代码及代码分析如下)
注:
if(a为1){if(a1有效)m_strResult=m+n;
if(a2有效)m_strResult=m-n……}
m_strResult赋值给m
刷新编辑框,并记录改变相应的标志位符号a4=1,flag=1,a=1,wei=0;
d=0,dotbl=1;
备注:
由于等号的消息处理函数与四则运算符号的很相似,在报告中就不予以单独说明
※算法4:
优先级括号运算
实现优先级括号运算,并能使用多层括号。
一旦点击左括号,则开始用结构体保存相应的数值和符号现场,把他们当成一个整体,当右括号出现的时候算出结构体中结果并赋值给一个变量。
并通过结构体指针,将各个保留的现场(结构体)进行链式连接,实则这个结构也类似于一个栈,这样便可以达成多层括号的目的。
structkuohao*newKuohao=(structkuohao*)malloc(sizeof(structkuohao));
//在点击左括号之后,先申请一个动态的空间,并用结构体指针指向相应的地址,然后将结构体中各个成员变量赋予初值。
(由于报告要求,在这里不予以列出赋值过程)
newKuohao->
next=myKuohamyKuohao=newKuohao;
//以上语句,是为了实现多层括号功能留有的余地,如果是第一次建立结构体,则先和mykuohao构成连接,如果已有kuohao结构体,以上操作则相当于头插法将新建立的结构体插入链头,相当于先入后出的栈。
if(myKuohao==NULL)return;
//当点击右括号的时候,则开始将之前的链逐一解开,也相当于栈中的结构体依次出栈,每次出栈都将结构体中的结果算出并将以保留,这样一个一个出栈后直到myKuohao这个指针为空即栈为空的时候,此时退出函数体。
2.4其他
为了实现多层括号功能,自己采用了一种栈的模型,实际上是由结构体组成的链来构成的。
在每次点击左括号时候,建立新的结构体并保留相应的数值和符号,然后将各个结构体连接起来,此处采用了头插法。
在最后点击右括号的时候,相当于栈中的结构体依照陷入后出的规则依次出栈,直至栈空。
此功能的实现并没有使用系统自带的STL中的栈,因为其各种参数和模式较为固定,使用起来较为死板,于是自己用结构体链的形式仿制成一个栈,巧妙地实现了该功能,这也是该实验最大的亮点。
3.程序运行结果分析
输入数据来源和格式:
对话框中按钮点击后产生的数值和符号
输出显示方式:
显示在计算器的编辑框中
主要界面:
操作流程:
该操作流程与Windows自带的标准型计算器相同,只不过编辑框是单行显示
响应时间:
2秒46
运行效果:
当输入5*(3+4)=之后
由于该课题使用double类型,不能以字符串的形式将运算式均显示在编辑框中,如果老师想要验证结果可以用VC6.0运行程序后验证。
4.总结
4.1课题的难点和关键点
由于第一次使用MFC,对其中各种操作形式比较陌生,即使有算法上的思路但是操作起来比较迷茫。
解决方法:
自己先阅读了黄维通版的《C++面向对象的可视化操作》,待明白MFC的操作过程和原理之后才开始进行算法的实现。
在实现了标准型计算器的基本功能之后,想要添加括号功能的时候遇到了很大的困难。
解决方法:
首先自己查阅了很多优先级实现的资料,发现可以使用栈来完成以上的功能,如果调用STL标准模板类,使用起来比较死板;
而如果自己去写一个栈,实现起来代码量较大并且较为复杂。
最后使用了将结构体连接的形式构成链,虽然是链结构但实际上运用的还是栈的思想,在多层括号实现过程中还采用了头插法的方式。
4.2本课题的评价
实验评价:
计算器的设计与实现是初学者经常会做的课题,网上也有很多版本的代码,为了与网上各种版本进行区分,自己在编辑框的类型中选择了double,并添加了多层括号的优先级功能。
虽然做的过程遇到不少困难,但是整体对自己完成情况还是比较满意,毕竟第一次做MFC的图形化操作。
不足之处:
与Windows自带的计算器比较有一个不足就是编辑框的显示问题,只能单行显示,并且不能整体字符串同时显示在编辑框中,这是由于自己编辑框类型定义为double确实无法用字符串的形式,将符号与数值都更新到编辑框上。
改进方法:
针对上述不足,我打算使用双行的编辑框,第一行的类型设置为CString,用来显示计算过程中的字符串,例如“1+(3+4)=”;
而第二行的类型设置为double,用来显示计算结果,因为结果一般只是以数值的形式显示出来。
这种方法实现过程中会将整个代码进行大的修改,可能遇到的麻烦事情就是会涉及到double类型和CString类型之间的转换等,不过克服之后应该会实现类似windows自带计算器的那种显示模式。
4.3心得体会
关于程序的一点重要体会就是,想起来容易做起来难,其实简易计算器的设计思路很简单,就是在每个按钮结构上添加相应的消息处理函数,然后实现计算的数值和编辑框里数值的互传。
但是当自己从头到尾开始做的时候,会遇到很多小问题,一个语句的错误就需要上网查阅相关资料,然后往往反复修改后才能得到正确的结果。
往往实现一个功能可能会有多种不同的方法,在此次实验中关于多层括号功能的实现,经过网上查阅资料和阅读数据结构书发现可以有至少三种思路,这时候就需要我们理智地分析下需要使用哪种思路,本实验采用的结构体链式结构实际上就是应用栈的思想,但是既不需要调用较为死板的STL,也不需要自行写一个栈出来,达到了优化代码的目的。
学过的知识一旦应用过后才会真正的掌握,之前在数据结构中学过各种各样的结构,链、栈、队列等等,但是学过之后只能应对考试而已。
经过此次实验将相应的数据结构知识比如栈和头插法,才对相关的知识有了更深入地理解。
5.参考文献
[1]《MFCWindows应用程序设计》,任哲等编著,北京:
清华大学出版社,2013
[2]《VisualC++权威剖析》,王颜国编著,北京:
清华大学出版社,2008
[3]《可视化程序设计VisualC++》,杨喜林,主编,北京:
北京理工大学出版社,2010