版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、目录一、 需要分析21) 课题要求22) 课题分析23) 实现功能步骤24) 承担模块工作详解25) 运行环境2二、 概要设计31) 系统流程图32) 提示输入模块43) 表达式正误判断模块44) 中缀表达式转为后缀表达式模块45) 后缀表达式计算模块4三、 详细设计41) main函数模块42) 提示输入模块53) 表达式正误判断64) 中缀表达式转为后缀表达式75) 后缀表达式的计算9四、 调试分析141) 调试过程中遇到的问题和解决方法142) 经验和体会14五、 用户使用说明14六、 测试结果15七、 参考文献17八、 附录18图表目录图表 1 .1 输入提示15图表 2 .1 输入选
2、择错误15图表 3 .1 正常表达式计算16图表 4 .1表达式错误提示171、 需要分析 1) 课题要求表达式计算(难度:B)要求:输入一个表达式,输出其结果。表达式由数字、运算符(+ - * / ( ) )常用数学函数组成。例如,输入 3*(sqrt(64)+(4/3),输出28。此外,如果输入的是错误的表达式,则提示错误。例如:2+*3则输出:表达式输入错误。2) 课题分析根据课题要求应该做到以下几点:1 提示输入,输出提示内容。包括数的类型(浮点型),运算符种类(+、-、*、/), 函数的种 类(sqrt(x)、log(x)、fabs(x)、sin(x)、cos(x)、tan(x))。
3、2 主函数中设置计算循环,实现可以运算多个表达式,并设置退出表达式计算按钮。3 实现表达式的正误判断,错误返回0并输出表达式错误,正确返回1。4 实现将中缀表达式转为后缀表达式的处理,返回后缀表达式。5 实现后缀表达式的运算,返回最后数值。3) 实现功能步骤由提示输入,输入“1”按回车进行表达式计算,输入要计算的表达式按回车就可以得出结果,由提示输入,输入“2”按回车退出表达式的计算程序。4) 承担模块工作详解我要做的是先做到输出提示输入的内容,用while语句做到多个表达式计算循环,再利用单向栈的知识做到将中缀表达式转为后缀表达式的处理,其中关乎括号和函数的处理,采用整体法思路,把括号里的内
4、容和函数内容看做整体处理,最后进行后缀表达式的计算,采用先分后整的方法,利用调用函数和递归,先进行表达式里的函数和括号里内容的计算,再整体计算。主要要编写出各部分的程序,合理的进行栈和递归的处理。5) 运行环境系统软件:Window 2000 以上系统语言选择:C语言工具软件:VC+2、 概要设计1) 系统流程图开始输入选择输入为1 输入表达式 是表达式正确 否 结束输出计算结果转为后缀表达式后缀表达式计算 是 否 2) 提示输入模块该模块进行一些输出提示,包括tishishuru(),tishishuru1() 两个函数,主要输出表达式的运算符种类,函数类型等提示,输出是否进行表达式计算板块
5、,采用printf,scanf 语句就可以完成。3) 表达式正误判断模块该模块包括函数panduan(char*x) 当输入一个表达式时,将表达式存入数组后,先进行表达式的正误判断。进行一个个字符的判断,用if语句进行判断,得找出所有表达式错误的情况,则剩下正确的表达式。4) 中缀表达式转为后缀表达式模块这一模块实现中缀表达式转为后缀表达式,包括函数trans(char *exp,char*postexp),利用单向栈的知识,实现入栈操作,该模块需采用整体法思想,把括号内内容和函数内容看做整体存入为后缀表达式,利于后一步的分部计算。5) 后缀表达式计算模块该模块包括compvalue (cha
6、r *postex) 函数,实现对后缀表达式的计算并且返回计算结果于主函数中,采用出栈计算操作,将计算结果存入数据栈中。3、 详细设计1) main函数模块进行对各个自定义函数的调用,输入表达式,输出计算结果并利用while 语句做循环,实现多次计算。核心代码:void main () /*主函数*/ float r; /*用于存入表达式最后结果*/ char *exp; /*存放输入的表达式*/ char *postexp; /*存放后缀表达式*/ exp=(char*)malloc(MAXSIZE*sizeof(char); postexp=(char*)malloc(MAXSIZE*si
7、zeof(char); /*取内存*/ tishishuru(); /*提示输入的内容*/tishishuru1(); while (n=1) printf("请输入的表达式:"); /*提示输入表达式*/ gets(exp); /*输入表达式*/ if (panduan(exp)=0) /*判断表达式正误*/ printf ("tt表达式错误!n"); else trans(exp,postexp); /*调用中缀表达式转后缀表达式函数*/ r=compvalue(postexp); /*调用函数*/ printf("tt输出最后结果: %g
8、",r); /*输出计算结果*/ tishishuru1(); printf("tt表达式计算结束n"); 2) 提示输入模块实现输入的提示,主要输出表达式的运算符种类,函数类型等提示,输出是否进行表达式计算,同时进行对输入选择“1”“2”的处理,处理输入字母造成的死循环问题。核心代码:oe: printf("请选择:");scanf("%s",c);getchar();if(!(c0='1'&&c1='0')|(c0='2'&&c1='
9、0') printf("输入错误!请重新输入!n"); goto oe; n=c0-'0'3) 表达式正误判断利用while 语句进行一个个字符的查看,利用if 语句判断是否出错,出错即返回0,若到最后一个字符都没有错则返回1。难点在于函数和括号内容的判断。核心代码:int panduan(char *x) /*自定义函数panduan表达式正误判断*/ int i=-1,j=0,a=b=0; /*定义整型变量*/ char tem4,tem15; /*定义数组存入函数名*/ while (x+i!='0') . (省略次要部分) i
10、f(xi>='a'&& xi<='z') tem0=xi; tem1=xi+1; tem2=xi+2; tem3='0' tem10=xi; /*将函数名存入数组*/ tem11=xi+1; tem12=xi+2; tem13=xi+3; tem14='0' if(strcmp(tem,"sin")&&strcmp(tem,"log")&& strcmp(tem,"tan")&&strcmp(te
11、m,"cos") if (!(strcmp(tem1,"fabs")&&strcmp(tem1,"sqrt") if(xi+4!='(') printf("tt函数名后非( 错误!n"); return 0;break; /*函数名后非( 错误*/ i=i+3;continue ; if(xi+3!='(') printf("tt函数名后非( 错误!n"); return 0;break; /*函数名后非( 错误*/ else return 0;b
12、reak; i=i+2; if(a!=b) printf("tt左括号数不等于右括号数错误!n"); return 0; /*左括号数不等于右括号数错误*/return 1; /*表达式正确返回1*/ 4) 中缀表达式转为后缀表达式利用入栈原理将中缀表达式转为后缀表达式,例如:3-5 变为:3#5- 采用整体法思想把函数和括号内容看做整体,例如:3+tan(5+8) 变为:3#tan(5+8)+ 利用while 语句和switch语句进行对不同字符的处理。核心代码1:定义字符栈struct char date MAXSIZE; int top ; op;核心代码2:whil
13、e (*exp!='0') switch (*exp) case 's': case 'l': case 't':case 'f':case 'c': while (*exp>='a'&&*exp<='z') /*存取基本函数名*/ postexpi+=*exp; /*遇到字母则存入postexp*/ exp+; postexpi+=*exp;exp+; k=1; while (k) if (*exp='(')k+; if
14、(*exp=')') /*把函数括号内内容整体存入*/ k-; postexpi+=*exp; exp+; postexpi+='#' /*存入后用#隔开*/ break; /*将函数作为整体存入数组*/ case '(': postexpi+=*exp; exp+; k=1; while (k) if (*exp='(') /*将非函数括号没的括号内内容整体存入*/ k+; if (*exp=')') k-; postexpi+=*exp; exp+; postexpi+='#' /*存入后用#隔
15、开*/ break; case '+': case '-': while(op.top!=-1) postexpi+=op.dateop.top; op.top-; /*进行加减号的处理*/ op.top+; op.dateop.top=*exp;exp+; break; case '*': case '/': while (op.dateop.top='*'| op.dateop.top='/') postexpi+=op.dateop.top; op.top-; op.top+; /*进行乘除的
16、处理*/ op.dateop.top=*exp; exp+; break; case ' ': exp+;break; /*空格跳过*/ default : while(*exp>='0'&&*exp<='9') |*exp='.') postexpi+=*exp; exp+; /*进行数字的处理*/ postexpi+='#' while (op.top!=-1) /*exp扫描完毕,栈非空时循环*/ postexpi+=op.dateop.top; /*数字后存入运算符*/ op.t
17、op-; 5) 后缀表达式的计算对后缀表达式进行计算,利用出栈原理,把计算的值存入数据栈中,采用先分计算后整计算的方式,例如:sqrt(9-8)#4+ 先进行9-8的运算,调用中缀表达式转为后缀表达式函数trans(),变为9#8-得值为1,再进行sqrt(1)#4-的运算,利用递归思想。核心代码1:数据栈的定义struct int top; float dateMAXSIZE; /*定义栈存入计算结果*/ st;核心代码2:加减乘除的处理while (*postex!='0') switch (*postex) case '+': a=st.datest.to
18、p; /*进行加法运算*/ st.top-; b=st.datest.top; st.top-; c=a+b; st.top+; st.datest.top=c; break; case '-': a=st.datest.top; /*进行减法运算*/ st.top-; b=st.datest.top; st.top-; c=b-a;st.top+; st.datest.top=c; break; case '*': a=st.datest.top; /*进行乘法运算*/ st.top-; b=st.datest.top; st.top-; c=b*a;st.t
19、op+; st.datest.top=c; break; case '/': a=st.datest.top; /*进行除法运算*/ st.top-; b=st.datest.top; st.top-; if(a!=0) /*判断分母是否为0*/ c=b/a;st.top+; st.datest.top=c; else printf ("ttIt is wrong分母不能为零n"); return 0;break; /*表达式出错返回返回0*/ break; default : /*进行对数的处理,转化为float型的数*/ d=0;i=0; while(*
20、postex>='0'&&*postex<='9')|*postex='.') while (*postex>='0'&&*postex<='9') d=10*d+(float) (*postex-'0'); postex+; if (*postex='.') postex+; while (*postex>='0'&&*postex<='9') /*进行对小数的处理*
21、/ i+; d=d+(float)pow(10,-i)*(*postex-'0'); postex+; st.top+; st.datest.top=d; break; postex+; return st.datest.top; /*返回表达式最后的值*/ 核心代码3:括号和函数的处理switch (*postex) case 't':case 's':case 'f': case 'c':case 'l': w=postex; /*w指向函数的第一个字母*/ while(*postex>=
22、'a'&&*postex<='z') postex+; postex+; /*遇到函数名先跳过*/ k=1;q=p; /*q取p的首地址进行操作*/ while (k) if (*postex='(') k+; if (*postex=')') k-; *q=*postex; q+;postex+; q-; *q='0' /*把函数括号内的内容存入新的内存p中组成新的字符串*/ trans(p,t); /*调用函数*/ e=compvalue(t); /*调用函数函数*/ st.top+; s
23、witch (*w) case 't': st.datest.top=(float)tan(e);break; /*进行tan()的运算*/ case 's': if (*(+w)='q') if (e<0) printf ("tt不符合函数取值范围出错!n"); /*不符合函数取值范围出错*/return 0;break; /*表达式出错返回返回0*/ st.datest.top=(float)sqrt(e);break; /*进行sqrt()函数的运算*/ else st.datest.top=(float)sin(
24、e);break; /*进行san()函数的运算*/ case 'l': if (e<0) printf ("tt不符合函数取值范围出错!n"); /*不符合函数取值范围出错*/ return 0;break; /*表达式出错返回返回0*/ st.datest.top=(float)log(e);break; /*进行log()函数的运算*/ case 'c': st.datest.top=(float)cos(e);break; /*进行cos()函数的运算*/ case 'f': if (e<0) printf
25、 ("tt不符合函数取值范围出错!n"); /*不符合函数取值范围出错*/ return 0;break; /*表达式出错返回返回0*/ st.datest.top=(float)fabs(e);break; /*进行fabs()函数的运算*/ break; case '(': /*进行括号的运算,把括号内的表达式看做整体采用先整后分*/ postex+; k=1;q=p; while (k) if (*postex='(') k+; if (*postex=')') k-; *q=*postex; /*把函数括号内的内容存入
26、新的内存p中组成新的字符再 调用函数对p进行运算处理*/ q+;postex+; q-;*q='0' if (panduan(p)=0) printf ("tt表达式错误!n"); /*输出错误提示*/4、 调试分析1) 调试过程中遇到的问题和解决方法第一,输入选择“1”“2”时输入字母造成死循环,解决方法:把输入的内容存入字符串数组中,进行判断是否为字符“1”“2”,不是则利用goto函数返回重新输入。第二,对于先有加减号的表达式不知道如何处理,解决方法:在表达式最前方加上一个字符0,构成一个新的表达式来处理,例如:-9+8 变成0-9+8。第三,不知道如
27、何处理函数的计算,采用转表达式整体法和计算先分后总的方法。2) 经验和体会对于本次课设,题目“表达式计算”,开始拿到这个题目时觉得很简单,自己很快就可以处理好,可真正开始写代码时,发现自己在机房发呆了几节课,前几节课都没有写出什么东西。因为自己都不知道怎么下手,所以开始几堂课都在找资料,有看书的,也有百度。找到思路后,自己自学了一下数据结构书中单向栈的知识,看了一个小例题,也知道如何下手了。这个课设花了我许多时间的,虽然是在规定的几周上机时间完成的,通过课设的学习,发现自己学到了不少,C语言的知识加强了不少,了解了栈的初步学习,同时知道了对于写一个代码数量较多的程序,一定不能把一大堆代码堆在一
28、起,而是要学会一小块一小块拼起来,确保小块正确后来确保大块的正确,那样才更容易找出错误并改正。课设的学习,让我对C语言更有兴趣,感觉到程序的实用性,自己也更喜欢写代码了,希望在以后的学习中,自己可以学到更多的知识,写出更好地程序。5、 用户使用说明1 本次运行程序的环境是:2 程序要包括两次输入,第一输入“1”或“2” ,选择是否进行表达式计算,输入1计算,输入2 退出,按回车键确认输入。若输入1则进行表达式计算,输入要计算的表达式,按回车键计算即可。6、 测试结果图表 1.1 输入提示图表 2.1 输入选择错误图表 3.1 正常表达式计算图表 4.1表达式错误提示7、 参考文献1 C语言程序
29、设计 (第二版)何钦铭,颜晖。2 数据结构 (C语言版) 严蔚敏,吴伟民。8、 附录/*27. 表达式计算(难度:B) 要求:输入一个表达式,输出其结果。表达式由数字、运算符(+ - * / ( ) ) 常用数学函数组成。例如,输入 3*(sqrt(64)+(4/3),输出28。此外, 如果输入的是错误的表达式,则提示错误。例如:2+*3则输出:表达式输入错误。*/ /*源代码*/#include<stdio.h>#include<string.h>#include<math.h>#include<stdlib.h>#define MAXSIZE
30、 200 int n; /*定义全局变量n*/int panduan (char *x); /*自定义函数判断表达式的正误*/float compvalue (char *postex); /*中缀表达式转为后缀表达式*/void trans(char *exp,char*postexp); /*进行后缀表达式的运算*/void tishishuru(); /*自定义函数提示输入的内容*/void tishishuru1(); void main () /*主函数*/ float r; /*用于存入表达式最后结果*/ char *exp; /*存放输入的表达式*/ char *postexp;
31、 /*存放后缀表达式*/ exp=(char*)malloc(MAXSIZE*sizeof(char); postexp=(char*)malloc(MAXSIZE*sizeof(char);/*取内存*/system("color 6");tishishuru(); /*提示输入的内容*/tishishuru1(); while (n=1) printf("请输入的表达式:"); /*提示输入表达式*/ gets(exp); /*输入表达式*/ printf("n"); if (panduan(exp)=0) /*判断表达式正误*/
32、 printf ("tt表达式错误!n"); printf("*n"); /*清屏*/ else trans(exp,postexp); /*调用中缀表达式转后缀表达式函数*/ printf("tt输出后缀表达式:%sn",postexp); /*输出后缀表达式*/ r=compvalue(postexp); /*调用函数*/ printf("n"); printf("tt输出最后结果: %g",r); /*输出计算结果*/ printf("n"); printf("*n"); /*清屏*/ tishishuru1(); printf("tt表达式计算结束n"); void trans (char*exps,char*postexp) /*进行对中缀表达式转为后缀表达式*/ struct char date MAXSIZE; int top ; op; /*定义栈存放运算符*/ int k,i=0; /*定义整型变量*/ char *p ,*exp,*q; /*定义指针变量*/ exp=(char*)malloc(MAXSIZE*sizeof(char)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 土木工程的实习报告4篇
- 2025年云数融合项目规划申请报告
- 2025年新型电子时间继电器项目申请报告模范
- 2024-2025学年武汉市乔口区三上数学期末预测试题含解析
- 银行的职员辞职报告(集合15篇)
- 出纳毕业生的实习报告
- 2025年压缩式垃圾车项目规划申请报告模范
- 平凡的世界读书有感2022
- 急诊2022年护理工作计划
- 律师事务所的实习报告模板集锦7篇
- ICD-10疾病编码完整版
- 幼儿园大班语言活动《新年礼物》课件
- 基于STM32的智能温控风扇设计
- 土壤盐碱化精华(图文并茂一目了然盐碱化的过程)(课堂PPT)
- 国家开放大学《房屋建筑混凝土结构设计》章节测试参考答案
- GB_T4897-2015刨花板(高清版)
- 帆软BIFineBI技术白皮书
- 费用报销单模板-通用版
- 绞车斜巷提升能力计算及绞车选型核算方法
- 建筑设计院设计流程
- [方案]铁路行车组织设计说明书
评论
0/150
提交评论