MFC简单计算器设计正文.docx

上传人:b****0 文档编号:17154553 上传时间:2023-07-22 格式:DOCX 页数:31 大小:23.91KB
下载 相关 举报
MFC简单计算器设计正文.docx_第1页
第1页 / 共31页
MFC简单计算器设计正文.docx_第2页
第2页 / 共31页
MFC简单计算器设计正文.docx_第3页
第3页 / 共31页
MFC简单计算器设计正文.docx_第4页
第4页 / 共31页
MFC简单计算器设计正文.docx_第5页
第5页 / 共31页
MFC简单计算器设计正文.docx_第6页
第6页 / 共31页
MFC简单计算器设计正文.docx_第7页
第7页 / 共31页
MFC简单计算器设计正文.docx_第8页
第8页 / 共31页
MFC简单计算器设计正文.docx_第9页
第9页 / 共31页
MFC简单计算器设计正文.docx_第10页
第10页 / 共31页
MFC简单计算器设计正文.docx_第11页
第11页 / 共31页
MFC简单计算器设计正文.docx_第12页
第12页 / 共31页
MFC简单计算器设计正文.docx_第13页
第13页 / 共31页
MFC简单计算器设计正文.docx_第14页
第14页 / 共31页
MFC简单计算器设计正文.docx_第15页
第15页 / 共31页
MFC简单计算器设计正文.docx_第16页
第16页 / 共31页
MFC简单计算器设计正文.docx_第17页
第17页 / 共31页
MFC简单计算器设计正文.docx_第18页
第18页 / 共31页
MFC简单计算器设计正文.docx_第19页
第19页 / 共31页
MFC简单计算器设计正文.docx_第20页
第20页 / 共31页
亲,该文档总共31页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

MFC简单计算器设计正文.docx

《MFC简单计算器设计正文.docx》由会员分享,可在线阅读,更多相关《MFC简单计算器设计正文.docx(31页珍藏版)》请在冰点文库上搜索。

MFC简单计算器设计正文.docx

MFC简单计算器设计正文

实用计算器程序

1.基本功能描述

计算器是人们日常生活中非常实用的计算工具。

预期设计目标与实际计算器为标准,Windows10系统提供的计算器为范例进行设计。

实用计算器要实现单目运算和双目运算。

单目运算主要包括阶乘、正弦、余弦;双目运算主要包括加、减、乘、除、乘幂等。

计算器要能够对输入的各种数据进行处理,包括小数、整数、负数等数据进行操作。

实际过程中要能够对不同的数据灵活判断执行。

同时要能够对不满足运算符的操作数,提示出错信息以方便用户进行处理。

用户的修改包括清屏和退格。

程序设计的重点和难点在于:

第一,能够对于不同的操作数和操作符进行连续运算,运算过程中要有优先级的判断,根据优先级执行不同的运算顺序;第二,能够用一个编辑框实现运算表达式的显示和结果的输出。

编程环境采用VisualStudio2017提供的MFC建立对话框应用程序,设计界面要简单大方,并提供程序所有功能的接口。

2.设计思路

表1操作符优先级设计

优先级

操作符

1

阶乘、正弦、余弦

2

乘幂

3

乘、除

4

加、减

对对话框编辑框关联一个变量从中读取数据,按下数字键时对数据数组num[]进行更新,其中num[0]表示的是当前已经存储变量的个数。

由于算法设计为四层优先级,且单目运算的优先级最高。

当按下相应单目运算符,首先将当前数据数组的最后一个存储(防止按下Backspace退格发生错误),并将此位数据执行运算后重新赋值。

但按下双目运算符相应按键后,将计数num[0]++,同时将运算符的类型和位置记录。

当按下等于之前,这样就将一个单目双目混合的运算表达式转化为双目运算。

如果没有按下等号键,则继续执行循环。

在按下等号按钮之后,按照先乘幂、再乘除、后加减的运算顺序执行运算,将最后结果保存并显示。

(在实际的计算器中,执行完运算之后,按下运算符的操作键,最终结果将按照左操作数的形式出现,故需要保存变量。

)如果用户没有结束程序,在运行初始化程序,进行下一次运算,否则直接退出。

图1程序流程图

3.软件设计

3.1设计步骤

1)创建基于对话框的程序

利用AppWizard建立应用程序框架,创建一个基于对话框的MFC工程,命名为“fengwanjincalculator”,如图2所示。

在图3显示的应用程序类型中选择基于对话框。

创建成功后,系统自动生成相应程序文件。

图2创建MFC工程图

图3应用程序类型选择图

2)定义成员变量

添加相应变量和标志位,以方便程序的编写,主要变量如表2所示:

表2成员变量表

变量名

变量类型

变量作用

mystr

CString

编辑框关联变量

m_editFont

CFont

设置编辑框字体

num

float

存储操作数

flagdian

bool

点号标志位

flagdengyu

bool

等号标志位

flagerror

bool

错误标志位

Jiajian

int

存储加减运算符的位置

4)添加事件处理程序

MFC应用程序是通过消息响应来进行各项操作的,必须在对话类中加入消息处理函数来处理这些事件。

当点击相应控件,在进入WinMain函数之前,每个可以响应消息的MFC类都生成了一个消息映射表,程序运行时通过查询该表判断是否需要响应某条消息。

在相应控件单击右键,弹出图4,选择添加事件处理程序,在图5的事件处理程序向导中选择fengwanjincalculatorDlg类,消息类型选择为BN_CLICKED,即左键单击。

图4添加事件处理程序

图5选择添加事件处理程序类型

在完成上述操作后MFC使用ClassWizard帮助实现消息映射,它在源码中添加一些消息映射的内容,并声明和实现消息处理函数。

首先,在类的定义(头文件)里,它增加了消息处理函数声明,并添加一行声明消息映射的宏DECLARE_MESSAGE_MAP。

在类的实现(实现文件)里,实现消息处理函数,并使用IMPLEMENT_MESSAGE_MAP宏实现消息映射。

BEGIN_MESSAGE_MAP

******

END_MESSAGE_MAP

3.2界面设计

图5向对话框添加控件

在项目的资源视图中找到位于Dialog下的对话框,如图4所示。

添加相应控件,完成用户界面设计。

图6用户界面设计

其中编辑框行为下Multiline属性设置为True,作为多行编辑框。

第一行显示算式,第二行结果。

整体上将控件分为四组,数值控件区NUM,加减乘除一般运算控件区NORMAL,阶乘、乘幂、正余弦科学运算控件区SCIENCE以及清零退格控件。

设计完成后的界面如图7所示。

图7用户界面

设计的界面中只有编辑框关联Cstring类型变量mystr。

其余控件关联相应的消息处理函数。

3.3关键功能的实现

程序主要分为数值、单目运算、双目运算、清除等。

1)数值控件消息处理函数

voidCfengwanjincalculatorDlg:

:

OnBnClickedButton1()

{

shuzihanshu(L'1',1);

}

考虑到0~9数字的处理函数有很大的相似处,所以都采用调用shuzhihanshu函数的方法执行。

shuzhihanshu包含两个参数,分别是数值对应字符和相应数值。

其具体实现如下:

voidCfengwanjincalculatorDlg:

:

shuzihanshu(charshuzi,intshuzhi)//0~9对应函数

{

UpdateData(TRUE);

if(flagdengyu)

{

OnBnClickedButtonClear();

}

flaglast=0;

mystr+=shuzi;

data=shuzhi;

changevalue();

UpdateData(FALSE);

}

首先,判断再点击数值控件之前是否按下等号键,如果按下执行OnBnClickedButtonClear(),即执行清除函数,然后将单击的数值显示在编辑框中。

如果之前没有单击等号,则直接将数值添加到显示字符串的最后,通过UpdateData(FALSE)更新编辑框控件。

同时需要将数值传递给data,通过changevalue()函数改变数值数组中的数值。

2)双目运算消息处理函数

voidCfengwanjincalculatorDlg:

:

OnBnClickedButtonJia()//加

{

sincos();

if((flaglast==0)||(flaglast==jiecheng))

{

shuangmusuanfu(L'+',jia);

flaglast=jia;

jiajian[0]++;

jiajian[jiajian[0]]=1;

}

}

双目运算首先设置相应标志和参数的改变,其主要的函数体部分由shuangmusuanfu函数概括,其中jia参量为用枚举定义的一个常量。

枚举定义如下:

enumsuit{jia=1,jian,cheng,chu,jiecheng,zhishu,Sin,Cos};

shuangmusuanfu中函数实现部分:

函数体中首先对是否按下等号是否有表达式错误进行判断,如果相应标志为1,则转到相应处理函数,否则将算符存储,数值计数器num[0]加一。

3)清除函数

voidCfengwanjincalculatorDlg:

:

OnBnClickedButtonClear()

{

UpdateData(TRUE);

mystr=L"";

flagdian=0;

beishu=1;

flagerror=0;

data=0;

flagdengyu=0;

for(inti=0;i<10;i++)

{

jiajian[i]=0;

chengchu[i]=0;

mizhi[i]=0;

num[i]=0;

nextdata[i]=0;

}

num[0]=1;

flaglast=0;

UpdateData(FALSE);

}

清除函数中主要讲各个参量重新初始化,同时通过UpdateData(FALSE)更新编辑框控件。

4.结论与心得体会

1、Windows编程中可能会遇到可能会遇到各种编译问题,例如编译环境的设置,具体函数的调用。

同时Windows为程序员提供了大量的库函数,在具体实践的过程中,要充分利用书籍和网络查阅相关函数和环境设置,减轻编程负担。

2、考虑到编程的难度,首先编写了未设置优先级的表达式运算,后又通过在原先程序的基础上,编写了设置优先级的程序。

由于两种方式在算法设计上有很大不同,导致了程序改进的困难。

3、由于在编程思想方面并没有参照网上的先例,也没有采取堆栈的方式进行优先级的运算,在具体编程的过程中遇到了很多细节问题。

所以在日后的编程中要注意,算法与数据结构的结合。

4、相较于传统的C++编程,MFC的编程不仅要考虑算法和数据结构的问题,还需要考虑环境、用户界面的美观便捷等问题,编程的难度更大,出现的问题也更多,在编程的过程中渐渐提高了自己的耐性和对于新事物的应用能力。

5、从本次编程的结果来看,此次编程需要提高的方面还很多,人机交互界面的设计、程序算法的统一性、可读性都有待提高。

在程序的设计过程中主要参考了Windows10参做系统自带的计算器,交互界面如图8所示:

图8Windows10计算器

仅从界面看,差距还很大。

但是任何一个程序都不可能是完美的,这款计算器在调试的过程中也发现了一些bug,所以在日后更加重要的学习和工作中的编程过程中,要注意程序的调试和检查,完善任何一个优秀程序都是需要细致耐心的打磨。

5.思考题

1、程序如何实现小数的显示和运算?

首先,数值数组采用float类型,可以实现整形和浮点型的统一运算。

在读取数值的过程中要加入小数点的判断,如果出现了小数点,则在之后读取的每一个数值需要将相应的倍数每次除以10乘以读出的数值与原数值相加得到。

例如changevalue函数:

voidCfengwanjincalculatorDlg:

:

changevalue()

{

if(!

flagdian)

{

num[(int)num[0]]=data+num[(int)num[0]]*10;

}

else

{

beishu/=10;

num[(int)num[0]]=num[(int)num[0]]+data*beishu;

}

}

对于例如阶乘等只能对于整形进行运算的运算符或函数,首先对数值取证判断其是否与原数据相等,如果相等则可以进行相应运算。

如果不同,则通过AfxMessageBox函数弹出错误提示,错误窗口如图9所示:

图9错误提示窗口

2、描述等号对应的消息处理函数中需要问题及相应实现代码?

点击等号控件,则首先要进行表达式是否正确的判断(本次程序编写过程中,运算符操作的合法性检查放在了每个运算符的函数中,故在等号的消息处理函数中不需要再添加),将结果计算得出并显示在窗口上,同时设置相应的标志。

具体代码如下:

voidCfengwanjincalculatorDlg:

:

OnBnClickedButtonDeng()//等于

{

sincos();

CStringtemp;

calculator();

if(!

flagerror)

{

temp.Format(_T("%g"),num[1]);

mystr+=L"\r\n";

mystr+=temp;

}

flagdian=0;

beishu=1;

flagerror=0;

flagdengyu=1;

UpdateData(FALSE);

}

在实现过程中,首先通过calculator()执行相应运算得到结果,发生没有错误则将结果显示在编辑框中。

同时设置标志位,标志等号消息处理函数已经运算完。

6、附录

6.1调试报告

程序编译运行过程中主要遇到了类型转换问题、函数调用或执行问题、结果错误问题等。

1、类型转换问题

此类问题错误提示比较明确,更改也比较容易,只需要双击错误提示,转到相应的出错代码,进行相应处理即可。

例如,num数组设置为float类型,而为了减少变量的个数,采用num数组的第一位作为数组中数值个数的计数器。

故采用num[num[0]]表示最后一位数值,程序报错,提示只能为整数下标。

改为强制类型转换即可——num[(int)num[0]]。

2、函数调用或执行问题

此类问题一般在编译过程中并不报错或者不能给出有效的错误提示,导致发现的困难性。

例如,在CfengwanjincalculatorDlg类自声明了一个函数,而在相应的.cpp文件中忘记相应函数实现的编写,编译运行过程中仅提示找不到相应的.exe文件。

通过pause函数等暂停函数到某一点,找到错误的区间解决问题。

2、结果错误问题

此类问题在本次编程过程中遇到的情况较多,采用的自己模拟程序执行流程发现问题,如果不能通过这种方式发现,则通过设置断点,单步执行观察变量在每一步中的变化,并于自己的设想相比较发现问题。

6.2测试结果

1、键入表达式125+6*5-8!

+7^3点击等号得到表达式的结果,与实际相一致,如图10所示。

图10键入数值并执行运算

2、点击加号后可以继续执行运算。

图11点击加号继续运算

3、按下数值9,清屏屏显示数值9

图12按下数值9

4、清屏

图13清屏

5、错误提示

图14错误提示

6.3关键源代码

1、fengwanjincalculatorDlg.h文件中自定义变量和函数的相应声明:

public:

intjiajian[10];//第一位为加减算符个数,后面几位的绝对值为位置,+为正,-为负

intchengchu[10];//第一位为乘除算符个数,后面几位的绝对值为位置,+为正,-为负

intmizhi[10];//第一位为乘幂算符个数,后面几位的绝对值为位置,+为正,-为负

floatnum[10];//操作数数值数组

intflaglast;//判断表达式最后一位为算符或者数值0为数值,1~8为相应算符

floatnextdata[10];

CStringmystr;//编辑框字符串

CFontm_editFont;//编辑框字体

boolflagdian;//0为没加点1为加了点

floatbeishu;//倍数

boolflagerror;//0未发生错误1发生错误

intdata;//按键数值

boolflagdengyu;//是否按下=

voidcalculator();//计算函数

voidchangevalue();//改变操作数

voidshuangmusuanfu(char,int);//双目算符对应函数

voidshuzihanshu(char,int);//数字对应函数

voidsincos();

afx_msgvoidOnBnClickedButton1();

afx_msgvoidOnBnClickedButton2();

afx_msgvoidOnBnClickedButton3();

afx_msgvoidOnBnClickedButton4();

afx_msgvoidOnBnClickedButton5();

afx_msgvoidOnBnClickedButton6();

afx_msgvoidOnBnClickedButton7();

afx_msgvoidOnBnClickedButton8();

afx_msgvoidOnBnClickedButton9();

afx_msgvoidOnBnClickedButtonDian();

afx_msgvoidOnBnClickedButton0();

afx_msgvoidOnBnClickedButtonClear();

afx_msgvoidOnBnClickedButtonBackspace();

afx_msgvoidOnBnClickedButtonJia();

afx_msgvoidOnBnClickedButtonDeng();

afx_msgvoidOnBnClickedButtonJian();

afx_msgvoidOnBnClickedButtonCheng();

afx_msgvoidOnBnClickedButtonChu();

afx_msgvoidOnBnClickedButtonZhishu();

afx_msgvoidOnBnClickedButtonJiecheng();

afx_msgvoidOnBnClickedButtonSin();

afx_msgvoidOnBnClickedButtonCos();

2、在fengwanjincalculatorDlg.cpp文件中声明的枚举类型

enumsuit{jia=1,jian,cheng,chu,jiecheng,zhishu,Sin,Cos};

3、CfengwanjincalculatorDlg构造函数中的初始化

CfengwanjincalculatorDlg:

:

CfengwanjincalculatorDlg(CWnd*pParent/*=NULL*/)

:

CDialog(IDD_FENGWANJINCALCULATOR_DIALOG,pParent)

mystr(_T(""))

{

m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);

//自添加

flagdian=0;

beishu=1;

flagerror=0;

data=0;

flagdengyu=0;

for(inti=0;i<10;i++)

{

jiajian[i]=0;

chengchu[i]=0;

mizhi[i]=0;

num[i]=0;

nextdata[i]=0;

}

num[0]=1;

flaglast=0;

}

4、CfengwanjincalculatorDlg:

:

OnInitDialog()设置编辑框字体

m_editFont.CreatePointFont(180,"宋体");

CEdit*m_Edit=(CEdit*)GetDlgItem(IDC_EDIT);

m_Edit->SetFont(&m_editFont);//设置新字体

5、清屏函数

voidCfengwanjincalculatorDlg:

:

OnBnClickedButtonClear()

{

//TODO:

在此添加控件通知处理程序代码

UpdateData(TRUE);

mystr=L"";

flagdian=0;

beishu=1;

flagerror=0;

data=0;

flagdengyu=0;

for(inti=0;i<10;i++)

{

jiajian[i]=0;

chengchu[i]=0;

mizhi[i]=0;

num[i]=0;

nextdata[i]=0;

}

num[0]=1;

flaglast=0;

UpdateData(FALSE);

}

5、退格函数

voidCfengwanjincalculatorDlg:

:

OnBnClickedButtonBackspace()

{

//TODO:

在此添加控件通知处理程序代码

UpdateData(TRUE);

//移除最右边一个字符

if(!

mystr.IsEmpty())

{

chartemp;

temp=mystr[mystr.GetLength()-1];

if(temp>=48&&temp<=57)

{

if(!

flagdian)

{

num[(int)num[0]]=(num[(int)num[0]]-(temp-48))/10;

}

else

{

num[(int)num[0]]=num[(int)num[0]]-(temp-48)*beishu;

beishu*=10;

}

mystr=mystr.Left(mystr.GetLength()-1);

}

elseif(temp=='.')

{

flagdian=0;

mystr=mystr.Left(mystr.GetLength()-1);

}

else

{

num[0]--;

switch(temp)

{

case43:

case45:

jiajian[jiajian[0]]=0;

jiajian[0]--;

mystr=mystr.Left(mystr.GetLength()-1);

break;

case42:

case47:

chengchu[chengchu[0]]=0;

chengchu[0]--;

mystr=mystr.Left(mystr.GetLength()-1);

break;

case33:

num[0]++;

num[(int)num[0]]=nextdata[2*(int)nextdata[0]];

nextdata[2*(int)nextdata[0]-1]=0;

nextdata[0]--;

mystr=mystr.Left(mystr.GetLength()-1);

break;

case94:

mizhi[mizhi[0]]=0;

mizhi[0]--;

mystr=mystr.Left(mystr.GetLength()-1);

break;

case110:

num[0]++;

num[(int)num[0]]=nextdata[2*(int)nextdata[0]];

nextdata[2*(int)nextdata[0]-1]=0;

nextdata[0]--;

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2