注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Hao的博客

I'm on my way……

 
 
 

日志

 
 
 
 

C#计算器实现  

2009-06-08 15:20:07|  分类: 小试牛刀 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

计算器的实现是以之前所画的流程图作为依据,在实际的编写过程中根据需要加以修改。对于类似的处理方法只编写一个函数,在实际的消息处理过程中,通过传递不同的参数来实现。


定义的全局变量

string preClick="";                                                       //存储前一个单击的数字键或是操作符
bool storeFlag = false;                                                 //存储标志,为true表示有存储的数据
string storeData="0";                                                  //保存的数据
Stack<string> dataStack=new Stack<string>();            //数据栈
Stack<char> operStack=new Stack<char>();                //操作符栈


处理单击数字键后的操作

        private void pressDigitButton(char digit){
            if (preClick == "" || preClick == "="){                        //是新的运算或是已经完成了之前运算
                dataStack.Clear();
                operStack.Clear();
                dataStack.Push(digit.ToString());
                lblResult.Text = digit.ToString();
            }
            //如果之前单击的也是数字则把当前单击的数字加到后面
            else if(preClick[0]>='0'&&preClick[0]<='9'){
                string temp = dataStack.Pop();
                if (temp.Length > 19) {                                          //最多输入19位
                    dataStack.Push(temp);
                    return;
                }
                temp+=digit;
                if (temp.Length == 2 && temp[0] == '0') temp = temp.Substring(1); //去除前导零
                dataStack.Push(temp);
                lblResult.Text = temp.ToString();
            }
            else if (preClick == "+" || preClick == "-" || preClick == "*" || preClick == "/")
            {
                dataStack.Push(digit.ToString());
                lblResult.Text = digit.ToString();
            }
            preClick = digit.ToString();
        }


处理单击小数点后的操作

        private void pressDotButton()
        {
            if (preClick == "" || preClick == "=")         //如果之前没单击过数字键,则整数部分默认为0
            {                                                      
                dataStack.Clear();
                operStack.Clear();
                dataStack.Push("0.");
                lblResult.Text = "0.";
                preClick = "0";
            }
            else if (preClick == "+" || preClick == "-" || preClick == "*" || preClick == "/")
            {
                dataStack.Push("0.");
                preClick = "0";
            }
            else if (preClick[0] >= '0' && preClick[0] <= '9')
            {
                string temp = dataStack.Pop();
                if (!temp.Contains("."))                     //操作数中不含小数点时此次单击才有效
                {
                    temp += '.';
                    dataStack.Push(temp);
                    lblResult.Text = temp;
                }
                else dataStack.Push(temp);
            }
        }


处理单击操作符后的操作,包括等号

        private void pressOperateButton(char oper) {
            if (dataStack.Count == 0) dataStack.Push("0"); //如果没输入第一操作数,默认为0 
            else if (preClick=="="||(preClick[0]>= '0' && preClick[0] <= '9')) {
                if (dataStack.Count == 2)
                {                                               //如果已经有两个操作数,则完成运算
                    double data1 = Convert.ToDouble(dataStack.Pop());
                    double data2 = Convert.ToDouble(dataStack.Pop());
                    char opr = operStack.Pop();
                    double result;
                    switch (opr)
                    {
                        case '+':
                            result = data2 + data1;
                            break;
                        case '-':
                            result = data2 - data1;
                            break;
                        case '*':
                            result = data2 * data1;
                            break;
                        case '/':
                            result = data2 / data1;
                            break;
                        default:
                            result = 0;
                            break;
                    }
                    dataStack.Push(result.ToString());
                    lblResult.Text = result.ToString();
                }
            }
            else if (preClick == "+" || preClick == "-" || preClick == "*" || preClick == "/"){
                operStack.Pop();            //如果之前单击的是操作符,原操作符无效
            }
            if (oper == '='){                 //如果单击的是等号,则默认操作为+,默认第二操作数为0
                double temp = Convert.ToDouble(dataStack.Pop());
                dataStack.Push(temp.ToString());
                operStack.Clear();
                lblResult.Text = temp.ToString();
                preClick = "=";
                return;
            }
            operStack.Push(oper);
            preClick=oper.ToString();
        }


处理单击sqrt,%,1/x,+/-,BackSpace后的操作

        private void pressChgButton(string change) { 
            if (dataStack.Count > 0) {                     //只有数据栈有元素时这些操作才有效
                string str = dataStack.Pop();
                double temp = Convert.ToDouble(str);
                if (change == "sqrt") {                     //开根号
                    temp = Math.Sqrt(temp);
                    str = temp.ToString();
                    preClick = "=";
                }
                else if (change == "%") {
                    //这个功能没有加
                }
                else if (change == "1/x"){                //求倒数
                    temp = 1 / temp;
                    str = temp.ToString();
                    preClick = "=";
                }
                else if (change == "+/-"&&str!="0"){   //求相反数
                    if (str[0] == '-') str=str.Substring(1,str.Length-1);
                    else str=str.Insert(0,"-");
                }
                else if (change == "BackSpace" && (preClick[0] >= '0' && preClick[0] <= '9'))
                {    //去除上一个输入的数字,上一次输入的是数字才有效
                    if (str.Length == 2 && str[0] == '-') str = "0";  //当前的操作数是-x(x是一位数),直接清0
                    else if (str.Length > 1)
                    {
                        str = str.Remove(str.Length - 1);
                    }
                    else
                    {
                        str = "0";                                  //如果当前操作数只有一位,则直接清0
                    }
                }
                dataStack.Push(str);
                lblResult.Text = str;
            }
        }


处理单击清除类按键后的操作

        private void pressClearButton(string clearFlag) {
            if (clearFlag == "CE") {               //清除上一步输入的操作数
                if (dataStack.Count > 0)         //数据栈有元素才有效
                {
                    dataStack.Pop();
                    if (operStack.Count > 0)  //如果之前单击过操作符,应更新操作符
                    {
                        preClick = operStack.Peek().ToString();
                    }
                    else {                              //否则要回到一次新的操作的初始状态
                        preClick = "=";
                    }
                }
            }
            else if (clearFlag == "C") {                    //清楚所有操作,一次新的运算前的初始化
                dataStack.Clear();
                operStack.Clear();
                preClick = "";
            }
            lblResult.Text = "0";
        }


单击存储按键后的操作

        private void pressStoreButton(string store) {
            if (store == "MC")       //存储清0
            {
                storeFlag = false;
                storeData="0";
                lblMemory.Text = "";
            }
            else if (store == "MR")      //导出存储的数,如果没有输出0
            {
                lblResult.Text = storeData;
                if (preClick==""||preClick=="="||(preClick[0] >= '0' && preClick[0] <= '9'))
                {
                    if (dataStack.Count > 0) dataStack.Pop();
                    preClick = "=";
                }
                dataStack.Push(storeData);
                lblResult.Text = storeData;
                preClick = "=";
            }
            else if (store == "MS")      //存储当前的数
            {
                storeFlag = true;
                storeData = lblResult.Text;
                lblMemory.Text = "M";
            }
            else if (store == "M+")      //将存储的数加上当前的数,再存回去
            {
                if (storeFlag)
                {
                    double data1 = Convert.ToDouble(storeData);
                    double data2 = Convert.ToDouble(lblResult.Text);
                    double result = data1 + data2;
                    storeData = result.ToString();
                }
            }
        }


键盘单击事件的处理

        private void Calculator_KeyDown(object sender, KeyEventArgs e){
                switch (e.KeyValue) {
                    case (int)Keys.Add:
                    case 187:                //主键盘上的”加号/等号“键,可以通过输出KeyValue的值得到
                        if (!e.Shift && e.KeyValue == 187) pressOperateButton('=');
                        else pressOperateButton('+');
                        break;
                    case (int)Keys.Subtract:
                    case 189:
                        pressOperateButton('-');
                        break;
                    case (int)Keys.Multiply: //键盘上的乘号是同时击shift键和主键上的8才有效,放在下面处理
                        pressOperateButton('*');
                        break;
                    case (int)Keys.Divide:
                    case 191:
                        pressOperateButton('/');
                        break;
                    case (int)Keys.Decimal:
                    case 190:
                        pressDotButton();
                        break;
                    case (int)Keys.Back:
                        pressChgButton("BackSpace");
                        break;
                    default:
                        if ((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
                            || (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)){
                            if (e.Shift && e.KeyCode == Keys.D8) pressOperateButton('*');
                            else   
//通过取KeyCode的最后一位来得到输入的数字
                                pressDigitButton(e.KeyCode.ToString()[e.KeyCode.ToString().Length - 1]);
                        }
                        break;
                }
        }


其他的键盘单击事件只要调用相应的函数即可,计算器的工作到现在为止基本告一段落,这里没有用什么特别巧妙的方法去解决,但是却也算实践了一番,也乐在其中了。里面肯定还存在一些bug,就先让它们多待会吧~

  评论这张
 
阅读(1665)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017