捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
`cy'ZyT"r{*R 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
gA0SC&f4h ~x$t8G /**************表达式计算器************/
o+H+DL"Nun #include <stdio.h>^"b~)nf{
#include <stdlib.h>
Iz*~V)Y #include <string.h>gcKo,]Rj#?J |n
#include <conio.h>+WG~9f*HEV
#include <malloc.h>a.kY5h'gR-o
.wL-Z n*iuZs
#define STACK_SIZE 100@yM2o(Fz5F
#define APPEND_SIZE 10)_/n#xK?r
6Y;@8Zg(z s^?m~
struct SNode{R(_.jy\u
    float data; /*存放操作数或者计算结果*/
y1n {FIq)~)t&h     char ch; /*存放运算符*/8KL Y |3S*H)I
};(sWG/kq f&XP@
JDUNW1{@8kC
struct Stack{
6VSd$rK8J*[(c~     SNode *top;;N ox!v2^)B:wS8j9W
    SNode *base;
1M(wH&OD     int size;4`(E5g.a|%B U7}8@
};
$bF lg c .v6phy'J
/*栈操作函数*/
Pu+T$I.Z(|v+uh2[ int InitStack(Stack &S); /*创建栈*//Z#]&x\6`!p0v Y0N+\ M1H
int DestroyStack(Stack &S); /*销毁栈*/
W UVjOXmQV int ClearStack(Stack &S); /*清空栈*/
x$C*ob!S9O _#Y?? int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
3k6L!m]%o.x6\ int Push(Stack &S,SNode e); /*将结点e压入栈*/
!t)Y:WF1^:k int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*//hUa T [O)T
5zm(w'X[ E
/*表达式计算器相关函数*/
4wiCcXS g char get_precede(char s,char c); /*判断运算符s和c的优先级*/-V"].K(h}j,z ^x
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
#qDR#x"P2g{.@ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
esh'g9pK#hI_ float compute(); /*表达式结算器主函数*/
r_ [6o;k{;Y char *killzero(float result); /*去掉结果后面的0*/
%C.DK7Bp5c a#r e9K-P3C T
int InitStack(Stack &S)
Ay)\8W7\%Z&\;U m {
[)m%R@3p5r0wL     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
N,oC8n udg0[-k     if(S.base==NULL)/I*zY;Y3d$K_
    {1U)oHvrX,@ l
        printf("动态分配内存失败!"); yo$P#s+F9j(V#G
        return -1;S7T$Gm R*}1my
    }
N'S~'lD h7CE     S.top=S.base; k(q dB({.Uy-_w4Wo*S
    S.size=STACK_SIZE;4U A'C)S#@$m1v
    return 0;.t)u'qTc%@6H2e
}SA7c7[t~S2a-k

1K L9^"mm0wIWpg int DestroyStack(Stack &S)
m8Mo/LFw%Z_0v~o {
%L `Wsrp     free(S.base);z-YUb7~/|-`'aVQ-e
    return 0;
3h!}~/wv0[1a~{E }
S'aZ ?1H X*V7J J$iiOn9}
int ClearStack(Stack &S)}0cX]3x+Q#~C,Z
{3pE"P)JN2Y3R
    S.top=S.base;
8X9~6o'u%O)j&W1[6m     return 0;
S$J#Ex} }
]'R#n&k3c1KF .B$FLo Xi9@Af e7v/a
int GetTop(Stack S,SNode &e)
5R5y hPd[Zm| {GzV }l }0A
    if(S.top==S.base)5rU*AcFA)W
    {*[;@ G7G0} G&a
        printf("栈以为空!");
Ah|^#[         return -1;l&K~r"ed$R
    }
v*g v*M M)B3p     e=*(S.top-1);
;_^!V7BcR5g$V*_ y     return 0;Dy"[U8S#Ly
} ~!`.B9YM,` f^*[

u Y8F(\jv int Push(Stack &S,SNode e)7_;PF,ga;C'W3];q
{e@!q5SQu
    if(S.top-S.base>=S.size)
"L` PQ2?|L;h     {
Z*^2^lb0I         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
%`#k`V%m]O{ Rt         if(S.base==NULL)
JHe!V?LIo         {@8q1]mgb pD.h
            printf("动态分配内存失败!");$FOs4|UF9k8f
            return -1;
i4[uCJ         } \2u%x;@ [m)S
        S.top=S.base+S.size;
@V&z3zv*Lc6bU e3j         S.size+=APPEND_SIZE;m0y6{!c7aJv
    } Cf#B[%j&d/R vz E`p
    *S.top=e;
$e5`Q!^$k.E M l     S.top++;
t)h%jA2r@     return 0;,J2l"W/V jr\
}
x6r;p,S6^+}LE6M;h$^ C.}W'Z'A ?c'f;Ryn
int Pop(Stack &S,SNode &e)
6B d)H'P#sA {UV/A5T(r0n-PRR
    if(S.top==S.base)
ub%pREM     {
v%nf `7S2[.f8r:r,r%p         printf("栈为空!");
V1lrdn%\@         return -1;z ^g"E1BG'y#Q$S
    }
0r v3p6]~j4P U(O     e=*(S.top-1);*\8~&v1hkCV8D
    S.top--;4V0?C9bc5j~
    return 0; |:[6O']V Q
}
I4sHjK e g&F!{e r2|6z9Zv*X
char get_precede(char s,char c)
V5|{4J@,Tb P.Z"\ aN {
+j2G h Tr]~     switch(s)
N*T8@:q,ix1Un*Wf     {3Qr maY [
        case '+':                 
$pps5sN&r-U         case '-':}n`KV mjH)e
             if(c=='+'||c=='-')
8[w egpeD(_ C m                  return '>';SG$P*d:f;\7^,s'Q"i
             else if(c=='*'||c=='/')
Y]MAMI)^                  return '<';
]yMc R              else if(c=='(')/I+m.?;B9Y.m D)D$H
                 return '<';]8~-A!j |&i6?@LV:J
             else if(c==')')
^ n8[c'a K5y                  return '>';
'C { ~mn"N#Y#p-W&?z              else %}7Ve;k!m
                 return '>';
dX)Q9F _         case '*':
Fht jyo}#i         case '/':
\2H;\t-Rb(vj/{              if(c=='+'||c=='-')!hE{YFwke4Yl
                 return '>';2Y3vF%IfZ
             else if(c=='*'||c=='/') Q x uJ8P[%B2{
                 return '>';
Lk`:a0\AHu              else if(c=='(')
O,l-t/tim0kT                  return '<';
5LJ4@xZ |c              else if(c==')')(n]${T5k-B tX*O0T
                 return '>';
+Lxu%R6O,U M T6u              else
%?b{A,|+yc*gk's k6Rk                  return '>';
kiK.I l o+Q dQ         case '(':
ZGo4zW?Z]wm              if(c=='+'||c=='-')-eJ8|d4Dj _|
                 return '<';7kcF,f{$k{G
             else if(c=='*'||c=='/')
-|?aA)G"_0~                  return '<';}"l!wJa A,fE(M
             else if(c=='(')
*@5?7qO r/|l                  return '<';
6ZQ vsB;L7E              else if(c==')')v8X-V8XSGE
                 return '=';j M+kof0H
             else
:IP#oyI(D&Kk                  return 'E';
0q.Ktg IPR7R         case ')':
s#AHr(HS7RR              if(c=='+'||c=='-')
:c:zMy.F(V+Y.n                  return '>';GA3G v![3nI
             else if(c=='*'||c=='/')
/n:tg$K pa^B%q-J                  return '>';
l5^3U)E.lb^.S              else if(c=='(')
Sb?+[2l(^ [+T                  return 'E';km(o8|xP0X/u
             else if(c==')')FZ'|ux
                 return '>';
`5Z_,l+A1W!z              else
z(t!`K0Xh                  return '>';]md z_-aR1K V ^
        case '#':
|9n3B/G i              if(c=='+'||c=='-')
,O)@O8rBL H+O"M                  return '<';c.`X2|!Y/X/Q f
             else if(c=='*'||c=='/'),N [iSM
                 return '<'; NXJ!Q X*r7M
             else if(c=='(')0^i;o0|#L
                 return '<';
k^D-G.z h"V$gI3`              else if(c==')')
SI0X6eR4@jR                  return 'E';7o'a/M~7B O9S
             else
pxkvV!o/?3T L                  return '=';-w w \2hNVo
        default:*A'}8k$uVt.^
             break;0~c)L*hsk-B
    }5p}SFGE0X.Q
    return 0;   
0@$wS;Af!i0`LN } g:d S,mZGl1B

/t_lsJ int isOpr(char c)? OH$`5x_7emR8k P
{ ?6r:xf-B8@0X
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='){JAk if#[
        return 0;T~$`T3^D
    else
I%V rkk&G         return 1;K#G-}L!U@S5Q
}
U'_0DpY
x$U n[gBPx float operate(float x, char opr, float y)
+bN9B9u3FSF {
K @| lz     float result;#B_;uWE
    switch (opr) @~c,j%xgL
    {f(nqE8GNG
        case '+':
%t.Pm2gC!WG&R},k4@;p x              result = x + y;3\(fkQN:`
             break;J+t0I-mPQ/rS
        case '-':
7R$V/O6o$zn5?B              result = x - y;
XT{J\ t4kD9hE              break;
U*tN/Q9r5~*kPA-^         case '*':
{1S ] XRSp-F6^&^@              result = x * y;zO#o[ p#\*n0H*?
             break;
(uA4Am~;cS9|         case '/':
^xb3t*N6a q              if (y == 0)
6TtT+s!^Cpl              {
#y"[ ZbO4X'{&Q                 printf("Divided by zero!\n");
#A6pxqM+u/Jl                 return 0;
SCvM8}i              }
b]b6y-Xq^\0u              else
w9c5s.o,~              {9zv4{${+C"g
                 result = x / y;2m)@?0]M'g:N$kFm
                 break;
msZH]              }*aqp*dCiD#v
       default:
fG5G3EHy              printf("Bad Input.\n"); a@.UP|2y
             return 0;9IDq \w/S"a
    }*s vG3]7b,|S
    return result;I [l(jn6f
}    8R;@5kV0Y,F7?V
%t-D6E3e&i9WE s
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
p)Nc Vc7w~7wP.@"Bt {
}&_R5a)t T     Stack optr,opnd;E%\[ FF}l T?)u"e
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
@`8T%D-\2Spw_o     char c;
FO r6H6y gq)i     char buf[16];"M*a8eF$]P
    int i=0;
}z[Z3b`t    
1V4i F)YQ:P.kV     InitStack(optr); /*用于寄存运算符*/
)qu2J0F |:v%Udr     InitStack(opnd); /*用于寄存操作数和计算结果*/h}c(LiJ
    memset(buf,0,sizeof(buf));
*d3B%` Zj    
JG[,E*dBzb7X)h     printf("Enter your expression:");
x$Q(h ~[ e8_/y         %rd ]?$@
    opr_in.ch='#';\&@9p[0T
    Push(optr,opr_in); /*'#'入栈*/]#Kx:YcmMOW&f]
    GetTop(optr,opr_top);
/K~@X.Je#x     c=getchar();8\ LV?U$z`mr
    while(c!='='||opr_top.ch!='#')
X:j gO9LX^ n     {*S ff!n4Fl
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/U*A;rr n&CO
        {2~ z0Dm mL+R2K|
            buf[i]=c;I5QRsg'b;Y
            i++;C`6FPX.RtZG,H
            c=getchar();
I/WZ8| S*Y9? oPF*L m         }nLi5ru(?w4V
        else /*是运算符*/
2s:n_'@#|7Ge         {&RL$ddl}'A
            buf[i]='\0';'TPJjv9]+JY/v
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/o ddf,Glyz
            {
/r(| hwW                  opn_in.data=(float)atof(buf);.v%X h!G+|%R Pe!C U
                 Push(opnd,opn_in);\"sY_ tzVM
                 printf("opnd入栈:[%f]\n",opn_in.data);K Z'Wv?/`S
                 i=0;
f!XW:i"gWb                  memset(buf,0,sizeof(buf)); ?^$KTQI7K
            }
T+R8H;lA%Y(i             opr_in.ch=c;vK8S]m&h
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/*l2}/o@!|P5p1U
            {1xBzU v!r
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
uQ @r2R%QG_                      Push(optr,opr_in);TgY.J$\N[ Z*u m
                     printf("optr入栈:[%c]\n",opr_in.ch);R G S3Rn)d#VY{/^,Z
                     c=getchar();
6?j N1d{M3W                      break;
-}gX"@u$L,t                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
g"Sh%[Q7T f                      Pop(optr,e);
x SEH ~                      printf("optr出栈:去掉括号\n"); XVh;B5\0A
                     c=getchar();
Bg#r!M2rXm3fG                      break;
Sb+}wtx!F Yi4D                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
0d*P Vq/`                      Pop(optr,opr_t);
#W M @SAJ0X8h                      printf("optr出栈:[%c]\n",opr_t.ch);;f^;hio ?m
                     if(Pop(opnd,b)<0)(z S;O|y ]n
                     { Ae(t-O&@6aZ
                         printf("Bad Input!\n");
g{dPjv7en                          fflush(stdin);
d!Ut-i#~'u"p                          return -1;6_6[mo2tp FR0k
                     }6M~t\f
                     printf("opnd出栈:[%f]\n",b.data);
T)W#p/bl&f                      if(Pop(opnd,a)<0)
l9Vx[4d`%lt                      {b4a%} n{ e1in5nJ^
                         printf("Bad Input!\n");:B3| ?Q2PAmA
                         fflush(stdin);.v9se9Y+BUe8R
                         return -1;#IV5X4_ @ d0R3Tu(_
                     }(]I*nXr e \9m
                     printf("opnd出栈:[%f]\n",a.data);
rDqU n$M                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/ p]f;^hp.z
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/B-pz'ihr
                     printf("结果入栈:[%f]\n",opn_tmp.data);
b&FE7GT-s?W                      break;
)DvJ\}*O8Z5}             }
f:k%}ql*VP7O         }
3N Kf+J[ REb:^         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                9s#t}smR!~ d2xL.]
    }
Tl| p)p0X#x`&A\ i     GetTop(opnd,opn_tmp);
0^&h,OT4L.OvEd ex     DestroyStack(optr);
M1Z U3{3KY     DestroyStack(opnd);eI.`L2g"VtG S1SU
    return opn_tmp.data;2gz h'T2b+p+x d
}h*C1YQ/A4V

m"? BSC;V} C6~R3E6R char *killzero(char *res,float result):?O oetc)}
{2O7^2B]8`Q@ yt!Q
    int i;R!A4@8tYTtg

o.Lr4Dsu q     sprintf(res,"%f",result);D7t3JZ6P{1lP+i
    i=(int)strlen(res)-1;
om(up7vgoYpz     while(i&&res[i]=='0')+^T$^#K(Wak;bb
    {
0c#^_$R:SXRDt.l         res[i]='\0';$x-aT2LF
        i--;%XE6Q.?.R0G Y
    }
AD1E {&Sqx5P     if(res[i]=='.')@ tG|+^\
        res[i]='\0';
h{ gj$kAz`5r     return res;
L4@Rai9s D3Tm }v1W5D(hB Oy Y,@&^Sr

2D N ]"B\ int main()n$sM'OOV
{A2N9``DM
    char ch;+?9O-d5VijN
    char res[64];$G^R6L]%j.i-nU$w2@d
    float result;B(VfL(B;tq
    while(1)
3iC [ v'q4Y/l     {
j'fX#Z!c3t         result=compute();"qn+[f+A
        printf("\nThe result is:%s\n",killzero(res,result));
9Cb9}:T:CG)y6|.Z(f7E#c         printf("Do you want to continue(y/n)?:") ;i CedX0P&B7n6|ZG
        ch=getch();*S.|1` Y` S1L
        putchar(ch);+{4A+w*JgV
        if(ch=='n'||ch=='N')u cL`z
            break;UW nTp.tj)m!zh\
        elseQ.B \ MNQ
            system("cls");(@7~?h pR1e
    }2XZO"M4UHz7G
    return 0;
9Tb(Y'I `K2J }[/i][/i][/i][/i][/i][/i]a][MD

3od"K9UA [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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