一、程序综合设计——简单计算器的实现(更)

1.计算器概述

主要内容是设计开发一个支持连续计算的简单计算器,其过程包括设计目标、设计分析与算法流程、界面设计、关键类图、运行调试与项目扩展。通过该项目的开发,使自己进一步了解基于图形用户界面的Windows应用程序的开发过程。

2.计算器设计

2.1 设计目标

1)简单计算器的实现


该项目是一个支持连续计算的四则运算计算器,通过点击相应的数字按钮和运算按钮,输入并完成如4*6+3、cos(x)或者取倒数等等类似的计算,并将运算结果显示输出在文本框中,同时此计算器也具备清空、退格等其他功能,其运行界面如图1-1所示。

图1-1 简单计算器

计算器是一个简单的单窗口桌面程序,在主窗体上放置了按钮、文本框等控件,通过改变窗体与控件的属性,使界面更加美观与人性化,并为不同的控件添加了相应的事件和可执行的代码,能够完成简单的加减乘除等操作。

 

2)贷款计算器的实现

首先为计算器增加开平方根、平方、求倒数等功能,使其更加接近科学计算器。

然后在主窗体上增加一个按钮控件,通过点击可以打开贷款计算器的窗口。

图1-2贷款计算器

2.2 设计分析与算法流程

计算器的主要功能是完成加减乘除四则运算,而且支持连续运算,如4+4-7或4×7-6等运算。连续运算的实现借助于数据结构中的Stack(栈),如图1-3所示:首先是输入数字A入栈,然后输入运算符,如果是开方、平方运算则直接输出结果替换数字A,否则将运算符入栈,接着输入数字B入栈;然后,如果输入“=”,则通过出栈计算A OP B,得到计算结果,否则,继续输入其他运算符,重复上述的过程,来实现连续运算。

图1-3简单计算器的算法路程图

 

2.3 界面设计

 

2.4 关键类图

btn_A_Click()

按下数字按钮将值显示在文本框上

btn_OP_Click()

按下操作符将文本框内容与操作入栈

btn_backspace_Click()

将文本框中的内容从右消除一个

btn_equal_Click

计算器的算式计算与结果输出

Tips:

A为0-9十个数字;

OP为+-×÷等。

3.计算器实现(运行调试)

 

4.计算器扩展

计算_Click()

贷款计算输出

5.总结

1)Stack(栈)的用法总结

为了使计算器支持连续计算,在项目中使用了Stack 类,Stack 类表示对象的简单后进先出非泛型集合,它位于 System.Collections命名空间中,它的特点是:后进先出的集合,Stack能接受空引用作为有效值并且允许重复的元素。

Stack常用的方法及属性如下:

public virtual void Clear(); 

从 Stack 中移除所有的元素

public virtual bool Contains( object obj ); 

判断某个元素是否在 Stack 中

public virtual object Peek();

返回在 Stack 的顶部的对象,但不移除它

public virtual object Pop();

移除并返回在 Stack 的顶部的对象

public virtual void Push( object obj );

向 Stack 的顶部添加一个对象

2)DialogResult方法

方法名称

说明

AbortRetryIgnore

提供“中止”、“重试”和“忽略”三个按钮

OK

提供“确定按钮”

OKCancel

提供“确定”和“取消”两个按钮

RetryCancel

提供“重试”和“取消”两个按钮

YesNo

提供“是”和“否”两个按钮

YesNoCancel

提供“是”、“否”和“取消”三个按钮

3)主要代码与分析

①计算器

private void btn_equal_Click(object sender, EventArgs e)
{
    try
    {
        st.Push(txtDisplay.Text);
        if (st.Count >= 3)
        {
            num1 = Convert.ToDouble(st.Pop());
            Operator = Convert.ToString(st.Pop());
            num2 = Convert.ToDouble(st.Pop());
            switch (Operator)
            {
                case "+":
                    tempresult = num2 + num1;
                    st.Push(tempresult);
                    break;
                case "-":
                    tempresult = num2 - num1;
                    st.Push(tempresult);
                    break;
                case "×":
                    tempresult = num2 * num1;
                    st.Push(tempresult);
                    break;
                case "÷":
                    tempresult = num2 / num1;
                    st.Push(tempresult);
                    break;
            }
            txtDisplay.Text = tempresult.ToString();
        }
        st.Clear();
        flag2 = true;
    }
    catch (Exception)
    {
        MessageBox.Show("先输入数字才能进行此运算!", "Error", MessageBoxButtons.OK);
    }
}

上面的代码是按下等于后的计算,首先将txtDisplay中显示的数字字符串Push进栈中,如果栈中的项大于或等于三个就可以进行运算。之后再用switch语句来判断操作符OP是+、-、×、÷中的哪个,然后在进行运算。

注意:num1是后进入的数字,num2是先进入的数字。如,5-6,num1即为6,num2即为5。

private void btn_7_Click(object sender, EventArgs e)
        {
            if (flag2)
            {
                flag2 = false;
                txtDisplay.Text = "7";
            }
            else if (flag)
            {
                txtDisplay.Text += "7";
            }
            else
            {
                flag = true;
                txtDisplay.Text = "7";
            }
        }
private void btn_equal_Click(object sender, EventArgs e)
{
    try
    {
        st.Push(txtDisplay.Text);
        if (st.Count >= 3)
        {
            num1 = Convert.ToDouble(st.Pop());
            Operator = Convert.ToString(st.Pop());
            num2 = Convert.ToDouble(st.Pop());
            switch (Operator)
            {
                case "+":
                    tempresult = num2 + num1;
                    st.Push(tempresult);
                    break;
                case "-":
                    tempresult = num2 - num1;
                    st.Push(tempresult);
                    break;
                case "×":
                    tempresult = num2 * num1;
                    st.Push(tempresult);
                    break;
                case "÷":
                    tempresult = num2 / num1;
                    st.Push(tempresult);
                    break;
            }
            txtDisplay.Text = tempresult.ToString();
        }
        st.Clear();
        flag2 = true;
    }
    catch (Exception)
    {
        MessageBox.Show("先输入数字才能进行此运算!", "Error", MessageBoxButtons.OK);
    }
}
上面的代码是按下等于后的计算,首先将txtDisplay中显示的数字字符串Push进栈中,如果栈中的项大于或等于三个就可以进行运算。之后再用switch语句来判断操作符OP是+、-、×、÷中的哪个,然后在进行运算。
注意:num1是后进入的数字,num2是先进入的数字。如,5-6,num1即为6,num2即为5。
private void btn_7_Click(object sender, EventArgs e)
{
      if (flag2)
      {
            flag2 = false;
            txtDisplay.Text = "7";
      }
      else if (flag)
      {
           txtDisplay.Text += "7";
       }
      else
      {
           flag = true;
           txtDisplay.Text = "7";
      }
}

private void btn_per_Click(object sender, EventArgs e)
{
    double num;
    try
    {
        st.Push(txtDisplay.Text);

        num = Convert.ToDouble(st.Pop());
        st.Push(num * 0.01);
        txtDisplay.Text = (num * 0.01).ToString();
        flag2 = true;
    }
    catch (Exception)
    {
        MessageBox.Show("请先输入一个数字!", "Error", MessageBoxButtons.OK);
    }
}

private void btn_sqrt_Click(object sender, EventArgs e)
{
    double num;
    try
    {
        st.Push(txtDisplay.Text);

        num = Convert.ToDouble(st.Pop());
        st.Push(Math.Sqrt(num));
        txtDisplay.Text = Math.Sqrt(num).ToString();
        flag2 = true;
    }
    catch (Exception)
    {
        MessageBox.Show("请先输入一个数字!", "Error", MessageBoxButtons.OK);
    }
}

private void btn_ping_Click(object sender, EventArgs e)
{
    double num;
    try
    {
        st.Push(txtDisplay.Text);

        num = Convert.ToDouble(st.Pop());
        st.Push(Math.Pow(num, 2));
        txtDisplay.Text = Math.Pow(num, 2).ToString();
        flag2 = true;
    }
    catch (Exception)
    {
        MessageBox.Show("请先输入一个数字!", "Error", MessageBoxButtons.OK);
    }
}


private void btn_dai_Click(object sender, EventArgs e)
{
    var fm = new Mortgage();
    fm.ShowDialog();
            
}

private void btn_re_Click(object sender, EventArgs e)
{
    double num;
    try
    {
        st.Push(txtDisplay.Text);

        num = Convert.ToDouble(st.Pop());
        st.Push(1 / num);
        txtDisplay.Text = (1 / num).ToString();
        flag2 = true;
    }
    catch (Exception)
    {
        MessageBox.Show("请先输入一个数字!", "Error", MessageBoxButtons.OK);
    }
}

private void btn_backspace_Click(object sender, EventArgs e)
{
    try
    {
        txtDisplay.Text = txtDisplay.Text.Substring(0, txtDisplay.Text.Length - 1);
    }
    catch (Exception)
    {
                
    }
}
private void btn_clear_Click(object sender, EventArgs e)
{
    txtDisplay.Text = "";
    st.Clear();
    flag = true; flag2 = false;
}

tip:上面的flag2是来判断是否计算出结果,如果得出结果,那么可以利用这个flag2来判断下次按下数字按键的时候是否会清空txtDisplay内容,并加入按下的数字。

 

②贷款计算器

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Calculator
{
    public partial class Mortgage : Form
    {
        public Mortgage()
        {
            InitializeComponent();
        }

        private void Mortgage_Load(object sender, EventArgs e)
        {
        }

        private void Mortgage_FormClosed(object sender, FormClosedEventArgs e)
        {
        }

        private void 计算_Click(object sender, EventArgs e)
        {
            if(string.IsNullOrEmpty(贷款年限.Text)||string.IsNullOrEmpty(贷款金额.Text)|| string.IsNullOrEmpty(贷款利率.Text))
            {
                MessageBox.Show("请填写完整数据!", "Error", MessageBoxButtons.OK);
            }
            else
            {
                double yearM, money, rate;
                double moHuan, moLi, moZli;
                yearM = Convert.ToDouble(贷款年限.Text) * 12;
                money = Convert.ToDouble(贷款金额.Text) * 10000;
                rate = Convert.ToDouble(贷款利率.Text) / 1200;
                if (等额本息.Checked)
                {
                    moHuan = money * rate * Math.Pow(1 + rate, yearM) / (Math.Pow(1 + rate, yearM) - 1);
                    moLi = moHuan * yearM - money;
                    moZli = moHuan * yearM;
                    月均还款.Text = moHuan.ToString("0.00");
                    利息总额.Text = moLi.ToString("0.00");
                    还款总额.Text = moZli.ToString("0.00");
                }
                else
                {
                    moHuan = (money / yearM) + (money - money) * rate;
                    moLi = (money / yearM + money * rate + money / yearM * (1 + rate)) / 2 * yearM - money;
                    moZli = (money / yearM + money * rate + money / yearM * (1 + rate)) / 2 * yearM;
                    月均还款.Text = moHuan.ToString("0.00");
                    利息总额.Text = moLi.ToString("0.00");
                    还款总额.Text = moZli.ToString("0.00");
                }
            }
        }

        private void 重新计算_Click(object sender, EventArgs e)
        {
            贷款年限.Text = "";
            贷款金额.Text = "";
            贷款利率.Text = "";
            月均还款.Text = "";
            利息总额.Text = "";8
            还款总额.Text = "";
        }
    }
}

贷款计算器主要是公式的运用,比如计算结果是double型,最后要将计算结果显示在文本框中。

首先判断等额本息被选中,然后调用Math中的方法加以简化算式,使得代码更加简洁。

猜你喜欢

转载自blog.csdn.net/weixin_42094220/article/details/82719168