基于MFC的科学计算器课程设计实验报告

时间:2024.4.13

课程设计实验报告

题    目                    

学    院                    

专    业                    

班    级                    

课程名称                    

学    号                    

学生姓名                    

指导教师                    

成    绩                    

二○##年一月


目  录

1 概述

1.1 课程设计目的

1.2 课程设计内容

1.3 课程设计思想

2 系统需求分析

2.1 系统目标

2.2 主体功能

2.3 开发环境

3 系统概要分析

3.1 设计步骤

3.2 界面设计

3.3 主要代码

4 结论与心得体会

4.1 遇到的问题与解决方法

4.2 心得

5 附录

5.1 测试

5.2 程序源代码


1 概述

1.1   课程设计目的

《面向对象程序设计》是一门实践性很强的计算机专业基础课程,课程设计是学习完该课程后进行的一次较全面的综合练习。其目的在于通过实践加深学生对面向对象程序设计的理论、方法和基础知识的理解,掌握使用C++语言进行面向对象设计的基本方法,提高运用面向对象方法分析实际问题、解决实际问题的能力。

1、巩固并加深学生对C++语言程序设计知识的理解;

2、培养学生面向对象的程序设计思想,使学生认识面向过程和面向对象两种设计方法的区别;

3、进一步掌握和应用VS 2010集成开发环境;

4、提高运用C++语言解决实际问题的能力;

5、掌握书写程序设计开发文档的能力(书写课程设计实验报告)。

1.2   课程设计内容

课题名称:功能齐全的计算器

说明:利用MFC实现一个功能齐全的计算器

要求:

1、实现的基本功能有:加、减、乘、除、计算带括号的运算式;

2、扩展功能有开平方、求三角函数、阶乘、自然底数e的幂、10的幂和普通数的幂、进制的转化等;

3、输入的原始数据、运算中间数据和结果都显示在窗口顶部的同一个编辑框中;

4、计算功能基本上是用系统内部函数;

5、“归零”按钮可以清除所有已输入的数据从头计算;

6、“←”按钮可以退位。

1.3   课程设计思想

如流程图1所示,先在编辑框中输入运算式,通过IsChar()函数判断表达式中是否有复杂的运算符。若无,则进行简单的双目运算;若有,则通过String_Replace()函数将IsChar()函数无法识别的运算符或字符用一定方式或浮点数替换,再进行简单的双目运算。

2   系统需求分析

2.1  系统目标

我们在学习生活中,常会遇到一些繁杂的数值运算,这时候我们就必须用到科学计算器,所以便着手开发了这个计算器程序,以便用于自己的学习工作。要计算功能有以下几个方面:加法,减法,乘法,除法,求幂,求平方根,求Sin,求Cos。

2.2  主体功能

1、十进制数的加、减、乘、除、乘方、阶乘等简单计算。

2、科学计算函数,包括正弦、余弦、正切、开方、指数等函数运算。

3、实现括号的优先级判断。

4、将编辑框里的内容以转化成二、八、十六进制。

2.3  开发环境

Windows 操作系统,Microsoft Visual Studio 2010。

3   系统详细设计

3.1 设计步骤

打开VS2010,在文件中点击新建,在弹出框内选择MFC AppWizard[exe]工程,输入工程名Calculator及其所在位置,点击确定,如图2所示。

图2新建MFC AppWizard[exe]工程

选择基于对话框,如图3所示

图3 基于对话框

3.2 界面设计

设计如图4所示的计算机界面,右击创建类向导,如表1所示,为每个控件添加ID号和单击响应事件的消息处理(BN_CLICKED)。

图4 计算机主界面

表1 各按钮和编辑框等对象的属性

如图5所示,为IDC_EDIT1和IDC_RADIO1添加变量。

图5 添加变量

3.3   主要代码

1)“=”键单击响应代码

void CCalculatorVersion3Dlg::OnBtnequal()

{

    UpdateData();

    m_str = m_string;

    while ( ! IsChar(m_str))// 判断表达式中是否有其他字符

    {

       Calculate(m_str);

    }

    double sum = Simple( m_str );

    if( sum > -9.9002032198673601e-10 && sum < 9.9002032198673601e-10) { sum = 0;} 

    if( sum > 0.4999999 && sum < 0.5000001) { sum = 0.5;}

    if( sum < -0.4999999 && sum > -0.5000001) { sum = -0.5;}

    char answer[30] ;

    gcvt(sum, 20, answer); //把浮点数转换成字符串,同时返回一个指向字符串的存储位置的指针

    SetDlgItemText(IDC_EDIT1,answer);

}

2)简单双目运算

double CCalculatorVersion3Dlg::Simple(string str)

{

    double a = 0 ;

    double b,c;

    char op;

    istringstream sin( str ); //定义字符流

    for ( sin >>b ; sin>>op>>c; ) //分别读入运算符和运算符前后¨两个浮点数

    {

        switch( op )

        {

        case '-':  // 减法运算

            c = - c;

        case '+':  // 加法运算

             a += b;

             b = c;

             break;

        case '*':  // 乘法运算

            b *= c;

            break;

        case '/':  // 除法运算

            if ( c == 0 )

            {

                MessageBox("Can't be divided by zero");break;

            }

            b =  b / c ;

            break;

        case '%':  // double 数据的取模

            if ( (long)c != 0 )

              b = fmod( b , c );

            break;

        default:

            break;         

        }      

    }

    return a + b;

}

3)判断是否有简单双目运算以外的字符或运算符

BOOL CCalculatorVersion3Dlg::IsChar(string str)

{

    int i;

    for ( i = 0 ; i < str.length (); i ++ )

    {

      if ( ! (( str[i] >= '0' && str[i] <= '9' ) || (str[i] == '+') || (str[i] == '-') ||

            (str[i] == '*') || (str[i] == '/') || (str[i] == '.') || ( str[i] == 'e') || ( str[i] == '%') ))

            return FALSE;

    }

    return TRUE;

}

4)转换函数

void CCalculatorVersion3Dlg::String_replace(string &strBig, const string &strsrc, const string &strdst)

{

    {

         string::size_type pos=0;

         string::size_type srclen=strsrc.size();

         string::size_type dstlen=strdst.size();

           while( (pos=strBig.find(strsrc, pos)) != string::npos)

           {

                strBig.replace(pos, srclen, strdst);

                pos += dstlen;

           }

     }

}

5)复杂运算

double CCalculatorVersion3Dlg::Calculate(string &str)

{

  // 递归计算括号内的值

    if ( IsChar(str) )

    {

        double tok = Simple(str);

        char token[20]  ;

        gcvt(tok,20,token);

        String_replace( m_str, str, token );

    }

    else

    {  

        // 是否有PI

        while ( str.find ("PI") != -1 )

        {

            String_replace(m_str, str.substr(str.find ("PI"), 2 ), PI);

        }

        // 是否有e

        while ( str.find ("EI") != -1 )

        {

            String_replace(m_str, str.substr(str.find ("EI"), 2 ), EI);

        }

        // 是否有括号

        while ( str.find(")") != -1 )

        {

            int rightBrk = str.find(")");

            int leftBrk = str.rfind ("(",rightBrk);

            str.erase( rightBrk, 1 );

            str.erase( leftBrk, 1 );

            return Calculate(str.substr (leftBrk, rightBrk - leftBrk - 1) );

        }

        // 是否有sqrt

        while ( str.find ("sqrt") != -1 )

        {

            int m1 = str.find ("sqrt");

            int r1 = FindRight(m1 + 3);

            double c1 = sqrt(atof(str.substr (m1 + 4 ,r1-m1-3).c_str()));

            char ch1[20];

            gcvt(c1,20,ch1);

            String_replace(m_str,str.substr(m1,r1-m1+1), ch1);

        }

        // 是否有log

        while ( str.find ("log") != -1 )

        {

            int m2 = str.find ("log");

            int r2 = FindRight(m2 + 2);

            double c2 = log10(atof(str.substr(m2 + 3,r2-m2-2).c_str()));

            char ch2[20];

            gcvt(c2,20,ch2);

            String_replace(m_str,str.substr(m2,r2-m2+1),ch2);

        }

        // 是否有ln

        while ( str.find ("ln") != -1 )

        {

            int m3 = str.find ("ln");

            int r3 = FindRight(m3 + 1);

            double c3 = log(atof(str.substr(m3 + 2,r3-m3-1).c_str()));

            char ch3[20];

            gcvt(c3,20,ch3);

            String_replace(m_str,str.substr(m3,r3-m3+1),ch3);

        }

        // 是否有阶乘

        while ( str.find ("!") != -1 )

        {

            int m4 = str.find("!");

            int l1 = FindLeft(m4);

            int c4 = atoi(str.substr(l1,m4-l1).c_str());

            int sum = 1;

            for ( int m = 1 ; m <= c4; m++ )

                sum *= m;

            char ch4[20];

            itoa(sum,ch4,10);

            String_replace(m_str,str.substr(l1,m4-l1+1),ch4);          

        }

        // 是否有三角函数

        while ( str.find ("sin") != -1 )

        {

            int m5 = str.find ("sin");

            int r5 = FindRight(m5 + 2);

            double c5 = sin(atof(str.substr(m5 + 3,r5-m5-2).c_str())/180*pi);

            if( c5 > -9.9002032198673601e-10 && c5 < 9.9002032198673601e-10) { c5 = 0;}

            if( c5 > 0.4999999 && c5 < 0.5000001) { c5 = 0.5;}

            if( c5 < -0.4999999 && c5 > -0.5000001) { c5 = -0.5;}

            char ch5[20];

            gcvt(c5,20,ch5);

            String_replace(m_str,str.substr(m5,r5-m5+1),ch5);

        }

        while ( str.find ("cos") != -1 )

        {

            int m6 = str.find ("cos");

            int r6 = FindRight(m6 + 2);

            double c6 = cos(atof(str.substr(m6 + 3,r6-m6-2).c_str())/180*pi);

            if( c6 > -9.9002032198673601e-10 && c6 < 9.9002032198673601e-10) { c6 = 0;}

            if( c6 > 0.4999999 && c6 < 0.5000001) { c6 = 0.5;}

            if( c6 < -0.4999999 && c6 > -0.5000001) { c6 = -0.5;}

            char ch6[20];

            gcvt(c6,20,ch6);

            String_replace(m_str,str.substr(m6,r6-m6+1),ch6);

        }

        while ( str.find ("tan") != -1 )

        {

            int m7 = str.find ("tan");

            int r7 = FindRight(m7 + 2);

            double c7 = tan(atof(str.substr(m7 + 3,r7-m7-2).c_str())/180*pi);

            if( c7 > -9.9002032198673601e-10 && c7 < 9.9002032198673601e-10) { c7 = 0;}

            if( c7 > 0.4999999 && c7 < 0.5000001) { c7 = 0.5;}

            if( c7 < -0.4999999 && c7 > -0.5000001) { c7 = -0.5;}

            char ch7[20];

            gcvt(c7,20,ch7);

            String_replace(m_str,str.substr(m7,r7-m7+1),ch7);

        }

        // 是否有“^”

        while ( str.find ("^") != -1 )

        {

            int md =  str.find("^");

            int left = FindLeft(md);

            int right = FindRight(md);

            char c[20];

            double aa, bb;

            aa = atof(str.substr(left,md - left ).c_str());

            bb = atof(str.substr (md + 1, right - md ).c_str());

            gcvt( pow( aa ,bb ),20,c);

            String_replace(m_str, str.substr(left,right - left + 1 ), c);

        }

    }

    return 0;

}

6)小数点的左部和右部

int CCalculatorVersion3Dlg::FindLeft(int m)

{

    for ( int i = m - 1; i >= 0 ; i -- )

    {

        if ( ! (( m_str[i] >= '0' && m_str[i] <= '9' ) || ( m_str[i] == '.')))

            return i + 1;

    }

    return 0;

}

int CCalculatorVersion3Dlg::FindRight(int m)

{

    for ( int j = m + 1; j < m_str.length() ; j ++ )

    {

        if ( ! (( m_str[j] >= '0' && m_str[j] <= '9' ) || ( m_str[j] == '.')))

            return j - 1;

    }

    return m_str.length() - 1;

}


4 结论与心得体会

4.1 遇到的问题与解决方法

1、Debug Assertion Failed.

       File: dlgdata.cpp

       Line: 43

       Solution: 编辑框Edit1属性选Group

2、Debug Assertion Failed.

       File: dlgdata.cpp

       Line: 269

       Solution: 单选IDC_RADIO1的属性选Group,其他不设

3、ASSERTION::IsWindow(m_hWnd) 断言

       Solution: 消除野指针

4.2 心得

这学期上过WINDOWS高级编程,书上有一个简易的计算器的制作,但是对于利用MFC这个类库制作能进行科学运算的方法还不是很了解。

这个计算器我命名为VERSION 3.0的原因,是我在这个版本之前还做了两个计算器。第一个不能实现科学的单目运算,第二个能进行三角函数等运算但不能实现括号。后来将网上下载来的资源整理后发现substr()、find()等函数的功能,才写出这个计算器。

感觉写得并不是很好,因为还有一些问题没有得到完全的解决,比如sin函数与括号的结合问题,至今还没找到解决的方法,只能以后有空再好好想想了!

本来还想上网学一下MFC的美化,把这个页面做得好看一些的,但时间不允许了,所以只是在同学的指点下添加了计算器的背景图。

总的来说,这次的课程设计,还是让自己学到不少东西,同时也感觉到自己现在的不足——基础不够扎实,很多东西都是一知半解,真的要好好加强对基础知识的学习了!很多问题,不仅仅只是把功能实现就行了,还要注意代码的优化,把结果做得更好!


5 附录

5.1 测试

1)(7-9)/5

结果正确,证明可以实现双目运算符的连续运算,菜单功能正常

2)sin30

运算结果证明单目运算符能运行成功

3)8/0

证明错误提示功能实现正常

5.2 程序源代码

// CalculatorVersion3Dlg.cpp : 实现文件

#include "stdafx.h"

#include "CalculatorVersion3.h"

#include "CalculatorVersion3Dlg.h"

#include "afxdialogex.h"

#include <string>

#include <sstream>

#include <cmath>

using namespace std;   

#define  pi  3.141592653579893

const char *  PI = "3.141592653579893";

const char *  EI = "2.718281828459045";

……

void CCalculatorVersion3Dlg::OnBtnclear()

{

    m_string = "";

    UpdateData(FALSE);

}

void CCalculatorVersion3Dlg::OnRadio1()

{

    m_num = 0;

    UpdateData();

    int answer1 = (int)atof(m_string.operator LPCTSTR());

    itoa(answer1,(char *)m_string.operator LPCTSTR(),2);

    UpdateData(FALSE);

}

void CCalculatorVersion3Dlg::OnRadio2()

{

    m_num = 1;

    UpdateData();

    int answer = (int)atof(m_string.operator LPCTSTR());

    itoa(answer,(char *)m_string.operator LPCTSTR(),8);

    UpdateData(FALSE);

}

void CCalculatorVersion3Dlg::OnRadio3()

{

    m_num = 2;

    UpdateData();

    int answer = (int)atof(m_string.operator LPCTSTR());

    itoa(answer,(char *)m_string.operator LPCTSTR(),10);

    UpdateData(FALSE);

}

void CCalculatorVersion3Dlg::OnRadio4()

{

    m_num = 3;

    UpdateData();

    int answer = (int)atof(m_string.operator LPCTSTR());

    itoa(answer,(char *)m_string.operator LPCTSTR(),16);

    UpdateData(FALSE);

}// 进制的转换

void CCalculatorVersion3Dlg::OnButton0()

{

    m_string += "0";

    UpdateData( FALSE );

}// 1~9和其他按钮类似

void CCalculatorVersion3Dlg::OnBtnback()

{

    m_string.Delete( m_string.GetLength() - 1, 1  );

    UpdateData( FALSE );

}// 撤销键

void CCalculatorVersion3Dlg::OnBtnei()

{

    m_string += "EI^";

    UpdateData( FALSE );

}

void CCalculatorVersion3Dlg::OnBtnpi()

{

    m_string += "PI";

    UpdateData( FALSE );

}

void CCalculatorVersion3Dlg::OnBtnsin()

{

    m_string += "sin";

    UpdateData( FALSE );

}

……

更多相关推荐:
计算器设计的java课程设计报告

华东交通大学课程设计华东交通大学课程设计课程设计题目计算器设计课程题目年级专业学号姓名组员指导教师Java程序设计信息一班1华东交通大学课程设计课程设计论文任务书基础学院信息与计算科学专业20xx1班一课程设计...

计算机综合课程设计报告

计算机综合课程设计报告小组编号06课题名称趣味贪吃蛇小组成员20xx年10月计算机综合课程设计报告目录目录11项目背景112系统目标121系统功能分析2211功能12212功能2222系统性能指标223系统平台...

MFC计算器课程设计报告

MFC计算器课程设计报告计算机应用3班黄锦湫罗洁饶益指导老师蒋鹏20xx315一题目利用MFC框架编写简易计算器要求使用MFC框架在VisualStudio60环境下编写一个简易的计算器支持任意位数的加减乘数正...

计算机网络课程设计报告

计算机网络课程设计报告一.课程设计的题目、目的及要求.........................................................2二.课程设计的内容(分析和设计).....…

C++简单计算器课程设计报告

武汉理工大学专业课程设计2课程设计说明书目录1基本功能描述12设计思路13软件设计431设计步骤44结论与心得体会127附设计中的关键源代码1472测试结果15简单计算器1基本功能描述简单计算器包括双目运算和单...

Java课程设计报告-计算器

Java课程设计报告计算器第一部分设计的内容要求11Windows自带计算器版面设计12计算器计算功能算法实现第二部分设计思想21根据图形用户界面设计方法设计计算器版面容器类窗口Window类面板Panel类框...

课程设计报告——计算器

北京化工大学20xx20xx课程设计报告计算机科学与技术计算器程序的设计与实现数据结构课程设计班级计科1001北京化工大学信息科学与技术学院计算机科学与技术专业北京化工大学20xx20xx课程设计报告计算机科学...

java计算器设计报告

枣庄学院信息科学与工程学院课程设计任务书题目学号031503070311姓名王宇刘志伟王传翔专业课程java程序设计与实践教程指导教师王琳琳职称讲师完成时间20xx年12月20xx年1月枣庄学院信息科学与工程学...

java课程设计报告—计算器

1计算器Java实习报告目录一课程设计目的2二课程设计任务221设计任务222课程设计要求223需求分析2三开发工具与平台331开发工具332开发平台3四设计思路441界面设计4421逻辑设计4422程序流程图...

Java带计算过程的计算器课程设计报告

20xx20xx年度第1学期Java程序设计课程设计报告保存计算过程的计算器专业网络工程陆春燕B计算机0920970704211徐森20xx年1月13日学生姓名班学级号指导教师完成日期保存计算过程的计算器保存计...

JAVA保存计算过程的计算器课程设计报告

保存计算过程的java计算器目录1概述111课程设计目的112课程设计内容12系统需求分析121系统目标122主体功能123开发环境13系统概要设计131系统的功能模块划分132系统流程图14系统详细设计25测...

java课程设计报告_简单图形界面计算器的设计

Java课程设计简单图形界面计算器的设计课程名称Java程序设计选题名称简单图形界面计算器的设计专业班级姓名学号指导教师简单图形界面计算器的设计1一设计任务与目标本次java程序设计我的设计任务是设计一个图形界...

计算器课程设计报告(34篇)