自己用C#做的第一个程序 —— 计算器

来源:互联网 发布:全球域名快讯 编辑:程序博客网 时间:2024/06/10 03:37

花了三天多时间,写了第一个完全自己写的程序。当然程序肯定有些小问题,小BUG,因为是初次写,所以希望能和大家交流交流。目前还在继续修改代码中。希望大家能提出意见。

主要代码:

 Window1.xaml 的交互逻辑

Code:
  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Linq;   
  4. using System.Text;   
  5. using System.Windows;   
  6. using System.Windows.Controls;   
  7. using System.Windows.Data;   
  8. using System.Windows.Documents;   
  9. using System.Windows.Input;   
  10. using System.Windows.Media;   
  11. using System.Windows.Media.Imaging;   
  12. using System.Windows.Navigation;   
  13. using System.Windows.Shapes;   
  14.   
  15. /************************************************/  
  16. /*******         本程序供学习交流         *******/  
  17. /*******         作者:  张骏南            *******/  
  18. /*******         最后修改时间             *******/  
  19. /*******       2011年3月10日21:03:17      *******/  
  20. /************************************************/  
  21.   
  22. namespace 计算器   
  23. {   
  24.     /// <summary>   
  25.     /// Window1.xaml 的交互逻辑   
  26.     /// </summary>   
  27.     public partial class Window1 : Window   
  28.     {   
  29.         private decimal m_dInput = 0;   
  30.         private int m_iPlaces = 0;          //数的小数位   
  31.         private bool m_bIsFloat = false;    //标记是否为小数   
  32.         private bool m_bNewInt = false;     //标记是否需要新的整数数   
  33.         private bool m_bNewFloat = false;   //标记是否需要新的浮点数   
  34.         private Counter m_ctrCounter = new Counter();   
  35.         private AboutBox1 m_abtAboutBox;   
  36.   
  37.         public Window1()   
  38.         {   
  39.             InitializeComponent();   
  40.             updateInput();   
  41.         }   
  42.   
  43.         //输入更新结果显示框   
  44.         private void updateInput()   
  45.         {   
  46.             //去除末尾多于的0   
  47.             if (m_bIsFloat)   
  48.                 while (m_dInput.ToString().LastIndexOf('0') == m_dInput.ToString().Length - 1 && m_dInput != 0)   
  49.                     m_dInput = Convert.ToDecimal(m_dInput.ToString().Substring(0, m_dInput.ToString().Length - 1));   
  50.   
  51.             //在结果加上适当的小数点   
  52.             if (m_dInput.ToString().Contains("."))   
  53.                 result.Text = m_dInput.ToString();   
  54.             else  
  55.                 result.Text = m_dInput.ToString() + ".";   
  56.         }  
  57.  
  58.         #region 数字单击事件   
  59.   
  60.         private void number_Click(object sender, RoutedEventArgs e)   
  61.         {   
  62.             newNumber();   
  63.             //确定是哪个数字被点击   
  64.             int inputNumber = Convert.ToInt32(sender.ToString().Substring(32, 1));   
  65.             try  
  66.             {   
  67.                 if (m_dInput >= 0)   
  68.                 {   
  69.                     if (m_bIsFloat)   
  70.                         m_dInput += (decimal)Math.Pow(10, -++m_iPlaces) * inputNumber;    //求 inputNumber 乘 10 的 -N 次方   
  71.                     else  
  72.                         m_dInput = m_dInput * 10 + inputNumber;   
  73.                 }   
  74.                 else  
  75.                 {   
  76.                     if (m_bIsFloat)   
  77.                         m_dInput -= (decimal)Math.Pow(10, -++m_iPlaces) * inputNumber;    //求 inputNumber 乘 10 的 -N 次方   
  78.                     else  
  79.                         m_dInput = m_dInput * 10 - inputNumber;   
  80.                 }   
  81.             }   
  82.             catch (OverflowException)   
  83.             {   
  84.                 MessageBox.Show("输入的数超过范围,请重新输入""错误");   
  85.                 buttonCE_Click(sender, e);   
  86.             }   
  87.             updateInput();   
  88.         }   
  89.   
  90.         //数字0的处理与其他不同   
  91.         private void number0_Click(object sender, RoutedEventArgs e)   
  92.         {   
  93.             if (m_bNewInt)   
  94.             {   
  95.                 m_dInput = 0;   
  96.                 m_iPlaces = 0;   
  97.                 if (m_bNewFloat)   
  98.                 {   
  99.                     m_bIsFloat = true;   
  100.                     m_bNewFloat = false;   
  101.                     result.Text = "0.";   
  102.                 }   
  103.                 else  
  104.                     m_bIsFloat = false;   
  105.                 m_bNewInt = false;   
  106.             }   
  107.             try  
  108.             {   
  109.                 if (m_bIsFloat)   
  110.                 {   
  111.                     ++m_iPlaces;   
  112.                     result.Text += "0";   
  113.                 }   
  114.                 else  
  115.                 {   
  116.                     m_dInput *= 10;   
  117.                     updateInput();   
  118.                 }   
  119.             }   
  120.             catch (OverflowException)   
  121.             {   
  122.                 MessageBox.Show("输入的数超过范围,请重新输入""错误");   
  123.                 buttonCE_Click(sender, e);   
  124.             }   
  125.         }  
  126.  
  127.         #endregion   
  128.   
  129.         //即将输入新的数   
  130.         private void newNumber()   
  131.         {   
  132.             if (m_bNewInt)   
  133.             {   
  134.                 m_dInput = 0;   
  135.                 m_iPlaces = 0;   
  136.                 if (m_bNewFloat)   
  137.                     m_bNewFloat = false;   
  138.                 else  
  139.                     m_bIsFloat = false;   
  140.                 m_bNewInt = false;   
  141.             }   
  142.         }  
  143.  
  144.         #region 操作按钮的单击事件   
  145.   
  146.         //清空按钮被单击,清空当前输入数据   
  147.         private void buttonCE_Click(object sender, RoutedEventArgs e)   
  148.         {   
  149.             m_bIsFloat = false;   
  150.             m_bNewFloat = false;   
  151.             m_bNewInt = false;   
  152.             m_dInput = 0;   
  153.             m_iPlaces = 0;   
  154.             updateInput();   
  155.         }   
  156.   
  157.         //退位操作   
  158.         private void buttonBackspace_Click(object sender, RoutedEventArgs e)   
  159.         {   
  160.             //不需要新的数   
  161.             m_bNewInt = false;   
  162.   
  163.             //判断是否为小数并退一位   
  164.             if (m_bIsFloat)   
  165.                 --m_iPlaces;   
  166.   
  167.             if (m_dInput.ToString().Length == 1)   
  168.             {   
  169.                 if (m_bIsFloat)   
  170.                 {   
  171.                     if (m_iPlaces == -1)   
  172.                     {   
  173.                         m_bIsFloat = false;   
  174.                         m_iPlaces = 0;   
  175.                     }   
  176.                     else  
  177.                     {   
  178.                         result.Text = result.Text.Substring(0, result.Text.Length - 1);   
  179.                         m_dInput = Convert.ToDecimal(result.Text);   
  180.                         return;     //结束方法   
  181.                     }   
  182.                 }   
  183.                 else  
  184.                     m_dInput = 0;   
  185.             }   
  186.             else  
  187.             {   
  188.                 if (m_bIsFloat)   
  189.                 {   
  190.                     if (m_iPlaces == -1)   
  191.                     {   
  192.                         m_bIsFloat = false;   
  193.                         m_iPlaces = 0;   
  194.                     }   
  195.                     else  
  196.                     {   
  197.                         result.Text = result.Text.Substring(0, result.Text.Length - 1);   
  198.                         m_dInput = Convert.ToDecimal(result.Text);   
  199.                         return;   
  200.                     }   
  201.                 }   
  202.                 else  
  203.                     m_dInput = Convert.ToDecimal(m_dInput.ToString().Substring(0, m_dInput.ToString().Length - 1));   
  204.             }   
  205.             updateInput();   
  206.         }   
  207.   
  208.         //负号按钮被单击事件   
  209.         private void minus_Click(object sender, RoutedEventArgs e)   
  210.         {   
  211.             m_dInput = -m_dInput;   
  212.             updateInput();   
  213.         }   
  214.   
  215.         //小数点按钮被单击事件   
  216.         private void dot_Click(object sender, RoutedEventArgs e)   
  217.         {   
  218.             if (m_bNewInt)   
  219.                 m_bNewFloat = true;   
  220.             m_bIsFloat = true;   
  221.         }   
  222.   
  223.         //重启按钮被单击事件,计算器重启   
  224.         private void buttonC_Click(object sender, RoutedEventArgs e)   
  225.         {   
  226.             m_ctrCounter.Clear();   
  227.             buttonCE_Click(sender, e);   
  228.         }   
  229.   
  230.         //开方按钮被单击事件   
  231.         private void operatorSqrt_Click(object sender, RoutedEventArgs e)   
  232.         {   
  233.             m_dInput = (decimal)Math.Sqrt((double)m_dInput);   
  234.             updateInput();   
  235.             m_bNewInt = true;   
  236.         }   
  237.   
  238.         //除法按钮被单击事件   
  239.         private void operatorDivide_Click(object sender, RoutedEventArgs e)   
  240.         {   
  241.             m_dInput = m_ctrCounter.Calculate(m_dInput, Counter.Operators.Divide);   
  242.             updateInput();   
  243.             m_bNewInt = true;       
  244.         }   
  245.   
  246.         //乘法按钮被单击事件   
  247.         private void operatorMultiply_Click(object sender, RoutedEventArgs e)   
  248.         {   
  249.             m_dInput = m_ctrCounter.Calculate(m_dInput, Counter.Operators.Multiply);   
  250.             updateInput();   
  251.             m_bNewInt = true;       
  252.         }   
  253.   
  254.         //减法按钮被单击事件   
  255.         private void operatorSubtract_Click(object sender, RoutedEventArgs e)   
  256.         {   
  257.             m_dInput = m_ctrCounter.Calculate(m_dInput, Counter.Operators.Subtract);   
  258.             updateInput();   
  259.             m_bNewInt = true;       
  260.         }   
  261.   
  262.         //加法按钮被单击事件   
  263.         private void operatorAdd_Click(object sender, RoutedEventArgs e)   
  264.         {   
  265.             m_dInput = m_ctrCounter.Calculate(m_dInput, Counter.Operators.Add);   
  266.             updateInput();   
  267.             m_bNewInt = true;       
  268.         }   
  269.   
  270.         //倒数按钮被单击事件   
  271.         private void operatorReciprocal_Click(object sender, RoutedEventArgs e)   
  272.         {   
  273.             if (m_dInput == 0)   
  274.             {   
  275.                 MessageBox.Show("操作有误","错误");   
  276.                 buttonC_Click(sender, e);   
  277.                 return;   
  278.             }   
  279.             //是否为小数   
  280.             if (m_dInput.ToString().Contains('.'))   
  281.             {   
  282.                 m_dInput = 1 / m_dInput;   
  283.                 Counter.ChangeToInteger(ref m_dInput);   
  284.             }   
  285.             else  
  286.                 m_dInput = 1 / m_dInput;   
  287.             updateInput();   
  288.             m_bNewInt = true;       
  289.         }   
  290.   
  291.         //等号按钮被单击事件   
  292.         private void operatorAssign_Click(object sender, RoutedEventArgs e)   
  293.         {   
  294.             m_dInput = m_ctrCounter.Calculate(m_dInput, Counter.Operators.Assign);   
  295.             updateInput();   
  296.             m_bNewInt = true;    //需要新的数   
  297.         }  
  298.  
  299.         #endregion   
  300.   
  301.         //打开关于对话框   
  302.         private void openAboutBox(object sender, RoutedEventArgs e)   
  303.         {   
  304.             m_abtAboutBox = new AboutBox1();   
  305.             m_abtAboutBox.ShowDialog();   
  306.         }   
  307.     }   
  308. }   

 

计算器类

Code:
  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Linq;   
  4. using System.Text;   
  5. using System.Windows;   
  6.   
  7. /************************************************/  
  8. /*******         本程序供学习交流         *******/  
  9. /*******         作者:  张骏南            *******/  
  10. /*******         最后修改时间             *******/  
  11. /*******       2011年3月10日21:03:17      *******/  
  12. /************************************************/  
  13.   
  14. namespace 计算器   
  15. {   
  16.     public class Counter   
  17.     {   
  18.         private decimal m_dCacheOfAdd = 0;          //缓存,存储被加数   
  19.         private decimal m_dCacheOfMultiply = 0;     //缓存,存储被乘数   
  20.         private decimal m_dResult = 0;              //显示结果   
  21.         private int m_iAddNumber = 0;               //加法次数   
  22.         private int m_iSubtractNumber = 0;          //减法次数   
  23.         private int m_iMultiplyNumber = 0;          //乘法次数   
  24.         private int m_iDivideNumber = 0;            //除法次数   
  25.   
  26.         //操作符,分别是:加、减、乘、除、赋值   
  27.         public enum Operators : byte { Add, Subtract, Multiply, Divide, Assign };   
  28.   
  29.         //将精度很高的小数修改为其对应相等的整数   
  30.         public static void ChangeToInteger(ref decimal value)   
  31.         {   
  32.             decimal floor = decimal.Floor(value);   
  33.             decimal ceiling = decimal.Ceiling(value);   
  34.             //差值小于10e-6则视为相等   
  35.             if (value - floor <= (decimal)10e-6)   
  36.                 value = floor;   
  37.             if (ceiling - value <= (decimal)10e-6)   
  38.                 value = ceiling;   
  39.         }  
  40.  
  41.         #region 基本算法   
  42.   
  43.         //加法运算   
  44.         private decimal operatorAdd(decimal input)   
  45.         {   
  46.             m_dCacheOfAdd += input;   
  47.             return m_dCacheOfAdd;   
  48.         }   
  49.   
  50.         //乘法运算   
  51.         private decimal operatorMultiply(decimal input)   
  52.         {   
  53.             m_dCacheOfMultiply *= input;   
  54.             ChangeToInteger(ref m_dCacheOfMultiply);   
  55.             return m_dCacheOfMultiply;   
  56.         }  
  57.  
  58.         #endregion  
  59.  
  60.         #region 传入五种新运算符调用的方法   
  61.   
  62.         //新运算符为加法,在此方法中判断并调用之前操作符的对应运算,并在此方法中更新结果   
  63.         private void add(decimal input)   
  64.         {   
  65.             //存储中间计算值   
  66.             decimal result = 0;    
  67.             //判断之前是否有乘号   
  68.             if (m_iMultiplyNumber > 0)   
  69.             {   
  70.                 result += operatorMultiply(input);   
  71.                 input = 0;      // input 被使用后,不能再被使用,这里很重要!   
  72.                 --m_iMultiplyNumber;   
  73.             }   
  74.             //判断之前是否有除号   
  75.             if (m_iDivideNumber > 0)   
  76.             {   
  77.                 result += operatorMultiply(1 / input);   
  78.                 input = 0;   
  79.                 --m_iDivideNumber;   
  80.             }   
  81.             //判断之前是否有加号   
  82.             if (++m_iAddNumber == 2)   
  83.             {   
  84.                 result += operatorAdd(input);   
  85.                 --m_iAddNumber;   
  86.             }   
  87.             else    
  88.             {   
  89.                 //判断之前是否有减号   
  90.                 if (m_iSubtractNumber > 0)   
  91.                 {   
  92.                     result = operatorAdd(-input - result);   
  93.                     --m_iSubtractNumber;   
  94.                 }   
  95.                 else  
  96.                     result = operatorAdd(input + result);   
  97.             }   
  98.             m_dResult = result;   
  99.         }   
  100.   
  101.         //新运算符为减法,在此方法中判断并调用之前操作符的对应运算,并在此方法中更新结果   
  102.         private void subtract(decimal input)   
  103.         {   
  104.             //存储中间计算值   
  105.             decimal result = 0;   
  106.             //判断之前是否有乘号   
  107.             if (m_iMultiplyNumber > 0)   
  108.             {   
  109.                 result += operatorMultiply(input);   
  110.                 input = 0;      // input 被使用后,不能再被使用,这里很重要!   
  111.                 --m_iMultiplyNumber;   
  112.             }   
  113.             //判断之前是否有除号   
  114.             if (m_iDivideNumber > 0)   
  115.             {   
  116.                 result += operatorMultiply(1 / input);   
  117.                 input = 0;   
  118.                 --m_iDivideNumber;   
  119.             }   
  120.             //判断之前是否有减号   
  121.             if (++m_iSubtractNumber == 2)   
  122.             {   
  123.                 result = operatorAdd(-input - result);   
  124.                 --m_iSubtractNumber;   
  125.             }   
  126.             else  
  127.             {   
  128.                 //判断之前是否有加号   
  129.                 if (m_iAddNumber > 0)   
  130.                 {   
  131.                     result += operatorAdd(input);   
  132.                     --m_iAddNumber;   
  133.                 }   
  134.                 else  
  135.                 {   
  136.                     result = operatorAdd(input + result);   
  137.                 }   
  138.             }   
  139.             m_dResult = result;   
  140.         }   
  141.   
  142.         //新运算符为乘法,在此方法中判断并调用之前操作符的对应运算,并在此方法中更新结果   
  143.         private decimal multiply(decimal input)   
  144.         {   
  145.             //判断之前是否有乘号   
  146.             if (++m_iMultiplyNumber == 2)   
  147.             {   
  148.                 operatorMultiply(input);   
  149.                 --m_iMultiplyNumber;   
  150.             }   
  151.             else  
  152.             {   
  153.                 //判断之前是否有除号   
  154.                 if (m_iDivideNumber > 0)   
  155.                 {   
  156.                     operatorMultiply(1 / input);   
  157.                     --m_iDivideNumber;   
  158.                 }   
  159.                 else  
  160.                     m_dCacheOfMultiply = input;   
  161.             }   
  162.             m_dResult = m_dCacheOfMultiply;   
  163.             return m_dCacheOfMultiply;   
  164.         }   
  165.   
  166.         //新运算符为除法,在此方法中判断并调用之前操作符的对应运算,并在此方法中更新结果   
  167.         private decimal divide(decimal input)   
  168.         {   
  169.             //判断之前是否有除号   
  170.             if (++m_iDivideNumber == 2)   
  171.             {   
  172.                 operatorMultiply(1 / input);   
  173.                 --m_iDivideNumber;   
  174.             }   
  175.             else  
  176.             {   
  177.                 //判断之前是否有乘号   
  178.                 if (m_iMultiplyNumber >0)   
  179.                 {   
  180.                     operatorMultiply(input);   
  181.                     --m_iMultiplyNumber;   
  182.                 }   
  183.                 else  
  184.                     m_dCacheOfMultiply = input;   
  185.             }   
  186.             m_dResult = m_dCacheOfMultiply;   
  187.             return m_dCacheOfMultiply;   
  188.         }   
  189.   
  190.         //等号运算   
  191.         private void assign(decimal input)   
  192.         {   
  193.             //存储中间计算值   
  194.             decimal result = 0;   
  195.             //标记是否只有等号   
  196.             bool flag = false;   
  197.             //判断之前是否有乘号   
  198.             if (m_iMultiplyNumber > 0)   
  199.             {   
  200.                 result += operatorMultiply(input);   
  201.                 input = 0;      // input 被使用后,不能再被使用,这里很重要!   
  202.                 --m_iMultiplyNumber;   
  203.                 flag = true;   
  204.             }   
  205.             //判断之前是否有除号   
  206.             if (m_iDivideNumber > 0)   
  207.             {   
  208.                 result += operatorMultiply(1 / input);   
  209.                 input = 0;   
  210.                 --m_iDivideNumber;   
  211.                 flag = true;   
  212.             }   
  213.             //判断之前是否有减号   
  214.             if (m_iSubtractNumber > 0)   
  215.             {   
  216.                 result = operatorAdd(-input - result);   
  217.                 --m_iSubtractNumber;   
  218.                 flag = true;   
  219.             }   
  220.             //判断之前是否有加号   
  221.             if (m_iAddNumber > 0)   
  222.             {   
  223.                 result += operatorAdd(input);   
  224.                 --m_iAddNumber;   
  225.                 flag = true;   
  226.             }   
  227.             if (flag)   
  228.                 m_dResult = result;   
  229.             else  
  230.                 m_dResult = input;   
  231.   
  232.             //清空缓存   
  233.             m_dCacheOfAdd = 0;   
  234.             m_dCacheOfMultiply = 0;   
  235.         }  
  236.  
  237.         #endregion   
  238.   
  239.         //供外部调用,并返回计算值   
  240.         public decimal Calculate(decimal input, Operators oper)   
  241.         {   
  242.             try  
  243.             {   
  244.                 //根据运算符执行相应方法   
  245.                 switch (oper)   
  246.                 {   
  247.                     case Operators.Add: add(input); break;   
  248.                     case Operators.Subtract: subtract(input); break;   
  249.                     case Operators.Multiply: multiply(input); break;   
  250.                     case Operators.Divide: divide(input); break;   
  251.                     case Operators.Assign: assign(input); break;   
  252.                 }   
  253.             }   
  254.             catch (DivideByZeroException)   
  255.             {   
  256.                 MessageBox.Show("操作有误""错误");   
  257.                 Clear();   
  258.             }   
  259.   
  260.             return m_dResult;   
  261.         }   
  262.   
  263.         //重启计算器   
  264.         public void Clear()   
  265.         {   
  266.             m_dCacheOfAdd = 0;   
  267.             m_dCacheOfMultiply = 0;   
  268.             m_dResult = 0;   
  269.             m_iAddNumber = 0;   
  270.             m_iSubtractNumber = 0;   
  271.             m_iMultiplyNumber = 0;   
  272.             m_iDivideNumber = 0;   
  273.         }   
  274.     }   
  275. }   

 

主程序界面:

 

关于对话框:

 

源代码:http://download.csdn.net/source/3082157