MFC制作个人简易计算器(超长代码预警)

学了快一年的c/c++,除了c语言能用来解数学题,c++多了个面向对象以外,什么都不会(可能在下学术不精,各位大佬勿喷)。最近老师在讲vc++,终于可以做个真正的应用程序出来了,莫名有些兴奋,所以废了九牛二虎之力用MFC做了个简易计算器,话不多说,先看界面。

这里写图片描述

下面一步步开始说明代码部分

1. 创建并初始化全局变量

public:
    CString num1;//用来绑定用户输入的第一个操作数
    CString num2;//用来绑定用户输入的第二个操作数
    CString IsTemple;//判断进行的是哪个运算符
    CString smallnum1;//判断输入的第一个数是否是小数
    CString smallnum2;//判断输入的第二个数是否是小数

这里写图片描述

    num1 = "";
    num2 = "";
    IsTemple = "";
    m_output = "0";
    smallnum1 = "";
    smallnum2 = "";

初始化变量

(m_output是我给输出框绑定的变量,也初始化)这里稍微说一下,为什么m_output要初始化为“0”,读者打开自己电脑上的计算器就知道了,计算器不论是归零,或是默认状态,输出框显示的都不为空,而是“0”,这里我们也尽量做到和真实的计算器一样。以上,第一部分,创建并初始化全局变量就算完成了。

2. 数字按钮代码的实现

void CCalc1Dlg::On1() 
{
    if(m_output == "0")
    {
        m_output = "";
        UpdateData(FALSE);
    }
    m_output += "1";
    UpdateData(FALSE);
}

void CCalc1Dlg::On2() 
{
    if(m_output == "0")
    {
        m_output = "";
        UpdateData(FALSE);
    }
    m_output += "2";
    UpdateData(FALSE);  
}

void CCalc1Dlg::On3() 
{
    if(m_output == "0")
    {
        m_output = "";
        UpdateData(FALSE);
    }
    m_output += "3";
    UpdateData(FALSE);  
}

void CCalc1Dlg::On4() 
{
    if(m_output == "0")
    {
        m_output = "";
        UpdateData(FALSE);
    }
    m_output += "4";
    UpdateData(FALSE);  
}

void CCalc1Dlg::On5() 
{
    if(m_output == "0")
    {
        m_output = "";
        UpdateData(FALSE);
    }
    m_output += "5";
    UpdateData(FALSE);  
}

void CCalc1Dlg::On6() 
{
    if(m_output == "0")
    {
        m_output = "";
        UpdateData(FALSE);
    }
    m_output += "6";
    UpdateData(FALSE);  
}

void CCalc1Dlg::On7() 
{
    if(m_output == "0")
    {
        m_output = "";
        UpdateData(FALSE);
    }
    m_output += "7";
    UpdateData(FALSE);  
}

void CCalc1Dlg::On8() 
{
    if(m_output == "0")
    {
        m_output = "";
        UpdateData(FALSE);
    }
    m_output += "8";
    UpdateData(FALSE);

}

void CCalc1Dlg::On9() 
{
    if(m_output == "0")
    {
        m_output = "";
        UpdateData(FALSE);
    }
    m_output += "9";
    UpdateData(FALSE);  
}

void CCalc1Dlg::On0() 
{
    if(m_output == "0")
    {
        m_output = "";
        UpdateData(FALSE);
    }
    m_output += "0";
    UpdateData(FALSE);

}

这里需要解释一下这段代码的含义这里写图片描述如果不加这段代码,输入“1”,就会变成“01”,因为我们的m_output初始化为“0”,所以需要加个判断,如果我摁数字键的时候,输出框当前显示为“0”,则将输出框的字符串变量置为“空”。别忘了UpdateData数据!

3. 加减乘除,取余操作

void CCalc1Dlg::Onjia() 
{
    smallnum2 = "";
    IsTemple = "jia";
    num1 = m_output;
    m_output = "";
    m_out = num1+"+";
    UpdateData(FALSE);
}

void CCalc1Dlg::Onjian() 
{
    smallnum2 = "";
    IsTemple = "jian";
    num1 = m_output;
    m_output = "";
    m_out = num1+"-";
    UpdateData(FALSE);  
}

void CCalc1Dlg::Oncheng() 
{
    smallnum2 = "";
    IsTemple = "cheng";
    num1 = m_output;
    m_output = "";
    m_out = num1+"×";
    UpdateData(FALSE);      
}

void CCalc1Dlg::Onchu() 
{
    smallnum2 = "";
    IsTemple = "chu";
    num1 = m_output;
    m_output = "";
    m_out = num1+"÷";
    UpdateData(FALSE);  
}
void CCalc1Dlg::Onquyu() 
{
    IsTemple = "quyu";
    num1 = m_output;
    m_output = "";
    m_out = num1 + "%";
    UpdateData(FALSE);  
}

smallnum2和m_out的作用在下面讲,但是这里有必要说明的是整个代码的核心,IsTemple的作用。当我点“=”的时候,到底进行什么运算呢?这时IsTemple就派上用场了,没错,在“=”的函数里面加上判断,if(IsTemple ==“xxx”)的时候就执行什么运算。到了这里,你已经掌计算器的大部分核心代码了,接下来的就是增加一些计算器的细节代码。

4. 倒数,相反数,平方,立方,根号的操作

void CCalc1Dlg::Ondaoshu() 
{
    smallnum1 = "1";
    double i;
    num1 = m_output;
    m_output = "";
    UpdateData(FALSE);
    if(num1 == "0")
    {
        m_output = "分母不能为0!";
        UpdateData(FALSE);
        m_output = "";
    }
    else
    {
        i = atof(num1);
        m_output.Format("%lf",1/i);
        UpdateData(FALSE);
    }       
}
void CCalc1Dlg::Onxiangfanshu() 
{
    smallnum2 = "";
    if(smallnum1 == "1")
    {
        double i;
        num1 = m_output;
        m_output = "";
        UpdateData(FALSE);
        i = atof(num1);
        m_output.Format("%lf",-i);
        if(i<=0)
        {
            m_out = num1;
            UpdateData(FALSE);
        }
        else
        {
            m_out = "-"+num1;
            UpdateData(FALSE);
        }
        i = atof(num1);
        UpdateData(FALSE);
    }
    else
    {
        int i;
        num1 = m_output;
        m_output = "";
        UpdateData(FALSE);
        i = atoi(num1);
        m_output.Format("%d",-i);
        UpdateData(FALSE);
    }
}
void CCalc1Dlg::Onpingfang() 
{
    smallnum2 = "";
    if(smallnum1 == "1")
    {
        double i;
        num1 = m_output;
        m_output = "";
        UpdateData(FALSE);
        i = atof(num1);
        m_output.Format("%lf",i*i);
        UpdateData(FALSE);
    }
    else
    {
        int i;
        num1 = m_output;
        m_output = "";
        UpdateData(FALSE);
        i = atoi(num1);
        m_output.Format("%d",i*i);
        UpdateData(FALSE);
    }   
}
void CCalc1Dlg::Onlifang() 
{
    smallnum2 = "";
    if(smallnum1 == "1")
    {
        double i;
        num1 = m_output;
        m_output = "";
        UpdateData(FALSE);
        i = atof(num1);
        m_output.Format("%lf",i*i*i);
        UpdateData(FALSE);
    }
    else
    {
        int i;
        num1 = m_output;
        m_output = "";
        UpdateData(FALSE);
        i = atoi(num1);
        m_output.Format("%d",i*i*i);
        UpdateData(FALSE);
    }           
}
void CCalc1Dlg::Ongenhao() 
{
    smallnum2 = "";
    double i;
    num1 = m_output;
    m_output = "";
    UpdateData(FALSE);
    i = atof(num1);
    if(i<0)
    {
        m_output = "无效输入!";
        UpdateData(FALSE);
        m_output = "";
    }
    else
    {
        m_output.Format("%lf",sqrt(i));//别忘了添加个math.h头文件,这里我就不加了
        UpdateData(FALSE);
    }   
}

为什么要把这几个代码和“加减乘除,取余”分开,是因为这几个代码不涉及到“等号”这个操作,用户输入的数,当他点击“倒数“,”相反数“,”平方“,”立方“,”根号”其中任意一个的时候,不需要点“等于”就可以产生结果了。这个逻辑要注意。

到这里为止,基本操作算是编写完成,接下来就开始实现这些操作,都在“等号”里面实现
—————————————————————————————————————————————————————

5. 等号的作用—>各个操作的实现

void CCalc1Dlg::Ondengyu() 
{
    if(IsTemple == "jia")
    {
        if(smallnum1 == "1")
        {
            double i,j,k;
            num2 = m_output;
            m_out += num2;
            m_output = "";
            UpdateData(FALSE);
            i = atof(num1);
            j = atof(num2);
            k = i + j;
            UpdateData(FALSE);
            m_output.Format("%lf",k);
            m_out += "="+m_output;
            UpdateData(FALSE);
        }
        else
        {
            int i,j,k;
            num2 = m_output;
            m_output = "";
            UpdateData(FALSE);
            i = atoi(num1);
            j = atoi(num2);
            k = i + j;
            UpdateData(FALSE);
            m_output.Format("%d",k);
            m_out += num2+"="+m_output;
            UpdateData(FALSE);
        }
    }
    if(IsTemple == "jian")
    {
        if(smallnum1 == "1")
        {
            double i,j,k;
            num2 = m_output;
            m_output = "";
            UpdateData(FALSE);
            i = atof(num1);
            j = atof(num2);
            k = i - j;
            m_output.Format("%lf",k);
            m_out += num2+"="+m_output;
            UpdateData(FALSE);
        }
        else
        {
            int i,j,k;
            num2 = m_output;
            m_output = "";
            UpdateData(FALSE);
            i = atoi(num1);
            j = atoi(num2);
            k = i - j;
            m_output.Format("%d",k);
            m_out += num2+"="+m_output;
            UpdateData(FALSE);
        }
    }
    if(IsTemple == "cheng")
    {
        if(smallnum1 == "1")
        {
            double i,j,k;
            num2 = m_output;
            m_output = "";
            UpdateData(FALSE);
            i = atof(num1);
            j = atof(num2);
            k = i * j;
            m_output.Format("%lf",k);
            m_out += num2+"="+m_output;
            UpdateData(FALSE);
        }
        else
        {
            int i,j,k;
            num2 = m_output;
            m_output = "";
            UpdateData(FALSE);
            i = atoi(num1);
            j = atoi(num2);
            k = i * j;
            m_output.Format("%d",k);
            m_out += num2+"="+m_output;
            UpdateData(FALSE);
        }
    }
    if(IsTemple == "chu")
    {
        if(m_output == "0")
        {
            m_output = "分母不能为0!";
            UpdateData(FALSE);
            m_output = "";
        }
        else
        {
            num2 = m_output;
            m_output = "";
            UpdateData(FALSE);
            if(smallnum1 == "1")
            {
                CString n1 = num1;
                CString n2 = num2;
                double i,j,k;
                i = atof(n1);
                j = atof(n2);
                k = i/j;
                m_output.Format("%lf",k);
                m_out += num2+"="+m_output;
                UpdateData(FALSE);
            }
            else
            {
                CString n1 = num1;
                CString n2 = num2;
                int i,j;
                i = atoi(n1);
                j = atoi(n2);
                if(i%j==0)
                {
                    int k = i/j;
                    m_output.Format("%d",k);
                    m_out += num2+"="+m_output;
                    UpdateData(FALSE);
                }
                else
                {
                    double s = atof(num1);
                    double x = atof(num2);
                    double k = s/x;
                    m_output.Format("%lf",k);
                    m_out += num2+"="+m_output;
                    UpdateData(FALSE);
                }
            }
        }

    }
    if(IsTemple == "quyu")
    {
        if(num1!="")
        {
            int i,j,k;
            num2 = m_output;
            m_output = "";
            UpdateData(FALSE);
            i = atol(num1);
            j = atol(num2);
            k = i % j;
            m_output.Format("%d",k);
            m_out += num2+"="+m_output;
            UpdateData(FALSE);
        }
    }
}

不要嫌代码长,先大概的看一遍,到这里读者应该发现了smallnum1的作用,当我点击“小数点”的时候,意味着有小数诞生了,这时我们就应该把操作全部变为“double”类型,而没点击“小数点”的时候,全是整数在进行运算,所以没必要定义为“double”类型,否则很不美观,所以定义为“int”类型。下面附上小数点的操作代码

void CCalc1Dlg::Ondian() 
{
    if((smallnum1!= "1"||smallnum2!= "1"))
    {
        smallnum1 = "1";
        smallnum2 = "1";
        m_output += ".";
        UpdateData(FALSE);
    }
}

至于为什么定义两个smallnum,这里就不解释了,读者可以思考一下,如果只定义一个smallnum会怎么样?这里还有一点要说的,if使用的很巧妙,如果不加if,直接m_output += “.”,用户就可以不停的点击“小数点”按钮,小数点就会不停的累加,这很不符合逻辑,对吧?

6. “CE,C和退格操作的实现”

在贴代码之前先给大家解释一下,计算器中CE的功能是什么。CE就是清除第二个操作数。举个简单的例子:我想计算15+5,但是我不小心点错了,点成了15+3,这个时候我还没点“=”,我点一下“CE”,那么计算器就会变为15+的状态,这时,我再点一下“5”,然后等于,就可以了。其他运算也相类似。下面附上代码

void CCalc1Dlg::Once() 
{
    smallnum1 = "";
    smallnum2 = "";
    num2 = "";
    if(m_output != "0")
    {
        m_output = "0";
    }
    UpdateData(FALSE);
}
void CCalc1Dlg::Onc() 
{
    smallnum1 = "";
    smallnum2 = "";
    m_output = "0";
    UpdateData(FALSE);
    IsTemple = "";
}
void CCalc1Dlg::Onhuitui() 
{
    smallnum1 = "";
    smallnum2 = "";
    if(m_output != "0")
    {
        if(m_output.GetLength() == 1)
        {
            m_output = "0";
            UpdateData(FALSE);
        }
        else
        {
            m_output = m_output.Left(m_output.GetLength()-1);
            UpdateData(FALSE);
        }   
    }
}

这部分代码没什么好说的,读者只要细心想想,当点击这些按钮的时候,什么应该清空,考虑周全就行。回退代码中可能这段代码读者额没见过,我稍微提一下m_output = m_output.Left(m_output.GetLength()-1);,这其实是MFC库函数当中删掉字符串的函数,不理解的可以去百度或者看一下API文档,这里就不多解释了。

到现在为止,简易计算器的所有功能全部实现了,下面讲到的是如何将输入的数字以及进行的操作展示到“历史记录”面板,也很简单,读者如果有兴趣可以继续阅读。
—————————————————————————————————————————————————————

7. “历史纪录功能”

这里首先提醒读者一句,历史纪录我用的变量名叫m_out,”历史纪录“实现的代码其实和只是简单的赋值,穿插在前六点当中,读者重新阅读一遍便可发现,因为“倒数“,”相反数“,”平方“,”立方“,”根号”都不涉及“等号”操作,因此我没有设置这几个操作符保存历史纪录。

8. “结语”

因为作者英语水平有限,所以变量命名用的拼音,希望读者谅解。另外,计算器代码还有可以优化的地方,例如,小数去掉后面多余的0,这点读者暂时想不到,要是各位大佬有好想法可以私聊作者,QQ:739616037,同时,附上一篇修改exe文件图标的文章链接http://blog.sina.com.cn/s/blog_8216ada70101bteh.html,毕竟,默认的图标实在是太丑了。这是我更改后的图标 这里写图片描述 最后,感谢观看!

MFC(Microsoft Foundation Class)是微软公司开发的一种基于 Windows 操作系统的 C++ 类库,常用于 Windows 平台下的应用程序开发。下面是一个简单的 MFC 计算器的实现步骤: 1. 创建一个 MFC 应用程序项目,选择“单文档”模板。 2. 在应用程序视图添加一个对话框,用于显示计算器界面。 3. 在对话框添加按钮,分别对应数字、运算符和功能键(如清空、等于、退格等)。 4. 在对话框类添加相应的变量和控件变量,用于实现计算器的功能。 5. 在对话框类添加响应按钮点击事件的函数,实现计算器的逻辑。 6. 在应用程序类设置主窗口为对话框,并启动应用程序。 下面是一个简单的 MFC 计算器代码示例: ``` // CalculatorDlg.h 文件 class CCalculatorDlg : public CDialogEx { public: CCalculatorDlg(CWnd* pParent = nullptr); enum { IDD = IDD_CALCULATOR_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); virtual BOOL OnInitDialog(); DECLARE_MESSAGE_MAP() private: CString m_strResult; double m_dOperand1, m_dOperand2; int m_nOperator; BOOL m_bNewNumber; void AppendNumber(int nNumber); void AppendOperator(int nOperator); void Calculate(); public: afx_msg void OnBnClickedBtn0(); afx_msg void OnBnClickedBtn1(); // 添加其他数字按钮的响应函数 afx_msg void OnBnClickedBtnAdd(); afx_msg void OnBnClickedBtnSubtract(); // 添加其他运算符按钮的响应函数 afx_msg void OnBnClickedBtnClear(); afx_msg void OnBnClickedBtnEqual(); afx_msg void OnBnClickedBtnBackspace(); // 添加其他功能键按钮的响应函数 afx_msg void OnEnChangeEditResult(); }; // CalculatorDlg.cpp 文件 CCalculatorDlg::CCalculatorDlg(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_CALCULATOR_DIALOG, pParent) , m_strResult(_T("")) , m_dOperand1(0) , m_dOperand2(0) , m_nOperator(0) , m_bNewNumber(TRUE) { } void CCalculatorDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT_RESULT, m_strResult); } BOOL CCalculatorDlg::OnInitDialog() { CDialogEx::OnInitDialog(); m_strResult = "0"; UpdateData(FALSE); return TRUE; } void CCalculatorDlg::AppendNumber(int nNumber) { if (m_bNewNumber) { m_strResult = ""; m_bNewNumber = FALSE; } m_strResult += CString(nNumber + '0'); UpdateData(FALSE); } void CCalculatorDlg::AppendOperator(int nOperator) { if (!m_bNewNumber) { Calculate(); } m_dOperand1 = _ttof(m_strResult); m_nOperator = nOperator; m_bNewNumber = TRUE; } void CCalculatorDlg::Calculate() { m_dOperand2 = _ttof(m_strResult); switch (m_nOperator) { case IDC_BTN_ADD: m_dOperand1 += m_dOperand2; break; case IDC_BTN_SUBTRACT: m_dOperand1 -= m_dOperand2; break; // 添加其他运算符的计算 } m_strResult.Format("%.2f", m_dOperand1); UpdateData(FALSE); } void CCalculatorDlg::OnBnClickedBtn0() { AppendNumber(0); } void CCalculatorDlg::OnBnClickedBtn1() { AppendNumber(1); } // 添加其他数字按钮的响应函数 void CCalculatorDlg::OnBnClickedBtnAdd() { AppendOperator(IDC_BTN_ADD); } void CCalculatorDlg::OnBnClickedBtnSubtract() { AppendOperator(IDC_BTN_SUBTRACT); } // 添加其他运算符按钮的响应函数 void CCalculatorDlg::OnBnClickedBtnClear() { m_strResult = "0"; m_dOperand1 = 0; m_dOperand2 = 0; m_nOperator = 0; m_bNewNumber = TRUE; UpdateData(FALSE); } void CCalculatorDlg::OnBnClickedBtnEqual() { Calculate(); } void CCalculatorDlg::OnBnClickedBtnBackspace() { if (m_bNewNumber) { return; } int nLength = m_strResult.GetLength(); if (nLength == 1 || (nLength == 2 && m_strResult[0] == '-')) { m_strResult = "0"; m_bNewNumber = TRUE; } else { m_strResult.Delete(nLength - 1, 1); } UpdateData(FALSE); } // 添加其他功能键按钮的响应函数 void CCalculatorDlg::OnEnChangeEditResult() { if (!m_bNewNumber) { Calculate(); } } ``` 注意:代码的 IDC_BTN_ADD、IDC_BTN_SUBTRACT 等都是控件 ID,需要在资源编辑器设置。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数学家是我理想

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值