1、 第 1 页 共 33 页安徽新华学院数据结构课程设计报告题目: 模拟计算器程序 学院: 信息工程学院 专业: 信息与计算科学 班级: 12 级信息与计算科学一班 姓名: 孙伟伟 学号: 1242155116 指导教师: 李明 设计时间: 2013.12.162013.12.31 第 2 页 共 33 页课程设计任务书一、设计任务设计一个模拟计算器的程序二、设计要求1、 要求对包含加、减、乘、除、括号运算符及 SQR 和 ABS 函数的任意整型表达式进行求解2、程序基本功能要求实现完整,并有简单的验证。3、设计报告要求格式规范,符合学校课程设计报告要求。4、报告中流程图要求描述规范,算法设计清
2、楚正确。 三、设计期限2013 年 12 月 16 日到 2013 年 12 月 31 日第 3 页 共 33 页前言利用本学期所学的C 语言程序设计课程,运用相关知识,查阅相关资料,编写 C语言程序,设计一个简单计算器,要求编写的简单计算器能够模拟 windows 系统的计算器,用户能够用键盘输入相关数据,要求对包含加、减、乘、除、括号运算符及 SQR 和 ABS 函数的任意整型表达式进行求解,并且在程序运行过程中能够正常的退出程序。这个程序实际上就是对一个表达式进行计算。而一个算术表达式中包含各种运算符,每个运算符的等级可能会不同,这就成了本程序需要解决的一个主要的问题之一了。另外计算器中
3、需要有各种数学函数,比如:abs sqrt sin cos tan 等,如何对这些函数进行处理,也是本程序能成功的一个关键。还有一个问题就是如何处理操作符和操作数之间的关系也是一个要点。例如:1+2*(3-2/1),经过怎么样的变换和处理能得出结果。数据的输入这里应该要用字符,然后通过字符和整形之间的关系进行转换即可,这样处理的话,就方便很多了。在计算器程序运行中,输入数据时如果遇到输入错误的情况,能够能过键盘上的退格键进行删除,并且重新输入正确的数据。在数据输入完成后,如果需要放弃本次计算操作,可以利用程序中设置好的按键进行清零,并为下一次运算作准备。本课程设计主要解决的是传统计算器中,不能
4、对表达式进行运算的问题,通过制作该计算器模拟程序,可以做到快速的求解表达式的值,并且能够判定用户输入的表达式是否合法。该模拟计算器的核心部分就在用户输入的中缀表达式的转化,程序中用到了“栈”的后进先出的基本性质。第 4 页 共 33 页目录第 1章 需求分析 51.1 系统设计流程图 5 1.2 主要功能表 6第 2章 总体设计 72.1 数据结构的选择 72.2 程序实现流程图 8第 3章 详细设计和编码 93.1 表达式的判断 103.2 栈的定义及存储 113.3 表达式的嵌套处理 143.4 中缀表达式转化为后缀表达式 14第 4 章 编码与调试 174.1 系统测试 174.2 调试
5、 174.3 错误原因分析 174.4 调试结果 19第 5 章 总结 21第 5 页 共 33 页参考文献 22 附录 23第 1 章 需求分析1.1 系统流程图本课程设计主要解决的是传统计算器中,不能对表达式进行运算的问题,通过制作该计算器模拟程序,可以做到快速的求解表达式的值,并且能够判定用户输入的表达式是否合法。该模拟计算器的核心部分就在用户输入的中缀表达式的转 化 , 程 序 中 用 到 了 “栈 ”的 后 进 先 出 的 基 本 性 质 。 利 用 两 个 “栈 ”,一个“数据栈 ”, 一 个 “运 算 符 栈 ”来 把 中缀 表 达 式 转 换 成 后 缀 表 达 式 。 最 后
6、 利 用 后 缀 表 达 式 来 求 解 表 达 式 的 值 。 该 算 法 的 复杂 度 为 O(n), 能 够 高 效 、 快 速 地 求 解 表 达 式的值,提高用户的效率。本次课程设计为计算器模拟程序,主要解决表达式计算的问题,实现分别按表达式处理的过程分解为几个子过程,详细的求解过程如下:1 、用户输入表达式。2 、判定表达式是否合法。3 、把中缀表达式转化为后缀表达式。4 、求出后缀表达式的结果。5 、输出表达式的结果。通过设计该程序,从而做到方便的求出一个表达式的值,而不需要一步一步进行运算。第 6 页 共 33 页输入第一个操作数加法减法乘法除法清零ABSSQRT显示结果输入第
7、二个操作数结束开始1.1 系统设计流程图1.2 主要功能表序号 文件名 主要功能 备注1 + 加法 两个操作数2 - 减法 两个操作数3 * 乘法 两个操作数4 / 除法 两个操作数5 aqrt 开方 一个操作数第 7 页 共 33 页6 abs 绝对值 一个操作数7 Enter 等于8 Tab 清零9 0 退出除了实现基本的功能外,我还增加了其它一些功能,比如支持输入数据为浮点数,更重要的是本程序还支持表达式的嵌套运算,例如:A(1+2*S(2)我的实现方法是利用函数的递归调用来解决此问题,即把 1+2*S(2)看成一个子表达式,这个子表达式中 2 也看成子表达式。这样使得程序的适用范围更加
8、的广泛,适应性更强,能支持更复杂的表达式的运算。这也是本程序的优点之一。第 2 章 总体设计2.1 数据结构选择输入的时候将一个算术表达式用一个字符数组来接收,故需要对这个数组进行处理,让操作数和操作符分开,这里我想把开始的算术表达式转换成一个后缀表达式,这样在进行计算的时候就简单多了。而在转换的过程中,对运算符的处理极为重要,这里运用堆栈,用堆栈的先进后出的特点,来处理运算符优先级的问题,让其成功转换成后缀表达式。而在对后缀表达式进行处理的时候,又需要一个堆栈,这个堆栈存放操作数的。并将运算结果存入该栈中。两个堆栈的数据结构如下:第 8 页 共 33 页struct char dataMax
9、len; int top; optr; /定义运算符栈struct double dataMaxlen; int top; opnd; /定义操作数栈这里定义了类型,并且一起定义了两者类型的对象 optr,opnd。在将算术表达式转换成后缀表达式,定义 change 函数;在对后缀表达式进行处理时,定义 jisuan 函数,另外本程序有个欢迎界面,由 meun 函数实现。因此主函数于各函数之间的关系为:meun()main() change()jisuan() 2.2 程序实现流程图第 9 页 共 33 页2.2 程序设计流程图这里的两个主要的函数具体算法在详细设计中有说明本课程设计需要考虑许
10、多的问题,首先是表达式的合法判断,然后是字符串表达式提取分离的问题,核心部分就是中缀表达式转化为后缀表达式。对于第一个问题,我是分步来判断,首先表达式中是否含有其它非法字符,然后判断括号是否合法,接着判断运算法两边是否合法比如除法时,除数不能为零。对于第二个问题,我是直接转换的,从左到右第 10 页 共 33 页遍历中缀表达式,把数据全部取出来。对于核心问题,利用了“栈”这种“后进先出”的数据结构,利用两个“栈” ,一个“数据栈” ,一个“运算符栈”来把中缀表达式转换成后缀表达式。最后利用后缀表达式来求解表达式的值。本程序用户界面总共分为 3 个模块,分别是操作提示,数据输入,数据输出。如图2
11、.3 所示。2.3 用户界面第 3 章 详细设计和编码第 11 页 共 33 页3.1 表达式的判断表达式的合法判定过程如图 3.1 所示首先是其它字符的判定,从左到右遍历中缀表达式,看是否存在其它非法的。然后是判定括号是否的匹配是否和合法,首先把“(”对应为 1,相应的“)”对应为-1。从左到右遍历表达式,如果遇到括号就加上其对应的值,用 sum 来保存其累加值。如果在中途出现小于零的情况,即出现“. )”那么的情况,即非法。在遍历的最后,还要判断 sum 的值是否为零,如果为零就是合法,否则就是非法。代码如下:for(i=0;i=0 if (strcmp(p,“0“)=0)return;if (change(p,q)=1) k=jisuan(q);if(k=derror)cout=0 else coutendl“开方内的数不能小于零!“endl;return derror;break;case e:opnd.dataopnd.top=exp(opnd.dataopnd.top);break;