C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/**************表达式计算器************/#V6\` D@e*q
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>Sl[Nr~
#include <malloc.h>+h.Ss"k mP
#define STACK_SIZE 100
#define APPEND_SIZE 10
Jpg#_7~
struct SNode{8P^{(}l2Z
float data; /*存放操作数或者计算结果*/3qYqw9^8urR
char ch; /*存放运算符*/
};
2b~B]I}Gz,O9K-L
struct Stack{
SNode *top;
SNode *base;
int size;
};u5}uU/o!r V8xQ
/*栈操作函数*/
int InitStack(Stack &S); /*创建栈*/&A'|1?3J e r,Jt
int DestroyStack(Stack &S); /*销毁栈*/"c4| e O[ e U
int ClearStack(Stack &S); /*清空栈*/
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/V4@ g@9Y
int Push(Stack &S,SNode e); /*将结点e压入栈*/
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/R2@ V{!J'SC
/*表达式计算器相关函数*/
char get_precede(char s,char c); /*判断运算符s和c的优先级*/@(`;r,K0hcvj
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/d\4Ggb
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
float compute(); /*表达式结算器主函数*/
char *killzero(float result); /*去掉结果后面的0*/ q3uq5@/obn&q
-Z^ ^*R Y6\i
int InitStack(Stack &S)5P w2r(QaLX
{
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));!U^4CY1BC
if(S.base==NULL)
{$p;~/K;J H1T |R |
printf("动态分配内存失败!");
return -1;1oX`2Jj
}
S.top=S.base;
S.size=STACK_SIZE;7hF {V\
return 0;#`zn#}(^?T
}
Q[&HN.v;n XbjtR#I
int DestroyStack(Stack &S)
{
free(S.base);p ebq3t9t I"W4_
return 0;2[7@'T(^ E3Bl#t
}#U)yM:q?8c.|2vdI9NS
zU'R'B{8b$~
int ClearStack(Stack &S)8J"{"U*v9q5F"`
{uT~TA f&P4} G
S.top=S.base;
return 0;
}
.T)Ml s a3Omb&_
int GetTop(Stack S,SNode &e)Ay1uU2|8e1yxN'_Z
{
if(S.top==S.base)xSN(Mt
{
printf("栈以为空!");1i W%ND$V
return -1;X9RDNnS
}5C@ FB8r-d&bL
e=*(S.top-1);\L&L;H#OE4j8g
return 0;
}SP6it6a[l
I9`||2O%V
int Push(Stack &S,SNode e)
{$A"i;AJ1Wcw
if(S.top-S.base>=S.size)
{
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));J9[l!e-oAh9U
if(S.base==NULL)
{
printf("动态分配内存失败!");[pB!F!gUC#s5F+tMt
return -1;[%d*yS8iS8S6K
}8o"{R*Kq7{
S.top=S.base+S.size;?,`Jf;S ^g
S.size+=APPEND_SIZE;
}JREg!|:s/k.n
*S.top=e;EG-f-Y&X.b9u
S.top++; |2i3],u'DVHh
return 0; Z/S"Y;I+l[PC9p
}EcM&}G!`K
int Pop(Stack &S,SNode &e)
{^*t0MUZS
if(S.top==S.base)
{7Zt(br |-a6OQ
printf("栈为空!");%w8z&tp1iG~2O4C
return -1;
}t8K gN%~N
e=*(S.top-1);#n4t"CL\i0N,WY-Y
S.top--;S${ ovw)eQ
return 0;
}
char get_precede(char s,char c)
{
switch(s)b#ZWe D%Oj
{pZA.PE1b%o
case '+':
case '-':
if(c=='+'||c=='-')s4Sh,JM&z0r.V3_
return '>';
else if(c=='*'||c=='/')-mC1oTAq ktq? }
return '<';
else if(c=='(')
return '<';
else if(c==')')
return '>';
else v4hi"?6u[I6l o
return '>';:k:e8W)Kj#X$u
case '*':@ kI%`B j {`,?]f
case '/':wQ%_n.e
if(c=='+'||c=='-')t"Bw _ FhG
return '>';
else if(c=='*'||c=='/')
return '>';
else if(c=='(')
return '<';
else if(c==')') f!k&x'pq
return '>';j/j ]BR6`*G
elsep:b!|e0J$n@$h
return '>';
case '(':
if(c=='+'||c=='-')
return '<';A a QTG_Q$IDbK
else if(c=='*'||c=='/'),vT"R kx4Y2v
return '<';.E+}~(k F2xO/S5j#a
else if(c=='(')
return '<';4Z3sH](UM2CY
else if(c==')')
return '=';dl9C3dJp
elsed!@(KeS%~1h8nUc~ _
return 'E';2\p0u}xXQz2t
case ')':9b)qr,Nh8o.E8[
if(c=='+'||c=='-')'[X|)gpB nA5?!q
return '>';C\%Zl5S6c'YR0Np
else if(c=='*'||c=='/');]nn.q'Re
return '>';
else if(c=='(')pe%\ cs pa
return 'E';1V/{Lerr
else if(c==')')/K8GKR6w5{O
return '>';s3`+_5N Do9\W7oY.y
elsel"WHJ V!H
return '>';"C i%Ij1z-{7jm
case '#':,m y_~%~}4N,g
if(c=='+'||c=='-')AQ\:T*z!w/^
return '<';
else if(c=='*'||c=='/')/{cd)E8]8h
return '<';
else if(c=='(')
return '<';
else if(c==')')
return 'E';n sJ7n4G_ C;N v*`M:~
elseR2|u+GIG)Y&j(rPL
return '='; ~u/J7u5M\*xa0|;[
default:
break;GS_1p.m8hxI
}
return 0;
};T CGi(nJeSQ
kB.{n`
int isOpr(char c)zkU}-s:X
{;^"|6\#w1RuJrh}+B
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
return 0;
else
return 1;
}
float operate(float x, char opr, float y)W*ZeG f1FA'H2k
{
float result;
switch (opr)c,N/n0QGi:BM[BR
{
case '+':
result = x + y;
break;
case '-':
result = x - y;}xVqf
break; l v Z{9H1m X%w:m\
case '*':
result = x * y;'vY+A rb/s{5O
break;
case '/':
if (y == 0)f"V ?hM:E0M
{$x^$C;zT!c/T2E'V
printf("Divided by zero!\n");$j)e R8H~[
return 0;5F7Q^]x? oc
}*Y3w&S:Fr g
else
{
result = x / y;
break;WoaPo@+g4?;kT(m
}*v ?Z"Qv N!|'L
default:
printf("Bad Input.\n");
return 0;
}"rOk,bwP\
return result;
}
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
{`S2x9z.{.D+fk'hS
Stack optr,opnd; O(wC g,_3@
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
char c;^BA qA5U*Qo8Q{y
char buf[16];
int i=0;3{ GdZb4?
sv~-_+~C&nb@e
InitStack(optr); /*用于寄存运算符*/
InitStack(opnd); /*用于寄存操作数和计算结果*/
memset(buf,0,sizeof(buf));
5~-sO%cfe
printf("Enter your expression:");
opr_in.ch='#'; BdU En#ow
Push(optr,opr_in); /*'#'入栈*/F2AQ2?CT qG
GetTop(optr,opr_top);
c=getchar();`-_!w~'G-lG \
while(c!='='||opr_top.ch!='#')+vo"eJ L iwV
{bj O]v JrKn
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/p@(J/TL2Mdm
{-Lif_u
buf[i]=c;'^U.Kk/{^K
i++;0uQ+z `.{"w
c=getchar();
}"Lu5z ^)G(YZ'Gu
else /*是运算符*/
{
buf[i]='\0';.FHi(^{Z0Ls
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/8U:L(UM"f Uk2k
{
opn_in.data=(float)atof(buf);
Push(opnd,opn_in);tlH/E9T%]_
printf("opnd入栈:[%f]\n",opn_in.data);J!UH/mMnz/c
i=0;5?K*E?y Q["?'~&[
memset(buf,0,sizeof(buf));
}
opr_in.ch=c;1UEgE#Cbk
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/7SJ3`6E!|v
{
case '<': /*优先级小于栈顶结点,则运算符入栈*/
Push(optr,opr_in);
printf("optr入栈:[%c]\n",opr_in.ch);
c=getchar();
break;
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
Pop(optr,e);-d(a#a{cM
printf("optr出栈:去掉括号\n");