捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.c1Q8o W;Q#\
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)= }&Yi3H"Z5A&g D
/**************表达式计算器************/
P,U.G(xb{ #include <stdio.h>
RU4HYJ #include <stdlib.h>D{'CS0{+wHo&u-~"E\(vx
#include <string.h>
Gh%c*N&Q0I9S#s #include <conio.h>
UDj1wm]*o#\ @ #include <malloc.h>
s7ya3t+k%n a E
8z@ rb(j"Q #define STACK_SIZE 100JaE Swl/o9L
#define APPEND_SIZE 10
2w9TO:q%J7O(i/{5p
b Jr^e5\lt E struct SNode{
f!HWl7PR [ ] gw     float data; /*存放操作数或者计算结果*/
!WZyE A^A1{     char ch; /*存放运算符*/
AKqJg:Y4w'H*o6vz };%WK\iC-{5@o

U{C(\+}Gx struct Stack{
7SH#AC9ii6j(_     SNode *top;
$D!{pAYESCy     SNode *base;
7mF(LcX4h5}     int size;A jc'v {Z%O ` F)G
};$~/`/S8| a4o

1L R'[q ?5E@ /*栈操作函数*/Qv'R!K+K
int InitStack(Stack &S); /*创建栈*/
]9Zf _I(X;Sg;K-D(X4` int DestroyStack(Stack &S); /*销毁栈*/
(|q C#@k rk'a*nN~t int ClearStack(Stack &S); /*清空栈*/
P$J A6PGO int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0G1u2j3K,`Jn:s%V int Push(Stack &S,SNode e); /*将结点e压入栈*/r`/m[{r;b%Z:H
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ NEL{ o ng
t)iAt5V(R\HL
/*表达式计算器相关函数*/
.x9T$d@u ? char get_precede(char s,char c); /*判断运算符s和c的优先级*/
Fdk$G^)K~#ltLj int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
eBF'h XM!Y t float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
9P[.VbJ float compute(); /*表达式结算器主函数*/
W]jQMg"F7_0_ char *killzero(float result); /*去掉结果后面的0*/
2r;D4dUX+e3y
_i t?izr @ int InitStack(Stack &S)&t'b+q+w&X0E2]j
{
pTX/}I7@~)s     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
i1vJE^9s#o? b3zv     if(S.base==NULL)
eB4{!pm0T?YF%[     {%\&xy_7H7sy
        printf("动态分配内存失败!");
6}7h%P+Qj{e3V         return -1;
~@a iuU:v#uEx     }J Ua`Z\K]%}v
    S.top=S.base;7m/V y,l3n/Jng
    S.size=STACK_SIZE;1PJ1Me4Y c$`
    return 0;
;I!mRmj5P$R{ }
iw4MD)S+N$dn P bl Y+P6J3Y0`0P
int DestroyStack(Stack &S){|9if@x2VM
{8T yfUg!\4u B#|!?G
    free(S.base);/W$D+R1qdd
    return 0;
f!Y4Dj`z \ }
R%y,|-^5sbCe
#Ry$|4^A'L int ClearStack(Stack &S)
's,{#xl5Nd4A {
,| j0@E/X%N%?l     S.top=S.base;
g`-mF c.si:o*mk,kX     return 0;
g.L+G:Ip Fv4E }
L1G;r}sY|~'_3d ]K
(m nKI@)T#CQ+Q int GetTop(Stack S,SNode &e)
5k1lU1I;l'Gs {
,k q!yE7u7m!j     if(S.top==S.base)
-qqfVYP#E8C/u     {wZ/SB-g0p(ex9[
        printf("栈以为空!");
^@y Y#|I0` K m;i         return -1;
;Lzw[*b[T4j1N(D@     }xN;B/QvQ;n
    e=*(S.top-1);
I#B.a ~O(hin1U     return 0;)H*{,Q/}vh#ppS K
}
!|:M'F K U1bh5j C4U*h0V&H
int Push(Stack &S,SNode e)3cy'wl"Z/kK
{
@Eed'zq[+`S'l     if(S.top-S.base>=S.size)
%W G0O_:h     {
?6?&Y?6Q o(U         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));X&u]5E%tr
        if(S.base==NULL)$L GD3Ls/M)WM._'x
        {'PTqj5xF
            printf("动态分配内存失败!");-W j5H9FC P
            return -1;
%H5{,os.T:L         }
z!h|'H [ MFz         S.top=S.base+S.size;4JjAT:X4m;]:u(o
        S.size+=APPEND_SIZE;
;m3H)GPOwv PR$H     }r&aP3w5?L2d u
    *S.top=e;
?T#S}1a     S.top++;$YSe-\5K
    return 0;
#@ M5ztS&x~$S }
n\&vx5y:bH,U"sW
[J6E$a|R'Y`nK int Pop(Stack &S,SNode &e)
2JQqtxh kF!Ksb {
)l+me!no \"_K     if(S.top==S.base)
9^Q)KjQr7i1l     {o5Py7_ m9fr
        printf("栈为空!"); |6nE1QV7D
        return -1; _+L7|#?h5H.W-Ly
    }v$K7W,GIR)Rc9n2H0o
    e=*(S.top-1);\m5bR9u
    S.top--;hP$zz\!};_4l%G
    return 0;(l t7lYG/}y3zf;p$[
}
Q j+SD6b;ON[ "t sV N6B
char get_precede(char s,char c)
-s'WD3p i.K_a {
4j$`(S&D I7_Y&_     switch(s)
lmJIE} W-E     {xA0d'j7y j]"D,oN
        case '+':                 %v d^%Oyw
        case '-':#b$Y9q9_7d6G
             if(c=='+'||c=='-')U~Z%C:]b5wO"j
                 return '>'; s[oLf@
             else if(c=='*'||c=='/')
b?jx8{%{?                  return '<';`7d+u@dp}
             else if(c=='(')
,~.RH1xm3y&_+a                  return '<';_3r8Ty*@
             else if(c==')')
[,| Cx'OR                  return '>'; L.uA0R:H
             else
!^p-HE7Y                  return '>';w2{"pA2YO;O
        case '*':r&Ts E$Ziyh
        case '/':8HB]c3_ w;Y8If3I
             if(c=='+'||c=='-')
dW [/Q!k#F+Q[|GC                  return '>';
8S&e9C:V\v9^q              else if(c=='*'||c=='/')Lc;|e:yz {
                 return '>';
{J"\/Y @ p              else if(c=='(')
7S-c@K}g)L}2cT                  return '<';![sO\4B`9t c^
             else if(c==')')
3hAE!Wc j4cO5hF                  return '>'; [J$ce#^0fM~
             else
+M!c(JP$M L&Q FJ\X                  return '>';
sxz'M%^9tEJ         case '(':
x1h&|I#wl Y @              if(c=='+'||c=='-')
$DdK,JQpT                  return '<';
H:O&]+iz&P.Lr              else if(c=='*'||c=='/')0}I1s.e*Li2K
                 return '<';
'yHk u0F^|              else if(c=='(')
3G1^*eoW%E                  return '<';
%uTj-n0a3I\t              else if(c==')')L`&k)^dL.| g
                 return '=';
3`We v \i6n              elset1y Z ` P*z{
                 return 'E';
j;]`L a(|A%s4[n         case ')':f(mGXK#^g
             if(c=='+'||c=='-')9n3N3]%lku-l5_ D
                 return '>'; Ut:Rm9e u
             else if(c=='*'||c=='/')
0X)P {6i({.e7\                  return '>';
G Uc'`A(S bE Y              else if(c=='(')
%r"|f}&y                  return 'E';hq3`n]
             else if(c==')')dvF2F3S4_![G&z
                 return '>';L0l-l%q&de)hY1L
             else AZ(k'RZ#lJ
                 return '>';dK/yy3uZ
        case '#':fAr8OfI
             if(c=='+'||c=='-')
w2d*KZ'l#`ynp                  return '<';8D^C1?$GR*]!O
             else if(c=='*'||c=='/')Y\A.A$tv$R q[
                 return '<';cC s z{
             else if(c=='(') ^'n4L/qt%R0\|
                 return '<';
U9m'C;U}wzp%c8o              else if(c==')')Ddcku;i~$vV0k
                 return 'E';b SI_\!^
             else
pb%bvVT                  return '=';bi(^q|Y |d(Sn b
        default:b!f9hBUe}f\3{
             break;F dT!\@+S])kc[1D
    }
z e?7Wg1t3vR     return 0;   
4^Z8i`,z#q dC#IK }],n4Hy9b;iYW4P

6@ k0qxR.Y:Vv9J int isOpr(char c)
&j,@NH {~[eY {
1t%Kg(u-Q,qQ,Y9z Jm     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
{q6u m8}Q*]1@         return 0;
Z'x j W!N+`4y     else K{E!OXQ
        return 1;
R1s/^wx }i-WAq.]1jS x*f
L:`,Ady5c5B\
float operate(float x, char opr, float y))HQ4b+s*FbY;I!A_
{]U6C2R7H)cCg
    float result;
F+Gu+|lF0Uz2i     switch (opr)
;zg!g3wi/U Ie ~     {d-nYK[,O
        case '+': r%O!W m Y N4IH
             result = x + y;/pC9}q0Q;T4zN*~\
             break;T`AzemA
        case '-':
B)JcQ*_mG              result = x - y;
8\J}m!s0\ F~6it2L              break;
!yXVq_zv1F         case '*':
7ZQ6pa9y c? D              result = x * y;
)rN hi4A-X%[Z              break;/l(JH z}
        case '/':
Y&gDd*{8ER@@}              if (y == 0)
rX1zKP ?V0PQ(w              {
X } ^J(NSC,[                 printf("Divided by zero!\n");
X#|wy3VB [o                 return 0;
E.iP[&vzj              }|Ux.xjvbP|!^:v
             else;}R_T-K7F p#VqB}
             {E2t)} Q:D c l.^O|
                 result = x / y;rN$ni0w
                 break;
SB#e im9k              }
f-zsQ1xFEw!k        default: C;i@x Q4Nxk c4|B
             printf("Bad Input.\n");
/kq.Az/U!f7Q1V(S+F%c(v/]              return 0;
I/KPn~)h,Y6n"a     }
K+pr(tSh8H.X     return result;Rcz#J#[:mQA$E#L-K\
}   
Z s*w ~Rgx
'Y$DP\$t^b:n-\ float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
+ZOP NQ7\} {
2y2{x+T+u     Stack optr,opnd;
"F$Hp-z:jCe     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
NHT{-K     char c;
2W qZ0C @ e8C,u     char buf[16];
C K!f!a0G     int i=0;3Y*UQ Gqq2p
    %P'ymhm ow5In
    InitStack(optr); /*用于寄存运算符*/4j `D+B P
    InitStack(opnd); /*用于寄存操作数和计算结果*/#r:s(M,zg?
    memset(buf,0,sizeof(buf));
$g[,KB{9U    
@~x*F.OZ)n{W     printf("Enter your expression:");
&I6h@R4UKE&C         
e t0]1Bl4I(Qi%jF1I     opr_in.ch='#';eD5y3RKC2OP u
    Push(optr,opr_in); /*'#'入栈*/Ug w x"Vi3Vg
    GetTop(optr,opr_top);
C'XP9_l     c=getchar();
So r.W8B     while(c!='='||opr_top.ch!='#')
]V dZ.dWY0qZ-}x     {F w2w8weI%cm&d
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
~;`5P\ VV         {]M!B7fI;kZ~3|
            buf[i]=c;
7u6E.{ O1TTfZ.^ k             i++;
)P^c.X^+r+^O2R             c=getchar();
iR'iS*~P I         }
u ].@?8aF:XV         else /*是运算符*/
r&N]g1Zxp         {`-a K ])m ^l
            buf[i]='\0';4z2j)I;J#w0R3uf3p'o1K4o
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
UP1i'A&Z*k             {UOO1ty i$H A2t
                 opn_in.data=(float)atof(buf);
O H2zz h.XW*]i                  Push(opnd,opn_in);
u6k @3z)AL                  printf("opnd入栈:[%f]\n",opn_in.data);
H)K vi:]:p                  i=0;W2m)EO `UqG9c(d
                 memset(buf,0,sizeof(buf));f ?)tM&Y~I{Y@\
            }
#J@9yUaE*R             opr_in.ch=c; j4B)n(qxA
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/se)x B+w+b
            {
8x!e"? ~1x-kqqP!r                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
8h{r0w0xo sl                      Push(optr,opr_in);
s^fS x|D;i7y                      printf("optr入栈:[%c]\n",opr_in.ch);/NBN&Tt%M0b
                     c=getchar();V0Y|9^k H
                     break;)h({i q9Y _F)|/t
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
@+gMF+| E\ c0E                      Pop(optr,e);Q-oI ?]
                     printf("optr出栈:去掉括号\n");x7|bu+pd,W3OA
                     c=getchar();6aZ3@"Br*up
                     break;a-dBS-J'S:WZ
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/`!Q)k%QB3AD:J"o
                     Pop(optr,opr_t);Qr.M/j~-n W7sS
                     printf("optr出栈:[%c]\n",opr_t.ch);
;XYyD@                      if(Pop(opnd,b)<0)
wx:d+?g ?-SC                      {
3m0Dq(g t                          printf("Bad Input!\n");1q"c XRU+I:D%r5O
                         fflush(stdin);:{6G9WOZ3OCS |+Cs"[
                         return -1;G Q!Dpt O5b
                     }
-v2t?4?9EE#J]                      printf("opnd出栈:[%f]\n",b.data);(P'K2@/C'K1x ao'Z!a
                     if(Pop(opnd,a)<0)Qdg1nmA
                     {
NL o$v@ t;E                          printf("Bad Input!\n");
5LJ8i!t\W                          fflush(stdin);s:mSm h\ JN!O
                         return -1;\3W(O8O6K }u
                     }1N&m:j9Z9^z
                     printf("opnd出栈:[%f]\n",a.data);
u cG7o}c                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/$\.u,XQ9} bR&I_
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/Q9VX:L/o
                     printf("结果入栈:[%f]\n",opn_tmp.data);
s;A.g]_w#T                      break;*BZ2`W2F)_'M2`)T }
            }^{6N$B[0~,K]
        }
E8n*U^s.N0u         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
u L-["JD     }zn#rQB,}Z
    GetTop(opnd,opn_tmp);U.b h8s"`X"r
    DestroyStack(optr);
/g2~R$X1V     DestroyStack(opnd);j{K9d;z
    return opn_tmp.data;
a9x:L _ ]y(Q*ycA }
0L0Xn&oZWh.i
~T4[F:vV char *killzero(char *res,float result)p:b@*xI&Dy
{lZ DEw%K.X%sD
    int i;
} w m:CQ&S'Q i8tZjuq
    sprintf(res,"%f",result);"wV(n#@saZ
    i=(int)strlen(res)-1;H4}0o-a4e5D9J^
    while(i&&res[i]=='0')
de%Jo;hcS     {IY{*F r$eHP,]
        res[i]='\0';
RSYyKA;SdRz         i--;b] @wtpA$r
    }-QOGi0~y(Ez D&Y!nk1?
    if(res[i]=='.')!]?o!y'E;b
        res[i]='\0';r \7\4D r v*W I0q
    return res;{ @ [ [1w/M1S[
}
-U+|!xr|"]
(g:{!w{c int main() k8BX r n-I
{
&C4F7t g)W s x e     char ch;bH7Q2m;C_
    char res[64];Vl.r7L4_s]8[!r
    float result;
CX1a.Y/OL-E&X c0j,^     while(1)
jF%{[UK$IK yn     {
/f0tZm+e VeC         result=compute();
BQ%i ?[zeg         printf("\nThe result is:%s\n",killzero(res,result));
D)P6`'D3P kx-y5Mu2T         printf("Do you want to continue(y/n)?:") ;
|qq#U8qS1d         ch=getch();-]B![dhE,X2P,{0]0B8Q
        putchar(ch);
B4eXr IOD         if(ch=='n'||ch=='N')
{Lp)Lk"`(\8Fl             break;"`RHo/Nme
        else
psQ@C             system("cls");)W*} QO"L2d5K"A
    }
'P$TA#Su,|h}     return 0;
k(V7f,f5]3\c }[/i][/i][/i][/i][/i][/i]0JB(@z*`z Y

5V4fF E#Pf1Szx [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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