当前位置:文档之家› 第6章 四则运算计算器

第6章 四则运算计算器

第6章四则运算计算器本章介绍的项目是大家十分熟悉的计算器,通过该项目的实践,我们将学习状态图的一些基本知识、C# 中方法的概念和应用以及键盘事件的运用,同时,训练编写一个略微复杂的Windows应用程序的设计思路。

为了使读者能够循序渐进地学习此类项目的设计,我们根据难度的不同,分为三个项目分别实现,首先完成项目一:整数的四则运算计算器,然后在此基础上完善,实现项目二:实数四则运算计算器,最后添加记忆功能,完成项目三:带记功能的实数四则运算计算器。

6.1 项目一:整数四则运算计算器设计6.1.1 工作目标终极目标:完成一个整数四则运算的计算器,界面如图6.1所示:图6.1 整数四则运算计算器促成目标:1.完成整数四则运算计算器整体设计——状态机分析;2.完成整数四则运算模块设计——流程分析;3.完成整数四则运算计算器的程序界面设计及属性设置;4.完成整数四则运算器的程序编码;5.对整数四则运算计算器进行必要的运行测试,如有错误进行调试修改。

6.1.2 工作任务工作任务一:构建计算器的状态图;工作任务二:设计程序模块的流程图;工作任务三:设计界面完成窗体及控件的属性设置;工作任务四:编写程序代码;工作任务五:测试软件,对错误进行调试修改。

6.1.3 工作任务一:构建计算器的状态图1、知识准备——状态图状态图(Statechart Diagram)是描述一个实体基于事件反应的动态行为,显示了该实体如何根据当前所处的状态对不同的事件做出反应的。

状态图用于显示状态机(它指定对象所在的状态序列)、使对象达到这些状态的事件和条件、以及达到这些状态时所发生的操作。

状态机由状态组成,各状态由转移链接在一起。

状态是对象执行某项活动或等待某个事件时的条件。

转移是两个状态之间的关系,它由某个事件触发,然后执行特定的操作或评估并导致特定的结束状态。

图6.2描绘了状态机的各种元素。

图6.2 状态机的各种元素一个简单的编辑器可被视为有限的状态机,其状态为Empty(空)、Waiting for a command(等待命令)和Waiting for text(等待文本)。

事件Load file(装载文件)、Insert text(插入文本)、Insert character(插入字符)和Save and quit(保存并退出)导致了状态机中的转移。

下面的图6.3描绘了编辑器的状态机。

图6.3 编辑器的状态机状态机最多地用于建立对象在其生命期内的行为模型。

当对象具有依赖于状态的行为时,尤其需要使用状态机。

可能具有状态机的对象包括:类、子系统、用例、接口(以声明实现该接口的对象必须满足的状态)和协议(以声明实现该协议的对象必须满足的状态)。

并非所有对象都需要有状态机。

如果对象的行为很简单,只是存储或检索数据,那么该对象的行为就与状态无关,它的状态机也没有多少用处。

2、整数四则运算计算器的状态图设计仔细分析计算器的状态变化,可以发现,计算器整体上有四个状态组成:接受第1个操作数、接受第2个操作数、输出计算机结果和出错。

而接受第1或第2个操作数的状态中又包含了接受数字的状态和接受+、-、×、/、=五种运算符状态两种情况,把这些状态表达成状态图,如图6.4到6.6所示。

图6.4 整数四则运算计算器的顶层状态图以上状态图描述了这样一个可循环的过程:首先系统进入输入第一个操作数的状态,如果此时继续输入数字,则系统保持当前状态,直到输入运算符,接收第一个操作数的状态结束,进入下一个状态——接收第二个操作数,这一状态也一直保持到输入一个运算符时结束,这时,运算符不一定是“=”号,也可以是+、-、×、/中的一个,无论是哪一个运算符,程序都先计算出结果并显示。

接下去,如果用户输入+、-、×、/中的一个运算符,则把前一次运算的结果作为第一个操作数,开始下一轮计算;如果用户输入数字,则将前一次运算的结果丢弃,开始新一轮的计算。

输入或运算中出现溢出或其它错误,则系统进入“ERROR”状态。

以上描述的是顶层的状态图,它还需要进行一些细化,主要是在接收第一个或第二个操作数的过程中接收的是操作数中的第一个数字还是第一个以后的数字,程序的处理会有所不同,因为如果是第一个数字,直接显示就行,但如果是第一个以后的数字,则应该跟在前面的数字后面显示,所以还应该把上图中接收操作数的两个状态进一步分解。

图6.5 初始/接受第一个操作数的分解子状态图图6.6 接受第二个操作数的分解子状态图状态图很清楚地说明了计算器的状态以及触发状态改变的事件,结合本章学习的方法的相关知识,编写计算器程序有了一个比较清楚的思路:首先可以编写一个方法InitMembers(),对计算器的状态进行初始化,另外编写两个方法Numbers_Click()和Operators_Click():前者用来处理接收到数字时计算器所做的工作,后者用来处理接收到运算符时,程序应当做出的正确反映,而具体接到的是哪一个数字或运算符可以考虑采用按钮的单击事件,通过参数传递给上述的两个方法。

此外,通过状态图还可以分析出当输入第1个操作数时,必须判断一下输入的是一个数字还有第1个以后的数字,所以程序中需要定义一个bool类型的变量bNumBegins,其初值为true,当输入一个数字之后就将它置为false,直到计算出结果后再置为true,准备进行下一轮的计算。

这里,有一点必须特别给予说明,由于该计算器的功能是比较简单的,所以暂时不考输入操作数是负数和情况。

6.1.4工作任务二:设计程序模块的流程图1.知识准备——方法方法(method)又常称为函数(function),是实现可以由对象或类执行的计算或操作。

一般而言,可以把一个程序中多次用到的某个任务,如常用的计算定义为方法,以便反复调用。

在前面的章节中曾经应用过的MessageBox类的Show、Math的Pow都是方法,方法是类的成员。

1)实例方法和静态方法C#的方法有实例方法和静态方法之分。

所谓的实例方法是指通过对象名调用的方法,也是本章应用到的方法。

静态方法与类关联,而不是与对象关联,定义静态方法时要使用static关键字,访问静态方法时要使用类名,而不是对象名。

2)方法定义的格式实例方法定义的格式化为:修饰符返回类型方法名(形参列表){声明和语句}静态方法定义的格式为:修饰符static 返回类型方法名(形参列表){声明和语句}其中“返回类型”指定该方法返回的值的类型。

如果方法无返回值,则返回类型为void;“方法名”是一个有效的标识符;“形参列表”中的“形参”是“形式参数”的简称,“形参列表”是一个可选项,指定方法的参数,如果有多个参数,可以用逗号分隔,每个参数与声明变量的方法一样,都是指定数据类型和参数名。

即使没有参数,括号也不能省略。

方法返回类型如果不是 void,则方法可以使用 return 关键字来返回值,如果语句中return 关键字的后面是与返回类型匹配的值,则该语句将该值返回给方法调用方。

return 关键字还会停止方法的执行。

如果返回类型为 void,则可使用没有值的 return 语句来停止方法的执行。

如果没有 return 关键字,方法执行到代码块末尾时即会停止。

具有非 void 返回类型的方法才能使用 return 关键字返回值。

2.整数四则运算计算器的程序流程图程序思路的大体框架基本清楚后,我们可以来构建计算器及其主要方法的流程图,以便根据流程图写出程序代码。

程序总流程图如图6.7所示。

图6.7 整数计算器程序总流程图图6.8 Numbers_Click()方法的流程图图6.9 Operators_Click()方法的流程图上述Operators_Click()方法的流程图在理解上会比较困难。

首先我们要考虑清楚,当新一轮计算开始时,第一次输入一个运算符(+、-、×、/中的一个),程序是不能进行计算的,因为此时只有一个操作数,只有当输入第二个操作数之后,第二次输入一个运算符(+、-、×、/或者=),才能进行四则运算,所以在Operators_Click()方法中对运算符的处理应当推迟一步,也就是说,本次输入的运算符应该保存起来(流程图中保存在cOperator中),而程序当前处理的是前一次输入的运算符,之后把运算的结果存入第一个操作数,以便开始新一轮的计算。

这里还有一个小问题,既然对运算符的处理是推迟一步进行的,那么在程序初始化的时候,应给运算符赋一个初值,作为第一个运算符的前一个运算符,那么初值应当是什么呢?试想,程序最开始时,用户输入一个操作数和一个运算符(+、-、×、/中的一个),由于此时不进行加、减、乘、除的四则计算,程序所做的工作只是保存运算符,并将输入的数放入存放第一操作数的变量中,所以初值不能是+、-、×、/中的一个,而只能是“=”。

6.1.5工作任务三:设计界面完成窗体及控件的属性设置首先创建一个Windows应用程序,命名为Cacle1,在窗体上添加一个文本框控件和15个按钮控件,设计程序界面如图6.10所示,图6.10 程序界面设计窗体、控件及相关属性如表6.1所示。

表6.1 控件属性表6.1.6工作任务四:编写程序代码在编写代码之前我们再来考虑一个问题,我们开发的这个计算器,用鼠标点单击各按钮时,触发了按钮的Click事件,通过编写按钮的单击事件我们可以实现数字或运算符的输入,但是为了提高输入的速度,许多人喜欢使用键盘进行操作,那么我们的计算器可不可以用键盘来操作呢,答案是肯定的,但我们需要为编写增加相关的键盘事件。

1.知识准备——键盘事件当用户按键盘键时,Windows 窗体提供两个事件,而当用户松开键盘键时,Windows 窗体提供一个事件。

1)KeyDown 事件发生一次;2)KeyPress事件,当用户按住同一个键时,该事件可以发生多次;3)当用户松开键时,KeyUp 事件发生一次。

我们用下表对三个事件进行说明:表6.2 键盘事件说明Windows 窗体将键盘输入标识为由按位 Keys 枚举表示的虚拟键代码。

使用 Keys 枚举,可以综合一系列按键以生成单个值。

可通过处理 KeyDown 或 KeyUp 事件来检测大多数物理按键操作。

如果通过组合按键得到一个字符,则可以通过处理 KeyPress 事件来检测该字符。

Keys枚举类包含用于处理键盘输入的常数。

键由键值标识,键值是由键代码和一组修饰符共同组成的一个整数值。

键值的左边四个数字包含键代码(与 Windows 虚拟键代码一样)。

键值的右边四个数字包含 SHIFT、CONTROL 和 ALT 键的修饰符位。

这里我们举例小部分Keys成员,供大家参考,如表6.3所示:表6.3 Keys枚举类部分成员在本项目中,我们采用文本框的key_Down事件,接收来自数字键盘的事件,其它的键盘事件有兴趣的读者可以自己添加。

相关主题