原帖及讨论: http://bbs.bc-cn.net/dispbbs.asp?BoardID=5&ID=172017 为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)= /**************表达式计算器************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #include <malloc.h> #define STACK_SIZE 100 #define APPEND_SIZE 10 struct SNode{ float data; /*存放操作数或者计算结果*/ char ch; /*存放运算符*/ }; struct Stack{ SNode *top; SNode *base; int size; }; /*栈操作函数*/ int InitStack(Stack &S); /*创建栈*/ int DestroyStack(Stack &S); /*销毁栈*/ int ClearStack(Stack &S); /*清空栈*/ int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/ int Push(Stack &S,SNode e); /*将结点e压入栈*/ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ /*表达式计算器相关函数*/ char get_precede(char s,char c); /*判断运算符s和c的优先级*/ int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/ float compute(); /*表达式结算器主函数*/ char *killzero(float result); /*去掉结果后面的0*/ int InitStack(Stack &S) { S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); if(S.base==NULL) { printf("动态分配内存失败!"); return -1; } S.top=S.base; S.size=STACK_SIZE; return 0; } int DestroyStack(Stack &S) { free(S.base); return 0; } int ClearStack(Stack &S) { S.top=S.base; return 0; } int GetTop(Stack S,SNode &e) { if(S.top==S.base) { printf("栈以为空!"); return -1; } e=*(S.top-1); return 0; } int Push(Stack &S,SNode e) { if(S.top-S.base>=S.size) { S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); if(S.base==NULL) { printf("动态分配内存失败!"); return -1; } S.top=S.base+S.size; S.size+=APPEND_SIZE; } *S.top=e; S.top++; return 0; } int Pop(Stack &S,SNode &e) { if(S.top==S.base) { printf("栈为空!"); return -1; } e=*(S.top-1); S.top--; return 0; } char get_precede(char s,char c) { switch(s) { case '+': case '-': if(c=='+'||c=='-') return '>'; else if(c=='*'||c=='/') return '<'; else if(c=='(') return '<'; else if(c==')') return '>'; else return '>'; case '*': case '/': if(c=='+'||c=='-') return '>'; else if(c=='*'||c=='/') return '>'; else if(c=='(') return '<'; else if(c==')') return '>'; else return '>'; case '(': if(c=='+'||c=='-') return '<'; else if(c=='*'||c=='/') return '<'; else if(c=='(') return '<'; else if(c==')') return '='; else return 'E'; case ')': if(c=='+'||c=='-') return '>'; else if(c=='*'||c=='/') return '>'; else if(c=='(') return 'E'; else if(c==')') return '>'; else return '>'; case '#': if(c=='+'||c=='-') return '<'; else if(c=='*'||c=='/') return '<'; else if(c=='(') return '<'; else if(c==')') return 'E'; else return '='; default: break; } return 0; } int isOpr(char c) { if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') return 0; else return 1; } float operate(float x, char opr, float y) { float result; switch (opr) { case '+': result = x + y; break; case '-': result = x - y; break; case '*': result = x * y; break; case '/': if (y == 0) { printf("Divided by zero!/n"); return 0; } else { result = x / y; break; } default: printf("Bad Input./n"); return 0; } return result; } float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/ { Stack optr,opnd; struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; char c; char buf[16]; int i=0; InitStack(optr); /*用于寄存运算符*/ InitStack(opnd); /*用于寄存操作数和计算结果*/ memset(buf,0,sizeof(buf)); printf("Enter your expression:"); opr_in.ch='#'; Push(optr,opr_in); /*'#'入栈*/ GetTop(optr,opr_top); c=getchar(); while(c!='='||opr_top.ch!='#') { if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ { buf[i]=c; i++; c=getchar(); } else /*是运算符*/ { buf[i]='/0'; if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/ { opn_in.data=(float)atof(buf); Push(opnd,opn_in); printf("opnd入栈:[%f]/n",opn_in.data); i=0; memset(buf,0,sizeof(buf)); } opr_in.ch=c; switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ { case '<': /*优先级小于栈顶结点,则运算符入栈*/ Push(optr,opr_in); printf("optr入栈:[%c]/n",opr_in.ch); c=getchar(); break; case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ Pop(optr,e); printf("optr出栈:去掉括号/n"); c=getchar(); break; case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/ Pop(optr,opr_t); printf("optr出栈:[%c]/n",opr_t.ch); if(Pop(opnd,b)<0) { printf("Bad Input!/n"); fflush(stdin); return -1; } printf("opnd出栈:[%f]/n",b.data); if(Pop(opnd,a)<0) { printf("Bad Input!/n"); fflush(stdin); return -1; } printf("opnd出栈:[%f]/n",a.data); opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/ Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ printf("结果入栈:[%f]/n",opn_tmp.data); break; } } GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ } GetTop(opnd,opn_tmp); DestroyStack(optr); DestroyStack(opnd); return opn_tmp.data; } char *killzero(char *res,float result) { int i; sprintf(res,"%f",result); i=(int)strlen(res)-1; while(i&&res[i]=='0') { res[i]='/0'; i--; } if(res[i]=='.') res[i]='/0'; return res; } int main() { char ch; char res[64]; float result; while(1) { result=compute(); printf("/nThe result is:%s/n",killzero(res,result)); printf("Do you want to continue(y/n)?:") ; ch=getch(); putchar(ch); if(ch=='n'||ch=='N') break; else system("cls"); } return 0; } |