1. 说明:

先看看我们的成果:

 
   网上的表达式计算器有很多,但这次我们来点,不同的,有两点:
   1)用户可以编程以扩充计算器的函数
     即右下角那个“添加函数按钮”
     比如,我们想增加一个"Factarial"阶乘函数,我们可以“添加函数”

 
然后编辑我们的函数

 
  最后“生成”即可,主窗口上会自动添加一个"Factarial"按钮,然后就可以使用了(该函数将一直存在,除非你手动删除它)
  其实,主窗口上的所有函数按钮都是这样生成的

2)我们对表达式的计算将摆脱传统的观点(即传统的对表达式进行词法分析,语法分析等等),在编写我们的计算器的代码中,不会有任何的词法分析、语法分析、后缀表达式转换等
   等。
     启发来自于这里:
     假设有一个函数F
     double F()
     {
         double r = 3*4.5+sin(50);
         return r;
     }

那么,我们就可以 Console.WriteLine("{0}",F());     
     我们计算了3*4.5+sin(50),但我们有进行麻烦的词法分析与语法分析吗?没有,谁帮我们做了,编译器,ok,关键就在这:如果计算器用户在计算器主窗口上输入表达式
     3*4.5+sin(50),我们负责把它传给F中的r,然后我们再把F的返回值输出到用户界面上就OK了,我们要做的就这些。

2 计算器上的函数
  2.1 函数按钮对应的函数在哪里?
      在Functions.dll中,不要指望这我微软给我们的,因为函数是用户编写的,我们也不知道用户会编写什么样的函数,他甚至可以编写一个播放音乐的函数(呵呵,我们的计算器
完全可以做到这点,不过似乎对于一个计算器来说这有些过分了)
  2.2 谁来负责Functions.dll的生成?
      不是.net2003,不是.net2005,是我们的计算器
      要在用户自定义函数的时候将函数打包到Functions.dll中,就涉及到一个编译问题,我们将负责这一工作
  2.3 谁给了我们编译的权利?
      System.CodeDom.Compiler和Microsoft.CSharp名字空间中有我们的答案(请参见Msdn)

我们的Functions.dll打包成功以后,我们就可以在计算表达式是调用其中的函数了

3 表达式的计算
   3.1 如何计算?
       在前面计算 3*4.5+sin(50)的例子中,已经说过,我们将利用编译器帮我们计算,我们仅仅像Console.WriteLine("{0}",F())一样简单地将函数F的返回值输出给用户(F的返回值就是表达式的值):
     double F()
     {
         double exp = 3*4.5+sin(50);//假设3*4.5+sin(50)就是用户输入的表达式
         return exp;
     }
   3.2 F()从哪里来?到哪里去?
   F()肯定不是我们事先写好的,因为其中的exp的初始表达式是用户来写的
   我们将这样来解决这一问题:在用户输入表达式以后动态地生成函数F()的代码 -> 将该代码编译 -> 调用编译成功后的程序集中的该函数
        /// <summary>
        /// 将数学表达式转化为C#程序
        /// </summary>
        /// <param name="express">用户输入的数学表达式</param>
        /// <returns>返回C#程序代码</returns>
        public static string TranslateToCSharp(string express)
        {
            string s = "";
            if (File.Exists(Function.GetPathOfFunctionDll()))
            {
                s += "using "+Function.FunctionNameSpace + ";\n";
            }
             
            s += 
             "using System;\n" +
             "namespace ComputeUnit\n" +
             "{\n" +
                "public class Compute\n" +
                "{\n" +
                "   public static double GetResult()\n" +
                "   {\n" +
                "      return "+  TranslateToCSharpExpress(express) + ";\n"+
                "   }\n" +
                "}" +
            "}\n";

return s;
        }
     这里的GetResult()函数也就是我们所说的函数F()
       
      3.3 谁帮我们取得计算结果?
          反射!
          
          假设用户输入了表达式express,我们将如同下面的代码所叙述的那样计算它

string source = TranslateUnit.TranslateToCSharp(express);

//这里加载了函数dll
            string[] dlls = new string[1];
            dlls[0] = Function.GetPathOfFunctionDll(); //这里加载了前面所说的Functions.dll
             //编译
            CompilerResults results = CompilerUnit.Compile(source, false,true, dlls,null);

//重要:利用反射获取计算结果
            if (results.Errors.Count == 0)
            {
                Assembly ass = results.CompiledAssembly;

Type tp = ass.GetType("ComputeUnit.Compute");//ass.GetType("MyNamespace.MyClass");

// 获取方法
                MethodInfo mi = tp.GetMethod("GetResult");//tp.GetMethod("MyMethodl");

// 创建实例
                Object obj = System.Activator.CreateInstance(tp);

//执行方法
                try
                {
                    object res = mi.Invoke(obj, null);
                    this.Output(res.ToString(), false, Color.Blue); //将计算结果输出给用户

}
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }

以上仅仅简要叙述了此程序的核心问题,除此之外还有许许多多的细节问题,如果需要了解更多,你可以下载此程序的源代码http://files.cnblogs.com/zhouyinhui/ProgramCalculator.rar,里面有详细的注释

电子科技大学软件学院03级 周银辉

转载于:https://www.cnblogs.com/top5/archive/2010/04/11/1709429.html

基于C#语言的可编程表达式计算器设计相关推荐

  1. linux c语言 信号,linux下基于C语言的信号编程实例

    搜索热词 本文实例讲述了linux下基于C语言的信号编程方法.分享给大家供大家参考.具体如下: #include #include #include #include #include void si ...

  2. 基于C语言的软件,基于C语言的计算机软件编程分析

    摘 要 C语言是在B语言的基础上发展而来,其功能强大,使用便利,是目前计算机软件编程最基础的语言.C语言有着特殊的编程技巧,他的函数库中包含了编程所需的大部分函数,因此不需要程序员再另外定义:C语言中 ...

  3. c语言编写计算机软件,基于C语言的计算机软件编程分析.doc

    基于C语言的计算机软件编程分析.doc 基于C语言的计算机软件编程分析 摘要:C语言是一种重要的编程语言,在当今IT业的运用十分广泛.使用C语言来编写的程序简单.直接.准确,极大地推动了计算机软件的更 ...

  4. 基于计算机程序设计语音,基于php语言分析计算机编程的发展前景.doc

    文档介绍: 基于php语言分析计算机编程的发展前景.docEvaluationWarning:ThedocumentwascreatedwithSpire..基于php语言分析计算机编程的发展前景吕昌 ...

  5. matlab hod on,基于Matlab语言定量反馈控制器的分析与设计_朱永文

    计算机测量与控制. 2002. 10( 12) 822 Computer Measurement & Control 文章编号: 1671- 4598( 2002) 12- 0822- 02 ...

  6. 基于Verilog语言的13进制计数器设计

    基于Verilog语言的13进制计数器设计 `timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2019/11/10 ...

  7. C语言五子棋禁手算法的编写,基于C语言的五子棋辅助软件的设计与实现.doc

    基于C语言的五子棋辅助软件的设计与实现 广东工业大学 本科毕业设计(论文) 基于C语言的五子棋辅助软件的设计与实现 系 部 专 业 年 级 班级名称 学 号 学生姓名 指导教师 2012 年 5 月 ...

  8. 基于51单片机的4乘4计算器设计

    具体实现功能 系统由STC89C52单片机+4乘4按键模块+LCD1602液晶显示屏+电源构成. 具体功能: 利用输入采用4×4矩阵键盘,可以进行加.减.乘.除等几种数字运算,并在LCD1602上显示 ...

  9. 基于Go语言实现高并发推荐系统架构设计

    猜你喜欢 0.[免费下载]2021年12月热门报告盘点1.史上最全推荐系统传统算法合集2.推荐系统模型:多场景下的星型CTR预估模型3.新一代Rank技术在阿里巴巴推荐系统中的应用实践4.预训练模型在 ...

最新文章

  1. 美国或将限制AI等14类新技术出口,有意针对中国
  2. android 判断横竖屏的方法
  3. 【redis】缓存击穿、雪崩、穿透
  4. linux wifi修改频率,Linux Custom CRDA WiFi regulatory.bin和40MHz BW 5GHz频...
  5. GDCM:gdcm::LO的测试程序
  6. Android textview 获取url,获取电话号码
  7. 要做互联星空的SP接口,一点头绪都没有
  8. nfs挂载出错:mount.nfs: access denied by server while mounting
  9. call to a member funciton get() on null
  10. Grid Search 网格搜索 介绍
  11. ubuntu系统下快速安装谷歌浏览器(图文教程)
  12. xml保存图片和读取图片(一)
  13. 将文件转换成json
  14. 【史上最最最高仿】V2EX论坛源码—React + Golang开源库,求高手拍砖提建议~
  15. 处理 __iob_func 无法链接的问题
  16. linux 查看用户访问ip,(总结)按时按登录IP记录Linux所有用户操作日志的方法(附脚本)...
  17. PMP备考错题集-作业习题二
  18. 智能阅读模型的构建(第六届泰迪杯C题)
  19. 【VB-01】离线语音模块,无需语音算法开发,直接嵌入式用。
  20. 京东 java开发 待遇_【京东金融工资】java开发工程师待遇-看准网

热门文章

  1. django 日志多个服务连接_Django多进程日志文件问题
  2. Idea运行报错Error running ‘Application‘: Command line is too long的解决方法
  3. liunx安装和部署nacos
  4. 【NOIP2017】【Luogu3954】成绩(模拟)
  5. python 调用父类classmethod_Python__子类调用父类的方法
  6. 大学计算机应用技术基础实践教程答案,【最新资料】大学计算机基础实践教程习题答案.doc...
  7. JAVA网络编程→BIO到NIO、IP域名服务器DNS端口、套接字编程Socket、TCP与UDP
  8. append在python中是什么意思_append在python里是什么意思
  9. JQueryDOM之插入节点
  10. python生成倒计时图片_python pygame--倒计时