Spiga

希望有一天变成口语编程

2011-08-17 13:20 by 在路上。。。, 2156 visits, 收藏, 编辑

一大早的头晕,迷迷糊糊,就此发一篇口水文吧!仔细看看代码也许对你会有收获,程序员总是容易迷失在小小的圈子

机器语言:最原始的控制计算机的语言。基本的语言是0和1。当时,表示0和1的最好模式是穿孔卡片和穿孔纸带,穿孔使光通过表示连接。

汇编语言:是软件设计的最初期语言。汇编语言的特点是直接与机器的CPU、计算机的基本输出输入控制系统大交道。大量直接调用计算机中断,直接使用CPU中的寄存器。控制计算机的效率特别高。

高级语言:是WINDOWS之前和初期的语言规范,高级语言是相对之前的低级语言汇编和机器语言而言。高级语言描述的层次是软件的模块、结构、内存管理。当时,结构化编程是当时先进的软件设计思想。代表的计算机语言是C、PASCAL等。指针、位移、驻留程序、扩展内存为当时的编程高手所津津乐道。面向对象是“紧贴”高级软件语言的模型体系,用于软件开发期间,而不是运行期间,其描述的层次是在软件的组件、对象一级。这是的常用术语是对象、类、包、控件、所见即所得等。统一建模语言(UML)是这一阶段的语言规范的代表,RUP是这一语言规则下产生的工具。

每一次语言的升级都是一次生产力的解放,不行的话看看下面的代码也许恍然大悟:

小小的计算器也许是除了helloworld之外的另一个经典例子呵呵:

别小瞧这么麻烦,因为他人类和computer交流的时候最起码不用拿穿孔卡片和穿孔纸带了:

DATA SEGMENT
INFO0  DB 13,10,'*************************************************************************$' 
INFO1  DB 13,10,'*                   JIANDAN ZHENGSHU JISHUANQI                          *$'
INFO2  DB 13,10,'*                                               ZHUOZHE ABCD            *$'
INFO3  DB 13,10,'$'
INFO4  DB 13,10,'*   SHUOMING:                                                           *$'
INFO5  DB 13,10,'* 1.ZHENGSHU + - * / ,FANWEI 0~65535.                                   *$'
INFO6  DB 13,10,'* 2.SHURU SHUJU DE SHIHOU ,RUGUO SHURU HUICHE ZHE TUICHU CHENGXU.       *$'
INFO7  DB 13,10,'* 3.CHUFA DE SHIHOU MEIYOU DUI CHUSHU WEI NING ZHUCHU CHULI.            *$'
INFO8  DB 13,10,'* 4.CAIYONG ZICHENGXU JI SANJI CAIDAN.                                  *$'
INFO9  DB 13,10,'* 5.SHIYONG SHI, GEGE SHU JI CAOCUO FU SHURU DE SHUNXU RENYI,           *$'
INFO10 DB 13,10,'*   QIZHONG CAOZHUO FU 1=+ 2=- 3=* 4=/ 5=exit                                      *$'
INFO11 DB 13,10,'PLEASE PRESS  KEY TO NEXT,OR ENTER KEY TO EXIT$'
BINFO0 DB 13,10,'*                   1.ADD                                               *$'
BINFO1 DB 13,10,'*                   2.SUB                                               *$'
BINFO2 DB 13,10,'*                   3.MUL                                               *$'
BINFO3 DB 13,10,'*                   4.DIV                                               *$'
BINFO4 DB 13,10,'*                   5.EXIT  (OR OTHER KEY)                              *$'
STRING DB 13,10,'*        PLEASE PRESS NUMBER 1(+),2(-),3(*),4(/),5(EXIT):               *$'
CINFO0 DB 13,10,'*                   1.INPUT THE FIRST NUMBER                            *$'
CINFO1 DB 13,10,'*                   2.INPUT THE SECOND NUMBER                           *$'
CINFO2 DB 13,10,'*                   3.EXIT(OR OTHER KEY                                 *$'
BUFF   DB 10 
       DB 0 
       DB 10 DUP(0) 
ARRAY1 DB 13,10,'PLEASE INPUT THE FIRST NUMBER:$' 
ARRAY2 DB 13,10,'PLEASE INPUT THE SECOND NUMBER:$'
ARRAY  DW 2 DUP(0) 
RESULT DB 10 DUP(0),'$'
CRLF   DB 0DH,0AH,'$' 
FLAGS  DB 0
DATA ENDS 
CODE SEGMENT 
     ASSUME CS:CODE,DS:DATA 
START:MOV AX,DATA 
      MOV DS,AX 
AB:   CALL DISPMAINMENU
      MOV AH,7
      INT 21H
      CMP AL,13
      JZ EEXIT
      CALL TWOMENU
      MOV [FLAGS],0FFH
      MOV AH,7
      INT 21H 
      CMP AL,31H
      JB  EEXIT
      CMP AL,34H
      JA  EEXIT
      MOV [FLAGS],AL
      MOV [ARRAY],0FFH
      MOV [ARRAY+2],0FFH
ADS:  CALL DISPTHMENU      
      MOV AH,7
      INT 21H
      CMP AL,'1' 
      JZ A1 
      CMP AL,'2' 
      JZ A2
      JMP EEXIT 
A1:   MOV DX,OFFSET ARRAY1 
      CALL INPUTNUMBER
      CMP CX,0
      JZ EEXIT
      MOV WORD PTR [ARRAY],AX
      CALL JISHUAN
      JC   AB
      JMP ADS
A2:   MOV DX,OFFSET ARRAY2
      CALL INPUTNUMBER
      CMP CX,0
      JZ EEXIT
      MOV WORD PTR [ARRAY+2],AX
      CALL JISHUAN
      JC AB
      JMP ADS
ABC     PROC 
        MOV CH,0 
        MOV BX,OFFSET BUFF
        MOV CL,[BX+1]
        CMP CX,0
        JZ ABCD
        PUSH CX  
        ADD BX,2
        PUSH BX 
 L0:    SUB [BX],30H 
        INC BX 
        LOOP L0
        POP BX 
        MOV AX,0 
        MOV CH,0 
        MOV CL,[BX-1]
 L1:   MOV DL,10 
       MUL DL 
       ADD AL,BYTE PTR [BX] 
        INC BX 
        LOOP L1
        POP CX 
ABCD:   RET 
ABC   ENDP 

DEF     PROC 
        MOV SI,OFFSET RESULT 
        ADD SI,4
        MOV [SI+1],"$"
        MOV CX,5    
AG1:   MOV DX,0
       MOV BX,10
       DIV BX
       PUSH DX
       ADD DL,30H
       MOV [SI],DL
       DEC SI
       POP DX
       LOOP AG1
       MOV CX,4
AG3:   INC SI
       MOV AL,[SI]
       CMP AL,30H
       JNZ NOZEARO
       LOOP AG3
       INC SI
NOZEARO:
       CALL DISPCRLF
       MOV DX,SI
       MOV AH,9
       INT 21H
       RET 
DEF    ENDP 

DISPCRLF PROC
      MOV DX,OFFSET INFO3
DISPINFO:MOV AH,9
      INT 21H
      RET
DISPCRLF ENDP
      
DISPMAINMENU PROC
      MOV DX,OFFSET INFO0
      CALL DISPINFO
      CALL DISPCRLF
      MOV DX,OFFSET INFO1
      CALL DISPINFO 
      MOV DX,OFFSET INFO2
      CALL DISPINFO
      MOV DX,OFFSET INFO4
      CALL DISPINFO
      MOV DX,OFFSET INFO5
      CALL DISPINFO
      MOV DX,OFFSET INFO6
      CALL DISPINFO
      MOV DX,OFFSET INFO7
      CALL DISPINFO
      MOV DX,OFFSET INFO8
      CALL DISPINFO
      MOV DX,OFFSET INFO9
      CALL DISPINFO
      MOV DX,OFFSET INFO10
      CALL DISPINFO 
      MOV DX,OFFSET INFO11
      CALL DISPINFO
      MOV DX,OFFSET INFO0
      CALL DISPINFO
      RET
DISPMAINMENU ENDP

TWOMENU PROC
      CALL DISPCRLF
      MOV DX,OFFSET INFO0
      CALL DISPINFO
      CALL DISPCRLF
      MOV DX,OFFSET INFO1
      CALL DISPINFO 
      MOV DX,OFFSET INFO2
      CALL DISPINFO
      MOV DX,OFFSET BINFO0
      CALL DISPINFO
      MOV DX,OFFSET BINFO1
      CALL DISPINFO
      MOV DX,OFFSET BINFO2
      CALL DISPINFO
      MOV DX,OFFSET BINFO3
      CALL DISPINFO
      MOV DX,OFFSET BINFO4
      CALL DISPINFO
      CALL DISPCRLF
      MOV DX,OFFSET INFO0
      CALL DISPINFO
      RET
TWOMENU ENDP

DISPTHMENU PROC
      CALL DISPCRLF
      CALL DISPCRLF
      MOV DX,OFFSET INFO0
      CALL DISPINFO
      CALL DISPCRLF
      MOV DX,OFFSET INFO1
      CALL DISPINFO 
      MOV DX,OFFSET INFO2
      CALL DISPINFO
      CALL DISPCRLF
      CALL DISPCRLF
      MOV DX,OFFSET CINFO0
      CALL DISPINFO
      MOV DX,OFFSET CINFO1
      CALL DISPINFO
      MOV DX,OFFSET CINFO2
      CALL DISPINFO
      CALL DISPCRLF
      CALL DISPCRLF
      MOV DX,OFFSET INFO0
      CALL DISPINFO
      RET 
DISPTHMENU ENDP          

INPUTNUMBER PROC
      MOV AH,9 
      INT 21H 
      MOV DX,OFFSET BUFF 
      MOV AH,0AH 
      INT 21H 
      CALL ABC
      RET    
INPUTNUMBER ENDP

JISHUAN PROC
      CMP [ARRAY],0FFH
      JZ NNN
      CMP [ARRAY+2],0FFH
      JZ NNN
      CMP [FLAGS],31H
      JZ ISADD
      CMP [FLAGS],32H
      JZ ISSUB
      CMP [FLAGS],33H
      JZ ISMUL
      JMP ISDIV
NNN:  CLC
      RET
ISADD:MOV BX,WORD PTR [ARRAY]
      MOV AX,WORD PTR [ARRAY+2]
      ADD AX,BX
      JMP DISP
ISSUB: MOV AX,WORD PTR [ARRAY]
      MOV BX,WORD PTR [ARRAY+2]
      CMP AX,BX 
      JB  SMALL
      SUB AX,BX
      JMP DISP
SMALL:SUB BX,AX
      MOV AX,BX
      JMP DISP
ISMUL:MOV AX,WORD PTR [ARRAY]
      MOV BX,WORD PTR [ARRAY+2]
      MUL BX
      MOV DX,0
      JMP DISP
ISDIV:MOV AX,WORD PTR [ARRAY]
      MOV BX,WORD PTR [ARRAY+2]
      MOV DX,0
      DIV BX
      MOV DX,0
DISP: CALL DEF
      STC
      RET            
JISHUAN ENDP                       
EEXIT:MOV AH,4CH 
      INT 21H  
CODE ENDS 
END START 

园子里面对这个感兴趣的应该没.NET的多呵呵,那就.NET吧!

从面向过程开始吧:

   private void btnOk_Click(object sender, EventArgs e)
        {
            int operandNum = Convert.ToInt32(this.txtOperandNum.Text.Trim());
            int isOperandNum = Convert.ToInt32(this.txtIsOperandNum.Text.Trim());
            string oper =this.cmbOper.SelectedItem.ToString();
            int result=default(int);

            switch (oper)
            {
                case "+": result = operandNum + isOperandNum; break;
                case "-": result = operandNum - isOperandNum; break;
                case "*": result = operandNum * isOperandNum; break;
                case "/": result = operandNum / isOperandNum; break;
                default:
                    MessageBox.Show("不支持您输入的操作!");
                    break;
            }

            this.txtResult.Text = result.ToString();
        }

  是不是觉得很简单,上学那会儿应该经常这么干 呵呵?是的就是做了个加减乘除,很明显很多地方还不强壮,因为本片不是讨论健壮的所以先不必吹毛就此了,是不是觉得不通用? 是的 很可恶,稍微改动下 也许就好点了

    private void btnOk_Click(object sender, EventArgs e)
        {
            int operandNum = Convert.ToInt32(this.txtOperandNum.Text.Trim());
            int isOperandNum = Convert.ToInt32(this.txtIsOperandNum.Text.Trim());
            string oper = this.cmbOper.SelectedItem.ToString();

            int outPut = Operate(operandNum, oper, isOperandNum);
            this.txtResult.Text = outPut.ToString();
        }

   private int Operate(int operandNum, string oper, int isOperandNum)
        {
            int result = default(int);

            switch (oper)
            {
                case "+": result = operandNum + isOperandNum; break;
                case "-": result = operandNum - isOperandNum; break;
                case "*": result = operandNum * isOperandNum; break;
                case "/": result = operandNum / isOperandNum; break;
                default:
                    MessageBox.Show("不支持您输入的操作!");
                    break;
            }

            return result;
        }

  这样或许好点了,但终究没逃出过程,让我们进入面向对象:在设计模式的世界中,所谓历史原则,在具体的子类中取实现的基类或接口吧!

  interface ICalcOp
    {
        int Execute(int operandNum, int isOperandNum);
    }

  

 class AddOp : ICalcOp
    {
        public int Execute(int operandNum, int isOperandNum)
        {
           return operandNum + isOperandNum;
        }
    }

  难道这样就行了,不行,总不能每次客户端调用的时候都产生一中类型的操作类吧!所以在把各种操作类也封装下吧,也许会更好点:

  class Operations
    {
        private static Dictionary<string, ICalcOp> operation ;

        public static void FillOper()
        {
            operation = new Dictionary<string, ICalcOp>();
            operation.Add("+",new AddOp());
        }

        public static int Operate(int operandNum, string oper, int isOperandNum)
        {
            ICalcOp calc = operation[oper];
            return calc.Execute(operandNum, isOperandNum);
        }

  这样调用也许就好点了

   private void btnOk_Click(object sender, EventArgs e)
        {
            int operandNum = Convert.ToInt32(this.txtOperandNum.Text.Trim());
            int isOperandNum = Convert.ToInt32(this.txtIsOperandNum.Text.Trim());
            string oper = this.cmbOper.SelectedItem.ToString();
            int result = default(int);
            Operations.FillOper();

            switch (oper)
            {
                case "+": result = Operations.Operate(operandNum, oper, isOperandNum); break;
                //  case "-": result = operandNum - isOperandNum; break;
                //  case "*": result = operandNum * isOperandNum; break;
                //  case "/": result = operandNum / isOperandNum; break;
                default:
                    MessageBox.Show("不支持您输入的操作!");
                    break;
            }

            this.txtResult.Text = result.ToString();
        }

  可是分装类还是有点不自在,好像还可以在前进一步,为什么一定要用接口呢?淡然可以不用,微软总是个我们提供更多利剑

  class Operations
    {
        delegate int CalcOp(int lhs, int rhs);

        static Dictionary<string, CalcOp> operation;

        public static void FillOper()
        {
             operation = new Dictionary<string, CalcOp>();
             operation["+"] = delegate(int operandNum, int isOperandNum) { return operandNum + isOperandNum; };
             
        }

        public static int Operate(int operandNum, string op, int isOperandNum)
        {
            CalcOp oper = operation[op];
            return oper(operandNum, isOperandNum);
        }
    }

  这样是不是好点了,至少不去专门搞个接口了,不过还是不够,程序员居多是懒人,总是在少些,是的,也许这样更简洁,但是他在一步步被面向对象而去。。。

   class Operations
    {
        delegate int CalcOp(int lhs, int rhs);

        static Dictionary<string, CalcOp> operation;

        public static void FillOper()
        {
             operation = new Dictionary<string, CalcOp>();
             operation["+"] = (int operandNum, int isOperandNum) => operandNum + isOperandNum;
        }

        public static int Operate(int operandNum, string op, int isOperandNum)
        {
            CalcOp oper = operation[op];
            return oper(operandNum, isOperandNum);
        }
    }

  其实以上都是铺垫,仅仅是一点代码片段而已,但是静静滴思考下,你也许会发现更多,也许它后面有更多有意思的东西,

对于一个面向对象者来看以上代码是既有可笑之处也有优雅之处,面向对象的世界里一切都是对象是东西是居多是个名字世界,但是

无论是lambda还是匿名委托都在背离这个对象世界而去,更多的关注了动作世界,其实在反过来想想LINQ何尝也不是,但是他确实给我们带了更大的方便,沟通更方便,应为他也强调的是我们要什么,而不是怎么要。无论c还是c#还是F#都是在解放生产力,不过也许有一天我们不在为程序,元编程、 动态和功能范式,XXX等等枯燥的编程烦恼,那时候的语言会和我们人类自然语言一样,那时候看现在的语言,也许你会觉得先都是甲骨文和象形文字,就像当初鼻祖们拿纸袋和计算机沟通的时候也一定没想到今天我们会是这么和计算交互的,在上升到软件开发也是;不要拿石器时代的好工具耕耘现在的田地  呵呵 口才笨拙,胡乱说了一通  欢迎拍砖!

http://www.smarteas.net/his/AgileHIS.html

代码下载:http://files.cnblogs.com/onmyway/SimpleCalc.rar

标签: AgileHIS, c#, net
Add your comment

29 条回复

  1. #1楼 xluo      2011-08-17 13:32
    请问有什么用?
     回复 引用 查看   
  2. #2楼 何戈洲      2011-08-17 13:33
    牛奔!啥时候来口语言呢?
     回复 引用 查看   
  3. #3楼 tigerkingdom      2011-08-17 13:39
    不久的将来有可能面向语义编程了,呵呵
     回复 引用 查看   
  4. #4楼[楼主] 在路上。。。      2011-08-17 13:40
    @xluo
    解放生产力
     回复 引用 查看   
  5. #5楼 曹西龙      2011-08-17 13:40
    来看看
     回复 引用 查看   
  6. #6楼 魏琼东      2011-08-17 13:50
    口语编程,真牛蹦
     回复 引用 查看   
  7. #7楼[楼主] 在路上。。。      2011-08-17 13:55
    @魏琼东
    水文,不过有时想想真不是没可能,大家一起失业也挺好 呵呵
     回复 引用 查看   
  8. #8楼 魏琼东      2011-08-17 13:56
    @在路上。。。
    引用在路上。。。:
    @魏琼东
    水文,不过有时想想真不是没可能,大家一起失业也挺好 呵呵


    语言编程还真说不定有一天实现
     回复 引用 查看   
  9. #9楼 象牛      2011-08-17 14:11
    @xluo
    什么时候都有你这种烦人的人
    别人博主写点东西大家探讨下多好
     回复 引用 查看   
  10. #10楼 Tongue      2011-08-17 14:13
    老魏也来了 呵呵 我感觉吧 这会出现的 但是想来很多的有打代码敲键盘习惯的 还是很喜欢敲的吧 呵呵
    口语言可以使编程更容易推广了 更容易进这个行当的门槛了。
     回复 引用 查看   
  11. #11楼 xluo      2011-08-17 14:13
    @象牛
    既然公开了,我就有评论的权利,
    我可以支持也可以反对,这是我的自由,
    博主都没有说什么,请问你有什么资格评论我?
     回复 引用 查看   
  12. #12楼 zhuhm      2011-08-17 14:21
    大胆假设说不定那天就出来了呢?
     回复 引用 查看   
  13. #13楼 poleices      2011-08-17 14:38
    我希望有一天连口语都省了,思维一动,程序就好了
     回复 引用 查看   
  14. #14楼 鹤冲天      2011-08-17 14:46
    引用poleices:我希望有一天连口语都省了,思维一动,程序就好了

    意念编程,强!
     回复 引用 查看   
  15. #15楼 陈梓瀚(vczh)      2011-08-17 15:03
    @poleices
    哪天建个matrix吧,机器人都知道自己要解决什么问题了,自己就把程序给写了,用不着我们发现问题了。
     回复 引用 查看   
  16. #16楼 delphing      2011-08-17 15:06
    如果真能口语编程也挺爽的
     回复 引用 查看   
  17. #17楼 Painful      2011-08-17 17:00
    希望有生之年可以盼到。。。
     回复 引用 查看   
  18. #18楼 唯自我      2011-08-17 17:00
    不错
     回复 引用 查看   
  19. #19楼 冷冷      2011-08-17 23:12
    估计有难度,自然语言本身的语义就不是很明确,我觉得还是不太适应用于编程语言,可能会是一种类自然语言的语法罢……
     回复 引用 查看   
  20. #20楼 拾玄      2011-08-17 23:21
    引用poleices:我希望有一天连口语都省了,思维一动,程序就好了

    如果真有那么一天,那应该是属于机器人统治这个世界的时代了。
    或许这也是自然选择,不可否认机器人比人类有更多的发展空间和潜力。
     回复 引用 查看   
  21. #21楼 Tony Qu      2011-08-17 23:36
    都口语变成了还要程序员干嘛?PM直接边读需求边生成代码,我们都会失业的
     回复 引用 查看   
  22. #22楼 阿毅      2011-08-17 23:52
    @Tony Qu
    我们改行当语文老师么!教人说话有逻辑无歧义。哈哈哈哈。
     回复 引用 查看   
  23. #23楼 xluo      2011-08-18 09:02
    这种文章就不要上首页了~
     回复 引用 查看   
  24. #24楼 没一句正经的业余程序员      2011-08-18 09:12
    现在学哲学搞文科逻辑的鼓吹形式化,批判自然语言的歧义和模糊性。搞计算机的想用自然语言编程,呵呵!
    现在欧美计算机科系搞程序设计语言理论的兄弟研究的东西,就是未来工业界可能流行的东西。计算机科学家正在发明各种各样的形式语言、五花八门的逻辑,包括将自然语言形式化。所以只要计算机形式化本质不变,符号逻辑就依然是程序设计语言的本源。
    从这几十年看,程序设计语言不但没有变简单,反而更加复杂,符号概念更多,方便的只是程序设计环境和代码库。上个世纪50年代的Fortran、70年代的C、90年代的Java和C#,学习的门槛难道不是越来越高了吗?因为编程问题更复杂了,程序设计语言也随之进化。
    如果真有所谓“伪”自然语言编程,那可以想象编程面对的问题要有多恐怖,语法超繁琐、符号概念超多、学习的门槛会更高,那绝对是程序员的福音。
     回复 引用 查看   
  25. #25楼 飞阿飞      2011-08-18 09:47
    当你可以做的更简单的时候,是别人用了更复杂的方式帮你实现的!
     回复 引用 查看   
  26. #26楼 风过 无痕      2011-08-18 11:49
    你这是越来越复杂了吧。
    代码量增加了,数据结构增加了,逻辑增多了!
    要么就用C语言式的switch,要么就用动态语言式的eval。
    在所用的语言里加入全面的动态语言支持(不是C#的dynamic),目前比口语编程可行实用
     回复 引用 查看   
  27. #27楼 红色壁虎      2011-08-18 13:32
    呵呵~~我觉得这个文章很有意思。
    不知道有没人看过 《100年后的编程语言》这篇文章,如果看过我想会明白楼主的意思:如果我们能知道100年以后的语言是什么样子的,那么我们现在就可以开始准备了。

    @没一句正经的业余程序员
    我赞同你的话,只要计算机的本质不变,那么编程工作,绝对是一个一丝不苟的逻辑组合过程。自然语言是有模糊性和二义性存在的。想用自然语言进行编程工作,绝对是一个比现在的代码编写方式更复杂的过程。

    即使通过人工智能来编程,也只是在有限的范围内进行,因为人工智能要理解自然语言所对应的数学逻辑,只有一个办法,那就是学习或者人工进行集成,所以必须要对人工智能本身进行不断的升级,这一点也需要非自然语言程序员的存在。
     回复 引用 查看   
  28. #28楼 tan_Cool      2011-08-18 23:42
    >>> def operate(op,x,y):
    	print eval("%d%s%d" %(x,op,y))
    
    	
    >>> operate('+',3,4)
    7
    >>> operate('*',4,15)
    60
    >>> 
    

    def operate(op,x,y):定义函数operate有三个参数
    print eval("%d%s%d" %(x,op,y))定义以op为运算符,计算x,y,打印结果
     回复 引用 查看   
  29. #29楼 红色壁虎      2011-08-21 12:02
    引用tan_Cool:
    >>> def operate(op,x,y):
    	print eval("%d%s%d" %(x,op,y))
    
    	
    >>> operate('+',3,4)
    7
    >>> operate('*',4,15)
    60
    >>> 
    

    def operate(op,x,y):定义函数operate有三个参数
    print eval("%d%s%d" %(x,op,y))定义以op为运算符,计算x,y,打印结果

    呵呵 你这是在读代码还是编程?
    如果真是自然语言的方式编程,我想这样可能更实在点:

    定义一个传入三个参数,返回后两个参数以第一个参数运算后的结果的函数
     回复 引用 查看