软件计算器课设报告_第1页
软件计算器课设报告_第2页
软件计算器课设报告_第3页
软件计算器课设报告_第4页
软件计算器课设报告_第5页
已阅读5页,还剩51页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1 选题背景计算机软件技术基础课程设计的目的是,通过设计掌握数据结构课程中学到的基本理论和算法并综合运用于解决实际问题中,它是理论与实践相结合的重要过程。设计要求学会如何对实际问题定义相关数据结构,并采用恰当的设计方法和算法解决问题,同时训练学生进行复杂程序设计的技能和培养良好的程序设计习惯。学习此课程,要求学生对软件技术的各个组成部分的基础知识、发展趋势有全面、系统的了解;掌握基本数据结构,达到能熟练运用解决实际问题的程度;掌握操作系统基本原理和类型,了解系统各种管理功能。通过自学了解软件工程的基本概念,软件设计开发的过程和相关技术。课程设计是实践性教学中的一个重要环节,它以某一课程为基础,

2、可以涉及和课程相关的各个方面,是一门独立于课程之外的特殊课程。课程设计是让同学们对所学的课程更全面的学习和应用,理解和掌握课程的相关知识。计算机软件技术基础是一门重要的专业基础课,是计算机理论和应用的核心基础课程。计算机软件技术基础课程设计,要求学生在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面,加深对课程基本内容的理解。同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。在这次的课程设计中我选择的题目是具有表达式求值功能的计算器软件设计。表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的一个典型例子。设计一个程序,演示用算

3、符优先法对算术表达式求值的过程。深入了解栈的特性,以便在解决实际问题中灵活运用它们,同时加深对这种结构的理解和认识。2 任务简述设计、开发一种计算器软件系统。通过此系统可以实现算术计算器基本功能,以及+-*/()等基本运算的表达式求值功能,并提供进行这些操作的界面(字符界面、图形界面均可)。系统应该至少提供以下模块:1) 主函数main()的功能是:根据菜单的选项调用各函数,并完成相应的功能。 2) Menu()的功能是:显示英文提示菜单。 3) Quit()的功能是:退出菜单。 4) CreateExpression ()的功能是:创建中缀表达式。 5) TransmitExpression

4、 ()的功能是:转换表达式,以用户创建的中缀表达式为入口参数,输出结果为后缀表达式。 6) EvaluateExpression ()的功能是:以后缀表达式作为入口参数,完成表达式的计算结果。 7) CreateStack()的功能是:创建一个堆栈,为表达式的转换、求值算法提供技术支撑。 8) Pop()的功能是:表达式转换、求值过程中关于堆栈的弹出信息操作。 9)Push()的功能是:表达式转换、求值过程中关于堆栈的入栈信息操作。 3 问题分析要实现具有表达式求值功能的计算器软件设计,就要对数据结构中的栈有深刻的理解。以字符列的形式从终端输入语法正确的、不含变量的整数表达式。利用已知的算符优

5、先关系,实现对算术四则混合运算表达式的求值,并仿照教科书的例子在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。一般来说,计算机解决一个具体问题时,需要经过几个步骤:首先要从具体问题抽象出一个适当的数学模型,然后设计一个解决此数学模型的算法,最后编出程序,进行测试,调试直至得到想要的答案。对于算术表达式这个程序,主要利用栈,把运算的先后步骤进行分析并实现简单的运算!为实现算符优先算法,可以使用两个栈,一个用以寄存运算符,另一个用以寄存操作数和运算结果。演示程序是以用户于计算机的对话方式执行,这需要一个模块来完成使用者与计算机语言的转化。程序执行时的命令:本程序为了使用具体,采用菜单式的

6、方式来完成程序的演示,几乎不用输入什么特殊的命令,只需按提示输入表达式即可。(要注意输入时格式,否者可能会引起一些错误)这次课程设计中我们主要应该解决如下问题:1. 在输入中缀表达式的时候系统怎样将中缀表达式转换为后缀表达式;2. 计算机如何判断符号的优先级别;3. 系统如何判断输入符号的优先级别进行相应的计算;4. 左括号的右括号的匹配问题;5. 应该解决如何存储;6. 如何利用后缀表达式求取最后的结果;7. 如何输入中缀表达式输出后缀表达式;8. 如何在main函数中调用等问题;9. 除数为0时程序如何报错;10. 界面如何能够设计的美观一点。4 设计原理4.1栈栈(stack)又名堆栈,

7、它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。栈是限定仅在表头进行插入和删除操作的线性表。要搞清楚这个概念,首先要明白”栈“原来的意思,如此才能把握本质。"栈“者,存储货物或供旅客住宿的地方,可引申为仓库、中转站,所以引入到计算机领域里,就是指数据暂时存储的地方,所以才有进栈、出栈的说法。首先系统或者数据结构栈中数据内容的读取与插入(压

8、入push和 弹出pop)是两回事!插入是增加数据,弹出是删除数据 ,这些操作只能从栈顶即最低地址作为约束的接口界面入手操作 ,但读取栈中的数据是随便的没有接口约束之说。很多人都误解这个理念从而对栈产生困惑。1  而系统栈在计算机体系结构中又起到一个跨部件交互的媒介区域的作用 即 cpu 与内存的交流通道 ,cpu只从系统给我们自己编写的应用程序所规定的栈入口线性地读取执行指令, 用一个形象的词来形容它就是pipeline(管道线、流水线)。cpu内部交互具体参见 EU与BIU的概念介绍。栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原

9、则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。4.2表达式表达式的表示形式有中缀、前缀和后缀3中形式。中缀表达式按操作符的优先级进行计算(后面代码实现只包括+、-、*、,小括号),即数学运算。 后缀表达式中只有操作

10、数和操作符。操作符在两个操作数之后。它的计算规则非常简单,严格按照从左到右的次序依次执行每一个操作。每遇到一个操作符,就将前面的两个数执行相应的操作。 4.3 atof(将字串转换成浮点型数)相关函数 atoi,atol,strtod,strtol,strtoul表头文件 #include <stdlib.h>定义函数 double atof(const char *nptr);函数说明 atof()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('0')才结束转换,并将结果返回。参数nptr

11、字符串可包含正负号、小数点或E(e)来表示指数部分,如123.456或123e-2。返回值 返回转换后的浮点型数。附加说明 atof()与使用strtod(nptr,(char*)NULL)结果相同。4.4字符串函数 字符串函数(String processing function)也成字符串处理函数,指的是编程语言中用来进行字符串处理的函数,如C,pascal,Visual以及LotusScript中进行字符串拷贝,计算长度,字符查找等的函数。Strcpy原型:extern char *strcpy(char *dest,char *src);用法:#include <string.h

12、>功能:把src所指由NUL结束的字符串复制到dest所指的数组中。返回指向dest结尾处字符(NUL)的指针。举例:/ strcpy.c#include <syslib.h>#include <string.h>main()char *s="Golden Global View"char d20;clrscr();strcpy(d,s);printf("%s",d);getchar();return 0;strcmp功 能: 将一个串与另一个比较用 法: intstrcmpi(char *str1, char *str2)

13、;程序例:#include <string.h>#include <stdio.h>int main(void)char *buf1 = "BBB", *buf2 = "bbb"int ptr;ptr =strcmpi(buf2, buf1);if (ptr > 0)printf("buffer 2 is greater than buffer 1n");if (ptr < 0)printf("buffer 2 is less than buffer 1n");if (ptr =

14、 0)printf("buffer 2 equals buffer 1n");return 0;system就是调用从程序中调用系统命令(和shell命令)。 4.5system("pause")system("pause")就是从程序里调用“pause”命令, 而“pause”这个系统命令的功能很简单,就是在命令行上输出一行类似于“Press any key to exit”的字,等待用户按一个键,然后返回。举例如下:#include <stdio.h>#include <stdlib

15、.h>  / 使用system ("pause");必须要加该头文件main ()    int a=1;        printf("%dn", a);    system ("pause");  / 输出a的结果后,等待用户按任意一个键,程序就结束 4.6

16、switch函数 在switch语句中,我们要记住四个关键词,分别是switch、case、default和break。switch是语句的特征标志(图中标作sw);case表示当switch后的表达式满足某个case后的常量时,运行该case以后的语句块。要注意,任意两个case后的常量不能相等,否则switch将不知道选择哪条路走。default表示当表达式没有匹配的case时,默认(default)地运行它之后的语句块(图4.4.1中未标出);break表示分岔路已经到头,退出switch语句。switch(表达式)   case 常量表达式1:  

17、0;      语句块1;      break;         case 常量表达式n:         语句块n;      break;      default:         语句块n+1;   4.7 结构体结构体:结构体(struct)是由一系列具有相同类型或不同类型的数

18、据构成的数据集合,叫做结构.在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问。结构体和其他类型基础数据类型一样,例如int类型,char类型 只不过结构体可以做成你想要的数据类型。以方便日后的使用。在实际项目中,结构体是大量存在的。研发人员常使用结构体来封装一些属性来组成新的类型。由于C语言内部程序比较简单,研发人员通常使用结构体创造新的

19、“属性”,其目的是简化运算。结构体在函数中的作用不是简便,其最主要的作用就是封装。封装的好处就是可以再次利用。让使用者不必关心这个是什么,只要根据定义使用就可以了. 在C语言中,可以定义结构体类型,将多个相关的变量包装成为一个整体使用。在结构体中的变量,可以是相同、部分相同,或完全不同的数据类型。在C语言中,结构体不能包含函数。在面向对象的程序设计中,对象具有状态(属性)和行为,状态保存在成员变量中,行为通过成员方法(函数)来实现。C语言中的结构体只能描述一个对象的状态,不能描述一个对象的行为。在C+中,考虑到C语言到C+语言过渡的连续性,对结构体进行了扩展,C+的结构体可以包含函数

20、,这样,C+的结构体也具有类的功能,与class不同的是,结构体包含的函数默认为public,而不是private。truct 结构体名  成员列表;  .结构体变量;结构体类型变量的定义结构体类型变量的定义与其它类型的变量的定义是一样的,但由于结构体类型需要针对问题事先自行定义,所以结构体类型变量的定义形式就增加了灵活性,共计有三种形式,分别介绍如下:1) 先定义结构体类型,再定义结构体类型变量:struct stu / *定义学生结构体类型* /     char name20; / * 学生姓名* /  &#

21、160;  char sex; / * 性别* /     long num; / *学号* /     float score3; / * 三科考试成绩* /;struct stu student1,student2;/ * 定义结构体类型变量* /struct stu student3,student4;用此结构体类型,可以定义更多的该结构体类型变量。2 ) 定义结构体类型同时定义结构体类型变量:struct data     int day;     int

22、month;     int year; time1,time2;也可以再定义如下变量:struct data time3,time4;用此结构体类型,同样可以定义更多的该结构体类型变量。3) 直接定义结构体类型变量:struct     char name20; / *学生姓名* /     char sex; / *性别* /     long num; / *学号* /     float score3; / *三科考试成绩* / pers

23、on1,person2; / *定义该结构体类型变量* /该定义方法由于无法记录该结构体类型,所以除直接定义外,不能再定义该结构体类型变量.4.8数组数组:谓数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。数组是在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来的一种形式。这些按序排列的同类数据元素的集合称为数组。a.数组是相同数据类型的元素的集合b.数组中的各元素是有先后顺序的,它们在内存

24、中按照这个先后顺序连续存放在一起c.数组元素用整个数组的名字和它自己在数组中的顺序位置来表示。例如,a0表示名字为a的数组中的第一个元素,a1代表数组a的第二个元素,以此类推。数组声明:在数组的声明格式里,“数据类型”是声明数组元素的数据类型,可以是java语言中任意的数据类型,包括简单类型和结构类型。“数组名”是用来统一这些相同数据类型的名称,其命名规则和变量的命名规则相同。数组声明之后,接下来便是要分配数组所需要的内存,这时必须用运算符new,其中“个数”是告诉编译器,所声明的数组要存放多少个元素,所以new运算符是通知编译器根据括号里的个数,在内存中分配一块空间供该数组使用。利用new运

25、算符为数组元素分配内存空间的方式称为动态分配方式。举例:intx; /声明名称为x的int型数组x=new int10; /x数组中包含有10个元素,并为这10个元素分配内存空间在声明数组时,也可以将两个语句合并成一行,格式如下:数据类型数组名= new 数据类型个数;利用这种格式在声明数组的同时,也分配一块内存供数组使用。如上面的例子可以写成:intx = new int 10;等号左边的intx相当于定义了一个特殊的变量x,x的数据类型是一个对int型数组对象的引用,x就是一个数组的引用变量,其引用的数组元素个数不定。等号右边的new int10就是在堆内存中创建一个具有10个int型变量

26、的数组对象。intx = new int 10;就是将右边的数组对象赋值给左边的数组引用变量。1.数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。2.数组名的书写规则应符合标识符的书写规定。3.数组名不能与其它变量名相同。4.可以只给部分元素赋初值。当 中值的个数少于元素个数时,只给前面部分元素赋值。例如:static int a10=0,1,2,3,4;表示只给a0a45个元素赋值,而后5个元素自动赋0值。5.只能给元素逐个赋值,不能给数组整体赋值。例如给十个元素全部赋1值,只能写为:static int a10=1,1,1,1,1,1,1,1,1,1

27、;而不能写为:static int a10=1;(请注意:在C语言中是这样,但并非在所有涉及数组的地方都这样)6.如不给可初始化的数组赋初值,则全部元素均为0值。7.如给全部元素赋值,则在数组说明中, 可以不给出数组元素的个数。例如:static int a5=1,2,3,4,5;可写为:static int a=1,2,3,4,5;动态赋值可以在程序执行过程中,对数组作动态赋值。这时可用循环语句配合scanf函数逐个对数组元素赋值.5 设计解决方案这个程序的关键是对数字与运算符的判断和运算符优先级的判断,以及出栈的运算。建立两个栈,分别存储数字与运算符,栈1存运算符,栈2存数字。依次读取表达

28、式的字符串,先判断是数字还是运算符,如果是数字不能马上压入栈2,因为可能是大于10的数字,应该继续循环,如果还是数字,则利用计算保存数值,直到指到运算符时停止,将计算后的数字压入栈2。压入运算符之前先将要压入的与栈顶的运算符优先级相比较,如果栈顶是(而当前不是),则不需比较优先级,直接压入;如果栈顶是(,当前是),则抵消(弹出(,指向表达式下一个字符);若当前的运算符优先级大于栈顶的,则压入;若当前的运算符优先级小于栈內时,弹出栈顶的运算符,同时弹出两组数字,经过运算符的运算后再重新压到栈内。为了方便判断运算结束,在存储运算符之前先将#压入栈1中,在输入表达式时以“0”结束,所以可以以运算符=

29、0并且栈1顶=0来结束运算,弹出栈2的数值,即为表达式求值的最终结果。由后缀表达式计算中缀表达式原理:计算机处理后缀表达式求值问题是比较方便的,即将遇到的操作数暂存于一个操作数栈中,凡是遇到操作数,便从栈中pop出两个操作数,并将结果存于操作数栈中,直到对后缀表达式中最后一个操作数处理完,最后压入栈中的数就是后最表达式的计算结果。 中缀表达式转换为等价的后缀表达式 :中缀表达式不方便与计算机处理,通常要讲中缀表达式转换为一个与之等价的后缀表达式。等价是指两个表达式的计算顺序和计算结果完全相同。 中缀表达式:0.3/(5*2+1) 等价后缀表达式是:0.3 5 2 * 1 + / 仔细观察这两个

30、等价的表达式可知,操作数的出现次序是相同的,但运算符的出现次序是不同的。在后缀表达式中,运算符的出现次序是实际进行操作的次序;在中追表达式中,由于受到操作符的优先级和括号的影响,操作符出现次序与实际进行操作的次序很可能是不一样的。 算法描述: 将中缀表达式转换为等价的后缀表达式的过程要使用一个栈放“(”,具体可以按照下面的方式进行。 (1)从左到右一次扫描中缀表达式的每一个字符,如果是数字字符和圆点“.”则直接将它们写入后缀表达式中。 (2)如果遇到的是开括号“(”,则将它们压入一个操作符栈(不需要与栈顶操作符相比较),它表明一个新的计算层次的开始,在遇到和它匹配的闭括号“)”时,将栈中的元素

31、弹出来并放入后缀表达式中,直到栈顶元素为“(”时将栈顶元素“(”弹出(不需要加入后缀表达式),表明这一层括号内的操作处理完毕。 (3)如果遇到的是操作符,则将该操作符和操作符栈顶元素比较: a、当所遇到的操作符的优先级小于或等于栈顶元素的优先级时,则取出栈顶元素放入后缀表达式,并弹出该栈顶元素,反复执行直到当前操作符的优先级大于栈顶元素的优先级小于; b、当所遇到的操作符的优先级大于栈顶元素的优先级的时则将它压入栈中。(4)重复上述步骤直到遇到中缀表达式的结束符标记“0”,弹出栈中的所有元素并放入后缀表达式中,转换结束.6 详细设计方案及模块分析实验的总体框图:开始输入中缀表达式中缀表达式转换

32、为后缀表达式表达式求值输出表达式的值结束图6 中缀变后缀6.1 main()的功能:在mian函数中调用menu函数和CreateExpression、TransmitExpression函数、EvaluateExpression函数。int main()char expressionM;char passwordM;char mima="baichao"int n = 0;int s=0;int result = 0;while(1)menu();scanf("%d", &n);switch (n)case 1:printf("请输入

33、登录口令");scanf("%s",&password);if(strcmp(mima,password)=0)while(1)menu1();scanf("%d", &n);switch (n)case 1:printf("请输入一个中缀表达式n");CreateExpression(expression);printf("%sn", expression);break;case 2:TransmitExpression(expression);break;case 3:result=E

34、valuateExpression(expression);printf("计算结果是%dn",result);break;case 4:exit(1);/给系统返回值1break;default:printf("您输入的数字有误n");break;return 0;break;else printf("口令输入错误"); break;case 2:system("pause");break;default:printf("您输入的数字有误n");break;主函数表达式转换表达式求值数据输入输

35、出输出图61 主函数 图6-1-1 菜单操作图6-1-2 菜单操作6.2 menu()和menu1()的功能显示英文提示菜单,为用户提供指示操作,方便用户。还有对程序界面起到美化作用。void menu()printf(" * ");printf(" *简易计算器* ");printf(" * n");printf("1.Entry:n");printf("2.Quit:n");printf("-n");printf("请选择要实现的功能:");void

36、menu1()printf(" * ");printf(" *简易计算器* ");printf(" * n");printf("请选择您要实现的功能:n");printf("1.CreateExpression ()n");printf("2.TransmitExpression()n");printf("3.EvaluateExpression()n"); printf("4.Quit()n");printf("-n&quo

37、t;);printf("请选择要实现的功能:");用到的是printf函数,进行用户界面的美化功能。6.3 Quit()的功能退出菜单。6.4 CreateExpression ()的功能:创建中缀表达式。void CreateExpression(char *expression)/创建一个中缀表达式scanf("%s", expression);主要用的是scanf函数来接受字符串的输入。6.5 TransmitExpression ()的功能转换表达式,以用户创建的中缀表达式为入口参数,输出结果为后缀表达式。从左到右遍历中缀表达式的每个数字和符号,

38、若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于找顶符号(乘除优先加减)则栈顶元素依次出找并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。(1). 初始化一空栈,用来对符号进出栈使用。(2). 第一个字符是数字9,输出9,后面是符号“+”,进栈。(3). 第三个字符是“(”,依然是符号,因其只是左括号,还未配对,故进栈。(4). 第四个字符是数字3,输出,总表达式为9 3,接着是“-”进栈。(5). 接下来是数字1,输出,总表达式为9 3 1,后面是符号“)”,此时,我们需要去匹配此前的“(”,所以栈顶依次出栈,并输出,直到“(”出栈

39、为止。此时左括号上方只有“-”,因此输出“-”,总的输出表达式为9 3 1 -(6). 接着是数字3,输出,总的表达式为9 3 1 - 3 。紧接着是符号“*”,因为此时的栈顶符号为“+”号,优先级低于“*”,因此不输出,进栈。(7). 之后是符号“+”,此时当前栈顶元素比这个“+”的优先级高,因此栈中元素出栈并输出(没有比“+”号更低的优先级,所以全部出栈),总输出表达式为 9 3 1 - 3 * +.然后将当前这个符号“+”进栈。也就是说,前6张图的栈底的“+”是指中缀表达式中开头的9后面那个“+”,而下图中的栈底(也是栈顶)的“+”是指“9+(3-1)*3+”中的最后一个“+”。(8).

40、 紧接着数字10,输出,总表达式变为9 3 1-3 * + 10。(9). 最后一个数字2,输出,总的表达式为 9 3 1-3*+ 10 2(10). 因已经到最后,所以将栈中符号全部出栈并输出。最终输出的后缀表达式结果为 9 3 1-3*+ 10 2/+double TransmitExpression(char *exp1)/输入中缀表达式输出后缀表达式SStack_num stack_num;/定义数栈FStack_sign stack_sign;/定义符栈My_style jisuan;/定义MYSIGN型运算符int i,j,k;/数组下标double number;char exp

41、2M,tempexpM;/定义后缀表达式exp2,整合数组tempexpdouble a,b;SetNull_num(&stack_num);/初始化数栈SetNull_sign(&stack_sign);/初始化符号栈i=0;/初始化j=0;/初始化k=0;/初始化tempexp0='0'/初始化整合数组while(exp1i != '0')/处理表达式转化为后缀表达式 if(exp1i>='0'&& exp1i<='9')/处理数字元素 while(exp1i>='0&

42、#39;&& exp1i<='9') | exp1i='.' ) exp2j=exp1i;/连续的数字不会被分开并依次存入后缀表达式 j+; i+; else if(exp1i='+' | exp1i='-')/处理运算符元素 exp2j=' ' ; /结束后用空格将其与后面的元素分开 j+; jisuan.mysign=exp1i;/char型数据 jisuan.level=1; while(gettop_sign(&stack_sign).level>=jisuan.leve

43、l)/当栈中符的等级大于当前等级是则取出符号存入后缀表达式 exp2j=pop_sign(&stack_sign).mysign; j+; exp2j=' ' ; /每两个运算符号之间用空格间隔开 j+; exp2j='0' ; push_sign(&stack_sign,&jisuan); i+; else if(exp1i='*' | exp1i='/' )/处理运算符元素 exp2j=' ' ; /结束后用空格将其与后面的元素分开 j+; jisuan.mysign=exp1i; ji

44、suan.level=2; while(gettop_sign(&stack_sign).level>=jisuan.level) exp2j=pop_sign(&stack_sign).mysign; j+; exp2j=' ' ; j+; push_sign(&stack_sign,&jisuan); i+; else if(exp1i='(') jisuan.mysign = exp1i;/如果是左括号则无条件进栈 jisuan.level=-1;/进栈后等级为-1,遇到右括号出去 push_sign(&sta

45、ck_sign,&jisuan); i+; else if(exp1i=')')/右括号 while(gettop_sign(&stack_sign).level != -1)/遇到右括号则不断出栈存入后缀表达式,直到找到左括号 exp2j=pop_sign(&stack_sign).mysign; j+; pop_sign(&stack_sign); i+; while(gettop_sign(&stack_sign).level !=0)/原表达式结束后对栈进行操作直到栈空 exp2j=' ' ; j+; exp2j=

46、pop_sign(&stack_sign).mysign; j+; exp2j='0' ;/最后结束后缀表达式printf("n后缀表达式是 : %sn",exp2); /* 得到后缀表达式 */exp2j='0' ;/最后结束后缀表达式 return 0 ;6.6 EvaluateExpression ()的功能以后缀表达式作为入口参数,完成表达式的计算结果. 从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。1. 初始化一个空栈。此桟用来对要运算

47、的数字进出使用。2. 后缀表达式中前三个都是数字,所以9、3、1进栈。3. 接下来是减号“-”,所以将栈中的1出栈作为减数,3出栈作为被减数,并运算3-1得到2,再将2进栈。4. 接着是数字3进栈。5. 后面是乘法“*”,也就意味着栈中3和2出栈,2与3相乘,得到6,并将6进栈。6. 下面是加法“+”,所以找中6和9出找,9与6相加,得到15,将15进栈。7. 接着是10与2两数字进栈。8. 接下来是符号因此,栈顶的2与10出栈,10与2相除,得到5,将5进栈。9. 最后一个是符号“+”,所以15与5出找并相加,得到20,将20进栈。10. 结果是20出栈,栈变为空。double Evalua

48、teExpression(char *exp1)SStack_num stack_num;/定义数栈FStack_sign stack_sign;/定义符栈My_style jisuan;/定义MYSIGN型运算符int i,j,k;/数组下标double number;char exp2M,tempexpM;/定义后缀表达式exp2,整合数组tempexpdouble a,b;SetNull_num(&stack_num);/初始化数栈SetNull_sign(&stack_sign);/初始化符号栈i=0;/初始化j=0;/初始化k=0;/初始化tempexp0='

49、0'/初始化整合数组while(exp1i != '0')/处理表达式转化为后缀表达式 if(exp1i>='0'&& exp1i<='9')/处理数字元素 while(exp1i>='0'&& exp1i<='9') | exp1i='.' ) exp2j=exp1i;/连续的数字不会被分开并依次存入后缀表达式 j+; i+; else if(exp1i='+' | exp1i='-')/处理运算符元素 exp2j=' ' ; /结束后用空格将其与后面的元素分开 j+; jisuan.mysign=exp1i;/char型数据 jisuan.level=1; while(gettop_sign(&stack_sign).level>=jisuan.level)/当栈中符的等级大于当前等级是则取出符号存入

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论