捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
/W:H6_R-a"Y9Se4P_ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=4? c;nJL4g
/**************表达式计算器************/\8iF^,Ak3X:T
#include <stdio.h>
Qv`$TZ.a/NN$iJ #include <stdlib.h>"}2]j7kE/J/l
#include <string.h>3g9].?h-^7~sL
#include <conio.h>
v;B0eEgSFe #include <malloc.h>
^"[7FD.cpv
jNn$['C*F #define STACK_SIZE 100 bLw'E$PJ0y"|
#define APPEND_SIZE 10h(BpcI OZu

)i:g2q$C2n,dAI struct SNode{
7QC8r3j+[7Qe6F     float data; /*存放操作数或者计算结果*/g1g:ta+y6p[
    char ch; /*存放运算符*/
ou!N"b D;A[(@ };%Z'z p;s2uw2x!eQ

_,\&Cm;FZ6@K(XD struct Stack{5MO5t3?TX^
    SNode *top; z*mJ*_ ~0y-c0s
    SNode *base;
CHRs:d o%Y#`\     int size;4[0C@:@M0pR1g1\%i?3E
};
%lRoDT
,E*M6c'ily /*栈操作函数*/
i H!Q]`4t p+R int InitStack(Stack &S); /*创建栈*/Qe:@#Z"]4b
int DestroyStack(Stack &S); /*销毁栈*/
P mx h&ygZ&y int ClearStack(Stack &S); /*清空栈*/!E#b Cy M K{`;H"su
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
~5p&gR9B int Push(Stack &S,SNode e); /*将结点e压入栈*/
y:j&Z1uF"[ Ee int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/W4H o0uTL'a"]k|

Y7CHa ]/x1I /*表达式计算器相关函数*/#CiE qr
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
nT'[@|U int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
~wN"Q"[T~q ~;_y float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
L7N FU/? float compute(); /*表达式结算器主函数*/Y#or9JE|Vy
char *killzero(float result); /*去掉结果后面的0*/ a+Qm7q:q8q}

5{e.k o iQ9c%I9P5| } C int InitStack(Stack &S):JS:]4SY)CA
{9B?TC|;q
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));6w4WQ#q;~vie
    if(S.base==NULL)
rA2eo(QL*`     {
Qu-B6]A8b#db?         printf("动态分配内存失败!");P6Wc.YwA:s9ey
        return -1;A]m y9l[?B&\
    }1?3d$x3g9{\:n
    S.top=S.base;
eG Z/wXFz     S.size=STACK_SIZE;
AB `6f5ci'b]$s     return 0;
&@%NW&Wh,B-RQ }?$NZIS
:h'_\,XvL/e
int DestroyStack(Stack &S)
0Q5G:l~5^)tV7OA-D {*e|1rFbG;`@
    free(S.base);
iZJ2L)c     return 0;
.|%\ ro,zr(mW0T }
W0{h yI QfA
%|l v9R6I(x8@%@!Hj0V int ClearStack(Stack &S)DSg[ e(b d@#wbg
{ Y,`:}h%A:t0J2C:V8Ki{
    S.top=S.base;Ll0l.M%{a:h!y R
    return 0;"iNntKX9z$x6{5]}$HU
}
'};k];uD4gJ;x J"u\;Q;|HJ}
int GetTop(Stack S,SNode &e)9EBV8x4^1ly
{d?H]^fz#P3rx
    if(S.top==S.base)
#wW W GWQ]xDQ     {
{VL6u6Odek         printf("栈以为空!");$ni3I:B0Vb V
        return -1;+VkIDh;o
    }w _$ugS-lEZ"s.}
    e=*(S.top-1);
!uz%Wi'|0b     return 0;v[[pJ
}3jY'jv aJ

sR B kanD int Push(Stack &S,SNode e)
U:lO!k|"{"K {
Q b(n^ r1g&hj     if(S.top-S.base>=S.size)#]a4L0dN`-b
    {
.Cy\lHf         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
h Fy+Z^'U&@         if(S.base==NULL)
/kb8Nd9c} ?         {
BQi4c9q6g9yC^U             printf("动态分配内存失败!"); U{LEU {Ya(A6}
            return -1;
XC7n:l?|u         }
r#MEP(vVBl         S.top=S.base+S.size;U#Gs.q&U_%r-Oj9m
        S.size+=APPEND_SIZE;:}b'`E8CQ0Ric:[
    },z([#b;iRkTE
    *S.top=e;7lH*z_T:A-F1d2{
    S.top++;\.[9yz%w
    return 0;t be)j"MY
}8BxwQ(C'e|#F

)y g7nx f,?G0R int Pop(Stack &S,SNode &e)
3`+|:?1bR4Z @,F {
]giT kk xH:R8w     if(S.top==S.base)
}E| k8Sq M;fxC     {%T s Qj"W mr/Y%xH
        printf("栈为空!");3p9@4Dfc
        return -1;
(h(E#N|(e%g     }'R"l*P6|:o1g%s
    e=*(S.top-1);2^(pU;\)u3BQ
    S.top--;
&z h4NK9d*g jq     return 0; [d+b`"hX}
}
tG-]'Q#Zlm Bo \8]ONK:?
char get_precede(char s,char c)
6\%`B!j"|'s {
.w+F%I-P\5^     switch(s)
A&v-y/}Ub)FW1](d     {
%LCJW6K6o R         case '+':                  |/[;c-r7Us
        case '-':
e7@6D-Q`'dsAAV              if(c=='+'||c=='-')
S6fBM _ G e                  return '>';
x+[ f)s sx,p              else if(c=='*'||c=='/')*q|,ik8`.o$q#}Dgz
                 return '<';
;bv t"?&Kj'P#V              else if(c=='(')~)bB2Fk
                 return '<';8T Tr/`_2n(e
             else if(c==')')"mW;hC8u(h:|C
                 return '>';
3J ^ |+dr-l4S              else
;tG4?&S.s.~ M)A                  return '>';ch c \wdoN
        case '*':/Rs.N F;J)r},e_0d
        case '/':
8L#e(^5W,VP n              if(c=='+'||c=='-')dw V^$IlT#m r\/\X
                 return '>';
h:cdB@2G'c^^f              else if(c=='*'||c=='/')
K0poRj(r\                  return '>';S^duF%S(L)n-ZY#Z
             else if(c=='(')tTTt)tHz
                 return '<';
v(U5W CH&^3G:x              else if(c==')')
gl4PP*iL                  return '>';
2p7m9h&Cgj"_zw              elsedBc4j4`4G
                 return '>'; rb `3z_R'@a
        case '(':
veih g"Ra              if(c=='+'||c=='-')
@nop Y$I^2^H                  return '<';`0j!VwF
             else if(c=='*'||c=='/')k.]+f%b1? `
                 return '<';$g~,] E bjm
             else if(c=='(')
+k0j])LO-^                  return '<';
&u*F+VF{$Kbk1n*gf"F              else if(c==')')
5y;IzS ~D                  return '=';(f*wVNk5]'R7zE
             else
%{tV$Tb/g?S ^+M                  return 'E';8qnQ6BM8cl
        case ')':f$vA @ T YIqq
             if(c=='+'||c=='-')
{J,l]xWA%Q,_(K                  return '>';a%mfX,?.L)m
             else if(c=='*'||c=='/')}t@;o$~y(q cy8k"y
                 return '>';
9?KlZ:N@8Yj8h)U              else if(c=='(')
0s}qTO1`B A:h                  return 'E';
B;_%l&E z&e.G              else if(c==')')
e i$H8C^&n                  return '>';
I}!@R"L$lI              else B~ \4[)M"M6o
                 return '>';!\T*FStc
        case '#':5O.Ety:i+a:S!|
             if(c=='+'||c=='-')wK]d p
                 return '<';
$hf*p#`6y4K;X              else if(c=='*'||c=='/')
-t2IOm6aRqA                  return '<';
v,m;dU D1z              else if(c=='(')
%g-{6`9]Wz5nw                  return '<';H2tUr5O4Y
             else if(c==')') ~~%{8L#fDhC
                 return 'E';J \.RQ y3v0J!B
             else*D,c.L!AN8|;\9eP
                 return '=';Z i S'T#zu
        default:
3EGP?EQ&d              break;4Uy'X*j(T1C3H
    }
dPz@5l$j:H;sx]     return 0;   
2aF3CY-I&q }
q`M sx"ki f fr$\l"|Aj
int isOpr(char c)+dE V.q(~SYc
{
zy]mO)U     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
E4LB:u W@.~ p         return 0;
7q8x)b L-_     else
%Q.rl.Pp\ l         return 1;
;|*\S0?*E`8`an%` };g#C NQ}O D
]*`G)B;e|9Q#]
float operate(float x, char opr, float y)
H Lt(j BcA+^ {
a-r1PA2_]*r     float result;w5Fjn;MkQ%p |
    switch (opr)
0@-R-{8TV.D     {E([k!u7o
        case '+':
uZ$z mP}0Z Y^_^              result = x + y;;V q+b3f5`,A
             break;YB}*],~
        case '-':
t(wJm[Bb              result = x - y;a SX"EN
             break;
1bmlkq Mt~         case '*':
*E@oaND8v              result = x * y;&X?mi\c0JWP9tg{
             break;7K){ db)M*A
        case '/': +F7may jB c)n
             if (y == 0))U9e:iQb8@{o}5W
             {R1}5an }j N
                printf("Divided by zero!\n");
&n SfW.L"k(d&V                 return 0;
.V-l1Q)lo&R6P_              }
6|jt"t7bf/y+e              else
B!@cE@-X0E9e              {
2U!T4~ ^Q&D+`h                  result = x / y;
9c m/~c*x0Z6_                  break;
ng|)iVO              }3V0C6y(zX8s`M4b
       default:
J7RT2S!I?y~#\HLs              printf("Bad Input.\n");
sg d"b$Yb%Ig6r M              return 0;
DY8wj$Q     }5E6lU~yN,D
    return result;U L7U,}X,Cwu
}   
Kga"?-nx3t o-P Ua3?$@9b:Z1p kU
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
]i(P!J0|z*`0o {z}&^'@b
    Stack optr,opnd;
2rNy"O]     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
[+P5f9o'E1Bb     char c;
ix0D(\7Sr^#L     char buf[16];z {tUBY$xpuE
    int i=0;uf;f ea'^O|
    ;Gx0R:m+U5r XKu`
    InitStack(optr); /*用于寄存运算符*/)\$Ap,w `[4`e x
    InitStack(opnd); /*用于寄存操作数和计算结果*/
.s]TC"?l2j*n"T,c     memset(buf,0,sizeof(buf));BPzO L
    D*S,fjoei:_@
    printf("Enter your expression:");
Pme8UAB2z\         }1M+R(P8W.j-dCd m
    opr_in.ch='#';5fv\'Fq
    Push(optr,opr_in); /*'#'入栈*/ZdXNT
    GetTop(optr,opr_top);6v&AOM0|+H[
    c=getchar();
D7a/xz7}     while(c!='='||opr_top.ch!='#')
S R%Ft{ ]8pP.t     {
*L^']f?9^c+Z ev         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
,@RAZ&HH         {Il-uc!Bs#S%M
            buf[i]=c;
0F Y s k5v2\5qK"Q             i++;P/vhl2j&CFYQ
            c=getchar();qfH*p+A|u4b:s
        }5`k}Y,i
        else /*是运算符*/
?.`h"Rvs5M^         {
RL(F] Tq`1G             buf[i]='\0';
B0f2N#W!?S%@7V-f             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/l`-y3Ao8l!},jt
            {
k]k hKP v                  opn_in.data=(float)atof(buf);
m ^ I ?${m                  Push(opnd,opn_in);yL4M_.FL
                 printf("opnd入栈:[%f]\n",opn_in.data);
R/f{%Un7Q,M                  i=0;
|]Mc%k6P6[                  memset(buf,0,sizeof(buf));
Z? m'M%d             }R"F1hkF
            opr_in.ch=c;FZ S?;J"Rc}
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/^W;] iA
            {p|3tsceA cs
                case '<': /*优先级小于栈顶结点,则运算符入栈*//Lg8trEx4\
                     Push(optr,opr_in);
.WZh7K3~ ]                      printf("optr入栈:[%c]\n",opr_in.ch);
4I.sr"X"Y9yggL                      c=getchar();;U7q4y8l r9Yh)w$J
                     break;
$fNj YL`wi                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
_ R y J^0ul                      Pop(optr,e);
7g2zp@;F0];@]                      printf("optr出栈:去掉括号\n");
0uL7z#b8s~:{ kR/f                      c=getchar();&k.G1r2ve deY(w&q
                     break; r6E8N;j6b5`G8S
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
a2h!|-h*r u_*g9k/?                      Pop(optr,opr_t);P_ @ ~+W9Fg?
                     printf("optr出栈:[%c]\n",opr_t.ch);
w9G's'WA5U$s4e c8PJ p                      if(Pop(opnd,b)<0)
+|*k:_hF7v1B                      {
.g&Q6Q*M2jU[b"r#vq                          printf("Bad Input!\n"); o.p_,Sb8N z J.s
                         fflush(stdin);
W,Ixk1}x\ C                          return -1;I"j7|4lW^d
                     }
6G)c(~? }9oG)w                      printf("opnd出栈:[%f]\n",b.data);
yE#jq$Ke| kgaG                      if(Pop(opnd,a)<0);EAN6ycMP^e
                     { }Y5tyu
                         printf("Bad Input!\n"); F$XJ,cL:Wpdl
                         fflush(stdin);)O+O3nG~l0s
                         return -1;
#U nu(@)m c^$O                      }0C i,]O+c BR^:b
                     printf("opnd出栈:[%f]\n",a.data);
@5T*b&pY8F&Q                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/6dzc.`G*} E{K+u
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/!_FO]5i uG4g1\
                     printf("结果入栈:[%f]\n",opn_tmp.data);
$G$eLT?tJ                      break;
L6p?zr ~             }
N @HX#~4T         }
;F1r0A#jPE:j4C*[         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                rTs[2]$N'_y
    } T+n S;IW*i"vD
    GetTop(opnd,opn_tmp);
E/{d C S1w     DestroyStack(optr);
k4} C5?'F/Qk/D'`-v r     DestroyStack(opnd);
3pf;T(Zb,wNV     return opn_tmp.data;x.p ]]!\\n4R*F
} O:}n6UJ%S#yS
e;h c/[C#~"} m\
char *killzero(char *res,float result)'N2y%n6La [%K
{
)xd"Bu#\^/caXMY     int i;
i*Ex(VS hov Qy Y{
    sprintf(res,"%f",result);
qUf7g6ZoOk0Y*H3Z     i=(int)strlen(res)-1;oE*R?'J
    while(i&&res[i]=='0')
\qc/x;` v     {3FbK0{?6U
        res[i]='\0';)\3WZ^,m5q
        i--;H F!xT,gf T
    }ri-^!h K
    if(res[i]=='.')
6{l\.w s:b         res[i]='\0';9RQK$D Wx5TaG ]-F
    return res;
|T7`p/e:?2@ _ }3m+X m1l9Pi2B-g4v0|

k\+]l4~#M Y int main() ^!n-vy)u#C
{&}%PXe.Z~'@
    char ch;zQ)p"tdx
    char res[64];
F@,bS7T G&|     float result;6U7S:bU#c[p]
    while(1)
:bN!E5H'D*`@     {
;NNX9]2r-d         result=compute();
N8Rv[;v,tH         printf("\nThe result is:%s\n",killzero(res,result));
;R|3r'{L Q%[         printf("Do you want to continue(y/n)?:") ;l(Ufk O
        ch=getch();
9M&I7f/zdo{)J }!S         putchar(ch);
sz%t8}"|a3n^!V:S         if(ch=='n'||ch=='N')XDJ5p5X3i
            break;-n!j y,gG4v
        else
/w b)e ]"`.E             system("cls");
D z a#n+RX     }
0Xz Gj a     return 0;
Yl3Zwl/sL }[/i][/i][/i][/i][/i][/i]
8d+l,o4hQ.M:_,P Ci,k ~1k
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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