捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.8O,Af%X6o
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
:Y9w$d;F ]+aQ /**************表达式计算器************/
$k,rM+C(\;}oI9@o*\6D-S #include <stdio.h>
P"Uxu8k2a#G4\A #include <stdlib.h>9JZ%SVd N rp
#include <string.h>
(I].Sa ieP4U8_k #include <conio.h>
A&I&OpB #include <malloc.h>
-HMC'_c9@,c$I
*n%C9N9B(Zou #define STACK_SIZE 100
+e*ke+oj!m G #define APPEND_SIZE 10 gQ+j g+b0h Q+}2K
P_ke3`
struct SNode{
1P3m5\7a |8@?9w     float data; /*存放操作数或者计算结果*/
2e3zez E/]:\RM     char ch; /*存放运算符*/7d5l!e0F%xK]
};7^*X#o%m\m
%w4Q|/hZj;t O(F
struct Stack{
zq?"hE r5^;p     SNode *top;I ]'Fx;t
    SNode *base;
!pT8{y3u"o-g6g     int size;
\dz CeQ6Hqp }; Z*k,O1Z F`?,g

9I*\7\Hq w"A4w1` /*栈操作函数*/
!l]"~#@&Nro0T int InitStack(Stack &S); /*创建栈*/
7E0f}0R'y/Ad? int DestroyStack(Stack &S); /*销毁栈*/o9P.js _'g1k
int ClearStack(Stack &S); /*清空栈*/
Y3z q!ozX6B int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
WK\6_1E4^.qx4m1A*g int Push(Stack &S,SNode e); /*将结点e压入栈*/N5b1G^"|4vu5c
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/B8d&r[#X0k-C
#U*CUF,@(|/C
/*表达式计算器相关函数*/
%G@"zs8f/Z char get_precede(char s,char c); /*判断运算符s和c的优先级*/
%A!h1?SY0r int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
Y:Lu*r/eDo-?O;Cx float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
+Z V5W.i9y)U float compute(); /*表达式结算器主函数*/'h+pk*TH@4ri
char *killzero(float result); /*去掉结果后面的0*/ m'p(g(U@Dx!D.C4L

9^0Um4xNaU[L int InitStack(Stack &S)
fsYc]%c {
1^7\O&C-|2UG:c     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
8h"_J+fNc O:q     if(S.base==NULL)
o\I;Tz,}     {.I:a3d%|h0U|
        printf("动态分配内存失败!");
m] W'M*] qYPJ         return -1;
*i0nanT V8ay     }
`N@b6B9^     S.top=S.base;s8K:DoFuL
    S.size=STACK_SIZE;/_!JC,A?/l Q o-t?
    return 0;
Xs3?,V V] X4Ky }*H3}_gDX.t

#j4\ {(X;~c([ q(V int DestroyStack(Stack &S)
l2^W-b$vT~!K {
vcF HL3D+x     free(S.base);
^xT0_;q1|Ha"^ e     return 0;} WRX fx]
}
,B1wE;N @ Kquz .S+X+l8h2b PV
int ClearStack(Stack &S)z9|L ~ m+?
{ { GZ~2]A&JS
    S.top=S.base;
&s*i]7F,}Sxl N     return 0;
2} @1S0c,~H(ij }V H4\VV"L
+R,e_g$h7u I%^ W3`
int GetTop(Stack S,SNode &e)
b/bNX,Xb5kV {rU\%pk}[u ck
    if(S.top==S.base),Gbz }#U
    {$`o!^,~fEHI
        printf("栈以为空!");0?y#xA#^6u$G.L
        return -1; h/X/q.In;k1z k
    }
u5\B'z|XY4s&_n7e P     e=*(S.top-1);/U:y8m tL$I8Pm u7L
    return 0;
UfM6I0Z n-IZ h }wH@1MkH?
k4kO I*D
int Push(Stack &S,SNode e)
7Z+e6\z6ou8c!Xd {
pw y8f};UK4U+E$W"U     if(S.top-S.base>=S.size)
1iD]a7dP     {
l \UXW L$xx         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
McZ A/{ s(L!]2Z         if(S.base==NULL)
.] w,S(pT;g;QYd6T         {5s"|~L3~ qH#q
            printf("动态分配内存失败!");
"Ei0R1Ob m/rdY             return -1;
)?9M {X8?4`zr0zT|n         }m+S6HSz$lx
        S.top=S.base+S.size;+h,EX?5\{8Q8e0E
        S.size+=APPEND_SIZE;gK1K!rz"P d
    }
,T6E[E8EP6Z n     *S.top=e;
b$@3_z ] I     S.top++;
#V5B(W^y+b1t3_     return 0;
PDQ2k%A4e2a/R#si5il }/Q"i6_K W
H)~ ~b$}1] K8v$p
int Pop(Stack &S,SNode &e)
S,ZKk8Ar|9C {
g1KAZ1st-X     if(S.top==S.base),d|zIhD mG
    {
Xl$c3O2?/x         printf("栈为空!");
e'R%gm3k9A1N         return -1;.l+H k.T$v B#e{ X3K
    }
nIFMG9D?J     e=*(S.top-1);
E0LC:s,?,]Inn e     S.top--;'} e$\ X@'~'~5[Q
    return 0;.K)b"G DH5Pe'y
}
v#FU\b(gE
B K~&h4I0x+^*pP char get_precede(char s,char c)
'P$X U7b!KU't {
_T?1\|-}8V     switch(s)
ZD1W#Cx     { p6W1W _N%d!JO5V
        case '+':                 
Y?o8z$q \3G [         case '-':m*tx,JF(X
             if(c=='+'||c=='-')
@c#G7k] T#B                  return '>'; g$l3ExzT(L"^
             else if(c=='*'||c=='/')
9NT(KP/rsB!a1WxE                  return '<';
2KE!N/K w.\              else if(c=='(')
)b'B3M2F y6`3M'_ ]B                  return '<';
^'m)q z @E$w}              else if(c==')')
]']9D6i"g*w                  return '>';
7U cy f/`{!l"R              else Pu gJAB\`
                 return '>'; a+Og\#n
        case '*':bT#}{;g3D:I
        case '/':3~h1@ e(Kf
             if(c=='+'||c=='-')`}3K5Z/Yp5oK4@(O3v
                 return '>';(C5H T"Np
             else if(c=='*'||c=='/')
UJ!s vv#A(efFS                  return '>';N-} PB4kt
             else if(c=='(')$Xn.{S+\F%Nl
                 return '<';
o1uFE l%YK j              else if(c==')')/bi7Cf9~$fh,I~.a `
                 return '>';%N3t b%A'M9v"Z;D
             else
Vqy6vx _&n7@.g"a*?                  return '>';/Ph0l-rj+bAcv
        case '(':/gEO2I/Y'B9O G%X L
             if(c=='+'||c=='-')4q?8f!xP*\'? Z*I
                 return '<';
WUG_*s4k              else if(c=='*'||c=='/')
!f-|S/Z(C%@c1~k4^                  return '<';}i6~_2oV6u
             else if(c=='(')
b)E}]+r4Y,N                  return '<';
1`A3qp"l              else if(c==')');JW#Y1M"C"D){N
                 return '=';
R6k'MBWwA              else;~sp4A?`}
                 return 'E';
gE$Az'B/g9_h8opir         case ')':)Oyx4kw/NZfP
             if(c=='+'||c=='-'),l:G!_@+}.](m$t K+e
                 return '>';
#i | }v0I-R n              else if(c=='*'||c=='/')
g;~ u5FdYj                  return '>';
"r7k#L%mE]@              else if(c=='(')
/D3mY2J5dW                  return 'E';
bM J+Yxo@ ~!l|!\G              else if(c==')')
;puvG`Ukv0Q%r.{ F                  return '>';}_F3q j2BSNZ
             else
&fs"g0cw3dX:x                  return '>';)p!O2X Zr)N ?+r
        case '#':aWJRu-d
             if(c=='+'||c=='-')
1y0A$tmx+j                  return '<';W7@v9V P}
             else if(c=='*'||c=='/') N-w({8G\b^3K
                 return '<'; @$i_2D9P VV
             else if(c=='(')
j z/Y$P+B^2i                  return '<';7_3p8{8k piP
             else if(c==')')
4?p1X1k^3t@k R]                  return 'E';s };i|L
             else
,QXB&[ o*n:|@z                  return '=';
5a \'G{r-{/X;P&s;r r8@         default:
G'vq]3@8me&xZb-L              break;7LI6D^? i+}e&Q{
    }
u FrS0{1_-ywA     return 0;   
x+N ZcGk2^z#XOy }
&p%I2c] d Atx5LH
lw^fN4YLS{ int isOpr(char c) Y]IW#M:AR
{.Flz1`9H0R
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='),U~ qw]&d;{!sM o l@fN
        return 0;
,{:h&k)qc? `Gs hn     else )kR,~K1_@%W D
        return 1;\)H(g8b6QvbMs3\
}
(c z7^ G F*\3A&r &^WYhU%d3\
float operate(float x, char opr, float y)
V5|{+R5B9XD {
8?"A3a!RS(A%g     float result;G-t(zis7Z5z
    switch (opr)
qj&n%JU X2x$b     {T9t)b^p2h2z K:m
        case '+':
_8JU M-eLd6^"X9Y              result = x + y;Y H9oFhkF
             break;
)?#A\FM8\,Z~8Iw         case '-':
-j/nU8p0G v              result = x - y;I|6M-_:X
             break;
{b4F'ZM4bpb         case '*': {#qL,]:UMzU;s,`
             result = x * y;
*u&lt O+H^7e              break; TO'L ];S'zm9odO+A?
        case '/': g:zS;Sg3[
             if (y == 0)$P Gs+~I E?*qr
             {
U1Up c AVP;Pt/g                 printf("Divided by zero!\n");BMm]r4k
                return 0;`C{/@\/BX
             }
#A5lA iovIy1D              else4g[.J/vTlO
             {
/mHI6d5u@J-v                  result = x / y;
:g/km.JE                  break;
5XO(|4O#B\%r(_,R              }lT+KF*d6K Ww#@
       default:
1u[c;f3o{              printf("Bad Input.\n");
F7LBl/kU              return 0;
*XR!xY4?)N     }
"egBz W1Eq"s o mz;Q(j     return result;kRY WwfC z-n
}   
+DH"C ]W
.E(h2Ba:^ Fz float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
CVh"HQ+w!C~9ov {
'}9h.N"E.^$s!w     Stack optr,opnd;U} T q:?o4bu
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
(IH#{1Q4KO     char c;_0Y*wX RvR!F2B`u5N
    char buf[16];
S9d|R+{*I;zI     int i=0;
;wkuBGw{3J@ ]     ,c5X XH\qRQ1c
    InitStack(optr); /*用于寄存运算符*/tj_2NR1x
    InitStack(opnd); /*用于寄存操作数和计算结果*/
J9gcI J)ekUysU     memset(buf,0,sizeof(buf));
_ |D^(N#~g/Ex     .T$o%T!O@ ];} R
    printf("Enter your expression:");
Y3k3jV%L6f*l         5|5@^'zUP4u5UL
    opr_in.ch='#';q ]Z6AH6LD
    Push(optr,opr_in); /*'#'入栈*/ E{ F(py
    GetTop(optr,opr_top);TtKK#^5[&^V P
    c=getchar();7wE'`3Hl U v!@ o
    while(c!='='||opr_top.ch!='#')
I }3Q2y]W1@/x     {,khODJ}sU
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/+L6fd dn5V,ZE XN
        {y.C6`-u%A:tMW
            buf[i]=c;
f6xh#p!E}9sPN             i++;
E&Y dN9mCz             c=getchar();|+WV,{w(`
        }[,@YDe9Q3jLx
        else /*是运算符*/!C2n X2L[k(M
        {(Xu-Y!p+G/N
            buf[i]='\0';
M[Z6c&O             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
?2mw5[W}3u)T3PZ             { u@R {;Ftl!r*_
                 opn_in.data=(float)atof(buf);3eZ4I)v3t_
                 Push(opnd,opn_in);
+E0_f T%n;Y1Dp;r                  printf("opnd入栈:[%f]\n",opn_in.data);cH+H;z@$o*O"S+C2e
                 i=0;5x9HHv(D(pCd5CI@
                 memset(buf,0,sizeof(buf));
A*}!r6nFbE_L             }m`d8p"XgG5Z
            opr_in.ch=c;
R c8l6m!Fc&FZ             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1Bh ?!Jc6^)h             {y"hj5G*y VS!E
                case '<': /*优先级小于栈顶结点,则运算符入栈*/(X;ot9D.c!u
                     Push(optr,opr_in);#E;lHW p
                     printf("optr入栈:[%c]\n",opr_in.ch);
,y B6]_(Shn9h                      c=getchar();uX"m$g5c:N.^:{$n
                     break;
j:mgB0S`R8];l                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/'a!|[+p*Gw
                     Pop(optr,e);E x*Fbw^5OE_
                     printf("optr出栈:去掉括号\n");
%Y,Fjn1F pU                      c=getchar();?+[.Hx7G&H
                     break;gA!iK/M&T1]-X
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
H.QkVE                      Pop(optr,opr_t);&k-ik*]7}2v
                     printf("optr出栈:[%c]\n",opr_t.ch);
:C {ri0{w}8|F`                      if(Pop(opnd,b)<0)
*u\*^^#v7P9Sk                      {_8V3k7r7K,e$Pqg
                         printf("Bad Input!\n");
0sp,Pu'{PT`                          fflush(stdin);
8~ZV1C!~N d#P                          return -1;I&M.v Va QiB*D
                     }mM#oP$Z*| {;d
                     printf("opnd出栈:[%f]\n",b.data);
5f;^~*U{.sf7y{                      if(Pop(opnd,a)<0)
5Zi`NN^q                      {
(AAQ*Y ~ IDI?q                          printf("Bad Input!\n");
e!k5u(XHQ                          fflush(stdin);,x0b$wq A\XP P
                         return -1;
!i.g X"h5L]s2s5]c%L                      }:h? ^eZyT
                     printf("opnd出栈:[%f]\n",a.data);
kF;C9TUx1Kii                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/b l)_k.a YN#^8i/C
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
;|O`Ww*f                      printf("结果入栈:[%f]\n",opn_tmp.data);n"sI R1ZR$a
                     break;
l,jS;u0B             }4}7Ysk N7W
        }
p q$z-N @+?+yX         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
B#wh\4KhTI     }
1@ ]:uAc^1S'so     GetTop(opnd,opn_tmp);
g;X\U`-z     DestroyStack(optr);,g'g _9h3b5{ V m1e
    DestroyStack(opnd);!nq'jmtX z:R
    return opn_tmp.data;
"O.\p*l+H SW3B9lUd C })S(C `^9r~ m!Dz8A

)v0M+X.v g!e^/f char *killzero(char *res,float result) vA%No!@g4^%J
{ BOH@\X@'L&W#l
    int i;
B j,h yG2b2@ D'd k:| Ke1D&R$rij
    sprintf(res,"%f",result);[ j~w0G
    i=(int)strlen(res)-1;J#E/R5U |o,OC.Y-I
    while(i&&res[i]=='0')
m@n/Ml"q     {7Fg{}!cuP9N
        res[i]='\0';;| O2j+l;C*n j9G
        i--;
} I*LB:qp6L@H     }7M AB P9WgT
    if(res[i]=='.')
+w hs~ES[         res[i]='\0';!a"y `4A9l&u+B/Q ^`'t
    return res; }6J$zXrM2VJ7A
};aSN }2x"CL
Q U'|0N6` B ttQ
int main()_#QunB"N5@
{6mGw-XIwg
    char ch;
!|9l+J o'Q y,Z     char res[64];5N!p"M1W yK
    float result;Q4^`c E;@3}I
    while(1)qn){'H(KB)G @
    {
E t,H6uJ Aq0a6x         result=compute();eEB)k-y2^
        printf("\nThe result is:%s\n",killzero(res,result));
!Q3Q0^q;L \ P         printf("Do you want to continue(y/n)?:") ;
'RZ@yT:E#K)b(I         ch=getch();0YGoov
        putchar(ch);2j0_nex@
        if(ch=='n'||ch=='N'),e9U%k;Q%a%v
            break;
i7kJ)L t;x G:^         else(|ebK-x0m/_
            system("cls");
3kin in]-BLG9n     }
/}4`Q~@v`     return 0;&L`TGcO
}[/i][/i][/i][/i][/i][/i]
@HP }N.^+i &u8AG,?-G
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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