捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.s0\Y(x [
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
j ?/I4MZ_!P:i0E/G$Y} /**************表达式计算器************/6Q {U\ X
#include <stdio.h>
mob:^(EKY #include <stdlib.h>8d$N-Bz|u&Qq7i
#include <string.h>
$KXz@@8}Rl #include <conio.h>
a$Km^ pc3F0SW #include <malloc.h>
-["n"i)~)A@ *v&z:c"S'r k_n H ?'R
#define STACK_SIZE 100 _3B!a4abb:i
#define APPEND_SIZE 10V,y$t ^+F(t]g
JB[&Qo!G8K
struct SNode{/TqX"kUL
    float data; /*存放操作数或者计算结果*/ c9_t/~WW
    char ch; /*存放运算符*/
)Dn l5rG.e.PKZ&d };
+k2IO#L^6dA!e'y
l&\xawKp Q struct Stack{gzn!{2p:X"VBl-t
    SNode *top;
\C^v.x&C3_g     SNode *base;
9Ki7Y!Dz     int size;gS RHg@7X
};
1sN z"K1Qh_#G{ g5N:go+J)LA
/*栈操作函数*/
Ec*wGT] iR0mi int InitStack(Stack &S); /*创建栈*/:o&RH!{&Xd
int DestroyStack(Stack &S); /*销毁栈*/
T8Ym dZGlU"M\c int ClearStack(Stack &S); /*清空栈*/esx3fn4d2co
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/;I9m6^LF5EW7z
int Push(Stack &S,SNode e); /*将结点e压入栈*/
7_M^Y V%tpVh int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ hXqQp
t|zUT
/*表达式计算器相关函数*/
?n.f}v~ char get_precede(char s,char c); /*判断运算符s和c的优先级*/
wJ `#h:Jb@-o-pL)? int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/l"}u0b6quzG
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/W`#Zr,xW.A9K3V N%O
float compute(); /*表达式结算器主函数*/
.[Xo x#p2~2} char *killzero(float result); /*去掉结果后面的0*/ [ LfmFE

0i6BPo.D/hjH [ int InitStack(Stack &S)
6I7S y'c]b2} {
&E3q.r?1e,f:Y3w^cZk     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));6H!x+Ta[8X/f
    if(S.base==NULL)
e'vlJ,V#Mfnm     {[*~aD0_;X/Ee
        printf("动态分配内存失败!");
+@e9Nk(L dw$X,M.G2V         return -1;p0g$A#gPe;j9CX
    }
I ru,AAY     S.top=S.base;)t-M'i/z,z{9m
    S.size=STACK_SIZE;
$]\7^x0Dq-[.y-N|\e     return 0; P*o~:c/s[hq&{
}wF'QSZ"Emk9q/S

y }yDmw6RA!M int DestroyStack(Stack &S)
0{C"q;~*Q oZ {
2a(O,S.X @ k B t     free(S.base);GkCnnx!U
    return 0;
2s5c [ z3H8`"e5B } LudkaL
BrR;hF f/f
int ClearStack(Stack &S)
{N2dyL rF {
A+k |{EWw     S.top=S.base; @-JDA8`+fl8IU
    return 0;
s|0R2i [6n_] }a8t,lh7YMN5_

#]uM;}/p int GetTop(Stack S,SNode &e)$YD*Jhy,S Y.OP0q K2g
{
R-woD.i9|,la8Cro     if(S.top==S.base)`Fq'e!g$M[ y
    {^L0d ?rl9_
        printf("栈以为空!");
Jj xR4?'hf         return -1;
{(alkeV:u&Cf     } F7w%u ZqL
    e=*(S.top-1);%Kx!ccE\
    return 0;$X:h2J[:Yo|/n~$l
}8k ? h \L ?F2j k

-L M3Q3t"w5K%U int Push(Stack &S,SNode e)v,y&l&vs
{#G^g2i(A2Pf~
    if(S.top-S.base>=S.size)
R C _2Z P     {
JB2ppB9M4f r         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));&E8U&Q+I9Q"a
        if(S.base==NULL),PL#O JzBw!w O[h
        {
Cb6\2]+Ya             printf("动态分配内存失败!");
Ex,x+p`             return -1;y?^{d
        }9_?(y$P,H\}1Pu
        S.top=S.base+S.size;
,D#M%D'DlESg         S.size+=APPEND_SIZE;9[/Z,@;X8zU3wo.I
    }
3v-ZD?9Cef&x     *S.top=e;lw)|3z`G
    S.top++;!RjY`q1z jQ
    return 0;XW0XL E$n
}:^PetjTM+O x
F/g.Ri.\$mQp.}&H+t
int Pop(Stack &S,SNode &e)
v?F"^0f`pK {
BA0A z$N%sa6F5}^     if(S.top==S.base)"]dE$^v
    {i9YJ|vE
        printf("栈为空!");;e(? V7]^`/YaW;z
        return -1; E)` k Q[ A$m
    }4}!M5x!KV3D
    e=*(S.top-1);%KkK3B k,?:_*\[-B
    S.top--;
q{0m[X5L [     return 0;:?"XZ8A+Qf/m-R!Z
}G0MDw|t
@H*t cpp
char get_precede(char s,char c)
^fU_9n r"` {j$LHP%z,w^psv*R
    switch(s)
s8k q0|dDj     {PTf@C0Ug!v
        case '+':                 V5y6PP"x]$L0Z6q-G
        case '-':
)^a2[[ x3Y              if(c=='+'||c=='-')W[(oK3`6d'@,J
                 return '>';
y6|v B{d              else if(c=='*'||c=='/')Pctx Z$z!z/@c
                 return '<';
,XhcyR?/_&U4_[              else if(c=='(')e&F\Zg8{
                 return '<';/[ ucn9YR$hX*y"ph
             else if(c==')')]yb F.M'SZ}
                 return '>';@L d8y,{ aXf:?
             else
i1?akJ,u6d_                  return '>';
\-U~ L1\         case '*': vQ`'D}4Ro
        case '/':
v:ra;Y{*FO              if(c=='+'||c=='-')
Fj2A Kv;g zo                  return '>';
Y*} a~?_2F!t'Nd              else if(c=='*'||c=='/')
}w(Qc#L IM#B+N                  return '>';
0h1m,E M.Lw ]W              else if(c=='(')
K:j,ktr*I                  return '<';
v,nvu&m"Td2F4J              else if(c==')')
]?{ thY,R                  return '>';
!ENA|q#z|)Z1~              else
Qif(} {{t+k                  return '>';Y#d\ N*L0o
        case '(':
1p2y O{!Ka+^)m              if(c=='+'||c=='-')v:k;T9\%A(yIx [
                 return '<';jRaL)N"P
             else if(c=='*'||c=='/')w m'yY"yo;k:\\V.c R
                 return '<';f ?-{TMxE#N@
             else if(c=='(')
|+Vgg!oR E} T                  return '<';
v7E3ns'C@2p              else if(c==')')L)G3{*|eW3d5cwo
                 return '=';
t|9}?&U B&W$kb              elseN!{Qr!]2g
                 return 'E';1tnB0_P y,e!U:L1k
        case ')':
F.Gx!HS              if(c=='+'||c=='-')
+r5q^"^+[m'a$z                  return '>';
)mU(na#n5iC&o              else if(c=='*'||c=='/')
%m1|xf `                  return '>';
!vY7bA_,nK              else if(c=='('):J5G@ Uk${,w4Rv2P
                 return 'E';#n-_6e1w+?.rf/W6N&W
             else if(c==')')
#~w7@u3N0{%M&U                  return '>';
Pm+[5yl*Z)p1i              elsew?-JJQx0o@
                 return '>';6^i+j;T6\x\DBt
        case '#'::Z9yKY*b C4p W#z
             if(c=='+'||c=='-')
?5]]&H'Nk Q                  return '<';:r\J9Xc1S#]7f&\W
             else if(c=='*'||c=='/')
9Wu o,rw#l%C                  return '<'; E y&iz3yd-J
             else if(c=='(')
SD[#kL n:^!X%O+D                  return '<';7z5y%e'OO }7\:U
             else if(c==')')*_{+J6x:zr&l
                 return 'E'; bvtvuB
             else![2}tJAE yUt._
                 return '=';
:xC Bu8_2B5AQ         default:axZS?(]&Q z
             break;*^#]3HUk/^
    } GTXl Wg
    return 0;   
+B!U Nx8VS }S:\4fg`d#Q,?

^;nm4L&F8ZA q int isOpr(char c)
m7h:x P_} {
'yWd^3\mL     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')$I&Vz7Lm.o G.x
        return 0;$O~ZgP JF x
    else B4EJ.|@8LK:bd
        return 1;.| ~tE,HY4@ | f0a$n }[
}dq Z^c?D4tvd0rt
m1x]M P^}*f `
float operate(float x, char opr, float y)DXBfP2v,I/L C
{
:V6Y6{;Rq:iK     float result;"mBb5f,P9R
    switch (opr)bX K D!{8fNg
    {
;g w PGR{0SUH         case '+': 'o0X ^J5|!y:I(r
             result = x + y;
q'T;?:hM,E;a              break;
*E4j5A/j#}:u)@9X|l         case '-':
K aH)Z]*q*? }              result = x - y;$@4Ysy;B8[f$I"m
             break;P|(jQ!x#O9R
        case '*': )A H7Tq0w-KA
             result = x * y;
Y{5XBfoe:L              break;
0DW)U@L(O"S V1L         case '/':
Gv s5a!d              if (y == 0)
%y6iU8LQ+cD;F4I              {
%r4R*krOr                 printf("Divided by zero!\n");
^-RTehir"x                 return 0;
K0P7T1P&jrF              }
XdxF8Oi?K              else
.x.l.XJc6P              {
+~m7DN2k8tb                  result = x / y;
7j7|DH7uC2`7Z)r                  break;;Py3A5\/?
             }
NW h"L.I"Y        default:
0~VK-Sd              printf("Bad Input.\n"); hQ{.jS{9\f2?
             return 0;BV6ecZx
    }0hn9K"T9}&mh!H4M
    return result;B4a*_,]/~ve-U {
}    Ip"X!QRm`6k
rM,Fr9j+J
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
|+v3y OY(V {
1[e2~8s q3[@     Stack optr,opnd;wN @GRM,j2u$Z(p
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
I3J?R(Y7Ja     char c;
]^$BUv8O     char buf[16]; e/|~h4])scN_
    int i=0;%kQp1{ IFc
   
3{5KA'd,p$R l O }     InitStack(optr); /*用于寄存运算符*/UB2| c(j4U YC?
    InitStack(opnd); /*用于寄存操作数和计算结果*//Y(_o @ |Fg
    memset(buf,0,sizeof(buf));
P*Nj*C,[4u     Ve4|(C#kH-|'\
    printf("Enter your expression:");??!n!Eyl5jkV&UvWK
        
Hc'p;T6]y6}7I     opr_in.ch='#';
&{eLET*nq     Push(optr,opr_in); /*'#'入栈*/
;Ehlou0A H]     GetTop(optr,opr_top);
H1WHM J_ y.Dp^     c=getchar();
$}d%vg#v j)AXI     while(c!='='||opr_top.ch!='#')
-A-k@6U3J b"Y7}3HA     {
YF,e8t$_ V         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
g!D(c0~&E5o+gn         {
(Q%nw'a!`@1F             buf[i]=c;
%d)z:z(XY+{7{-C:p0v             i++;
+L o ~i/|5J1cQ             c=getchar();;|,C?e7N ~M?
        }
y.u@"[I:kj,h         else /*是运算符*/
e.CD*U9Gb r|         {*f+w|4gfrN
            buf[i]='\0';
-W$G`XE Sk,R             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
2^P*h+zB             {1_I y*]dq,E
                 opn_in.data=(float)atof(buf); Sc j2^`0j?-]CbV U9v
                 Push(opnd,opn_in);9J9GAtD U l*h B8P^
                 printf("opnd入栈:[%f]\n",opn_in.data);
];v#bZ"EvQm                  i=0;k E8wwi/z;p@
                 memset(buf,0,sizeof(buf));4s{/@C0O7ps
            }-~!a eN5l:?`P
            opr_in.ch=c;
)soY0Nn5@O-Kj&u^             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*//GR(_+p#n0B
            {hv"n%R1tOj"n
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
oLZUA"} p                      Push(optr,opr_in);}"?)|7c%u
                     printf("optr入栈:[%c]\n",opr_in.ch);c;f2y qPv#tG_
                     c=getchar();
]:v~X ? Y4d                      break;
1u3g&C }!O@ \                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/M G ?0Y ]!Li
                     Pop(optr,e);
/o},~2Im(`,JG                      printf("optr出栈:去掉括号\n");
6Siy,L`V5S.y1Cmg                      c=getchar();:[RE9n#b5^
                     break;
M Ms~W)H5a                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/uIZa}SS d:U
                     Pop(optr,opr_t);#G_9K;Gz ^G
                     printf("optr出栈:[%c]\n",opr_t.ch);
Uc3dbtq                      if(Pop(opnd,b)<0)UOf*{1u
                     {5OO1dG LOQZ
                         printf("Bad Input!\n");.@$T3rm,B$Y
                         fflush(stdin);
&P&Z i!~z{s                          return -1;7`%Z9srn
                     }
u?/PSEA c                      printf("opnd出栈:[%f]\n",b.data);7bL,i;x#fUj_4rhw
                     if(Pop(opnd,a)<0)*r#q xZ ySn7XIu
                     {
H,tS!sz:AU7j                          printf("Bad Input!\n"); E3?V0B JX"q%I
                         fflush(stdin);
5Se9Ha5W@t&H                          return -1;q9gz}N,mR'O
                     }
P!}Nh q S                      printf("opnd出栈:[%f]\n",a.data);
FL-M*nT%Cl                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
"fr[U;x9v                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
t6@4OWd1`%}                      printf("结果入栈:[%f]\n",opn_tmp.data);
8V4tL%eP\ F                      break;/j"B)[+K!oGxR
            }
ej4|(_:[2`!E1xV         } fmQQ\
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                Go._C1U,C3ed0pL
    }
/]FgM"k&R'{ zHE     GetTop(opnd,opn_tmp);Ap.Y k]!c:u0K
    DestroyStack(optr);
)It$C8c5k%V     DestroyStack(opnd);BV+L{T
    return opn_tmp.data;
TY5k6gfM!QD3x t }I qayCDOz"Y
0U3d!r7DkH0o}
char *killzero(char *res,float result)
3Ts fwJ(U {A|z5?(B m%M
    int i;J O2T9oM1Zo

ZVz Snxg |Y     sprintf(res,"%f",result);,}3\ ~ C5wLu+d-FO
    i=(int)strlen(res)-1;`(}r)\k`
    while(i&&res[i]=='0'):C'B'h?2?#u:g2r/}*?D`
    {
J)D0YBic         res[i]='\0';
$OGlPM?G f{a-p2x         i--;s4BAe rH U,m l(a
    }{sObT8Vl8RZ.A
    if(res[i]=='.')
3e7D0@W BT         res[i]='\0';3]C&q4i-O*r[ \
    return res;-JZ.rVx4Rz
}@/LR/g V\~5@_b

w noN+k int main()'z1X f3M:hffq&c
{tWjb'X9m
    char ch;B9` s6~ \6W
    char res[64];kh6q-qn#AD |
    float result;2B!p;~NR
    while(1)
T+QD6J},F/F h0S     {6i5@OxysAK4AR)i
        result=compute();)v g+mHt!gM
        printf("\nThe result is:%s\n",killzero(res,result)); U0z%li1X9F#Y
        printf("Do you want to continue(y/n)?:") ;Wd~ o*Ofo+z(X
        ch=getch();/q(aX `g[a
        putchar(ch);~3g$Ekgk(Y
        if(ch=='n'||ch=='N')
/zehg.{8Y(^             break;B}5@ ^`_ kGW@t"I O
        else
6Kd*v&cB"J             system("cls");
o*Pa.V.S4Gl6]K v ~     }vvS*rk
    return 0;
3Dn-wx^5h"\#r)v%I }[/i][/i][/i][/i][/i][/i]f%ZJdo
2a6ON*l!} vc
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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