捌玖网络工作室's Archiver

zw2004 发表于 2008-1-21 17:17

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6gBg,L'Z?H@
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=4WI8VBu6^_
/**************表达式计算器************/
.l"JD5n,N0r^J|wg #include <stdio.h>3BM!x6|g;oF+I
#include <stdlib.h>
?'] hk/Zf #include <string.h>.\WY c~#^Ws@
#include <conio.h>Tw`;Z%LM
#include <malloc.h>
:b9W9C3eb'ru u
&|F$@ RA*w P #define STACK_SIZE 100$f&f Nl9i A?N.F#x
#define APPEND_SIZE 10
JF q6[#A%q1b1X &w:MLD3[ I
struct SNode{@|y:G l;hz
    float data; /*存放操作数或者计算结果*/
mLT.l_!r X     char ch; /*存放运算符*/-`Qb3E'X | kCF^
};
uQ4B,C;}B
$[P k(H&B/v struct Stack{2_+@R+L$x7z0X(pX
    SNode *top;"z*`8JnS#k x
    SNode *base;
8[8DJ gykW|     int size;7UsO3F2j
};
.rs&NN-N-K
Lu ]Fu)c N /*栈操作函数*/
)?H1c~q7m*Y8xJv int InitStack(Stack &S); /*创建栈*/
n%Y A8FaH.l1W int DestroyStack(Stack &S); /*销毁栈*/
J{5l3P6AW N int ClearStack(Stack &S); /*清空栈*/!h+d]iW0Y9fg])Tw
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
g?3QAJB-g int Push(Stack &S,SNode e); /*将结点e压入栈*/,G@o1CcLH
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ pKb6]!{Lif7c9E

Q7Oe'R!R&` /*表达式计算器相关函数*/
7I {t*s!x T.l char get_precede(char s,char c); /*判断运算符s和c的优先级*/V,B)r9F&d Il
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/%K~.zQj
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/'X v0^#?joC5e
float compute(); /*表达式结算器主函数*/0p2r+R]5[!A
char *killzero(float result); /*去掉结果后面的0*/ *`-s*Ucim6Kq
Yb5j:ISWC?$r3dY
int InitStack(Stack &S)3v5g+G.k/m
{
0EY.u$Otx#M     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
W%RBV8d o @     if(S.base==NULL)
W0vm1v3c_R     {
4_K lW.C;w         printf("动态分配内存失败!");
tx2ZT4K S         return -1;A6`6J\ie3\ t \
    }*K+Q]x+a,i2A J J
    S.top=S.base;
C/e foIZ:r/e"C&LjH     S.size=STACK_SIZE;
N!Q4r ZP1n3w;C     return 0;s ooQ%G/i
}+|1{-C9p o
P!H`"i a e#x
int DestroyStack(Stack &S) Cl8hF&L[w
{jyf0h+g
    free(S.base);
ZF cnl,c3?.d1L3`'~0X     return 0;o Il4r pG
}ak,MDI

"Q:L.qobsi4OY int ClearStack(Stack &S)
;p!O/pKW6qt {
rI5|bp"of-|     S.top=S.base;0PFG,U6~5h}\(K?)fn
    return 0; _*D J8Q5Tq9Zj$N
}:pzwsaE,t

U"a*B5l'c{ int GetTop(Stack S,SNode &e)w U%A{ r(A B*N,u3E:k'a
{
fm)UwY/KI z     if(S.top==S.base)E0gA-Oc.i
    {-X)J6G0|/` oJk2I
        printf("栈以为空!");
%tVS ZU(m/u(t         return -1;
;T;hZ}[B.X     }
r'?y] C U-IMm'o     e=*(S.top-1);*Y#A @(we1K]5Pci
    return 0;o AbD!v_4o z
}"R*D(vY I\3u
t'h3@\6D0c:i4u+G'y
int Push(Stack &S,SNode e)
Wr2y:h'{5t7A {%|6E|pu5jd
    if(S.top-S.base>=S.size)P+E[ f,z4_
    { NC"eHe(gyk
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));vYtB wkN
        if(S.base==NULL)H@4@p RK d f
        {
1C I,iC~"g             printf("动态分配内存失败!");/C%Tr0h+TH*{ ?7w y
            return -1;]!M} K:`6C
        }0FSQe6?-Hvf Pc
        S.top=S.base+S.size;$W^z/A*yj r$T[1W
        S.size+=APPEND_SIZE;Cud6Y7m
    }^(M-x5vYmkF5g
    *S.top=e;
Og/tAp_:l     S.top++;3`&d*k7[I
    return 0;
`Drz%RL8INd;jU }
n4r o*CxIU
?.PLd A6M int Pop(Stack &S,SNode &e)-clI'fT1]B7J}&Z
{\TNxlP S
    if(S.top==S.base)
.AN0S+Wg XX     {
P2@3rbO;q         printf("栈为空!");
{"u*p^#U         return -1;
0A8aD"m4vq     }x ?0|Y,{!Y+b9b @
    e=*(S.top-1);6E$Ff*pbSf
    S.top--;
&q4hj:J'By     return 0;:eq"_0W*HI e/uU
}
bp!u#}t}Bn ? T%zT%da4f
char get_precede(char s,char c)
$MT\ M2D"bo-Q$a {
!O4C Z-R5J/X1x P     switch(s)2i4j*I![,Uqn6p
    {
M8AH2qtc'\         case '+':                 
%aR m1g^m{ w         case '-': |%WO(V8q3SE%x^U
             if(c=='+'||c=='-')(T.H6w_ W4Dt
                 return '>';(oIRF-D.Lan
             else if(c=='*'||c=='/')jmB ]j0H]*_*];H
                 return '<';'n)x'e M9f
             else if(c=='(')
Bm.t0^Z+I$t0|                  return '<';
2j'Y#v }$IJ              else if(c==')')
~7Jat6E*r                  return '>';
A6Bg.P4@f jXE              else 6V#kezy'z8m c/x M B
                 return '>';
m,Pb/f5]mi         case '*':
6A*qR0M#w.|A~/Y         case '/':+iD)Cl)ol,|*@ Kc
             if(c=='+'||c=='-')
HN^COiSN                  return '>';
!^h1`_8P a              else if(c=='*'||c=='/')
)m1B bN_~$^)L9Lr                  return '>';$S ] Ymcq
             else if(c=='(')
)Qml @ u7qs)[                  return '<';C!^m%e8EZ T\
             else if(c==')')
+]h S.cT#CZ$E                  return '>';
(O }DI!bsw              else sXLH;e5y2Y]^xD
                 return '>';(\#|*v~(C EM
        case '(':
/{8[o#Eq"[cx              if(c=='+'||c=='-')
&C#Kn,Lty                  return '<';
^},E$j^Q              else if(c=='*'||c=='/')Z,nw2A8Rrc
                 return '<';
^3M3FyI^*{              else if(c=='(')g?I|]0h8A#hKO
                 return '<';
Gw-s.TV OE6L jI              else if(c==')')
)[4W!O[eA                  return '=';
+g b#k)W y              else+i&bU[;[r(V;y
                 return 'E';
%CF&v:D#O#Ww         case ')':
CZF0x$^o |EN              if(c=='+'||c=='-') D:k;H+Yd!u3@
                 return '>';
'`9qD@ y1p+rH              else if(c=='*'||c=='/')vC;fr K O
                 return '>';
!G|uY0~9eM7w              else if(c=='(')#bm!B?V#\%pg
                 return 'E';
W bYTNA1|t              else if(c==')')
W+D5gSB@@ I2rz J                  return '>';(C%~.UW cZmw
             else
3S5hl.Q i!i(n                  return '>';
J pL Jh@h"Yz         case '#':
Z3H An UR r              if(c=='+'||c=='-')E+eq^n1R t_
                 return '<';
1W[/s1JEC              else if(c=='*'||c=='/')eAe1z6w?dD^ U
                 return '<';
0zgB"s8s              else if(c=='(')
vU|_6]-gr ]                  return '<';_PO$Sy)w^j
             else if(c==')')+iqGw,q}(\
                 return 'E';
1tpdMC"n(Ow6KKE&B              else#@Ma DV$v H
                 return '=';
_ulN0f"Kz|1s)p         default:
1xK(\H?:g"V9~%\ |1n@+s              break;2y"vErY
    }2v`1H/DQ-X2W
    return 0;   
.rE;{ j5R o(A _ }
V7Maq2P
Tu(T{T)Ie@K int isOpr(char c)
ml Y D Krw(m't {1t o-BTb,E%o'n1ea
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=');[B^bCP)E|\
        return 0;
L'P| d/Kl5n^     else gb2^$QL+kW
        return 1;
)` h#saK }
/L ]qq`&i-de/i 2Qu-K)a\
float operate(float x, char opr, float y)
h?j7[~CK!j {R`t+E \+A
    float result;G5G r8l^F8I eFM
    switch (opr)X;K'|X-`k [
    {
a/~MBN;u%Z-?         case '+': ?vlr z
             result = x + y;3? c W/CaA
             break;l {;J b4J7zb
        case '-':
n\ky?]0J              result = x - y;
%S+u;`%@%F-`.Y              break;LWz&j@ r_X'M
        case '*':
&aL:Ct,GOX;l              result = x * y;0E!Ml^P
             break;
-Nk+xZk IN0w         case '/': W&e a.`7Rk
             if (y == 0)*nd8Bkq8@7a
             {
o8N,V,Bm4}z                 printf("Divided by zero!\n");Z"Ew l,Y!V
                return 0;
.r9D"G'n1vG              }
W5_ D,? @,}              else3lq/z |4KXe}7y
             {FB9A;fk!mcQ9Z
                 result = x / y;
:r]3V:f%\yx,[                  break;'X;X(CX9ZD:^W4Lw
             }0bZ:u6aKf&X
       default:
:wJ:ow0B+e!O.g              printf("Bad Input.\n"); [5v eC l!Z U
             return 0;
$BT{3E-f     }U(`/F3C F c
    return result;b3tPB4s;?K
}   
1e$hS Q)s(Y s_'OC~E O&n
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/0Y'|e!I4U4h4W!f
{
Q]7yHa*^/O,?     Stack optr,opnd;-{fz$Y oYbU_
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$x2~8s&Jo4G n aZz
    char c;?&R w#n0L
    char buf[16];
B8uL4`|+A     int i=0;7Dcs6TS"^:[8~
   
:M,ac\ez3?     InitStack(optr); /*用于寄存运算符*/"Ajl.W(W
    InitStack(opnd); /*用于寄存操作数和计算结果*/9JK1y ^A~
    memset(buf,0,sizeof(buf));Y3ip3vP*l/F
   
4Po \5lV(a     printf("Enter your expression:");
x1lk/N9S2_F         +S,\ \Nsd
    opr_in.ch='#';0X9DL+o D ?
    Push(optr,opr_in); /*'#'入栈*/j ]U ht1Kl
    GetTop(optr,opr_top);|e Yhu/EwKip#c
    c=getchar();
UgZ A9iP_C F"?     while(c!='='||opr_top.ch!='#')
2F/rNuF X0c     {
\;{b*~7N$S         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ s#MPr5a#?W
        {
$k0?&c1T4Y l6DI|Z             buf[i]=c;
#\3]PRG2XO]+Z'y             i++;3~Q,l8VR6J_6[3of
            c=getchar();
&W`AP}8Ym         }
CE4Y2c${a+p&rZq         else /*是运算符*/
_H+wp@{         {!T;f:]*o3F:La{
            buf[i]='\0';{z lh%pY2F
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
6hA:k g;R#w9`1oM.\             {
9A L*e:Y.F'g"e^s                  opn_in.data=(float)atof(buf);
Q,y*^O xD3_;h,t3]1?                  Push(opnd,opn_in);-E'h)k/j&s"R(jV
                 printf("opnd入栈:[%f]\n",opn_in.data);U q#_)Z.jv&w
                 i=0;
A$V ]RbM3n9`j0a4k~n                  memset(buf,0,sizeof(buf));
/T%o8k-m'DA L s`             }:D x![a7]5P"jO
            opr_in.ch=c;
"^4H9B"Qsc6NF[             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
\K ~v,x$s&Ch             {I)u K:O(B2sn7ZJ?
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
u8I2AV9l G#qC                      Push(optr,opr_in);
wZ9P^M&{                      printf("optr入栈:[%c]\n",opr_in.ch); S oWOFd Z
                     c=getchar();;UXK S4o|C
                     break;
9K;ZhOC-}:}3?                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
OYx:{ OZW:y/z                      Pop(optr,e);Lr T&|l;n9A8A(Q.@
                     printf("optr出栈:去掉括号\n");
KB~ I k3M/f+]k!C:S2Q:`                      c=getchar();v5sL4t!Bp
                     break;
5kH C/M[N k9U                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/A8H8f5zt A%^.h8O8o
                     Pop(optr,opr_t);
cor'E"[L9i|                      printf("optr出栈:[%c]\n",opr_t.ch);
_ja$W P"e9W                      if(Pop(opnd,b)<0)
c _#\Js@ [ G:d                      {9A2f"K7pS a A*}#`
                         printf("Bad Input!\n");,ks$Ch8vk[s9s
                         fflush(stdin);9l%_c[7m
                         return -1;
)v8I~:Lm,y6l Xpd                      }
'nY4]$Fg4R                      printf("opnd出栈:[%f]\n",b.data);
z[3Ur!k5K D                      if(Pop(opnd,a)<0)
9r;RP6K6@[X? RxC6l8R                      {
qTQ(h-GFu'__                          printf("Bad Input!\n");
'C'XG![h                          fflush(stdin);1Pfr8F7M'TpXc
                         return -1;
8o8hHwB CF9{-Z                      }
.?pt3A6zY t6\+_8bH                      printf("opnd出栈:[%f]\n",a.data);W(t5Y,MkhQ5aT
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/HZ%L3Q R9r/U~V
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/.M G Vm`(x BsGJ
                     printf("结果入栈:[%f]\n",opn_tmp.data);2g)o2T-q9l
                     break;
`(e}E5|:[rR5e             }G O4w,eY
        }$G4Q2K~"\D_
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ,_%\b'f4yb
    }Z;O;E@-N
    GetTop(opnd,opn_tmp);.UM_ g"G|
    DestroyStack(optr);
h'^D ~U5y     DestroyStack(opnd);Mu8A y l6d%]
    return opn_tmp.data;0q"fzyGZ4`
}
V5hh(v)C
%p9w9NU k)W/bf%U char *killzero(char *res,float result))Ev"\k;I)X;C|
{
Ot-?1g!zP gy!U     int i;#nm]%HX(Mhf

{D`K;{ t!b     sprintf(res,"%f",result);G%L!?oJ
    i=(int)strlen(res)-1;
XY ?Ig Y{O     while(i&&res[i]=='0')
6O!fGN d"r+?     {8M:b(j(W`5l1G,Y
        res[i]='\0';vvX*iOWGZ/S7Bw:\
        i--;
*f E2Nf z5e?     } Z$~`(e6K o$A
    if(res[i]=='.') \\"\Z)X_
        res[i]='\0';
#R$s2EIRa%E l'{s7V][     return res;5e~ b3^TQ*I1Z.G
}DU5aGu2jI b;a/AO#K1D

$KEt{2PX int main()'M \$lV4cI"LiZR{
{
D5h9bu)Q5?y     char ch;D_;QW ];Np
    char res[64];
a{S!FO9Nx'lV     float result;
I)MfJ'?p     while(1)
!Q#X DU"p8X_.M9vW     {
B-Q%~(COH`         result=compute();
KZ/P;D6H0L         printf("\nThe result is:%s\n",killzero(res,result));!nvu0lM.X*[ v`
        printf("Do you want to continue(y/n)?:") ; |RcM*ol kr4{ Q!q
        ch=getch();
(RB8v]X|!z2FVC$i         putchar(ch);)m([@G"\m&`8ly5k
        if(ch=='n'||ch=='N')?m.jH z@
            break;/@ @2GR8A2? L`
        else3[%N,n2hVMHqxp
            system("cls");W/_ Y(Q2@1cY0f9^
    }
N4vr+e _ w%X'NR     return 0;
O+@)s4o.E&J2f2h6c BV }[/i][/i][/i][/i][/i][/i]ysL1Whk2`7F

n0S3y.R)q2P [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

页: [1]
【捌玖网络】已经运行:


Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.