数据结构课程设计(简单计算器C语言).doc

上传人:xin****828 文档编号:6705467 上传时间:2020-03-02 格式:DOC 页数:27 大小:215KB
返回 下载 相关 举报
数据结构课程设计(简单计算器C语言).doc_第1页
第1页 / 共27页
数据结构课程设计(简单计算器C语言).doc_第2页
第2页 / 共27页
数据结构课程设计(简单计算器C语言).doc_第3页
第3页 / 共27页
点击查看更多>>
资源描述
郑州师范学院信息科学与技术学院 简单计算器课程设计报告设计题目: 简单计算器 班 级: B15计科二班 组 长: 组 员: 指导教师: 完成日期: 2016 年 12 月 23 日 成绩: 摘 要本次选做的课程设计是实现简单计算器的问题。计算器是一个常用的运算工具,本次课题要求用程序语言的方式解决问题。此问题仅使用数据结构中的栈操作就可以解决此问题。而在为了方便使用,添加了easyx图形库实现了UI设计。为了接近平常使用的计算器,特地创建死循环而且添加了“CE”清空输入和“-”删除键来控制输入错误或者循环使用的问题。在UI方面主要是实现按键和点击响应等交互,方便输入和修改,在程序框上面有输入和显示结果的文本框。在计算过程中,以栈出栈进站的特性把中缀形式的算数表达式转化为计算机方便计算的后缀表达式,最后计算出结果以文本方式显示在结果输出框内。 目 录摘 要I目 录II1需求分析31.1功能简介及分析31.2设计平台32概要设计32.1 Trans函数32.2 Compvalue 函数42.3 GetKey函数43详细设计和实现43.1转化为逆波兰式43.2计算逆波兰式63.3实现流程图73.3部分具体程序84调试与操作说明134.1调试情况134.2操作说明145设计总结15参考文献161需求分析1.1功能简介及分析本次选做的课程设计是实现简单的计算器并且添加UI的交互。此计算器是以软件的形式实现的计算器,运行在windows系统。计算器在功能上分为三类,分别是:常见计算器,专用计算器,综合功能计算器。常见的计算器又分为四种: 简单型计算器:只实现基本的加减乘除和括号运算。 科学型计算器:可以进行乘方、开方、指数、对数、三角函数、统计等方面的运算,又称函数计算器。 程序员计算器:专门为程序员设计的计算器, 主要特点是支持And, Or, Not, Xor: 最基本的与或非和异或操作, 移位操作 Lsh, Rsh:全称是Left Shift和Right Shift,也就是左移和右移操作,你需要输入你要移动的位数(不能大于最大位数) RoL, RoR:全称是Rotate Left和Rotate Right,对于RoL来讲,就是向左移动一位,并将移出的那位补到最右边那位上,RoR类似。 统计型计算器:为有统计要求的人员设计的设计的计算器。本次课程设计只是实现了常见的简单计算器:在界面上:简单的计算器需要有简单的按键和按键响应,有输入和结果的显示。在功能上:能进行加减乘除混合运算,可以使用括号,有“M”键可以存储结果,以便下次计算使用,可以对输入的文本删除和重置。并且可以在重置后继续使用。1.2设计平台Windows7操作系统;Visual Studio 20152概要设计2.1 Trans函数主要功能中缀算术表达式转化成后缀表达式,然后存到栈里,以便计算时使用,转化时包括对小括号的匹配。2.2 Compvalue 函数主要功能是对栈中的后缀表达式进行计算,然后返回float类型的结果。2.3 GetKey函数GetKey主要是在UI界面中获取按键然后保存成字符数组或者对字符数组的增减操作的函数。此函数为内置死循环,可以重复使用。3详细设计和实现实现软件形式的常用简单计算机,主要用到栈的特点,把平常使用的表达式,转化为能够让计算机计算的逆波兰表达式。中缀表达式(或中缀记法)是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。与前缀表达式(例:+ 3 4)或后缀表达式(例:3 4 +)相比,中缀表达式不容易被计算机解析,但仍被许多程序语言使用,因为它符合人们的普遍用法。与前缀或后缀记法不同的是,中缀记法中括号是必需的。计算过程中必须用括号将操作符和对应的操作数括起来,用于指示运算的次序。例:(1)8+4-6*2用后缀表达式表示为:62*84+-(2)2*(3+5)-4+7/1用后缀表达式表示为:35+2*71/4-+3.1转化为逆波兰式首先需要分配2个栈,一个作为临时存储运算符的栈S1(含一个结束符号),一个作为输入逆波兰式的栈S2(空栈),S1栈可先放入优先级最低的运算符#,注意,中缀式应以此最低优先级的运算符结束。可指定其他字符,不一定非#不可。从中缀式的左端开始取字符,逐序进行如下步骤:(1)若取出的字符是操作数,则分析出完整的运算数,该操作数直接送入S2栈(2)若取出的字符是运算符,则将该运算符与S1栈栈顶元素比较,如果该运算符优先级大于S1栈栈顶运算符优先级,则将该运算符进S1栈,否则,将S1栈的栈顶运算符弹出,送入S2栈中,直至S1栈栈顶运算符低于(不包括等于)该运算符优先级,则将该运算符送入S1栈。(3)若取出的字符是“(”,则直接送入S1栈底。(4)若取出的字符是“)”,则将距离S1栈栈底最近的“(”之间的运算符,逐个出栈,依次送入S2栈,此时抛弃“(”。(5)重复上面的14步,直至处理完所有的输入字符。(6)若取出的字符是“#”,则将S1栈内所有运算符(不包括“#”),逐个出栈,依次送入S2栈。完成以上步骤,S2栈便为逆波兰式输出结果。不过S2应做一下逆序处理。便可以按照逆波兰式的计算方法计算了!例如转换:2-(1+2)*3+4转换后的逆波兰表达式是:2 1 2 + 3 * - 4 +3.2计算逆波兰式逆波兰式的计算同样用到了栈的特点,首先需要建立一个空栈T,然后从头遍历逆波兰式,如果是数字则直接放到栈顶,如果遇到操作符则连续取出两个栈顶数据,分别赋值给n1,n2,再根据操作符计算n1和n2,把得到的结果放到T栈栈顶,继续操作,直到遍历完毕。以上面的例子计算过程如图:最后得出的结果是-3,即2-(1+2)*3+4=-3;所以计算的具体过程是先转化中缀表达式为逆波兰表达式,然后由逆波兰表达式计算出结果,在转化的过程和最后的计算过程都用到了栈的思想,利用栈的进栈和出栈的特点实现转换。3.3实现流程图开始通过界面按键获得输入内容转换为逆波兰式结束保存输入内容到字符数组继续输入对字符数组里的数字字符进行转义成数据型计算并显示出结果是否继续使用?否清空显示是简单运行流程图3.3部分具体程序/界面显示文字,”$”表示结束位置char KeyStr4 = CE , Stri;/用于保存数组里的临时元素i+;int LastStrPos = 1, StackTop = 0;/StackTop用于表示栈顶while (ChStr != #)switch (ChStr)case(:/*判定为左括号*/StackTop+; StackStackTop = ChStr;break;case):/*判定为右括号*/while (StackStackTop != ()LastsLastStrPos = StackStackTop; StackTop-; LastStrPos+;StackTop-;/扔掉(break;case+:/*判定为加减号*/case-:while (StackTop != 0 & StackStackTop != ()LastsLastStrPos = StackStackTop;StackTop-;LastStrPos+;StackTop+;/保留(StackStackTop = ChStr;break;case*:/*判定为乘除号*/case/:while (StackStackTop = * | StackStackTop = /)LastsLastStrPos = StackStackTop;/如果栈顶是*或者/弹出,放到后缀数组里StackTop-;LastStrPos+;StackTop+;StackStackTop = ChStr;break;case :break;/忽略空格default:while (ChStr = 0 & ChStr Stri;i+;i-;LastsLastStrPos = ;/输出的时候隔开元素LastStrPos+;ChStr = InStr-Stri; i+;while (StackTop != 0)LastsLastStrPos = StackStackTop;LastStrPos+; StackTop-;LastsLastStrPos = ;LastStrPosT = LastStrPos;float Compvalue(char LastStrTemp)/*计算后缀表达式的值*/float StackMAX;/*作为栈使用*/char ChStr;/临时栈元素int StackTop = 0;/*LastStrPos为Lasts下标,StackTop为Stack下标*/int LastStrPos = 1;ChStr = LastStrTempLastStrPos;LastStrPos+;while (ChStr != )switch (ChStr)case+:StackStackTop - 1 = StackStackTop - 1 + StackStackTop;StackTop-;break;case-:StackStackTop - 1 = StackStackTop - 1 - StackStackTop;StackTop-;break;case*:StackStackTop - 1 = StackStackTop - 1 * StackStackTop;StackTop-;break;case/:if (StackStackTop != 0)StackStackTop - 1 = StackStackTop - 1 / StackStackTop;elseexit(0);/*异常退出*/StackTop-;break;default:float NumStr = 0;/把数字字符转化为数字bool FlNum = 0;while (ChStr = 0 & ChStr 0)/判断是否有输入的字符GetStrInCon - 1 = 0;putimage(1, 1, &ClearImgUp);InCon-;PrintStr();break;case 3:strcat_s(GetStr, M_Str);InCon+;PrintStr();break;case 24:settextstyle(50, 0, _T(Prestige Elite Std);/设置字体大小,宽度,文字样式putimage(1, WINKEYY * 2 / 3, &ClearImgDown);GiveStr(GetStr, TheLastStr);drawtext(_T(TheLastStr), &r, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);break;case 7:case 8:break;default:strcat_s(GetStr, KeyStrtemp - 1);InCon+;PrintStr();Sleep(50);break;case WM_RBUTTONDOWN:setlinecolor(BLUE);rectangle(Postemp.x0, Postemp.y0, Postemp.x1, Postemp.y1);switch (temp) case 3:strcpy(M_Str, TheLastStr);break;break;setlinecolor(BLACK);rectangle(PosProPos.x0, PosProPos.y0, PosProPos.x1, PosProPos.y1);if (temp != 0) setlinecolor(RED);rectangle(Postemp.x0, Postemp.y0, Postemp.x1, Postemp.y1);ProPos = temp;4调试与操作说明4.1调试情况这次的课程设计的代码很冗长,在实现整个思路之后难免会有很多错误。编写代码过程中遇到很多错误和难题。不过经过一点点的改正和攻克,错误也慢慢地变少,难题也逐个解开。在计算机领域代码无论在逻辑上还是在编写上都不允许有一点错误,因为一点的错误就会使整个程序崩溃,有时即便能够成功运行,得出的结果也有可能和预期的结果千差万别,但是也是因为这样的严谨编写和工作学习中,使得调试或者编写代码的人逐渐培养出了有耐心,有毅力,并且严谨细心的心境。一般在编写代码过程留下的逻辑错误或者编写错误都会在调试的时候遇到,这个时候就体现出了调试的重要性。调试可以使程序的可运行性、健壮性、效率性上大幅度提高。本程序在调试中遇到了很多问题,如计算结果的准确性、显示结果的准确性或者显示位置等等。本程序还存在的问题是对计算的精确度支持低,只支持两位小数点,并且在应对错误计算或者错误输入没有进行匹配,这些问题都会在使用的过程中可能造成程序的崩溃,但是这些问题都会在以后的设计中进行完善和增强。4.2操作说明生成界面如图所示:生成界面当程序运行的时候会出现如上图所示,要求使用者通过按键输入运算表达式,使用者只需点击输入想要计算的表达式,最后点击“=”键后,系统便会计算出结果并且显示出来。然后可以点击“-”键删除修改表达式,或者通过“CE”键清空表达式和显示的结果,当然也可以通过点击“M”键暂时保存当前计算的结果,以便于下次计算使用(右键M把当前结果存到M中,默认是0,左键M输入当前M内的值)。5设计总结本次课程设计大概花费了两周的时间,其中10天左右用来编写和调试程序代码,4天左右用来对程序编写报告。在此之间,遇到了许多编写上的难题和遇到错误的抓狂,但是这些都在耐心的,一次一次的调试中解决和攻克。当再次总结后感觉收获很大,首先在编写代码上,增加自己的代码量,提高了编写的熟练度。其次增加了对栈的使用和理解,也有了一些在使用栈的方法和经验。然后是对界面设计的认识,如按键反馈、按键响应速度、颜色的搭配、字体的格式等等。最后是对在修改和调试代码的经验,代码调试的过程是最辛苦的但也是最能体现编写代码能力的地方,看一个人代码编写能力怎么样,不是说让实现一个功能,而是在拿到一个存在诸多BUG时能一步步解决这些问题。当然,在编写这个报告时,程序可能还是存在一些错误没被发现,这些都需要在后继的补充完善中慢慢发现和更正,还有是本程序功能少,只是实现了常用的简单计算器,对于和科学计算器或者程序员计算器等功能都为涉及,这些也将会成为我在后续的设计中一点点添加上去,因为我相信,每一个复杂的庞大的系统或者程序都是在简单的基础上一点点完善的。也希望我能在后续的开发设计中能学习更多,收获更多,并且能一直坚持下去。参考文献1 栾大成. 大话数据结构M. 北京清华大学学研大厦A座:清华大学出版社, 2011. 1-433 2 甘勇, 李晔, 卢冰. C语言课程设计M. 北京市西城区右安门西街8号:中国铁道出版社, 2014. 1-3403 严蔚敏,吴伟民. 数据结构M. 北京清华大学学研大厦A座:清华大学出版社, 2007. 1-3344 张宏林,孔艳,王哲等编著按实例学Microsoft Visual Studio 2005 6.0M.北京:人民邮电出版社,20005 Brian W Kernighan , Dennis M Ritchie. The C Programming LanguageM. Pubilished:Prentice-Hall , 2004.6 陈朔鹰, 陈英. C语言趣味程序百例精解M. 北京理工大学:北京理工大学出版社, 1996. 1-4357 谭浩强. C 程序设计(第二版)M. 清华大学:清华大学出版社, 2014. 1-3508 谭浩强. C 语言程序设计题解与上机指导M. 清华大学:清华大学出版社, 2014. 1-2459 白中英, 戴志涛. 计算机组成原理M. 北京东黄城根北街16号:科学出版社, 2013. 1-350全部代码如下:VS2015调试通过(未加入错误检测)使用C11新标准/* 数据结构期末课程设计 * 作业名称:多项式计算器 * 使用的数据结构:栈 * UI:使用easyx实现 */#include #include #include #include #include / 就是需要引用这个图形库#include #define WINSIZEX 401/窗口大小#define WINSIZEY 471#define WINKEYY (WINSIZEY - 1) / 8/行间距#define WINKEYX (WINSIZEX - 1) / 4#define MAX 100#define TRUE 1#pragma warning(disable:4996) typedef struct char StrMAX;/*存储原算术表达式*/int Long;STR;struct int x2;/对象的左上坐标x和右下坐标x,x0表示坐上x、x1表示右下xint y2;/同上Pos25;char KeyStr4 = CE , Stri;/用于保存数组里的临时元素i+;int LastStrPos = 1, StackTop = 0;/StackTop用于表示栈顶while (ChStr != #)switch (ChStr)case(:/*判定为左括号*/StackTop+; StackStackTop = ChStr;break;case):/*判定为右括号*/while (StackStackTop != ()LastStrLastStrPos = StackStackTop; StackTop-; LastStrPos+;StackTop-;/扔掉(break;case+:/*判定为加减号*/case-:while (StackTop != 0 & StackStackTop != ()LastStrLastStrPos = StackStackTop;StackTop-;LastStrPos+;StackTop+;/保留(StackStackTop = ChStr;break;case*:/*判定为乘除号*/case/:while (StackStackTop = * | StackStackTop = /)LastStrLastStrPos = StackStackTop;/如果栈顶是*或者/弹出,放到后缀数组里StackTop-;LastStrPos+;StackTop+;StackStackTop = ChStr;break;case :break;/忽略空格default:while (ChStr = 0 & ChStr Stri;i+;i-;LastStrLastStrPos = ;/输出的时候隔开元素LastStrPos+;ChStr = InStr-Stri; i+;while (StackTop != 0)LastStrLastStrPos = StackStackTop;LastStrPos+; StackTop-;LastStrLastStrPos = ;LastStrPosT = LastStrPos;float Compvalue(char LastStrTemp)/*计算后缀表达式的值*/float StackMAX;/*作为栈使用*/char ChStr;/临时栈元素int StackTop = 0;/*LastStrPos为LastStr下标,StackTop为Stack下标*/int LastStrPos = 1;ChStr = LastStrTempLastStrPos;LastStrPos+;while (ChStr != )switch (ChStr)case+:StackStackTop - 1 = StackStackTop - 1 + StackStackTop;StackTop-;break;case-:StackStackTop - 1 = StackStackTop - 1 - StackStackTop;StackTop-;break;case*:StackStackTop - 1 = StackStackTop - 1 * StackStackTop;StackTop-;break;case/:if (StackStackTop != 0)StackStackTop - 1 = StackStackTop - 1 / StackStackTop;elseexit(0);/*异常退出*/StackTop-;break;default:float NumStr = 0;/把数字字符转化为数字bool FlNum = 0;while (ChStr = 0 & ChStr = 9 | ChStr = .)if (ChStr = .) FlNum = 1;else if (!FlNum) NumStr = 10 * NumStr + ChStr - 0;/*将数字字符转化为对应的数值*/else if (FlNum) NumStr += 0.1 * (ChStr - 0);/*计算小数*/ChStr = LastStrTempLastStrPos;LastStrPos+;StackTop+;StackStackTop = NumStr;ChStr = LastStrTempLastStrPos;LastStrPos+;return StackStackTop;void GiveStr(char GetString , char *TheStr) STR InStr;char LastStrMAX;/*存储后缀表达式*/InStr.Long = 0;for (int i = 0; GetStringi != 0; i+) InStr.Long+;InStr.StrInStr.Long = GetStringi;InStr.Long+;InStr.StrInStr.Long = #;Trans(&InStr, LastStr);LastV = Compvalue(LastStr);LastV = (int)LastV ? sprintf(TheStr , %.0f , LastV) : sprintf(TheStr, %.2f, LastV);void InitPos() Pos0.x0 = 0; Pos0.y0 = 0; Pos0.x1 = WINSIZEX; Pos0.y1 = WINKEYY * 2;int k = 1;for (int i = 2; i 8; i+) for (int j = 0; j 0 & x 0 & y WINKEYY * 2)/判断文本输出框return 0;for (int i = 1; i = Posi.x0 & x = Posi.x1) for (int j = i; j = Posj.y0 & y 0)/判断是否有输入的字符GetStrInCon - 1 = 0;putimage(1, 1, &ClearImgUp);InCon-;PrintStr();break;case 3:strcat_s(GetStr, M_Str);InCon+;PrintStr();break;case 24:settextstyle(50, 0, _T(Prestige Elite Std);/设置字体大小,宽度,文字样式putimage(1, WINKEYY * 2 / 3, &ClearImgDown);GiveStr(GetStr, TheLastStr);drawtext(_T(TheLastStr), &r, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);break;case 7:case 8:break;default:strcat_s(GetStr, KeyStrtemp - 1);InCon+;PrintStr();Sleep(50);break;case WM_RBUTTONDOWN:setlinecolor(BLUE);rectangle(Postemp.x0, Postemp.y0, Postemp.x1, Postemp.y1);switch (temp) case 3:strcpy(M_Str, TheLastStr);break;break;setlinecolor(BLACK);rectangle(PosProPos.x0, PosProPos.y0, PosProPos.x1, PosProPos.y1);if (temp != 0) setlinecolor(RED);rectangle(Postemp.x0, Postemp.y0, Postemp.x1, Postemp.y1);ProPos = temp;/输出按键文字void DrawTe() LOGFONT f;settextcolor(RGB(20, 20, 20);/设置字体颜色settextstyle(30, 0, _T(Prestige Elite Std);/设置字体大小,宽度,文字样式setbkmode(TRANSPARENT);/设置输出背景为透明色gettextstyle(&f); / 获取当前字体设置 / f.lfHeight = 48; / 设置文字高度为48 / _tcscpy(f.lfFaceName, _T(黑体); / 设置字体为“黑体”f.lfQuality = ANTIALIASED_QUALITY; / 设置输出效果为抗锯齿 settextstyle(&f); / 设置字体样式for (int i = 0, j = 0; strcmp(KeyStri, $); i+) /循环输出字符数组里的文字if (i % 4 = 0 & i != 0) j+;outtextxy(WINKEYX / 2.5 + (i % 4) * WINKEYX, WINKEYY * (2 + j) + WINKEYY / 3, _T(KeyStri);/输出按键文字/绘制按键方块void DrawWindow() setfillcolor(RGB(230, 230, 230);solidrectangle(0, 0, WINSIZEX, WINKEYY * 2);/绘制背景区域setfillcolor(RGB(120, 120, 120);solidrectangle(0, WINKEYY * 2, WINSIZEX, WINSIZEY);/绘制操作区域setfillcolor(RGB(100, 100, 100);solidrectangle(WINKEYX * 3, WINKEYY * 3, WINKEYX * 4 , WINSIZEY);/绘制操作区域solidrectangle(0, WINKEYY * 2, WINSIZEX, WINKEYY * 3);/绘制操作区域setlinecolor(RGB(0, 0, 0);for (int i = 2; i = 8; i+) line(0, i * WINKEYY, WINSIZEX, i * WINKEYY);/画横线line(i - 2) * WINKEYX, WINKEYY * 2, (i - 2) * WINKEYX, WINSIZEY);/画竖线line(0, WINKEYY * 2 / 3, WINSIZEX , WINKEYY * 2 / 3);int main()initgraph(WINSIZEX, WINSIZEY); / 创建一个500*600的窗口DrawWindow();DrawTe();InitPos();GetKey();closegraph(); / 关闭图形库 return 0;
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 中学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!