学过编程的人都知道,编写一个计算器不简单,传统方案是对表达式进行词法分析,语法分析等来达到计算的目的,而今天我要讲的不是传统方法,而是另一种方法。
这个计算器的编写我会分成3片文章来讲,本文先来个普通的计算器,仅仅是带括号的表达式计算器,第二篇文章将介绍用同样的方法编写带科学运算的计算器,而第三篇则是扩展可编程计算器。
本人也是刚刚入门的菜鸟,本教程若有错之处,欢迎指正。
废话不多说了,本方案不需要词法分析和语法分析等,只是简单的将的表达式转换为JavaScrpit的代码,对,你没有看错,相信说到这里大家都已经猜出 来了,这个方案采用C#调用js引擎的eval函数,学过js的程序猿都深谙eval函数的威力了吧,我们就是要利用eval函数将字符串形式的表达式转 换为js代码并计算出结果。
项目目录如下:
界面布局和控件:
控件清单:
此外需要注意的一点就是,项目中需要用到js引擎,所以要在引用中加入:Microsoft.JScript库。具体如下:
<1>在项目目录中右键单击【引用】,选择添加引用
<2>在弹出框中选择程序集中的框架:Microsoft.JScript
下面开始上代码:清单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];
}
}
}
调试:
以上便是核心代码,此方案避免了传统的此法分析,语法分析等繁琐的操作,减少了程序员的开发周期,和开发压力。这个方案的巧妙之处在于通过简单的表达式组合,再调用js引擎的eval函数,由此便可得出结果。
其实这个项目并非我本意,是友人在面试面试过程中的一道面试题,面试官考验我的朋友,让他5天内完成这个项目便录取他。友人求助我,刚开始我也是绞尽脑汁 也想不到更好的方案,正当放弃之时,脑门一道灵光,让我想起了以前用过的js的eval函数,深谙其威力,故接下来的问题便是度娘C#怎么调用js引擎 啦。皇天不负有心人,不到半个小时,便将此项目做完。
由于项目完成的仓促,本人亦是菜鸟中的菜鸟,必定还有许多bug,需要读者自行修改,大神手下留情,下篇文章将介绍怎么将此项目扩展成具备科学运算的科学计算器。欢迎有兴趣的同学一起讨论:tqxhxb@live.cn
本文出自 “ssh整合cxf” 博客,请务必保留此出处http://6756585.blog.51cto.com/6746585/1741426
原文:http://6756585.blog.51cto.com/6746585/1741426