mfc计算器实验报告
C++程序设计设计性实验报告
实验项目名称:高级计算器设计与开发
专业班级:;姓名:;学号:
实验起止日期:起于年月日止于年月日
实验目的:
学会用C++语言和数据结构知识实现表达式的解析与计算;学会使用动态链接库技术进行编程;学会编辑、编译、运行MFC应用程序的基本过程.学会MFC可视化编程技术。
实验要求:
1.能完成双精度型数值的加、减、乘、除计算;编程中使用了动态连接库技术.
2.能完成双精度型数值的加、减、乘、除计算;编程中使用了动态连接库技术;能实现表达式的输入,解析与计算
实验内容:
1.C++语言的顺序结构,分支结构,循环结构,函数,结构体,指针,MFC可视化编程技术。
2.数据结构中的二叉树数据组织、存贮、后序遍历及其操作。
3. 使用动态链接库进行函数模块的设计,实现计算功能。
实验具体方案:
按照系统设计要求,用Visual C++设计和开发一个MFC应用程序---高级计算器。计算器的界面设计、计算功能实现、算式计算和动态链接库的使用等。提交由需求分析:系统设计说明、系统技术文档、系统使用说明书和源程序代码为附录构成的实验报告。
需求分析:
系统设计说明
1.计算器界面
计算器界面包括主题“高级计算器”和背景图片以及电子日历。在计算区上有显示文本框和数字按钮以及运算符按钮。在计算区上部分有运算模式选择模块和小
提示语句。
2.模块功能简介
系统分为多个模块,分别为计算模块、错误分析模块、界面显示模块和模式选择模块。其中计算模块用来进行各种基本的加、减、乘、除的运算并且显示运算结
果;错误分析模块用来进行错误处理;界面显示模块用来美化计算器界面;模式选
择模块用来进行运算模式的选择和切换,以实现不同的运算要求。
3.系统结构图
系统技术文档
1.系统各模块主要流程图
(1) 单步运算流程图
(2) 算式运算流程图
2.软件总体测试方案与测试记录
运行程序,然后查看计算器界面和设计是否相同,进行运算模式的切换,看是否能正确的进行模式切换,查看日历显示是否正确。经测试没有发现错误,系统运
行正常。
3.局部测试方案与测试记录
运行程序,在不同的运算模式下输入数据然后进行调试。在单步运算模式下应分别测试加、减、乘、除以及除数为0和被除数小于除数这两种特殊情况。在算式运
算模式下除了要测试与单步运算相同的内容外,还应注意算术优先级是否正确,运
算结果是否正确。注意清零功能是否能够正确实现。经测试没有发现错误,系统运
行正常。
系统运行结果和记录
1.软件运行界面图
2.软件运行数据输入和结果界面图
(1)单步运算界面图
①单步运算模式显示界面
②计算5.6÷9的输入过程和结果界面
③清零时的界面
④除数为0时的错误判断界面
(2)算式运算界面图
①算式运算模式显示界面
②计算2.3+3.6÷6-2×6.5+66.8的输入过程和结果界面
③清零时的界面
④除数为0时的错误判断界面
系统使用说明书:
首先进行模式选择,在单步运算时,先点击下一个数字,再点击运算符,再点击下一个数字,然后点击等于号显示结果,如果被除数为零,则提示错误,按清零键后重新输入。
在算式运算时,随便输入一个算式,计算器可识别算式错误不显示,显示的就是输入的算式,点等于号后显示结果,如果被除数为零,则提示错误,按清零键后重新输入,如果输入一个运算符后,只能输入数字不能再输入运算符,如果此时点击运算符,则不会显示在算式中。C++程序设计设计性实验收获与总结:
1.通过这次实验,我进一步了解并掌握了MFC控件的基本用法,在之前制作简单计算
器的基础上,增加了新的功能,制作了高级计算器。
2.在制作算式运算模式的过程中,由于涉及到算术优先级和运算符号的匹配问题,因此
用到了二叉树的数据存储结构,通过对数据组织、存储、以及二叉树的后序遍历及其
它操作实现了算式运算的识别和计算。
3.通过使用动态链接库,将计算器的基本计算功能在程序外进行实现,使得整个程序结
构化更加鲜明,也使得程序的修改和维护更加方便简单。
4.通过这次实验,使我对C++语言有了更深的掌握,提高了我的编程能力和Visual C++
的使用能力。
5.在这次的高级计算器制作之后,我掌握了面向对象技术相关的一些软件开发技术,包
括利用MFC开发Windows应用程序以及使用动态链接库。
参考文献
1. 谭浩强编著《C程序设计(第三版)》北京清华大学出版社 2005
2.谭浩强编著《C程序设计题解与上机指导(第三版)》北京清华大学出版社 2005
3. Decoder编著《C/C++程序设计》北京中国铁路出版社 2002
4. 朱站立编著《数据结构(C语言版)》西安西安交通大学出版社 2006
附录:源程序代码
(1)动态链接库源程序代码
_declspec(dllexport) double Add(double a, double b)
{return a+b; }
_declspec(dllexport) double Sub(double a, double b)
{return a-b; }
_declspec(dllexport) double Multiply(double a, double b)
{return a*b; }
_declspec(dllexport) double Divide(double a, double b)
{return a/b;}
(2)计算器源程序代码
#include "stdafx.h"
#include "MyGrant_Caculator.h"
#include "MyGrant_CaculatorDlg.h"
//#include
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
char oper,ch[20];
int dian=0,q=0;
CString s1,stri;
int m=0,k=0,n=0,a=0;
//m=0输入单步运算, m=1 输入算式运算
CString tt,aa,ss;
CString str,num[20];
double aaa;
int s=0,i=0,j,www;
double x1,x2,x;
_declspec(dllexport) double Add(double a,double b);
_declspec(dllexport) double Sub(double a,double b);
_declspec(dllexport) double Multiply(double a,double b);
_declspec(dllexport) double Divide(double a,double b);
//////////////////////////////////////////////////////////////////////// /////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////// /////
// CMyGrant_CaculatorDlg dialog
CMyGrant_CaculatorDlg::CMyGrant_CaculatorDlg(CWnd* pParent /*=NULL*/) : CDialog(CMyGrant_CaculatorDlg::IDD, pParent)
{//{{AFX_DATA_INIT(CMyGrant_CaculatorDlg)
m_text = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMyGrant_CaculatorDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMyGrant_CaculatorDlg)
DDX_Text(pDX, IDC_EDIT1, m_text);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMyGrant_CaculatorDlg, CDialog)
//{{AFX_MSG_MAP(CMyGrant_CaculatorDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_num1, Onnum1)
ON_BN_CLICKED(IDC_num2, Onnum2)
ON_BN_CLICKED(IDC_num3, Onnum3)
ON_BN_CLICKED(IDC_num4, Onnum4)
ON_BN_CLICKED(IDC_num5, Onnum5)
ON_BN_CLICKED(IDC_num6, Onnum6)
ON_BN_CLICKED(IDC_num7, Onnum7)
ON_BN_CLICKED(IDC_num8, Onnum8)
ON_BN_CLICKED(IDC_num9, Onnum9)
ON_BN_CLICKED(IDC_Dian, OnDian)
ON_BN_CLICKED(IDC_num0, Onnum0)
ON_BN_CLICKED(IDC_Add, Onadd)
ON_BN_CLICKED(IDC_Sub, Onsub)
ON_BN_CLICKED(IDC_Multiply, Oncheng)
ON_BN_CLICKED(IDC_Divide, Onchu)
ON_BN_CLICKED(IDC_Deng, OnDeng)
ON_BN_CLICKED(IDC_Esc1, OnEsc1)
ON_BN_CLICKED(IDC_RADIO1, OnRadio1)
ON_BN_CLICKED(IDC_RADIO2, OnRadio2)
ON_BN_CLICKED(IDC_EDIT2, OnEdit2)
ON_NOTIFY(DTN_CLOSEUP, IDC_DATETIMEPICKER1, OnCloseupDatetimepicker1) //}}AFX_MSG_MAP
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////// /////
// CMyGrant_CaculatorDlg message handlers
BOOL CMyGrant_CaculatorDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control }
void CMyGrant_CaculatorDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework.
void CMyGrant_CaculatorDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags // the minimized window.
HCURSOR CMyGrant_CaculatorDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CMyGrant_CaculatorDlg::Onnum1()
{// TODO: Add your control notification handler code here
if(m==0)
{
s1=s1+"1";
}
else if(m==1)
{ q=0;
num[i]=num[i]+"1";
m_text=m_text+"1";
}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onnum2()
{// TODO: Add your control notification handler code here if(m==0)
{
s1=s1+"2";
m_text=s1;
}
else if(m==1)
{
num[i]=num[i]+"2";
m_text=m_text+"2";
q=0;
}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onnum3()
{// TODO: Add your control notification handler code here if(m==0)
{
m_text=s1;
}
else if(m==1)
{
num[i]=num[i]+"3";
m_text=m_text+"3";
q=0;
}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onnum4()
{// TODO: Add your control notification handler code here
if(m==0)
{
s1=s1+"4";
m_text=s1;
}
else if(m==1)
{num[i]=num[i]+"4";
m_text=m_text+"4";
q=0;
}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onnum5()
{
// TODO: Add your control notification handler code here if(m==0)
{
s1=s1+"5";
m_text=s1;
}
else if(m==1)
{q=0;
num[i]=num[i]+"5";
m_text=m_text+"5";
}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onnum6()
{// TODO: Add your control notification handler code here if(m==0)
{
s1=s1+"6";
m_text=s1;
}
else if(m==1)
{num[i]=num[i]+"6";
m_text=m_text+"6";
q=0;
}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onnum7()
{// TODO: Add your control notification handler code here if(m==0)
{
s1=s1+"7";
m_text=s1;
}
else if(m==1)
{num[i]=num[i]+"7";
m_text=m_text+"7";
q=0;}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onnum8()
{// TODO: Add your control notification handler code here if(m==0)
{
s1=s1+"8";
m_text=s1;
}
else if(m==1)
{num[i]=num[i]+"8";
m_text=m_text+"8";
q=0;}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onnum9()
{// TODO: Add your control notification handler code here if(m==0)
{
s1=s1+"9";
m_text=s1;
}
else if(m==1)
{
num[i]=num[i]+"9";
m_text=m_text+"9";
q=0;
}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::OnDian()
{
// TODO: Add your control notification handler code here if(m==0)
{ if(dian==0)
{
s1=s1+".";
m_text=s1;dian=1;
}
}
else if(m==1)
{
if(dian==0)
{num[i]=num[i]+".";
m_text=m_text+".";
dian=1;q=0;}
}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onnum0()
{// TODO: Add your control notification handler code here
if(m==0)
{
s1=s1+"0";
m_text=s1;
}
else if(m==1)
{num[i]=num[i]+"0";
m_text=m_text+"0";
q=0;}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onadd()
{// TODO: Add your control notification handler code here if(m==0)
{
x1=atof(s1);
m_text="+";
s1=_T("");dian=0;
oper='+';
}
else if(m==1)
if(q==0){
m_text=m_text+"+";
ch[i++]='+';dian=0;q=1;}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onsub()
{// TODO: Add your control notification handler code here if(m==0)
{
x1=atof(s1);
m_text="-";
s1=_T("");dian=0;
oper='-';
}
else if(m==1)
if(q==0){q=1;
m_text=m_text+"-";
ch[i++]='-';dian=0;}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Oncheng()
{
// TODO: Add your control notification handler code here if(m==0)
{
x1=atof(s1);
m_text="*";
s1=_T("");dian=0;
oper='*';
}
else if(m==1)
if(q==0)
{q=1;
m_text=m_text+"*";
ch[i++]='*';dian=0;}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::Onchu()
{// TODO: Add your control notification handler code here if(m==0)
{
x1=atof(s1);
m_text="/";
s1=_T("");dian=0;
oper='/';
}
else if(m==1)
if(q==0)
{q=1;
m_text=m_text+"/";
ch[i++]='/';dian=0;}
UpdateData(false);
}
void CMyGrant_CaculatorDlg::OnDeng()
{// TODO: Add your control notification handler code here if(m==0)
{
x2=atof(s1);
if((x2==0)&&(oper=='/'))
{
m_text="被除数不能为零!重新输入";
UpdateData(false);
s1=_T("");
}else
{
switch(oper)
{
case '+': x=Add(x1,x2);break;
case '-': x=Sub(x1,x2);break;
case '*': x=Multiply(x1,x2);break;
case '/': x=Divide(x1,x2);break;
}
stri.Format("%lf",x);
m_text=stri;
x1=x; //控制连等
UpdateData(false);
}
}else
if(m==1)
{ /*while(s>0)
{
if((str[i]<='9')&&(str[i]>='0')||(str[i]=='.')) {
num[i]=num[i]+(CString)str[i];
s--;i++;
continue;
}
if((str[i]=='+')||(str[i]=='-')||(str[i]=='*')||(str[i]=='/')) {
switch(str[i])
{
case '+': op[i++]='+';break;
case '-': op[i++]='-';break;
case '*': op[i++]='*';break;
case '/': op[i++]='/';break;
}
}
}
for(n=0;n
if((ch[n]=='*')||(ch[n]=='/'))
a++;