【问题描述】 表达式计算是实现程序设计语言的基本问题之一 也是栈的应用的一个典型的例子设计一个程序,使用算法优先打法对算术表达式求值。 【基本要求】 (1)实现栈的顺序存储结构的基本操作 包括初始化栈、清空栈、入栈、出栈、取栈顶元素等。 (2)以字符序列的形式从终端输入语法正确的、不含变量的整数表达式 利用教科书p35页表3.1给出的算符优先关系,实现对算术四则混合运算表达式的求值。 【测试数据】 4*(7-2):99-34;2038/24 【实现提示】 (1)设置运算符栈和算数栈。 (2)在读入表达式的字符的同时,完成运算符和运算数(整数)的识别处理 以及相应的运算。 (3)在识别出运算的同时,要将其字符序列形式转换成整数形式。*/
下面展示一些 内联代码片。
这里是基操 #include "stdio.h" #include "malloc.h" #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1//不可行的 #define OVERFLOW -2//溢出 typedef int Status;//状态 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 typedef struct{ SElemType *base; SElemType *top; int stacksize; }SqStack; //构造一个空栈 Status InitStack(SqStack *S){ S->base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if(!S->base) exit(OVERFLOW); S->top=S->base; S->stacksize=STACK_INIT_SIZE; return OK; } //判断是否为空栈 Status StackEmpty(SqStack S){ if(S.top == S.base) return TRUE; else return FALSE; } //用e返回S的顶元素 Status GetTop(SqStack S, SElemType *e){ if(S.top == S.base) return ERROR; *e = *(S.top-1); return OK; } //插入e为新的顶元素 Status Push(SqStack *S, SElemType e){ if((S->top - S->base) >= S->stacksize){ S->base = ( SElemType*)realloc(S->base, (S->stacksize+STACKINCREMENT)*sizeof(SElemType) ); if(!S->base) exit(OVERFLOW); S->top = S->base +S->stacksize; S->stacksize += STACKINCREMENT; } *(S->top)=e; S->top++; return OK; } //删除S的顶元素,并用e返回其值 Status Pop(SqStack *S, SElemType *e){ if(S->top == S->base) return ERROR; S->top--; *e = *(S->top); return OK; } //从栈底到栈顶依次对S的每个元素调用函数Visit(),一旦失败操作无效 Status ListTraverse(SqStack S,Status (*visit)(SElemType)){ SElemType *p; p=S.base; for(p=S.base;p<S.top;p++) (*visit)(*p); return OK; } //输出元素e Status output(SElemType e){ printf("%d ",e); return OK; } 这里是源码1 #include<iostream> #include<string> #include<stdlib.h> #include"stack.h" #include<Windows.h> using namespace std; /* 是让命名空间中的名称曝光的最简单的方法。命名空间像是在众多名称的可见范围之间竖起一道道围墙。 可以避免和应用程序发生命名冲突的问题 所谓命名冲突是指在应用程序内两个不同的实体具有相同的名称 导致程序无法区分两者。命名冲突发生时,程序必须等到该命名冲突获得解析之后,才得以继续执行*/ char Precede(char a, char b) /*这是一个定义了算术优先级的表单 分别对应加减乘除和括号情况*/ { int i, j; char pre[][10] = { /*运算符之间的优先级制作成一张表格*/ { '>','>','<','<','<','>','<','<','<','>' }, { '>','>','<','<','<','>','<','<','<','>' }, { '>','>','>','>','<','>','<','<','<','>' }, { '>','>','>','>','<','>','<','<','<','>' }, { '<','<','<','<','<','>','<','<','<','0' }, { '>','>','>','>','0','=','>','>','>','>' } }; switch (a) { case '+': i = 0; break; case '-': i = 1; break; case '*': i = 2; break; case '/': i = 3; break; case '(': i = 4; break; case ')': i = 5; break; } switch (b) { case '+': j = 0; break; case '-': j = 1; break; case '*': j = 2; break; case '/': j = 3; break; case '(': j = 4; break; case ')': j = 5; break; } return pre[i][j]; } int tranNum(stackL *postexp, string exp, int i) //将中缀表达式中的多位数,按照从低位到高位顺序压入postexp栈中,方便后续计算 { int len = 0,j; char expRead = exp[i]; while (expRead <= '9'&&expRead >= '0')//获得数符长度 { //PushL(postexp, expRead); i++; expRead = exp[i]; len++; } for (j = i-1; j >= i - len;j--) { PushL(postexp, exp[j]); } i--; //使i恰好下次循环指向非数字 PushL(postexp, '#'); return i; } void tranPost(stackL *op, stackL*postexp, string exp)//将中缀表达式转化为后缀表达式 { int i; char expRead, tempChar,preOp; InitStackL(op); InitStackL(postexp); PushL(op, '#'); PushL(postexp, '#'); for (i = 0; i < (int)exp.length(); i++) { expRead = exp[i]; if (expRead == '#') //表达式尾端 break; else if (expRead == ' ') //忽略空格 continue; else if (expRead <= '9'&&expRead >= '0') //处理操作数,传入i,postexp,exp,返回i { i = tranNum(postexp, exp, i); } else if (expRead != '(' && expRead != ')' && expRead == exp[i + 1])//处理单目运算符(++、--) { if (expRead == '+') PushL(op, 'a'); else if (expRead == '-') PushL(op, 's'); else { cout << "error\n"; break; } i++; //使遍历跳过自增自减符号到下一字符 } else //处理普通操作符 { tempChar = GetTopL(op); preOp = Precede(tempChar, expRead); if (expRead == ')') { tempChar = PopL(op); while (tempChar != '(') { PushL(postexp, tempChar); //PushL(postexp, '#'); tempChar = PopL(op); } } else if (preOp == '>') { PushL(postexp, PopL(op)); PushL(op, expRead); //PushL(postexp, '#'); } else if (preOp == '<') PushL(op, expRead); } } while (op->next->data != '#') { tempChar = PopL(op); PushL(postexp, tempChar); } } int ary(int expn) { int i; int sum = 1; for (i = 0; i < expn; i++) { sum *= 10; } return sum; } int getValue(stackL *assistStack)//求得属于同一数值的连续数符的值 { int value = 0; int ex = 0; char charValue; charValue = PopL(assistStack); while (charValue != '#') { value += (charValue - 48)*ary(ex); ex++; charValue = PopL(assistStack); } return value; } void pushBack(stackL *postexp, int valueBack)//将计算出来的int值化作字符,并从低位到高位压入主栈中 { int i = 0; char valueChar; if (valueBack == 0) PushL(postexp, '0'); while (valueBack != 0) { valueChar= (valueBack % 10)+48; PushL(postexp, valueChar); valueBack = valueBack / 10; } PushL(postexp, '#'); } int power(int value, int expn) { int result = 1; for (int i = 0; i < expn; i++) { result *= value; } return result; } int partCalu(stackL *postexp,stackL *assistStack )//计算小段式的值,此时两个操作数分别在两个栈中,操作数在辅助栈里 { int value_1, value_2, value_3; char opera; PushL(assistStack, PopL(postexp)); while (GetTopL(postexp) <= '9'&&GetTopL(postexp) >= '0')//使两个操作数和运算符都在辅助栈中,方便操作数的还原 { PushL(assistStack, PopL(postexp)); } value_1 = getValue(assistStack); value_2 = getValue(assistStack); opera = PopL(assistStack); switch (opera) { case '+': value_3 = value_1 + value_2; break; case '-': value_3 = value_1 - value_2; break; case '*': value_3 = value_1 * value_2; break; case '/': if (value_2 == 0) { cout << "error:除数为0" << endl; return 0; } else value_3 = value_1 / value_2; break; case'^': value_3 = power(value_1, value_2); default: break; } if (assistStack->next == NULL && postexp->next == NULL) { cout << value_2; return 0; } else if (assistStack->next == NULL && postexp->next->next == NULL)//结束条件 { cout << value_3; return 0; } pushBack(postexp, value_3);//将部分求值结果重新压入主栈 if (GetTopL(assistStack) <= '9'&&GetTopL(assistStack) >= '0')//再次满足部分求值条件 partCalu(postexp, assistStack); } int caluValue(stackL *postexp) { int control = 1; int value = 0; stackL *assistStack; char postRead,opera; assistStack = (stackL*)malloc(sizeof(stackL)); InitStackL(assistStack); postRead = GetTopL(postexp); while (postexp->next != NULL) { /*主栈栈顶为#时进行是否部分求值检测, 如果辅助栈顶为数符的话,则进行部分求值,求值后将值继续压入主栈, 压入时注意低位先压入,这样就可以在连续求值时进行递归*/ if (postRead == '#'&&assistStack->next!=NULL) { if (GetTopL(assistStack) <= '9'&&GetTopL(assistStack) >= '0') { control =partCalu(postexp, assistStack); if (control == 0) return 0; } else if(GetTopL(assistStack) > '9'|| GetTopL(assistStack) < '0') PushL(assistStack, PopL(postexp)); } else if (postRead == 'a'||postRead == 's') { opera=PopL(postexp); if (GetTopL(postexp) != '#') { cout << "单目运算符运用错误,应放在数字后" << endl; exit(0); } else { PushL(assistStack,PopL(postexp)); while (GetTopL(postexp) <= '9'&&GetTopL(postexp) >= '0')//将数符弹出主栈 并压入辅助栈中 { PushL(assistStack, PopL(postexp)); } if (opera == 'a') pushBack(postexp, getValue(assistStack) + 1); else if (opera == 's') pushBack(postexp, getValue(assistStack) - 1); } } else PushL(assistStack, PopL(postexp)); postRead = GetTopL(postexp); } } int main() { while (1) { string express; cout << "please enter the expression statement,and end with '#'" << endl; cin >> express; stackL *op, *postexp; op = (stackL*)malloc(sizeof(stackL)); // 操作符栈 postexp = (stackL*)malloc(sizeof(stackL)); //后缀表达式栈 tranPost(op, postexp, express); //将输入的中缀表达式转化为后缀表达式 cout << express << " = "; caluValue(postexp); //计算后缀表达式的值 cout << "\n\n"; free(op); free(postexp); } }下面展示一些 内联代码片。
上面运行出错是少包了啦小笨蛋,文件名字就写成少包的名字 #include<stdlib.h> #include<iostream> using namespace std; typedef char Elemtype; typedef struct LinkStack { Elemtype data; struct LinkStack *next; }stackL; //初始化 void InitStackL(stackL *lst) { lst->next = NULL; } //判断是否为空,为空则返回1 int StackLEmpty(stackL *lst) { return (lst->next == NULL); } //压入 void PushL(stackL *lst, Elemtype x) { stackL *p; p = (stackL*)malloc(sizeof(stackL)); p->next = lst->next; p->data = x; lst->next = p; } //弹出 Elemtype PopL(stackL* lst) { stackL *toFree; if (lst->next == NULL); //cout << "the stack is empty\n"; else { Elemtype x; x = (lst->next)->data; toFree = lst->next; lst->next = (lst->next)->next; free(toFree); return x; } return 0; } //获取栈顶元素 Elemtype GetTopL(stackL* lst) { if (lst->next == NULL); //cout << "the stack is empty\n"; else { Elemtype x; x = lst->next->data; return x; } return 0; }下面展示一些 内联代码片。
源码二 typedef int SElemType; /*放入堆栈的元素的类型*/ #include <ctype.h> #include "stack_s.c" /*判断输入的某个字符是否是运算符 *c表示输入的字符 *op数组中存放系统能识别的运算符 */ Status in(char c,char op[]){ char *p; p=op; while(*p != '\0'){ if(c == *p) return TRUE; p++; } return FALSE; } /*比较两个运算符的优先级 *a,b中存放待比较的运算符 *'>'表示a>b *'0'表示不可能出现的比较 */ char Precede(char a, char b){ int i,j; char pre[][7]={ /*运算符之间的优先级制作成一张表格*/ {'>','>','<','<','<','>','>'}, {'>','>','<','<','<','>','>'}, {'>','>','>','>','<','>','>'}, {'>','>','>','>','<','>','>'}, {'<','<','<','<','<','=','0'}, {'>','>','>','>','0','>','>'}, {'<','<','<','<','<','0','='}}; switch(a){ 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(b){ 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 pre[i][j]; } /*进行实际的运算 *a,b中分别以整数的形式存放两个待运算的操作数 *theta中存放代表操作符的字符 *结果以整数的形式返回 */ int Operate(int a, char theta, int b){ int i,j,result; i=a; j=b; switch(theta) { case '+': result = i + j; break; case '-': result = i - j; break; case '*': result = i * j; break; case '/': result = i / j; break; } return result; } /*从输入缓冲区中获得下一个整数或运算符,并通过n带回到主调函数 *返回值为1表示获得的是运算符 *返回值为0表示获得的是整形操作数 */ int getNext(int *n){ char c; *n=0; while((c=getchar())==' '); /*跳过一个或多个空格*/ if(!isdigit(c)){ /*通过函数判断如果字符不是数字,那么只能是运算符*/ *n=c; return 1; } do { /*能执行到该条语句,说明字符是数字,此处用循环获得连续的数字*/ *n=*n*10+(c-'0'); /*把连续的数字字符转换成相对应的整数*/ c=getchar(); } while(isdigit(c)); /*如果下一个字符是数字,进入下一轮循环*/ ungetc(c,stdin); /*新读入的字符不是数字,可能是运算符,为了不影响下次读入,把该字符放回到输入缓冲区*/ return 0; } int EvaluateExpression(){ int n; int flag; int c; char x,theta; int a,b; char OP[]="+-*/()#"; SqStack OPTR; SqStack OPND; InitStack(&OPTR); Push(&OPTR,'#'); InitStack(&OPND); flag=getNext(&c); GetTop(OPTR, &x); while(c!='#' || x != '#') { if(flag == 0) { Push(&OPND,c); flag = getNext(&c); } else { GetTop(OPTR, &x); switch(Precede(x, c)) { case '<'://栈顶元素优先级低 Push(&OPTR,c); flag = getNext(&c); break; case '='://脱括号并接受下一字符 Pop(&OPTR,&x); flag = getNext(&c); break; case '>':// 退栈并将运算结果入栈 Pop(&OPTR, &theta); Pop(&OPND,&b); Pop(&OPND,&a); Push(&OPND, Operate(a, theta, b)); break; } } GetTop(OPTR, &x); } GetTop(OPND, &c); return c; } void main(){ int c; printf("Please input one expression:"); c=EvaluateExpression(); printf("Result=%d\n",c); getch(); } #include<iostream> #include<string> #include<stdlib.h> #include"stack.h" #include<Windows.h> using namespace std; char Precede(char a, char b) { int i, j; char pre[][10] = { /*运算符之间的优先级制作成一张表格*/ { '>','>','<','<','<','>','<','<','<','>' }, { '>','>','<','<','<','>','<','<','<','>' }, { '>','>','>','>','<','>','<','<','<','>' }, { '>','>','>','>','<','>','<','<','<','>' }, { '<','<','<','<','<','>','<','<','<','0' }, { '>','>','>','>','0','=','>','>','>','>' }, { '>','>','>','>','<','>','>','<','<','>' }, { '>','>','>','>','<','>','>','>','>','>' }, { '>','>','>','>','<','>','>','>','>','>' }, { '<','<','<','<','<','0','<','<','<','=' } }; switch (a) { 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; case 'a': i = 7; break;//用a代替++符号方便处理 case 's': i = 8; break;//用s代替--符号方便处理 case '#': i = 9; break; } switch (b) { 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; case '++': j = 7; break; case '--': j = 8; break; case '#': j = 9; break; } return pre[i][j]; } int tranNum(stackL *postexp, string exp, int i)//将中缀表达式中的多位数,按照从低位到高位顺序压入postexp栈中,方便后续计算 { int len = 0,j; char expRead = exp[i]; while (expRead <= '9'&&expRead >= '0')//获得数符长度 { //PushL(postexp, expRead); i++; expRead = exp[i]; len++; } for (j = i-1; j >= i - len;j--) { PushL(postexp, exp[j]); } i--; //使i恰好下次循环指向非数字 PushL(postexp, '#'); return i; } void tranPost(stackL *op, stackL*postexp, string exp)//将中缀表达式转化为后缀表达式 { int i; char expRead, tempChar,preOp; InitStackL(op); InitStackL(postexp); PushL(op, '#'); PushL(postexp, '#'); for (i = 0; i < (int)exp.length(); i++) { expRead = exp[i]; if (expRead == '#') //表达式尾端 break; else if (expRead == ' ') //忽略空格 continue; else if (expRead <= '9'&&expRead >= '0') //处理操作数,传入i,postexp,exp,返回i { i = tranNum(postexp, exp, i); } else if (expRead != '(' && expRead != ')' && expRead == exp[i + 1])//处理单目运算符(++、--) { if (expRead == '+') PushL(op, 'a'); else if (expRead == '-') PushL(op, 's'); else { cout << "error\n"; break; } i++; //使遍历跳过自增自减符号到下一字符 } else //处理普通操作符 { tempChar = GetTopL(op); preOp = Precede(tempChar, expRead); if (expRead == ')') { tempChar = PopL(op); while (tempChar != '(') { PushL(postexp, tempChar); //PushL(postexp, '#'); tempChar = PopL(op); } } else if (preOp == '>') { PushL(postexp, PopL(op)); PushL(op, expRead); //PushL(postexp, '#'); } else if (preOp == '<') PushL(op, expRead); } } while (op->next->data != '#') { tempChar = PopL(op); PushL(postexp, tempChar); } } int ary(int expn) { int i; int sum = 1; for (i = 0; i < expn; i++) { sum *= 10; } return sum; } int getValue(stackL *assistStack)//求得属于同一数值的连续数符的值 { int value = 0; int ex = 0; char charValue; charValue = PopL(assistStack); while (charValue != '#') { value += (charValue - 48)*ary(ex); ex++; charValue = PopL(assistStack); } return value; } void pushBack(stackL *postexp, int valueBack)//将计算出来的int值化作字符,并从低位到高位压入主栈中 { int i = 0; char valueChar; if (valueBack == 0) PushL(postexp, '0'); while (valueBack != 0) { valueChar= (valueBack % 10)+48; PushL(postexp, valueChar); valueBack = valueBack / 10; } PushL(postexp, '#'); } int power(int value, int expn) { int result = 1; for (int i = 0; i < expn; i++) { result *= value; } return result; } int partCalu(stackL *postexp,stackL *assistStack )//计算小段式的值,此时两个操作数分别在两个栈中,操作数在辅助栈里 { int value_1, value_2, value_3; char opera; PushL(assistStack, PopL(postexp)); while (GetTopL(postexp) <= '9'&&GetTopL(postexp) >= '0')//使两个操作数和运算符都在辅助栈中,方便操作数的还原 { PushL(assistStack, PopL(postexp)); } value_1 = getValue(assistStack); value_2 = getValue(assistStack); opera = PopL(assistStack); switch (opera) { case '+': value_3 = value_1 + value_2; break; case '-': value_3 = value_1 - value_2; break; case '*': value_3 = value_1 * value_2; break; case '/': if (value_2 == 0) { cout << "error:除数为0" << endl; return 0; } else value_3 = value_1 / value_2; break; case'^': value_3 = power(value_1, value_2); default: break; } if (assistStack->next == NULL && postexp->next == NULL) { cout << value_2; return 0; } else if (assistStack->next == NULL && postexp->next->next == NULL)//结束条件 { cout << value_3; return 0; } pushBack(postexp, value_3);//将部分求值结果重新压入主栈 if (GetTopL(assistStack) <= '9'&&GetTopL(assistStack) >= '0')//再次满足部分求值条件 partCalu(postexp, assistStack); } int caluValue(stackL *postexp) { int control = 1; int value = 0; stackL *assistStack; char postRead,opera; assistStack = (stackL*)malloc(sizeof(stackL)); InitStackL(assistStack); postRead = GetTopL(postexp); while (postexp->next != NULL) { /*主栈栈顶为#时进行是否部分求值检测, 如果辅助栈顶为数符的话,则进行部分求值,求值后将值继续压入主栈, 压入时注意低位先压入,这样就可以在连续求值时进行递归*/ if (postRead == '#'&&assistStack->next!=NULL) { if (GetTopL(assistStack) <= '9'&&GetTopL(assistStack) >= '0') { control =partCalu(postexp, assistStack); if (control == 0) return 0; } else if(GetTopL(assistStack) > '9'|| GetTopL(assistStack) < '0') PushL(assistStack, PopL(postexp)); } else if (postRead == 'a'||postRead == 's') { opera=PopL(postexp); if (GetTopL(postexp) != '#') { cout << "单目运算符运用错误,应放在数字后" << endl; exit(0); } else { PushL(assistStack,PopL(postexp)); while (GetTopL(postexp) <= '9'&&GetTopL(postexp) >= '0')//将数符弹出主栈 并压入辅助栈中 { PushL(assistStack, PopL(postexp)); } if (opera == 'a') pushBack(postexp, getValue(assistStack) + 1); else if (opera == 's') pushBack(postexp, getValue(assistStack) - 1); } } else PushL(assistStack, PopL(postexp)); postRead = GetTopL(postexp); } } int main() { while (1) { string express; cout << "please enter the expression statement,and end with '#'" << endl; cin >> express; stackL *op, *postexp; op = (stackL*)malloc(sizeof(stackL)); // 操作符栈 postexp = (stackL*)malloc(sizeof(stackL)); //后缀表达式栈 tranPost(op, postexp, express); //将输入的中缀表达式转化为后缀表达式 cout << express << " = "; caluValue(postexp); //计算后缀表达式的值 cout << "\n\n"; free(op); free(postexp); } }下面展示一些 内联代码片。
这个是我认为初学者最好理解的,但对栈的使用相对较少,所以放到最后面 #include <stdio.h> #include <string.h> #include <stack> #include <stdlib.h> #include <ctype.h> using namespace std; stack<double>num; stack<char>ch; //将字符对应的行数以数字形式返回 int tonum(char c) { switch(c) { case '+':return 0;break; case '-':return 1;break; case '*':return 2;break; case '/':return 3;break; case '(':return 4;break; case ')':return 5;break; case '=':return 6;break; } } //计算 double cal(double a,double b,char c) { if(c=='+') return a+b; if(c=='-') return a-b; if(c=='*') return a*b; if(c=='/') return a/b; } //比较两个运算符的大小 char compare(char a,char b) { //运算符优先表 char oper[7][8]={ ">><<<>>", ">><<<>>", ">>>><>>", ">>>><>>", "<<<<<= ", ">>>> >>", "<<<<< ="}; int x=tonum(a); int y=tonum(b); //返回比较结果 return oper[x][y]; } int main() { char str[105];//拿到所有的输入 while(scanf("%s",str)!=EOF)//保证输入不为空 { //清空结果栈 while(!num.empty())//num栈里面不是空的 num.pop(); //清空运算符栈 while(!ch.empty())//ch栈里面不是空的 ch.pop(); ch.push('=');//ch栈放入=号 char temp[30];//这个数组是存放输入的东西里面的数字小数点的 int len=strlen(str);//这里是拿到整个输入的长度 int k=0; str[len]='=';str[len+1]='\0'; for(int i=0;i<=len;)//遍历整个输入找到数字类型的东西 { //如果是0-9或者小数点,计算继续for循环求其值 if(isdigit(str[i])||str[i]=='.') //这个循环是判断整个输入找到数字类型的东西放入temp数组 { temp[k++]=str[i]; i++; continue; } if(k!=0) { //将字符串temp通过atof函数转换成double类型的浮点数 num.push(atof(temp)); //初始化字符串temp memset(temp,0,sizeof(temp)); //初始下标k k=0; } // printf("%c",compare(ch.top(),str[i])); switch(compare(ch.top(),str[i])) { //如果栈顶运算符小于当前运算符,将当前字符加入运算符栈 case '<':ch.push(str[i]);i++;break; //如果栈顶运算符等于当前运算符,消去栈顶运算符 case '=':ch.pop();i++;break; //如果栈顶运算符大于当前运算符,计算当前值,并使其结果进结果栈 case '>':{ double a=num.top();num.pop(); double b=num.top();num.pop(); // printf("%lf %c %lf\n",b,ch.top(),a); num.push(cal(b,a,ch.top())); ch.pop(); break; } } } //保留两位小数输出结果 printf("%.2lf\n",num.top()); num.pop(); } return 0; }认真看看!!!代码里面有注释!!!!