310计1表达式求值.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
310计1表达式求值

例3.3 表达式求值 表达式的计算与括号匹配一样是程序设计语言编译系统中的一个基本问题,它的实现是堆栈应用的一个典型实例。 任何一个表达式都是由运算对象(也称操作数)和运算符(也称操作符)以及分界符组成的。这些运算对象、运算符以及分界符称为单词。根据运算符的类型,通常可以把表达式分为逻辑表达式、关系表达式和算术表达式三类。为了简化问题而又不失一般性,这里仅仅讨论只含二元运算符的算术表达式的求值问题,读者不难将它推广到一般表达式。 先要说明的是,通常在数学中看到的或者出现在程序中的算术表达式都称为中缀表达式,中缀表达式中的运算符一般出现在两个运算对象之间(单目运算符除外)。例如, a- b+c*d /e 在计算机系统内多遍处理的编译程序中,在处理这样的表达式并将其生成一系列机器指令或者直接求值之前,往往先将它变换成另外一种形式,即后缀表达式形式。顾名思义,后缀表达式就是表达式中的运算符出现在运算对象之后。在后缀表达式中,不存在括号,也不存在运算符优先级的差别,计算过程完全按运算符出现的先后次序进行;整个计算过程仅需一遍扫描便可完成,比中缀表达式的计算简单得多。例如,前面给出的中缀表达式写成后缀形式为: abcd*+e/- 这样处理的好处是:编译程序处理表达式时,首先从左至右一次扫描后缀表达式的各个单词,如果读到的一个单词为运算符,就对该运算符前面的两个运算对象施以该运算符所代表的运算;然后将结果存入一个临时单元Ti中(i≥1),并作为一个新的运算对象重复进行上述过程,直到表达式处理完毕。例如:abcd*+e/-的运算过程如表3.1所示。 表3.1 后缀表达式的计算过程 操作顺序 后缀表达式 T1←c*d abT1+e/- T2←b+T1 aT2e/- T3←T2/e aT3- T4←a-T3 T4 从上面的讨论知道,后缀表达式之所以容易被编译程序处理,是由于它具有以下特点: (1) 后缀表达式中不出现括号; (2) 后缀表达式与中缀表达式的运算对象的先后次序相同,只是所读到的运算符先后次序可能有所改变。 正是由于后缀表达式具有以上特点,所以,处理时不必考虑运算符的优先关系。在具体的处理过程中,需要设置一个堆栈,用来保存已经读到的运算对象。也就是说,从左至右依次扫描后缀表达式,每读到一个运算对象就将其压入堆栈;每读到一个运算符,就从堆栈中取出相应的运算对象进行该运算符所代表的操作,并把运算结果作为一个新的运算对象压入堆栈。表达式最后的计算结果就是位于堆栈中栈顶的值。 综上所述,表达式的值的计算过程需要经过两个步骤:一是把中缀表达式变换为后缀表达式;二是根据后缀表达式产生计算表达式的机器指令序列。相对而言,第二个步骤较为简单些,我们先讨论实现第二个步骤的算法。 算法3.8 #includeseqstack.c Void evalution char c; int op1,op2,c1,result,x 0,val ; seqstack *opd; /*栈opd存放操作数及计算结果*/ initstack opd ; /*初始化栈*/ printf “请从键盘输入后缀表达式:”); while c getchar ! \n /*后缀表达式未结束*/ if c continue; /*空格则读入下一个字符*/ if c 0 c 9 /*若读入字符是数字*/ c1 c-0; /*将字符数字转化为数值数字*/ push opdata opd,c1 ; /*将该数值数字作为操作数进栈*/ else if c + || c - || c * || c / /*若读入字符为运算符*/ op1 pop opd,x ; op2 pop opd,x ; result val c,op2,op1 ;/*两操作数出栈,进行运算*/ push opd,result ;/*运算结果进栈*/ printf 该后缀表达式的值为:%d,pop opd,x ;/*计算完后栈中只剩计算结果*/ 算法3.9 int val char tag, int a1, int a2 /*函数val进行算术运算*/ switch tag case +: return a1+a2 ;break; case -: return a1-a2 ;break; case *: return a1*a2 ;break; case /: return a1/a2 ; 下面来讨论如何把中缀表达式变换为后缀表达式。 首先,已知中缀表达式与后缀表达式的运算对象的排列次序完全相同,只是运算符按某种规则可能改变了位置。根据这个特点,可以从左到右依次扫描中缀表达式,每读到一个运算对象就把它作为后缀表达式的一部分输出。关键在于处理运算符时

文档评论(0)

haocen + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档