我的第一个winform程序:简单的计算器(3)
接上篇
接下来,是运算符按钮了。
4.运算符:
1) +、--键,按下后计算已输入的表达式值,也就是说按一下,计算一次。Calculation类的left和right成员即是表示一个表达式的左右操作数,只需要把left和right的运算结果存入left,并把新输入的数存入right就可以了。
2) *、/键,与加减号类似,但考虑到优先级的问题,当前一个运算符也是乘除号的话就按与加减号相同的方法处理;如果是加减号的话就暂时不计算,等待下一次输入。这就需要一个量来存储这个没有计算的值。
还有一个问题,如果是第一次按下预算符键,很显然,右操作数还没有输入,无法计算,因此必须等待下一次输入。如果反复按下运算符键,就应当以最后一次按下的为准。
先写一个Calculate方法,用来进行加减乘除运算,这个很简单:
需要说明的是,计算的时候要处理一些特殊的情况,为了使显示屏总有显示,就要求当只有一个操作数时,返回该数。自定义异常将在以后说明。
接下来便是实现实现按钮事件了,与数值键不同,运算符更改的是左操作数left,编写代码令人头痛的就是要考虑各种情况:
接下来,是运算符按钮了。
4.运算符:
1) +、--键,按下后计算已输入的表达式值,也就是说按一下,计算一次。Calculation类的left和right成员即是表示一个表达式的左右操作数,只需要把left和right的运算结果存入left,并把新输入的数存入right就可以了。
2) *、/键,与加减号类似,但考虑到优先级的问题,当前一个运算符也是乘除号的话就按与加减号相同的方法处理;如果是加减号的话就暂时不计算,等待下一次输入。这就需要一个量来存储这个没有计算的值。
还有一个问题,如果是第一次按下预算符键,很显然,右操作数还没有输入,无法计算,因此必须等待下一次输入。如果反复按下运算符键,就应当以最后一次按下的为准。
先写一个Calculate方法,用来进行加减乘除运算,这个很简单:
1 private static string Calculate(string left,string right,string operators) //基本加减乘除运算
2 {
3 if(right=="0"&&operators=="/")
4 throw new MathExcption("被除数不能为0");
5 else if(left==string.Empty&&right==string.Empty)
6 return string.Empty;
7 else if(left==string.Empty&&right!=string.Empty)
8 return right;
9 else if(left!=string.Empty&&right==string.Empty)
10 return left;
11 else
12 {
13 if(operators=="+")
14 return (Convert.ToDecimal(left)+Convert.ToDecimal(right)).ToString();
15 else if(operators=="-")
16 return (Convert.ToDecimal(left)-Convert.ToDecimal(right)).ToString();
17 else if(operators=="*")
18 return (Convert.ToDecimal(left)*Convert.ToDecimal(right)).ToString();
19 else if(operators=="/")
20 return (Convert.ToDecimal(left)/Convert.ToDecimal(right)).ToString();
21 else
22 throw new CalculationExcption();
23 }
24 }
2 {
3 if(right=="0"&&operators=="/")
4 throw new MathExcption("被除数不能为0");
5 else if(left==string.Empty&&right==string.Empty)
6 return string.Empty;
7 else if(left==string.Empty&&right!=string.Empty)
8 return right;
9 else if(left!=string.Empty&&right==string.Empty)
10 return left;
11 else
12 {
13 if(operators=="+")
14 return (Convert.ToDecimal(left)+Convert.ToDecimal(right)).ToString();
15 else if(operators=="-")
16 return (Convert.ToDecimal(left)-Convert.ToDecimal(right)).ToString();
17 else if(operators=="*")
18 return (Convert.ToDecimal(left)*Convert.ToDecimal(right)).ToString();
19 else if(operators=="/")
20 return (Convert.ToDecimal(left)/Convert.ToDecimal(right)).ToString();
21 else
22 throw new CalculationExcption();
23 }
24 }
接下来便是实现实现按钮事件了,与数值键不同,运算符更改的是左操作数left,编写代码令人头痛的就是要考虑各种情况:
1 public static void ComputeClick(string sender) //运算按钮事件
2 {
3 if(left==string.Empty&&right!=string.Empty)
4 {
5 left=sign+right;
6 right=string.Empty;
7 operators=sender;
8 n=0;
9 }
10 else if(left!=string.Empty&&right!=string.Empty)
11 {
12 if(((operators=="+"||operators=="-")&&(sender=="+"||sender=="-"))||((operators=="*"||operators=="/")&&(sender=="*"||sender=="/")))
13 {
14 left=Calculate(left,sign+right,operators);
15 right=string.Empty;
16 operators=sender;
17 n=0;
18 }
19 else if((operators=="+"||operators=="-")&&(sender=="*"||sender=="/"))
20 {
21 tempNum=left;
22 tempOperator=operators;
23 left=sign+right;
24 right=string.Empty;
25 operators=sender;
26 n=0;
27 }
28 else if((operators=="*"||operators=="/")&&(sender=="+"||sender=="-"))
29 {
30 left=Calculate(tempNum,Calculate(left,sign+right,operators),tempOperator);
31 tempNum=string.Empty;
32 tempOperator=string.Empty;
33 right=string.Empty;
34 operators=sender;
35 n=0;
36 }
37 else
38 throw new CalculationExcption();
39 }
40 else
41 {
42 operators=sender;
43 n=0;
44 }
45 if(left.Length>MaxLength)
46 throw new CalculationExcption("计算结果越界",true);
47 sign=string.Empty;
48 }
2 {
3 if(left==string.Empty&&right!=string.Empty)
4 {
5 left=sign+right;
6 right=string.Empty;
7 operators=sender;
8 n=0;
9 }
10 else if(left!=string.Empty&&right!=string.Empty)
11 {
12 if(((operators=="+"||operators=="-")&&(sender=="+"||sender=="-"))||((operators=="*"||operators=="/")&&(sender=="*"||sender=="/")))
13 {
14 left=Calculate(left,sign+right,operators);
15 right=string.Empty;
16 operators=sender;
17 n=0;
18 }
19 else if((operators=="+"||operators=="-")&&(sender=="*"||sender=="/"))
20 {
21 tempNum=left;
22 tempOperator=operators;
23 left=sign+right;
24 right=string.Empty;
25 operators=sender;
26 n=0;
27 }
28 else if((operators=="*"||operators=="/")&&(sender=="+"||sender=="-"))
29 {
30 left=Calculate(tempNum,Calculate(left,sign+right,operators),tempOperator);
31 tempNum=string.Empty;
32 tempOperator=string.Empty;
33 right=string.Empty;
34 operators=sender;
35 n=0;
36 }
37 else
38 throw new CalculationExcption();
39 }
40 else
41 {
42 operators=sender;
43 n=0;
44 }
45 if(left.Length>MaxLength)
46 throw new CalculationExcption("计算结果越界",true);
47 sign=string.Empty;
48 }
可以看到,为了应付各种情况使用了大量的if语句。该方法主要就是处理各操作数及运算符的。为了实现优先级,单独使用了2个变量分别存储暂时不计算的数和运算符。与数值按钮不同,每次按下运算符按钮后,所有的变量几乎都需要被修改。这个开销是很大的。
(未完待续)