算术表达式求值
算术表达式的求解

软件综合课程设计算术表达式的求解&车厢调度二〇一四年六月目录算数表达式的求解 (3)一、前言 (3)二、问题陈述 (3)三、需求分析 (3)四、概要设计 (4)五、详细设计和编码 (6)六、上级调试过程 (10)七、总结与心得 (12)八、参考文献 (13)附录(源程序): (13)车厢调度 (20)一、问题陈述 (20)二、问题分析与设计 (20)三、运行结果 (20)四、设计体会与总结 (21)附录(源程序) (21)算数表达式的求解一、前言表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的一个典型例子。
设计一个程序,演示用算符优先法对算术表达式求值的过程。
在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。
因而在程序设计时,借助栈实现。
算法输入:一个算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。
为简化,规定操作数只能为正整数,操作符为+、-*、/,用#表示结束。
算法输出:表达式运算结果。
算法要点:设置运算符栈和操作数栈辅助分析算符优先关系。
在读入表达式的字符序列的同时,完成运算符和运算数的识别处理,以及相应运算。
二、问题陈述(算数表达式的求解)给定一个算数表达式,通过程序求出最后的结果。
要求如下:1、从键盘输入要求解的算术表达式;2、采用栈结构进行算数表达式的求解过程;3、能够判断算数表达式的正确与否;4、对于错误表达式给出提示;5、对于正确表达时给出最后的结果。
三、需求分析有题目可知,程序要求给定一算数表达式并计算最后的结果,我们知道,在高级语言中,任何一个表达式都是有操作数、运算符和界限符组成。
在计算过程中,还要考虑表达式中有无括号以及左右括号之分。
由于运算符有优先级的高低,因此一个算数表达是不可能总是按顺序执行。
通过以上可知,可以用栈来实现运算符的优先级完成算术表达式的求解。
数据结构-算术表达式求值(含需求分析和源代码)

需求分析(附代码)一、需求分析(1)首先定义两个栈OPTR、OPND,栈OPTR用于存放运算符,栈OPND 用于存放操作数;定义一个一维数组expr【】存放表达式串。
(2)主函数主要包括两部分:(1)判断运算符优先权,返回优先权高的;(2)操作函数。
(3)开始将‘#’入操作符栈,通过一个函数来判别算术运算符的优先级。
且规定‘#’的优先级最低。
在输入表达式的最后输入‘#’,代表表达式输入结束。
在表达式输入过程中,遇操作数则直接入栈。
遇到运算符则与栈顶运算符比较优先级,当前运算符优先级高(前面的运算还不应执行)则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符(注意当前运算符未变)与新栈顶运算符。
如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。
(4)最初实现的加、减、乘、除及带小括号的基本运算,但考虑到实用性,后来的设计中有加上了乘方运算。
在乘方运算中借用了C库中自带的乘方函数pow。
二、概要设计1、设定栈的抽象数据类型定义:ADT Stack {数据对象:D={ ai | ai∈ElemSet, i=1,2,...,n,n≥0 }数据关系:R1={ <ai-1, ai >| ai-1, ai∈D, i=2,...,n }约定an端为栈顶,a1端为栈底。
基本操作:InitStack(&S)操作结果:构造一个空栈S。
DestroyStack(&S)初始条件:栈S已存在。
操作结果:栈S被销毁。
StackEmpty(S)初始条件:栈S已存在。
操作结果:若栈S为空栈,则返回TRUE,否则FALE。
StackLength(S)初始条件:栈S已存在。
操作结果:返回S的元素个数,即栈的长度。
GetTop(S, &e)初始条件:栈S已存在且非空。
操作结果:用e返回S的栈顶元素。
ClearStack(&S)初始条件:栈S已存在。
c语言算术表达式求值

c语言算术表达式求值C语言是一种广泛应用的编程语言,其强大的算术表达式求值功能使其在科学计算、数据处理、游戏开发等领域有着重要的应用。
本文将介绍C语言中算术表达式求值的相关知识,包括运算符、运算符优先级、表达式求值的顺序等内容。
我们需要了解C语言中常用的算术运算符。
C语言支持的算术运算符包括加法(+)、减法(-)、乘法(*)、除法(/)和求余(%)等。
这些运算符用于对数值进行基本的加减乘除运算。
在C语言中,运算符的优先级决定了表达式求值的顺序。
常见的运算符优先级从高到低依次为:1. 括号(()):括号中的表达式具有最高的优先级,可以改变默认的运算次序。
2. 一元运算符:包括正号(+)和负号(-),用于表示正负数。
3. 乘法、除法和求余:乘法(*)、除法(/)和求余(%)的优先级相同,从左到右依次计算。
4. 加法和减法:加法(+)和减法(-)的优先级相同,从左到右依次计算。
在使用C语言进行算术表达式求值时,我们需要遵循这些运算符的优先级规则,以保证表达式的正确求值。
如果表达式中包含多个运算符,我们需要根据优先级确定运算的顺序,可以使用括号来改变默认的运算次序。
下面我们将通过几个例子来说明C语言中算术表达式求值的过程。
例1:求解一个简单的算术表达式假设我们需要计算表达式 3 + 4 * 2,根据运算符优先级规则,先计算乘法,再计算加法。
具体的求解过程如下:1. 计算4 * 2,得到8。
2. 计算3 + 8,得到11。
所以,表达式3 + 4 * 2的值为11。
例2:使用括号改变运算次序假设我们需要计算表达式(3 + 4) * 2,根据运算符优先级规则,先计算括号内的加法,再计算乘法。
具体的求解过程如下:1. 计算3 + 4,得到7。
2. 计算7 * 2,得到14。
所以,表达式(3 + 4) * 2的值为14。
通过以上两个例子,我们可以看到,C语言中的算术表达式求值是按照运算符优先级和运算次序进行的,遵循从左到右的计算规则。
c语言算术表达式求值

c语言算术表达式求值【实用版】目录1.引言2.C 语言算术表达式的基本概念3.C 语言算术表达式的求值方法4.实际应用示例5.总结正文【引言】在 C 语言编程中,算术表达式是用来进行数值计算的重要工具。
本篇文章将为大家介绍 C 语言算术表达式的求值方法。
【C 语言算术表达式的基本概念】C 语言中的算术表达式主要包括以下几种:1.一元运算符:例如+、-、*、/等,用于对一个数值进行操作。
2.二元运算符:例如+、-、*、/等,用于对两个数值进行操作。
3.关系运算符:例如<、>、<=、>=、==、!=等,用于比较两个数值的大小或相等性。
4.逻辑运算符:例如&&、||、! 等,用于进行逻辑判断。
【C 语言算术表达式的求值方法】C 语言中,算术表达式的求值主要遵循以下规则:1.先进行括号内的运算,再进行括号外的运算。
2.先进行乘除法运算,再进行加减法运算。
3.关系运算符和逻辑运算符的优先级较低,从左到右依次进行运算。
【实际应用示例】下面我们通过一个实际的 C 语言程序,来演示算术表达式的求值过程。
```c#include <stdio.h>int main() {int a = 10, b = 5;int result;result = a + b * (a - b) / (a * b);printf("The result is: %d", result);return 0;}```在这个程序中,我们定义了两个整数变量 a 和 b,并通过算术表达式计算 result 的值。
根据我们之前提到的算术表达式求值规则,我们可以将这个表达式分解为以下几个步骤:1.计算括号内的值:a - b = 10 - 5 = 52.计算乘法运算:b * (a - b) = 5 * 5 = 253.计算除法运算:(a * b) / (a * b) = 14.计算加法运算:a + 25 = 10 + 25 = 355.输出结果:printf("The result is: %d", result); 输出 35【总结】通过本篇文章的介绍,相信大家已经对 C 语言算术表达式的求值方法有了更加深入的了解。
简单算术表达式求值

简单算术表达式求值01:简单算术表达式求值
总时间限制:
1000ms
内存限制:
65536kB
描述
两位正整数的简单算术运算(只考虑整数运算),算术运算为:
+,加法运算;
-,减法运算;
*,乘法运算;
/,整除运算;
%,取余运算。
算术表达式的格式为(运算符前后可能有空格):
运算数运算符运算数
请输出相应的结果。
输⼊
⼀⾏算术表达式。
输出
整型算数运算的结果(结果值不⼀定为2位数,可能多于2位或少于2位)。
样例输⼊
32+64
样例输出
96
#include<stdio.h>
int a(int x,char y,int z)
{
int sum,b;
b=y;
if(b==43)
{
sum=x+z;
}
else if(b==45)
{
sum=x-z;
}
else if(b==42)
{
sum=x*z;
}
else if(b==47)
{
sum=x/z;
}
else if(b==37)
{
sum=x%z;
}
return sum;
}
int main()
{
unsigned int A,C;
char B;
scanf("%u %c %u",&A,&B,&C);//注意字符两侧可能有空格printf("%d",a(A,B,C));
return 0;
}。
C#算术表达式求值(后缀法),看这一篇就够了

C#算术表达式求值(后缀法),看这⼀篇就够了⼀、种类介绍算术表达式有三种:前缀表达式、中缀表达式和后缀表达式。
⼀般⽤的是中缀,⽐如1+1,前后缀就是把操作符移到前⾯和后⾯,下⾯简单介绍⼀下这三种表达式。
1、前缀表⽰法前缀表⽰法⼜叫波兰表⽰法,他的操作符置于操作数的前⾯(例:+ 1 2),是波兰数学家扬·武卡谢维奇1920年代引⼊的,⽤于简化命题逻辑。
因为我们⼀般认为操作符是在操作数中间的,所以在⽇常⽣活中⽤的不多,但在计算机科学领域占有⼀席之地。
⼀般的表⽰法对计算机来说处理很⿇烦,每个符号都要考虑优先级,还有括号这种会打乱优先级的存在,将使计算机花费⼤量的资源进⾏解析。
⽽前缀表⽰法没有优先级的概念,他是按顺序处理的。
举个例⼦:9-2*3这个式⼦,计算机需要先分析优先级,先乘后减,找到2*3,再进⾏减操作;化成前缀表⽰法就是:- 9 * 2 3,计算机可以依次读取,操作符作⽤于后⼀个操作数,遇到减就是让9减去后⾯的数,⽽跟着9的是乘,也就是说让9减去乘的结果,这对计算机来说很简单,按顺序来就⾏了。
2、中缀表⽰法这也就是我们⼀般的表⽰法,他的操作符置于操作数的中间(例:1 + 2),前⾯也说过这种⽅法不容易被计算机解析,但他符合⼈们的普遍⽤法,许多编程语⾔也就⽤这种⽅法了。
在中缀表⽰法中括号是必须有的,要不然运算顺序会乱掉。
3、后缀表⽰法后缀表⽰法⼜叫逆波兰表⽰法,他的操作符置于操作数的后⾯(例:1 2 +),他和前缀表⽰法都对计算机⽐较友好,但他很容易⽤堆栈解析,所以在计算机中⽤的很多。
他的解释过程⼀般是:操作数⼊栈;遇到操作符时,操作数出栈,求值,将结果⼊栈;当⼀遍后,栈顶就是表达式的值。
因此逆波兰表达式的求值使⽤堆栈结构很容易实现,且能很快求值。
注意:逆波兰记法并不是简单的波兰表达式的反转。
因为对于不满⾜交换律的操作符,它的操作数写法仍然是常规顺序,如,波兰记法/ 6 3的逆波兰记法是6 3 /⽽不是3 6 /;数字的数位写法也是常规顺序。
利用栈来实现算术表达式求值的算法

利用栈来实现算术表达式求值的算法利用栈来实现算术表达式求值的算法算术表达式是指按照一定规则组成的运算式,包含数字、运算符和括号。
在计算机中,求解算术表达式是一项基本的数学运算任务。
根据算术表达式的性质,我们可以考虑利用栈这一数据结构来实现求值算法。
一、算法思路首先,我们需要明确一个重要概念——逆波兰表达式(ReversePolish notation)。
逆波兰表达式是一种没有括号的算术表达式,其运算规则是先计算后面的数字和运算符,再计算前面的数字和运算符。
例如,对于算术表达式“3+4*5-6”,其对应的逆波兰表达式为“3 45 * +6 -”。
那么,我们可以利用栈来实现将中缀表达式转化为逆波兰表达式的过程,具体步骤如下:1. 创建两个栈——操作数栈和操作符栈。
2. 从左到右扫描中缀表达式的每一个数字和运算符,遇到数字则压入操作数栈中,遇到运算符则进行如下操作:(1)如果操作符栈为空或当前运算符的优先级大于栈顶运算符的优先级,则将当前运算符压入操作符栈中。
(2)如果当前运算符的优先级小于或等于栈顶运算符的优先级,则将栈顶运算符弹出并加入操作数栈中,重复此过程直到遇到优先级较低的运算符或操作符栈为空为止,然后将当前运算符压入操作符栈中。
3. 扫描完中缀表达式后,若操作符栈不为空,则将其中所有运算符弹出并加入操作数栈中。
4. 最终,操作数栈中存放的就是逆波兰表达式,我们可以按照逆波兰表达式的计算规则来计算其结果。
二、算法优点利用栈来实现算术表达式求值的算法具有以下优点:1. 代码简洁易懂,易于实现和维护。
2. 由于将中缀表达式转化为逆波兰表达式后,可以减少运算符的优先级关系而消除括号,从而减少求值的复杂度,提高程序的执行效率。
三、代码实现下面是利用栈来实现算术表达式求值的算法的Python代码实现:```pythonclass Stack:def __init__(self):self.items = []def push(self, item):self.items.append(item)def pop(self):return self.items.pop()def peek(self):return self.items[-1]def is_empty(self):return len(self.items) == 0def size(self):return len(self.items)def calculate(op_num1, op_num2, operator):if operator == "+":return op_num1 + op_num2elif operator == "-":return op_num1 - op_num2elif operator == "*":return op_num1 * op_num2elif operator == "/":return op_num1 / op_num2def infix_to_postfix(infix_expr):opstack = Stack()postfix_expr = []prec = {"+": 1, "-": 1, "*": 2, "/": 2, "(": 0} token_list = infix_expr.split()for token in token_list:if token.isdigit():postfix_expr.append(token)elif token == '(':opstack.push(token)elif token == ')':top_token = opstack.pop()while top_token != '(':postfix_expr.append(top_token)top_token = opstack.pop()else:while (not opstack.is_empty()) and(prec[opstack.peek()] >= prec[token]):postfix_expr.append(opstack.pop())opstack.push(token)while not opstack.is_empty():postfix_expr.append(opstack.pop())return " ".join(postfix_expr)def postfix_eval(postfix_expr):opstack = Stack()token_list = postfix_expr.split()for token in token_list:if token.isdigit():opstack.push(int(token))else:op_num2 = opstack.pop()op_num1 = opstack.pop()result = calculate(op_num1, op_num2, token) opstack.push(result)return opstack.pop()infix_expr = "3 + 4 * 5 - 6"postfix_expr = infix_to_postfix(infix_expr)print(postfix_expr)print(postfix_eval(postfix_expr))```四、总结算术表达式求值是一项常见的数学运算任务,利用栈这一数据结构来实现求值算法是一种简单有效的方法,它将中缀表达式转化为逆波兰表达式后,可以消除括号并减少运算符的优先级关系,从而提高程序的执行效率。
算术表达式的概念

(float)5 / 2(等价于(float)(5)/2) /*将5转换成实型,再除以
2(=2.5)*/
(float)(5 / 2)
/*将5整除2的结果(2)转换成
【注意】
实型(2.0)*/
强制转换类型得到的是一个所需类型的中间量,原表达式 类型并不发生变化。例如,(double)a 只是将变量a的值转换成
2、表达式求值 (1)按运算符的优先级高低次序执行。例如,先乘除后 加减。 (2)如果在一个运算对象(或称操作数)两侧的运算符 的优先级相同,则按C语言规定的结合方向(结合性)进行。 例如,算术运算符的结合方向是“自左至右”,即:在执 行“a – b + c”时,变量b先与减号结合,执行“a - b”;然 后再执行加c的运算。
(2)纵向向上的箭头,表示不同类型的转换方向。 例如,int型与double型数据进行混合运算,则先将int 型数据转换成double型,然后在两个同类型的数据间进行运 算,结果为double型。
【注意】
箭头方向只表示数据类型由低向高转换,不要理解为int 型 先 转 换 成 unsigned 型 , 再 转 换 成 long 型 , 最 后 转 换 成 double型。
四、数据类型转换
1、在C语言中,整型、实型和字符型数据间可以混合运 算(因为字符数据与整型数据可以通用)。
如果一个运算符两侧的操作数的数据类型不同,则系统按 “先转换、后运算”的原则,首先将数据自动转换成同一类型, 然后在同一类型数据间进行运算。转换规则如图2-8所示。
(1)横向向左的箭头,表示必须的转换。char和short 型 必须转换成 int 型,float型必须转换成double型。
2、除自动转换外,C语言也允许强制转换。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <stdio.h>#include <math.h>#include <malloc.h>#include <errno.h>#include <stdlib.h>#include <string.h>#define DEBUG#define ERROR -1#define STACKSIZE 20/* 定义字符类型栈*/typedef struct{char stackname[20];char *base;//栈底指针char *top; //栈顶指针} Stack;/* ----------------- 全局变量--------------- */ Stack OPTR, OPND; /* 定义前个运算符栈,后个操作数栈*/char expr[255]; /* 存放表达式串*/char *ptr = expr;int step = 0; /* 计算的步次*//*构造一个空栈*/int InitStack(Stack *s, char *name){s->base=(char*)malloc(STACKSIZE*sizeof(char));if(!s->base) exit (ERROR);strcpy(s->stackname, name);s->top=s->base;return 1;}/*定义四则运算符*/int In(char ch){return(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('| |ch==')'||ch=='#');}/*输出相关变量的值*/void OutputStatus( ){char *s;/* step */printf("\n%-8d", ++step); /* OPTR */for(s = OPTR.base; s < OPTR.top; s++) printf("%c", *s);printf("\t");/* OPND */for(s = OPND.base; s < OPND.top; s++) printf("%d ", *s);/* input char */printf("\t\t%c", *ptr);}/*插入*/int Push(Stack *s,char ch){#ifdef DEBUGchar *name = s->stackname;OutputStatus();if(strcmp(name, "OPND") == 0)printf("\tPUSH(%s, %d)", name, ch);elseprintf("\tPUSH(%s, %c)", name, ch);#endif*s->top=ch;s->top++;return 0;}/*删除*/char Pop(Stack *s){char p;#ifdef DEBUGOutputStatus();printf("\tPOP(%s)", s->stackname);#endifs->top--;p=*s->top;return (p);}char GetTop(Stack s){char p=*(s.top-1);return (p);}/* 判断运算符优先权,返回优先权高的*/char Precede(char c1,char c2){int i=0,j=0;static char array[49]={'>', '>', '<', '<', '<', '>', '>','>', '>', '<', '<', '<', '>', '>','>', '>', '>', '>', '<', '>', '>','>', '>', '>', '>', '<', '>', '>','<', '<', '<', '<', '<', '=', '!','>', '>', '>', '>', '!', '>', '>','<', '<', '<', '<', '<', '!', '='};switch(c1){/* i为下面array的横标*/case '+' : i=0;break;case '-' : i=1;break;case '*' : i=2;break;case '/' : i=3;break;case '(' : i=4;break;case ')' : i=5;break;case '#' : i=6;break;}switch(c2){/* j为下面array的纵标*/case '+' : j=0;break;case '-' : j=1;break;case '*' : j=2;break;case '/' : j=3;break;case '(' : j=4;break;case ')' : j=5;break;case '#' : j=6;break;}return (array[7*i+j]); /* 返回运算符*/}/*操作函数*/int Operate(int a,char op,int b){#ifdef DEBUGOutputStatus();printf("\tOPERATE(%d, %c, %d)", a, op, b); #endifswitch(op){ case '+' : return (a+b);case '-' : return (a-b);case '*' : return (a*b);case '/' : return (a/b);}}int EvalExpr( ){char c,theta,x,m,ch;int a,b;c = *ptr++;while(c!='#'||GetTop(OPTR)!='#'){if(!In(c)){m=atoi(&c);Push(&OPND,m);c = *ptr++;}elseswitch(Precede(GetTop(OPTR),c)){case '<':Push(&OPTR,c);c = *ptr++;break;case '=':x=Pop(&OPTR);c = *ptr++;break;case '>':theta=Pop(&OPTR);b=Pop(&OPND); a=Pop(&OPND);Push(&OPND,Operate(a,theta,b));break;}}return GetTop(OPND);}main( ){printf("Input the expression(end with \"#\" sign):");do{gets(expr);}while(!*expr);InitStack(&OPTR, "OPTR"); /* 初始化运算符栈*/Push(&OPTR,'#'); /* 将#压入运算符栈*/ InitStack(&OPND, "OPND"); /* 初始化操作数栈*/printf("\n\nresult:%d\n", EvalExpr());//return;}第二个作者:麻英圳学号:20031302202算法思想:具体做法是设两个栈,一个是操作数栈opnd,另一个是运算符栈oprt,分别存放操作数与运算符。
首先判断是否只有操作数时,直接出栈,当只有运算符,也出栈,显示栈为空。
按照栈后进先出的原则进行;1)遇到操作数,进操作数opnd栈,计算机继续扫描下一符号;2)遇到运算符时,需将此运算符优先级与oprt栈顶运算符优先级比较。
(1)若栈顶元素优先级低则进oprt 栈,继续扫描下一符号;(2)若栈顶元素优先级高,则运算符栈oprt栈顶元素退栈,形成一个操作码Q,同时,操作数栈opnd栈顶元素两次退栈,形成两个操作数a、b,计算机对操作数与操作码完成一次运算操作,即aQb。
其运算结果存放在操作数opnd栈中,作为一次运算的中间结果进opnd栈。
(3)若与栈oprt栈顶元素优先级相等则栈顶元素退栈。
当遇到栈顶元素是‘\0’时,表示整个运算结束,否则,继续扫描下一符号。
本程序调用了比较符号优先级函数,在除法中判断值是否为小数,化成相应的整数。
比较过程:C1C2+ - * / ( ) ‘ ‘ +-*/()‘’> > < < < > >> > < < < > >> > > > < > <> > > > < > << < < < < => .> > >> >< ,< < < < =操作过程:例:3*(7-2).步骤oprt opnd 输入字符主要操作1 ‘’3*(7-2)pushopnd(3)2 ‘’3 *(7-2)pushoprt(*)3 ‘’* 3 (7-2)pushoprt( ( )4 ‘’*( 3 7-2)pushopnd(7)5 ‘’*( 3 7 -2)pushoprt( - )6 ‘’*(- 37 2)pushopnd(2)7 ‘’*(- 3 7 2) evaluate( 7-2 )8 ‘’*( 3 5 ) popoprt( () )9 ‘’* 3 5 ‘ ‘evaluate( 3*5 )10 ‘’ 15 ‘ ‘result(15)C程序:#include"stdio.h"#include"string.h"#include"stdlib.h"#define STACKSIZE 100 /*表达式的最长字符数*/int topt=-1;int topd=-1;double opnd[STACKSIZE]; /*数字栈*/ char oprt[STACKSIZE]; /*符号栈*/ char expression[STACKSIZE];/*存储表达式*/void pushopnd(double x)/*数字压栈*/{if(topd==STACKSIZE-1)printf("Operend Stack overflow!\n");opnd[++topd]=x;}void pushoprt(char x) /*符号压栈*/ {if(topt==STACKSIZE-1)printf("Operate Stack overflow!\n");oprt[++topt]=x;}double popopnd() /*数字出栈*/{if(topd==-1) printf("Operend Stack underflow!\n");return(opnd[topd--]);}char popoprt()/*符号出栈*/{if(topt==-1) printf("Operate Stack underflow!\n");return(oprt[topt--]);}double getopnd()/*取得数字栈顶元素*/{if(topd==-1) printf("Operend Stack underflow!\n");return(opnd[topd]);}char getoprt() /*取得符号栈顶元素*/{if(topt==-1) printf("Operate Stack underflow!\n");return(oprt[topt]);}char priority(char c1,char c2)/*比较符号优先级*/{if((c1=='*'||c1=='/')&&(c2!='(')) return '>';if((c1=='+'||c1=='-')&&(c2=='+'||c2=='-'||c2==' )'||c2=='\0' )) return '>';if((c1=='+'||c1=='-')&&(c2=='*'||c2=='/'||c2=='( ')) return '<';if((c1=='*'||c1=='/')&&(c2=='(')) return '<';if(c1=='('&&c2!=')') return '<';if(c1=='('&&c2==')') return '=';if(c1==')') return '>';if(c1=='\0'&&c2=='\0') return '=';if(c1=='\0'&&c2!='\0') return '<';}double calculate(double a,char symbol,double b) /*单个符号计算*/{double result;if(symbol=='+') result=a+b;if(symbol=='-') result=a-b;if(symbol=='*') result=a*b;if(symbol=='/') result=a/b;return result;}void initexpression() /*输入表达式,以回车键结束*/{printf("Please input arithmetic expression, never input a space or a tab.\n");printf("Press Enter button to end input:\n");scanf(" %s",expression);}double dtod(char s[]) /*判定小数与整数*/{int isfrac=0; /*isfrac 指示是否小数,‘1’代表是小数*/char *p;double power=1,value=0;p=s;while(*p!='\0'){/*是小数,计算整数的值*/if(*p=='.') isfrac=1;else if(isfrac==0)value=value*10+(double)(*p-48);else{power=power*10; /*计算小数的值*/value=value+(double)(*p-48)/power;}p++;}return(value);}double evaluate(void) /*计算表达式的值*/{double a,b,gd,tempresult;char c,symbol,gt,temp[20];int i=0,isfigure=0,issigned=0;int j=0; /*issigned指示是否是带符号的数,‘1’代表是带符号的*/double number; /*isfigure指示是否是数字,‘1’代表是数字*/pushoprt('\0');c=expression[0];if(c=='+')c=expression[i++];if(c=='-')pushopnd(0);gt=getoprt();while(c!='\0'||gt!='\0'){if(c>='0'&&c<='9'||c=='.'){isfigure=1;issigned=0;temp[j++]=c;c=expression[++i];}else{if(isfigure==1){temp[j]='\0';number=dtod(temp);pushopnd(number);}/*数字压栈,清零*/isfigure=0;j=0;if(c=='(')issigned=1;if(c=='-'&&issigned==1)pushopnd(0);if(c=='+'&&issigned==1)i++; /*是有符号的数,负数压零,正数加号不要*/gt=getoprt();switch(priority(gt,c)) /*比较优先级*/{case'<':{pushoprt(c);c=expression[++i];break;}case'=':{symbol=popoprt();c=expression[++i];break;}case'>':{symbol=popoprt();b=popopnd();a=popopnd() ;tempresult=calculate(a,symbol,b);pushopnd(tempresult);break;}}}gt=getoprt();}gd=getopnd();return(gd);}main(){double result;initexpression();result=evaluate();printf("=========================\n") ;printf("* value = %f *\n",result); printf("=========================\n") ;}。