C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.bT/~wV1ap}nW程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/**************表达式计算器************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>/s%P(~v G|yZZu
#include <conio.h>|{#eWP G;d[7H+B
#include <malloc.h>-iLM)@Iv1g
#define STACK_SIZE 1003nU[B5m F }+kBQ`
#define APPEND_SIZE 106O,tgx n
struct SNode{
float data; /*存放操作数或者计算结果*/2W4U,rL$mm
char ch; /*存放运算符*/!EEW\p"?c k!{ }
};i1f!^2z.r G;bxa[1J
struct Stack{
SNode *top;T$OSR:r0?
SNode *base;
int size;
};
x4aMd(U&[,`
/*栈操作函数*/yY9wHoY%L
int InitStack(Stack &S); /*创建栈*/
int DestroyStack(Stack &S); /*销毁栈*/
int ClearStack(Stack &S); /*清空栈*/
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/pP @o*Vu
int Push(Stack &S,SNode e); /*将结点e压入栈*/
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/T^)u@2Q2g
wO/RgCG$Ts7M+X4h
/*表达式计算器相关函数*/
char get_precede(char s,char c); /*判断运算符s和c的优先级*/NRB~*s8L(y5T
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/pQ-s,|6IT)k2O!FAP
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/l0H V6P}"?
float compute(); /*表达式结算器主函数*/7T6q3M+vOqh
char *killzero(float result); /*去掉结果后面的0*/
int InitStack(Stack &S)0V5J+}-j!r B!Fx
{-J,XX.QxK Ru\8c
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); c.Go)~?%\
if(S.base==NULL)T`ox}Wt2G
{3AC#xdWFs(P.},KM
printf("动态分配内存失败!");Hq8T%B)r CQ3dF1e
return -1;wc ~-{!P&A
}
S.top=S.base;
S.size=STACK_SIZE;U!H"l'@#wv9TN
return 0;
}
4j6WH*P'Q ?
int DestroyStack(Stack &S)+f8PUe:V/Eb5@? g7i
{
free(S.base);
return 0;"y;p"z8Ge
}J#?s-o`3^
int ClearStack(Stack &S)
{+G+B \ k(K&A3]$w7l
S.top=S.base;
return 0;
}
8`y}hSL(_b b(s
int GetTop(Stack S,SNode &e)3A]M:K'n'v
{I;G/T&}+Y;@
if(S.top==S.base)6JCd!Dau
{'lb$B+rf"U7~
printf("栈以为空!");s'h{wi0mk+H j
return -1;
}bR? q\e:T
e=*(S.top-1);g2FUV1m2i s
return 0;?0k1{!b4L;G2R/R
}
int Push(Stack &S,SNode e);|gK!BGz/W7v-f9I
{&R sR8S5Ukj9i
if(S.top-S.base>=S.size)
{
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));izC$t0k0^_2r
if(S.base==NULL)
{
printf("动态分配内存失败!");
return -1;
})J(o(eK3N
S.top=S.base+S.size;
S.size+=APPEND_SIZE;-S$ZT8Q'^#p
}
*S.top=e;
S.top++;
return 0;y NGtZAr3~gJ
}+vR"r5P G
-?DO;OS a6DxX:B
int Pop(Stack &S,SNode &e) @ sE\4Di{
{ ps:Fs!U`'nf2x*k+X
if(S.top==S.base)
{sHi^H+c j0a"Rh
printf("栈为空!"); v0lq}q
return -1;
}?A}9v3E
e=*(S.top-1);
S.top--;
return 0; j$`M2iEp c0? w
}+_}:F.StQ9yv0m,[
O.tA,RX#~*[n
char get_precede(char s,char c)
{
switch(s)
{cV~6DaKBS.y
case '+': 8W \ZB3r$p)`z
case '-':
if(c=='+'||c=='-'))] e1?"U7`9W;cl
return '>';7e` H2x4g u
else if(c=='*'||c=='/')
return '<';?1t7tSq,g6t/]
else if(c=='(')]b.m.C C2kb
return '<';&}uYS'M[:s-w
else if(c==')')
return '>';_Y3|V,Ag$^Y
else L gV9iDSjy
return '>';
case '*':
case '/':O"F'?6[Ww
if(c=='+'||c=='-')
return '>';
else if(c=='*'||c=='/')
return '>';_!yp'u#?B
else if(c=='(')
return '<';
else if(c==')')#\9v8aV2X
return '>';#D*WQC5kj6D
elsew*soz8~+a7U,fbY
return '>';
case '(':
if(c=='+'||c=='-')
return '<';
else if(c=='*'||c=='/')O)N0N*A'a'woG!V
return '<';+xiSZ;^%]&i9{ A
else if(c=='(')tMK*j:Z
return '<';
else if(c==')')q`TH#L}Ag
return '=';
else*R5[6Aj$R1RKu
return 'E';
case ')':2x2rSAU0o3V1d"|z
if(c=='+'||c=='-')
return '>'; KC-{LI6^#E
else if(c=='*'||c=='/')
return '>';
else if(c=='(')0@+{Y M{+eS*K
return 'E';
else if(c==')') g`-Yd!vl
return '>';
elseN I1LH1y/c Y
return '>';$l;b&ME)|'E
case '#':
if(c=='+'||c=='-')
return '<';H3G c1xG"Av@6M
else if(c=='*'||c=='/')
return '<';
else if(c=='(')#T(L ES'rW?D-`
return '<';
else if(c==')')^ V)[kZB0tqyi5]
return 'E';
elseR {2[1A!H^$|Px7Y7@
return '=';{u2gWnpls
default:
break;
}*g_9HC R9] ])s
return 0; p s6w;j$j/w mH sT
}4n `3I9dm
int isOpr(char c)
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')0@.Xe^)oco
return 0; PB!oP9C D
else
return 1;
} s8RFO~ @Q/M
2^Z QL?@mDe
float operate(float x, char opr, float y)2sIxV)WesU
{
float result;
switch (opr)
{P8w#V/^X#s _p
case '+':
result = x + y;Y"bb$Hd-I1W!x)z'Z-Q
break;i!l4`3gfUB
case '-': 7o;xj+R Cq!M R9qw
result = x - y;
break;
case '*':
result = x * y;'s ?NdL"E
break;
case '/': %i2m9j1N2I*h4A
if (y == 0)1}a_"WP
{
printf("Divided by zero!\n");t.L `%u"Y
return 0;4_:@3I3b;eG'{,w4k+ZXU
}
else
{0N4Q4lT2HKi,N j
result = x / y; EK'MGM1U
break;\l5dYkJ\
}
default:
printf("Bad Input.\n");
return 0;|*c-H'whta'G
}A7sq+Rbxh&G$F
return result;C1h M7l o N*}~|x
}
f6l/s%b"WiqK
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
{
Stack optr,opnd;
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;,[(u4U4I ?{ z
char c;!K:h^$O5tbOow Q-zi5R
char buf[16];
int i=0;6H;Rb;f'X r(r*Y)`
8{#y$^S.N v
InitStack(optr); /*用于寄存运算符*/
InitStack(opnd); /*用于寄存操作数和计算结果*/+rl!\i5D;u
memset(buf,0,sizeof(buf));
printf("Enter your expression:");ut L^L9Jx Tiq6a[
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;[K_g$@iW
i++;Hk+AppoS4J
c=getchar();-I:`3X7}F-T
}g9Z9M9uL3g(A S\n
else /*是运算符*/
{I}A'J`
buf[i]='\0';
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/!q#Fgn6E:q
{
opn_in.data=(float)atof(buf);"_ uv4ZMik&r;s
Push(opnd,opn_in);J]z3x;g
printf("opnd入栈:[%f]\n",opn_in.data);J%}7D!r2^&QB
i=0;
memset(buf,0,sizeof(buf));3H NE8J U/ec
},u9H1@!SZ#gY8A
opr_in.ch=c;
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
{