基于C#的计算器(1) 带括号


       学过编程的人都知道,编写一个计算器不简单,传统方案是对表达式进行词法分析,语法分析等来达到计算的目的,而今天我要讲的不是传统方法,而是另一种方法。

       这个计算器的编写我会分成3片文章来讲,本文先来个普通的计算器,仅仅是带括号的表达式计算器,第二篇文章将介绍用同样的方法编写带科学运算的计算器,而第三篇则是扩展可编程计算器。

       本人也是刚刚入门的菜鸟,本教程若有错之处,欢迎指正。

        废话不多说了,本方案不需要词法分析和语法分析等,只是简单的将的表达式转换为JavaScrpit的代码,对,你没有看错,相信说到这里大家都已经猜出 来了,这个方案采用C#调用js引擎的eval函数,学过js的程序猿都深谙eval函数的威力了吧,我们就是要利用eval函数将字符串形式的表达式转 换为js代码并计算出结果。

       项目目录如下:

 基于C#的计算器(1) 带括号_第1张图片

界面布局和控件:

       基于C#的计算器(1) 带括号_第2张图片

 

    控件清单:

基于C#的计算器(1) 带括号_第3张图片

       此外需要注意的一点就是,项目中需要用到js引擎,所以要在引用中加入:Microsoft.JScript库。具体如下:

      <1>在项目目录中右键单击【引用】,选择添加引用

      <2>在弹出框中选择程序集中的框架:Microsoft.JScript

基于C#的计算器(1) 带括号_第4张图片

下面开始上代码:清单Form1.cs

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 WindowsFormsApplication1
{
 
   public partial class 计算器 : Form
   {
       public 计算器()
       {
           InitializeComponent();
       }

       int tab = 0;
       //记录指针
       int Precord = 0;
       //记录数
       int RecordNum = 0;
       public String text="";
       //存储记录
       public String[] record=new String[10];
       //存储表达式
       public String[] texts=new String[10000];
       //加载js引擎
       Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
           

       //处理表达式
       public void addComments(String s)
       {
           this.text += s;
           this.texts[tab] = s;
         
           this.richTextBox1.Text = this.text;
           tab++;
       }

       //0按钮的触发事件
       private void button10_Click(object sender, EventArgs e)
       {
           this.addComments("0");
       }
       //小数点.按钮的触发事件
       private void button12_Click(object sender, EventArgs e)
       {
           this.addComments(".");
       }

       //1按钮的触发事件
       private void button1_Click(object sender, EventArgs e)
       {
           this.addComments("1");
       }

       //2按钮的触发事件
       private void button2_Click(object sender, EventArgs e)
       {
           this.addComments("2");
       }

       //3按钮的触发事件
       private void button3_Click(object sender, EventArgs e)
       {
           this.addComments("3"); ;
       }

       //4按钮的触发事件
       private void button4_Click(object sender, EventArgs e)
       {
           this.addComments("4");
       }

       //5按钮的触发事件
       private void button5_Click(object sender, EventArgs e)
       {
           this.addComments("5");
       }

       //6按钮的触发事件
       private void button6_Click(object sender, EventArgs e)
       {
           this.addComments("6");
       }

       //7按钮的触发事件
       private void button7_Click(object sender, EventArgs e)
       {
           this.addComments("7");
       }

       //8按钮的触发事件
       private void button8_Click(object sender, EventArgs e)
       {
           this.addComments("8");
       }

       //9按钮的触发事件
       private void button9_Click(object sender, EventArgs e)
       {
           this.addComments("9");
       }

       //(按钮的触发事件
       private void button18_Click(object sender, EventArgs e)
       {
           this.addComments("(");
       }

       //)按钮的触发事件
       private void button17_Click(object sender, EventArgs e)
       {
           this.addComments(")");
       }

       //+按钮的触发事件
       private void button13_Click(object sender, EventArgs e)
       {
           this.addComments("+");
       }

       //-按钮的触发事件
       private void button14_Click(object sender, EventArgs e)
       {
           this.addComments("-");
       }

       //*按钮的触发事件
       private void button15_Click(object sender, EventArgs e)
       {
           this.addComments("*");
       }

       //按钮/的触发事件
       private void button16_Click(object sender, EventArgs e)
       {
           this.addComments("/");
       }

       /// <summary>
       /// =按钮的触发事件,最终计算结果并显示
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private void button11_Click(object sender, EventArgs e)
       {
           try
           {
               //就是结果
               String result = Microsoft.JScript.Eval.JScriptEvaluate(this.text, ve).ToString();
               this.richTextBox1.Text = result;
               this.record[RecordNum] = this.text;
               this.text =result;
             
               this.RecordNum++;
 
               this.Precord = this.RecordNum;

           }  
           catch(Exception){
               this.richTextBox1.Text = "输入错误!";
               this.text = "";
               tab = 0;
           }
         
       }

       //清屏按钮的触发事件
       private void button20_Click(object sender, EventArgs e)
       {
           this.text = "";
           this.richTextBox1.Text = this.text;
       }

       //退格按钮的触发事件
       private void button19_Click(object sender, EventArgs e)
       {
          if(tab>0){
               tab -= 1;
          }
           this.text = "";
           for (int i = 0; i < tab;i++ )
           {
               this.text += this.texts[i];
           }

           this.richTextBox1.Text = this.text;
       }

       //<-按钮的触发事件
       private void button21_Click(object sender, EventArgs e)
       {
           Precord--;
           if ( Precord< 0)
           {
               Precord = RecordNum;
           }
          // this.text = this.record[Precord];
           this.richTextBox1.Text=this.record[Precord];
       }

       //->按钮的触发事件
       private void button22_Click(object sender, EventArgs e)
       {
           Precord++;
           if(Precord>RecordNum){
               Precord = 0;
           }
          // this.text = this.record[Precord];

           this.richTextBox1.Text = this.record[Precord];

       }


   }
}

      调试:

基于C#的计算器(1) 带括号_第5张图片

基于C#的计算器(1) 带括号_第6张图片

         以上便是核心代码,此方案避免了传统的此法分析,语法分析等繁琐的操作,减少了程序员的开发周期,和开发压力。这个方案的巧妙之处在于通过简单的表达式组合,再调用js引擎的eval函数,由此便可得出结果。

         其实这个项目并非我本意,是友人在面试面试过程中的一道面试题,面试官考验我的朋友,让他5天内完成这个项目便录取他。友人求助我,刚开始我也是绞尽脑汁 也想不到更好的方案,正当放弃之时,脑门一道灵光,让我想起了以前用过的js的eval函数,深谙其威力,故接下来的问题便是度娘C#怎么调用js引擎 啦。皇天不负有心人,不到半个小时,便将此项目做完。

        由于项目完成的仓促,本人亦是菜鸟中的菜鸟,必定还有许多bug,需要读者自行修改,大神手下留情,下篇文章将介绍怎么将此项目扩展成具备科学运算的科学计算器。欢迎有兴趣的同学一起讨论:[email protected]


你可能感兴趣的:(JavaScript,js,计算器)