C#简易计算器

来源:互联网 发布:python多行注释快捷键 编辑:程序博客网 时间:2024/06/07 05:25

本文用于纪念大一下学期的C#语言课程设计。

1.设计目标

    利用逐步求精程序设计思想,设计一简单的计算器模拟程序。它的功能是读入一个表达式,然后计算出它的值。这里表达式是指满足下列要求的简化形式:

    (1)运算符为“+”、“*”;

    (2)运算对象为实数(有小数点或无小数点);

    (4)表达式以“;”结束。

    例如:2.3*(6+5.7); (3.2+3.6+5)*126; 76*(81+25)+92*(65+31);  都是满足上列要求的表达式。

2.设计思路

    2.1节展示总体实现思路,2.2-2.6节展示2.1节中提到的各要点的实现细节。

2.1总思路

用C#来编写这一程序,采用逐步求精的方法,简易计算器可按以下步骤实现。

第一步:根据课题要求,程序结构可以写为:

Static void Main(string []args){    String temp;         //表达式字符串    Boolean IsLeave=false;//是否退出系统    Boolean IsTrue=false;//是否表达式出错    Double Value;//表达式的值     "系统欢迎使用界面"    IsLeave="询问是否离开系统的结果";     While(!IsLeave)     {         "初始化相关的变量";         Temp="读入正确的表达式字符串";         IsTrue="判断表达式正误";          if(IsTrue)        {             Value="求出temp表达式的值";             "打印Value的值"。        }         Else        {             "打印“出错”信息";        }     }}
2.2 系统欢迎使用界面实现




2.3 “询问是否离开系统”实现

提供退出的按钮,点击之后弹出弹窗,让用户选择确认,确认之后即可退出系统;未点击默认不退出,isLeave=false;{Boolean isClicked=false;If(isClicked){    弹出弹窗;    DialogResult result=弹窗上的选择;    If(result)    {        退出系统;    }}}
2.4读入正确的表达式

1)保证表达式的正确,需要遵循如下规则:

符号说明:Exp :表达式,Ele:因数,Dig:数字,UnDig:正整数

Exp->Ele|(Exp)|Exp+Exp|Exp*Exp

Ele->UnDig|UnDig.UnDig

UnDig->Dig|0|DigUnDig|UnDig 0

Dig->1|2|3|4|5|6|7|8|9

2)框架:(采用边读边判断的思想,使用一个文本框来存储读入的部分表达式,文本框S;
{

Char Former="判断并读入正确的首字符";

S=Former;

While(former!=';')

{

    Current="当前读入的与Former适合的字符";

    Former=Current;

    S+=Former;

}

判断表达式S正误;     //主要判断括号是否匹配

如果正确,temp=该表达式S;

否则,清零重新执行本段程序。

}

3)"判断并读入正确的首字符"

tempChar=点击的字符值;

If(tempChar==数字||tempChar==左括号)

     Former=tempChar;

Else {提示用户本次输入不正确;继续执行本函数;}

   3.1)temp==数字,则是判断是否是数字

       If(temp<='9'&&temp>='0')

             Return true;

       Else return false;

4)"当前读入的与Former适合的字符"

   {

       Bool isSuited=true;

       Char tempChar;

 

       tempChar=点击的字赋值;

       isSuited=”判断与Former字符是否是相适应的“;

       If(!isSuited)

       {

           提醒用户填入了不正确的字符;

           忽略本次读入的字符,继续执行本函数;

        }

   }

4.1)判断与Former字符是否是相适应的

{

     Boolean reValue=true;

     Switch(former)

    {

          Case 数字:   tempChar是否是数字或+或*或小数点或右括号;                              break;

          Case (:     tempChar是否是数字;break;

          Case  ):      tempChar是否是分号或+或*;break;

          Case 小数点: tempChar是否是数字;break;

          Case +:        tempChar是否是数字或左括号;break;

          Case *:       tempChar是否是数字或左括号;break;

    }

}

2.6 判断表达式正误

由于本输入方法,无法保证输入括号能够匹配,所以还需要专门设置判断表达式的函数。

{   Stack <char>S;Char tempChar=读入当前字符;Boolean hasError=false; While(tempChar未到表达式temp的末尾){Switch(tempChar){   Case 左括号:S.push(tempChar);   Case 右括号:        {              If(S.count==0)//栈为空            {               hasError=true;               Break;            }            char te=S.top();//栈顶元素            If(te==左括号)              S.pop();//匹配了栈顶元素        }}tempChar=表达式中的下一个字符;}If(S不为空)     hasError=true;Return (!hasError);}


2.6计算表达式的值

求出temp表达式的值:采用堆栈的思想逐步求出表达式的值,利用两个堆栈,一个数字栈,一个符号栈,当遇到数字压入数字栈中,遇到符号与当前栈顶元素比较,如果优先级小于栈顶元素,则取出操作数做计算,结果压入数字栈。这样直至进行到表达式末尾或者符号栈顶为末尾结束符。

{     数字栈、符号栈;     While(!表达式末尾||Top(符号栈)不是末尾结束符)     {          If(当前元素为数字)          {              取出因数放入数字栈中;              调整表达式指针;          }          Else          {               Switch(当前元素与Top(符号栈)比较优先级)               {  Case 小于:计算部分表达式的值;break;                  Case 相等:取出符号栈顶端元素丢弃                    调整表达式指针;break;                  Case 大于:当前元素存入符号栈                  调整表达式指针。Break;               }          }     }}具体细化如下:{Stack<double>Num;Stack<char>Mark;Int count=0;//count标记执行到的位置Mark.Push(';');     while (未执行到表达式末尾 || Mark堆栈顶端不是末尾结束符)    {                if (当前字符temp[count]==数字)                               {                    integer = 从表达式分离出来的因数;                    Num.Push(integer);                }                else                {                    char temp = Mark.Peek();//Mark顶端元素                    Int returnValue = 分析temp[count]与temp的优先级;                    switch (returnValue)                    {                        Case  'X': isTrue = false; break;//出错                        Case '<': Mark.Push(express[count]); count++;                                         break;                        Case '=': Mark.Pop(); count++; break;                        Case '>':                            {                                double a = Num.Pop();//本次仅是计算                                double b = Num.Pop();                                char c = Mark.Pop();                                Num.Push(Shared.CalValue(a, b, c, out isTrue));                                if (isTrue == false)                                {                                    break;                                }                            }                            break;                    }                }            }            if (isTrue == true)                value = Num.Pop();       Return isTrue;}
3. 类设计

3.1 Input类

本类主要完成输入正确的表达式,

私有变量:

private StringBuilder express;//用于存储输入的表达式

private int count;//用于指明输入的字符串的位置

公有函数:

public Input();//主要初始化私有变量

public void Clear()//主要清零私有变量

public Boolean SetFirstChar(string s,chara)//实现读入第一个字符,包含特殊情况:首字符是上一次运算的结果

public Boolean GetWheHarmony(char a,char b)//判断即将读入的字符是否正确

public Boolean SetChar(char a)//读入后续字符,当读入"=",判断表达式是否正确,若正确,使之开始调用表达式求值函数

属性:public string Express;//返回私有变量express的值

3.2 Computer类

本类主要完成计算表达式的值,假定输入的表达式是形式正确的。

私有变量:

 private Boolean isTrue;//表示计算中是否出错

 private String express;//记录表达式

 private double value;//记录表达式的值

公有函数:

public Computer(string s)//初始化相关变量

 publicvoid CalExpression()//计算表达式的值

属性:

public Boolean IsTrue;//返回私有变量isTrue的值

public string Express;//传递相关值给私有变量express

public double Value;//获取私有变量value的值

3.3 Shared类

本类包含上述两个类需要使用到的一些公共函数,全部被申明为static静态函数。

public static Boolean JudgeInteger(char a)/判断D是否是数字

public static Boolean JudgeChar(char a)//判断a是否是非数字类字符

public static char CalPriority(char a, charb)//计算优先级

public static double CalValue(double a,double b, char c, out Boolean wheTrue)

//计算只含两个操作数的表达式的值

private static Boolean InMark(char temp)//判断temp是否是运算符

public static double ReadNum(string s, intlocation, out int count)//在字符串中读出一个因数

public static Boolean JudgeExpression(strings)//判断表达式是否出错,主要检测括号是否匹配

3.4 界面类CalculatorWindow

私有变量:

一些列关于界面的类对象;

 private Input input = new Input();//输入类对象

 private Computer computer;//计算类对象

 private Boolean hasFirst = false;//是否已经输入

公有函数

private void Initial()//初始化变量

private void InputProcessError(char temp)//字符出错,通知用户

private void Error(string s)//表达式出错,通知用户

private void PrintValue(string expr,doublevalue)//打印结果

private void In(string s,char tempChar)//输入一个字符

private void Btn_Click(objectsender,EventArgs e)//键盘上的按键点击

private void Back_Click(object sender,EventArgs e)//点击Back退格键

private void Power_Click(object sender,EventArgs e)//点击关闭

private void Clear_Click(object sender,EventArgs e)//点击清零

4. 实现结果

优点:

1)满足课题全部要求

2)支持循环使用前一步骤执行的结果

3)同时支持多层括号,具体如下:

缺点:

1)不支持键盘输入

2)不支持光标移动输入(计算器无法做到此功能,因为无法判断表达式的正误)








原创粉丝点击