捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.5fv!u0Ga"Z @
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=/l9\BXJpU'I
/**************表达式计算器************/ ?k Ui |'g
#include <stdio.h>
8RdB,j&|B9Eo#~ #include <stdlib.h>
c gZ~JN4g!b #include <string.h>
E:gNJN3NF0H-?/M #include <conio.h>
'e(j`i2~}.Uz6o"u #include <malloc.h>l"t ~}7y/]/j

`i{qSsvnB #define STACK_SIZE 100
Y(r/~+q$R;K*ux-q #define APPEND_SIZE 10
zT9Ti ~RX9B+?"d~-WfC
y P\Jlx'\vg7s OH{ struct SNode{8iGbr J
    float data; /*存放操作数或者计算结果*/
I"f du-}l.u     char ch; /*存放运算符*/7}%h(?my
};a^3PO*Zz$GT2F
LjJ0DO-ev0C6B.g
struct Stack{
"?/?cJ6O+Icro     SNode *top;
}V[BV9v&}9d |     SNode *base;
,r SwZm$Ed     int size;
u%A2a+e x} \ };z^,s7L Q L;r
#VO~d E%W+B)g
/*栈操作函数*/
4e0B)~ `5IA#L int InitStack(Stack &S); /*创建栈*/8S Y!Su ^uB
int DestroyStack(Stack &S); /*销毁栈*/
F1SIEfr,[ rf int ClearStack(Stack &S); /*清空栈*/?,N0}2a$g}x*\
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/!e xg.x3c1z|
int Push(Stack &S,SNode e); /*将结点e压入栈*/t:n h]p(uO0U
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ Wj7t$w%mGf

+?0k}v l~0D /*表达式计算器相关函数*/
$z|yDd(S&OI!J J char get_precede(char s,char c); /*判断运算符s和c的优先级*/
&`?`k8rwO int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/I rri}[
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/'q8j5nd1}S/]
float compute(); /*表达式结算器主函数*/
*f'],fqLQ char *killzero(float result); /*去掉结果后面的0*/ ogQ7CTH

&[e'K]t|^ int InitStack(Stack &S)I*{4DvB
{
/WqT`$q1jt-B:Dz     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); ^#HZ%uN ~-k
    if(S.base==NULL)8Ry}b&J!J ~ H&W*a
    {
!AR?+}Aq.de         printf("动态分配内存失败!");/`9d.o5D]
        return -1;
1J}g+U ^roJ2T     }
(D8e:B!Fg     S.top=S.base;
fA5{ b5`'I-O1n;\7[,\8yEl     S.size=STACK_SIZE;Q%We$H%t,p
    return 0;
F%J?`7~Lr }1p*GWMw%f[
oQIfnFXW
int DestroyStack(Stack &S),xH8d Wt J)[J
{
z V1Nw.N5Z`     free(S.base);
c"j!Frt)sE     return 0;
|D$RI2_2mFS }$[_u G8h

8y+L+PJ^7tF|S*v int ClearStack(Stack &S)9MvCx pngL
{(W,d7R0]8NK
    S.top=S.base;.__.x'e ae"sv:iq'H
    return 0;r;vm3z+hi
}
\-}l7if{'FH8n
/n5v:M*eR|| int GetTop(Stack S,SNode &e)d/Fs:nq[1l_
{BIO*l^X$e W
    if(S.top==S.base) _~ b7Y6]5z:HSV5~
    {8Vi2W/T m7cV
        printf("栈以为空!");
V(i"nt#t T,JWY         return -1;#^0W4Op8Y!R1X.y
    }
)R,{3S+E:GH     e=*(S.top-1);Ot~*V'XKIS
    return 0;*Y^e?O0j%\z
}MZ S{9L [
W/h!|h5n:I#gl
int Push(Stack &S,SNode e)-n/|}!Q$r7S
{%`M+Qu _QV!y/J
    if(S.top-S.base>=S.size)6wT/s.b2@A
    { F4O2{DP:C x
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
KW;G?B0V         if(S.base==NULL)
5G&]9Il*qbS         {Qb(ko!^ k\4e
            printf("动态分配内存失败!");(u&xR1p)?!d3s/Fc
            return -1;
Pw `,^M/O:R6[5H3{S4OF         }
~1i2Ak#}e%~(i8^         S.top=S.base+S.size;
'cp$q6b` b         S.size+=APPEND_SIZE;&ff]+@ Fm)j#ut
    }W `V&|[o
    *S.top=e;
Y*o^W#x!N     S.top++;] ](i K#M;`
    return 0;
A!@ f0t;uc^;x }6nAq/r(\*`z'h0X

o[l }yv int Pop(Stack &S,SNode &e)
c,vkG0FI'|p {
5ht|pB     if(S.top==S.base)Xf0Lt ]oy2^.D
    {
Bi!U2UoE7MU,` U         printf("栈为空!");
` UK,B!]4mp$S         return -1;6_*p'~9t2x ~
    }
IZN'xN/lP     e=*(S.top-1);2|(\x(yV@N
    S.top--;
(Ye}ax1mS     return 0;:ELe ?\g1H:C
})gU,v$T6l`*~
iu$z Vf5Z5R
char get_precede(char s,char c)1X6kv3bQ)LK
{
2S"`b8B6P     switch(s)1HJV`-A,J8k v h%UZ
    {
7A*}6Mn1r(Drnw         case '+':                 ItXmoh I7@
        case '-':9b-RD.mz{fh
             if(c=='+'||c=='-')
,j`BUWamm                  return '>';;j"b/V,gnp
             else if(c=='*'||c=='/')
q5TW'|y T Dt                  return '<';
r6QP {4I!PJj              else if(c=='(')
w `H"uX7HIS0SA                  return '<';
Tt dC,X_F"`i"N'I S              else if(c==')')
4AL"Y$iB'^u6QW \                  return '>';
7?f ^\5`Xj              else
}+]EK4t7H                  return '>';
p!JNCu         case '*':
V4A(``0A.t5p         case '/':
n.`w:F7f1? X"E              if(c=='+'||c=='-')cHu2|m y ^
                 return '>';
Mj'M${9Tu              else if(c=='*'||c=='/')
~] sr&q;O f,C R|h                  return '>';VSCr(toY
             else if(c=='(')
z _S3`1k` ?5X                  return '<'; I5y:K rRT u
             else if(c==')')
|7YB!e(Ny|4]                  return '>';'Q7rB d+C
             else
:CSh"W:K,M+c? Xpp                  return '>';G'w:w0B&W7c
        case '(':4s y7Hc!lS~i
             if(c=='+'||c=='-')
C.tD3f,a L_                  return '<';8OeX D.a#p
             else if(c=='*'||c=='/'):EV"f d/h;ms
                 return '<';"Al%i!o0qe7a
             else if(c=='(')
T}"T(E$Y aL                  return '<';4R&q*u%w/I6^y
             else if(c==')')1BF#k.as(Z0w1k
                 return '=';
Ry.lw4ed              else6iKu)M?5pK
                 return 'E';
!G0|+V%Hr+H         case ')':
7~Z;m MaUw!s              if(c=='+'||c=='-')
B'N3x7Q$Mg                  return '>'; ?&O7h? A-Fcl'O8f dv(N
             else if(c=='*'||c=='/')$yz1Pj4~3^-M
                 return '>';eC|8k^0g]
             else if(c=='(');u5m(o3u1G;C g0N
                 return 'E';KZ W wn$b!x;V~M
             else if(c==')')C3KD XC H A2}
                 return '>';Y A6p3E?
             else7ChmSVQ$X
                 return '>';gs:T)W'Wi|6z!W
        case '#':
"A*qw{;Q Fa,g              if(c=='+'||c=='-').m/]o/c^z&m ^9LHx
                 return '<';
4t0EY*~!}#jX"qD              else if(c=='*'||c=='/')Y rU`-P
                 return '<';
_s{E M;X;m4}1h              else if(c=='(')
'@;t;tu_z                  return '<';
^s z2]iqk c$mw              else if(c==')')}X$mt$Q^ [(S
                 return 'E';
5G Fe mlZ(Ks"T.e              else!fU/R7Se"s,p
                 return '=';
2RY&\4N7W5f2jy         default:
zNzD~9~M7lN#K              break;
1iYo-lgQ ?{     }
$c8q;C"X.S3B     return 0;    &K!@/C+B _m/m%PZj
}+GN8d:V7X$M D

J3y8lQ,X&k4zg_ int isOpr(char c)8CQV@3b@3M7g+g.])G!H.w
{
q?l(q&mn     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')3X*Lk+do+P/p2z] l
        return 0;
%UO+U^$z     else
y@0t_K         return 1;
c$UVKI"K,L u }
Sg$NL!z3p
ODmtZSwk u float operate(float x, char opr, float y)
-Y4o9Mn1l;o-z {
9R2X2R i[3^,j9tO     float result;
Y0_$c JXYnD     switch (opr)
8rH@7P$BB+y'O     {n*W/o)J(Z.`w^
        case '+': -z7v,bq b*Jw
             result = x + y;0S&EP0U.?JA%H5g`$]V
             break;.YYXEjk#qm-@
        case '-':
D;Q)V'Sbb;d3|              result = x - y;$R\b!E zN
             break;
.u*vl0Ac D9N'q _         case '*':
0_ ~J4N+y-^)V              result = x * y;(yw8BJr
             break;
H#bF&zL1EE[o         case '/':
3r1F g@,|I4v(A$h!U              if (y == 0)
Q t,j}q0| b              {
(R*o-\2vFo                 printf("Divided by zero!\n");
,eozj2A9v)I                 return 0;
v}U/?4ZhJjE              }
E(}^;G5nT              else8p7O:bE(eP{EE
             {
ZlMsA^                  result = x / y; zTN*V*N
                 break;4Nox^,N;x
             }K+KB|C
       default: 9]I(wa,v3LJ
             printf("Bad Input.\n"); W)CB4w4v7|s~;nl
             return 0;
_+A C-e'z Y/\     }
v#~W*N1X     return result;?LQM%|!d"Q8m
}    )VSQ:l ob7s7Il
'Ok#QMg6q1H_
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
E m*pV{!t,r {]2Q4If@C
    Stack optr,opnd;WQ?C5v&q5o
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; BGc3e9Q/S5V%I
    char c; M&V\6`C![Um]
    char buf[16]; P"tKz!F
    int i=0;
&{d|:j+}#T(A @E}*J     p-Y|!x Or5ilT_J
    InitStack(optr); /*用于寄存运算符*/
8H(e}3n5H^*UY     InitStack(opnd); /*用于寄存操作数和计算结果*/
-w9q%OXr%j(yq     memset(buf,0,sizeof(buf));GbF6W,Q;Y*Yv
   
cGanm \     printf("Enter your expression:");
:W Kz4O4I([ _uFt         hfk%[s3N
    opr_in.ch='#';9c!{(D"SL3KQ.f u
    Push(optr,opr_in); /*'#'入栈*/he&FQ'vd^
    GetTop(optr,opr_top); B e"a(Jo0H:aL~
    c=getchar();
*dp`]F c     while(c!='='||opr_top.ch!='#')"M)spy0N'? ?-F.qz
    {c|6~0E,^
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
!? M.@ uw Q0ki^         {
!E0ZR(mM/cPH             buf[i]=c;
rSl)m tr)\             i++;X[-_scIH
            c=getchar();6{R#`'uC2\)a"q
        }`C2p*TG"Cy"j/Y hUQ
        else /*是运算符*/
/|2aD"F`K8p \T         {
b7A_2pqWd             buf[i]='\0';
MWa3D&LE!a%y;e[1L.U             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
zD$ys L"B ^#[             {P2c x2JD(~r Z5N U4@
                 opn_in.data=(float)atof(buf); U+^}3UGj0Zq$ni
                 Push(opnd,opn_in);
$`w&Ht W#d                  printf("opnd入栈:[%f]\n",opn_in.data);
|7a {"](? E*Hz.c                  i=0;
)K,y#^D"L1bH                  memset(buf,0,sizeof(buf));
Bi ["on             }
A&l8I#~XE8{\0J1r:X             opr_in.ch=c;
B`-A@8p W#Fm;j#s9q             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
0j rf`.~/@`:o             {q3w ~?6UP
                case '<': /*优先级小于栈顶结点,则运算符入栈*/5df2H\gKw
                     Push(optr,opr_in);
0K kPN D!b-X                      printf("optr入栈:[%c]\n",opr_in.ch);Js,NgW9qP&QD@
                     c=getchar();
xZ"vA+L7T!zf                      break;
(j!f E2WI:YC:x6yVc8t                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/e8L8DS1f|b
                     Pop(optr,e);
$k#KT$[)e4j4pL0JG                      printf("optr出栈:去掉括号\n");\2H$xI9EM"Kw
                     c=getchar();V zq E']\;DL,}a
                     break;9PmLK ^4MR
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/.T u pZ(M#QD
                     Pop(optr,opr_t);
,YCrc6{+]                      printf("optr出栈:[%c]\n",opr_t.ch);
o7n3vUe`vt9tN                      if(Pop(opnd,b)<0) n(?%sd8\7Q-A,vg
                     {J_.~)M+M!_J-B
                         printf("Bad Input!\n");
/W^d5_)Sk#r                          fflush(stdin);
s [c!}&Km+C }|o                          return -1;N;g7z\*{S
                     }
2Qmmw|Q                      printf("opnd出栈:[%f]\n",b.data);
5^J'x5N:c S&B%_9q3_.a                      if(Pop(opnd,a)<0) qjoP{,|
                     {0sio1i8p;y?5K8t
                         printf("Bad Input!\n");
a1})gssN2Ll                          fflush(stdin);4q4EMT;E;x,UP @j.Z(Q*e
                         return -1;G4K"fU['kM5O!U!s
                     }
!O `;@'^7v0lX\p p                      printf("opnd出栈:[%f]\n",a.data);,} zpSpK7h9|1F'O'~d
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/A.X*~A"QgFj5y
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/P7H$k7p/yb{
                     printf("结果入栈:[%f]\n",opn_tmp.data);(FJ$NG`1k,s}
                     break;
kJ{.v7VbA             }
|BmGg wrp         }#D/gqA,L
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                E9h+A.q$A A)C
    }
S3X8Qo e)n9E     GetTop(opnd,opn_tmp);`;SPF!x
    DestroyStack(optr);h+mk1fp3LDj^*z
    DestroyStack(opnd);0?7ZA$iI` Z
    return opn_tmp.data;
"_.E:ua1qi8aC }
0tM9{;p|)B7P4?4p :RI7@FB?H
char *killzero(char *res,float result)
-`Y/HD:L_Q {
I*LU}b^u0??     int i;:I v'zX)a*h.Ci~$fP)B

jO-r@C0aR@     sprintf(res,"%f",result);g-VS8y ~
    i=(int)strlen(res)-1;v k&Y8_.@ m,G3LrVS
    while(i&&res[i]=='0')LO+lw%r)m UH:~4L{
    { S-s9ow%uS*b+r)zp
        res[i]='\0';V/XZ w5k[
        i--;
'\qQO-es     } Yj-NX&N/Gq8?O&z
    if(res[i]=='.')
5T*a,iH9M{H&l         res[i]='\0';m,w7I(h8~
    return res;
2dm$E6E4Y A:d r6i#P@ }0O\&CZ{^

0n8{/J p? int main()+wg.?Z#K!?*D:~ K
{Kq;I7c(HC6Vv4L
    char ch;
Wn,x1p9V4rM     char res[64];y|u8uk0t({ MH
    float result;!V&X~g*J
    while(1)
8L&~)p\#J?     {8V:O3WC V Y?1j#{
        result=compute();?.K[Wd7lMxF
        printf("\nThe result is:%s\n",killzero(res,result)); h6O4aJo
        printf("Do you want to continue(y/n)?:") ;;b:EY-t7q/|Oy/@
        ch=getch();o2~!Q)I+r$K2w
        putchar(ch);1]OT,@ RL {
        if(ch=='n'||ch=='N')^Mi@hc
            break;MQ}4Y#r@ ]
        else C#|R"FL9@#Zf&_$O
            system("cls");
|9s1e c{#s     }
o8R2Z-se:UB }A     return 0;
*B:u3[)~m0O }[/i][/i][/i][/i][/i][/i]
`2dqd"~8sO(H6a
c/J?S3f(o T)D [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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