捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
GS~h7{r 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
-r-M?U Oc,p oG /**************表达式计算器************/
9zIQ\!\G(if #include <stdio.h>
h7|&xy"@ #include <stdlib.h>;Nh W3I1[X UF(V{
#include <string.h>
2z)X"Y*IkP3?/~&qY #include <conio.h>
P p(M~P~ #include <malloc.h>
#SQ@0f7`(j S$B2M P` [Ey1F:s
#define STACK_SIZE 100
.j Fe#}h~_/B #define APPEND_SIZE 10\tgOBei

{a#QpH5m6|C struct SNode{
~ r!c}3kK     float data; /*存放操作数或者计算结果*/
0B2jeT`d     char ch; /*存放运算符*/
-LtD ]`\mS };
D!m5nO0^9c#W `'C'f9a 6NhW;C,yN O
struct Stack{
h UT4QL(Kbkn:k2U     SNode *top; Hp:b:gw
    SNode *base;
C:c:sC%|6J?     int size;
z6sQd!|5AL9KK };
3H$MOy Sji6j$w DV#h5uF|:?+G
/*栈操作函数*/
7J6f&Eq/ePm:rR int InitStack(Stack &S); /*创建栈*/
%V%}BW.{WD int DestroyStack(Stack &S); /*销毁栈*/
.T,l&K eA L int ClearStack(Stack &S); /*清空栈*/
l sj:p mRPB int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/t7Nu"Z)XA"p
int Push(Stack &S,SNode e); /*将结点e压入栈*/g@ fF.x
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
;i*I\!y2pfD(Z(ww 9o?.Q9{.~ ? g
/*表达式计算器相关函数*/
n,Xd(|lVN2I char get_precede(char s,char c); /*判断运算符s和c的优先级*/5I:ToDD$^ H
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
,gm0H:pFe-fm"P k float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/u)P x@o$F
float compute(); /*表达式结算器主函数*/
5N ON+i"Hh char *killzero(float result); /*去掉结果后面的0*/ uC&v g5Kd;s
+J9E2_tdp
int InitStack(Stack &S)
8j1M9VIq4l {
O\zF@JWF'{9|D     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));\ZO+]4iyqc3f
    if(S.base==NULL)
`;\NgM,m,{&{,H     {!d%R,EAVI
        printf("动态分配内存失败!");e~;r(UO bOG
        return -1;
1o1O R7Fy0tY:X SN     }WhPW }[XK7k
    S.top=S.base;
xQh$X1LWJ}m     S.size=STACK_SIZE;
*H IW;J:@U6W:N)X     return 0;C6oHhHxsnU
}
4TWg]'bF _(k
7h']"Jpo wtt$v)d2^7s int DestroyStack(Stack &S)
7NL-fEh;[u~%^? {O3}&Qms3m
    free(S.base);d.s)Qo4W@
    return 0;
R'U7ir8g }
vA1U,]{7}:qm
+c o,PWR6_~ _ int ClearStack(Stack &S)rn[(g3M-j+y;@j
{pG%u:M V5v*y8l
    S.top=S.base;
1px$G3a2r     return 0;
v0l'RQ"_cmiVl }R&Wu8r3GV} Y

M#s#U4o3M3R;l int GetTop(Stack S,SNode &e)'c$up&QFh^c2J
{5Gja AnJl
    if(S.top==S.base)FT nl+[ j;w}hK}({
    {
#H6L TG7[m7S7Jw         printf("栈以为空!");
Mv#d-wb7[/Dq         return -1;N)y]"t8[ lL*w
    }
$n.|/MGs     e=*(S.top-1);O)}9k JX.Y
    return 0;3zv7i+v:KA
}
~HY|W3I
E d0l+YQws| int Push(Stack &S,SNode e)
9TC3oR)K O M kn8@|? {
%i ]1zUw-|[     if(S.top-S.base>=S.size)
kN7D*D y}_     {8S a%hEH%l c)]H
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));5|lX(I6P ?;J(yt'V3W
        if(S.base==NULL)
Hs:IA8qr+um3uz         {?m7Q`y } J\:FW#R
            printf("动态分配内存失败!");
%d8q&xU%RN'z;o*U             return -1;
0Z| m.m3NT         }
N O4W0F5A:d'A^         S.top=S.base+S.size;
'i:j%p x&w$}^4Q-l$Ed N         S.size+=APPEND_SIZE;u2ok8q)d&L#S
    }
Z.v'^$X(n     *S.top=e;
ozY5mU bog#m!|     S.top++;
#TD#NI)p     return 0;Kh,GKj6I+\1i
}{4glw6](d9_\0P7z
?;T OQ Y{"Vx/v
int Pop(Stack &S,SNode &e)
3\7LYW_?0v?@ [ {rL oN$y*x(Ih-B
    if(S.top==S.base)
j-h T:~&k-BW.J     {
:i*KhW^f"J5u         printf("栈为空!");
v4`c*l#c~,]u} ?         return -1;8ieF S&m$j4I
    }
#rwfCEJ'I#a     e=*(S.top-1);
WdSG$w bj     S.top--;
gZ)e)gf6t u4a$\%D     return 0;
[~ Yv1[;W }
g#v'dPcO}
#_M.rSk"esk char get_precede(char s,char c)cO ~#L&K\%V
{g m5EVB r^:_/No@
    switch(s) m'{SH9x)Lbr.C+N
    {
O5g}sa:b;qJay         case '+':                  Ocv k!@N[
        case '-':$T%v1nh n/EUGS
             if(c=='+'||c=='-')
'y+i2H,n}o"lL4?                  return '>';
AU#xd(]&z5S Z)@              else if(c=='*'||c=='/')
LoV y6_e'L(c4f                  return '<';
~6@+m L^\}q B              else if(c=='(') ^,izSQN
                 return '<';
y8Q'Pm*R3l              else if(c==')')
'Cu/\v4M2]5V                  return '>';|1ot4^+aA
             else A9PT!S/C(uF
                 return '>';IG"Gz)xy F.t?.B7H
        case '*':]C.KS1e v Cr
        case '/':
M-v MRr$C/I              if(c=='+'||c=='-')
L)i)Vz&Q5F                  return '>';i-Y~\3z,HV}f
             else if(c=='*'||c=='/')
R,p0]%@7w6\ o                  return '>';
$D3n:[5o:^9nq              else if(c=='(')q"_&qBr&x~*g
                 return '<';
rLl,u6]]!M(N              else if(c==')').kv5^'g8L1iU#[,@7{$Q-e;G
                 return '>';*a!j\c3p?O R
             else[1p5q C3[!rf
                 return '>';
*RA7_a`F_?0O'l&[         case '(':
Gk @ \9pFy              if(c=='+'||c=='-')
"[{5N_#Pie5c7v WD                  return '<';
,Tp.OU]              else if(c=='*'||c=='/')
:wQK D pl P1C:Bj                  return '<';
$f` ?C6R!O*eGH              else if(c=='(')
Ha Qdw5jW@"DZ                  return '<';4in,KQc+^9v q
             else if(c==')')1fb*zZ3F5H+b2p
                 return '=';
&Y.vR"|3L U7ax              else-KWbj;Xw
                 return 'E';
h f%HQ#g9B@         case ')':
"dF;C'z[              if(c=='+'||c=='-') ^4z;Qra
                 return '>';
\uc~.H              else if(c=='*'||c=='/')(t4@c0r0B
                 return '>';
7@+_LU }7V              else if(c=='(')
d,~(O5Ha~%KpNh4^                  return 'E';
8Q,k{.k8m!jS              else if(c==')')
~0m"ps!OS                  return '>';
/js7XM,Zh              else"X4](^v:W C1c%b h6q
                 return '>'; t[5W,mk1?4y
        case '#':
?r"BK6| o0z              if(c=='+'||c=='-')
KafF#C#Q!s                  return '<';}!~ pYv ivV
             else if(c=='*'||c=='/')6[FD"Q#@+T
                 return '<'; Ra-}!M@@ j/Et
             else if(c=='(')
RvJx3uZC+}                  return '<';
E CBC1GIt]6R/c              else if(c==')')
Vl;|d6}(l |,A!\                  return 'E';sy;d?O|
             elseQOXjd~|
                 return '=';,b R)G(l-a5U({s bxI
        default:0quA'foo3ap
             break;(B'P'Qp'[[/|W
    }
F_)F2D9y/b     return 0;    :T@v0]J0Ew` T \
}4t+f%\,lG ^6T2jw
J0UR fB
int isOpr(char c))B8H+CR#e
{
1]'q8G6v1C I%r7?     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')b9p8]A?o#`%@V
        return 0;"?,nnziX
    else
(yS#YdQ:e+x+K         return 1;w"N0|(e.tZ-_}+SH
}
5s%Kw'b\
Vo/Gir}:o_ float operate(float x, char opr, float y)*I6aH KIL|g'`
{3q+P)[n4]]:z f o,v%b^sS
    float result;&hf M)cc
    switch (opr)oES` |.rz#u
    {T Gu-sf1P:Z:Q!\$FVx/^
        case '+': Y2\s.x-Y"aE%O j
             result = x + y;
4e2[s x:O Z              break;j1C'J8Gv(W3Q
        case '-': &c4G"R.b!yrDI
             result = x - y;
6\G3NJs.t1F ^h@-H9[              break;[Uq3pc*v uEBa
        case '*': 8? oR$^*I`"rL
             result = x * y;
fR8gH-Ji Z#QEw              break;?@ h F4X
        case '/': 4_)`}n{F%J*\r)j0h
             if (y == 0)f%SGsNt`
             {6i0\6^C_1rj
                printf("Divided by zero!\n");(nE5|Z}1[{2v.@$bf-s
                return 0;
KC;y;dW              }
+C!j V8I Sq              else)_v Z#Y2`o
             {1T5m'`:kt"h&KS9ba
                 result = x / y;f]R1q v0s5LTJ2i
                 break;A._BE'i1Q+Z/W,q
             }
u_4xXM*s        default:
I'kZ3rS              printf("Bad Input.\n");
3DxE d3~ik;Ox!kV%L              return 0;
TQ(o*ED)u+J0T7w     },}&k uap/u
    return result;
s5T'Z'G hV+r M+| }   
~ @Y r r@L~
,W|hB ZA4f#xl7}? float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
a0V)M9DE"t` {
-E%klwJ     Stack optr,opnd;4i4`L\9EzS5UAD#U
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
-V7@3\tc:DgI3`     char c;1^2Oc5TC4OEr
    char buf[16];Fs0j'S|;j(\&u
    int i=0;XS"k9Q+B @7u!dQ
    .F:[r6W:eN
    InitStack(optr); /*用于寄存运算符*/
$TG2?U-U*\.AW     InitStack(opnd); /*用于寄存操作数和计算结果*/LPr%s#J7r
    memset(buf,0,sizeof(buf));
,W+d*OY7r+F/@,Zo     Ln.Y6zf#B^
    printf("Enter your expression:");
2e qaTM"TeU\         +nhiP C6A
    opr_in.ch='#';xX&G4Uy0c+o.H
    Push(optr,opr_in); /*'#'入栈*/2v2_Q"vBd
    GetTop(optr,opr_top);
w{!lnFBa     c=getchar();y%B:uL0e6V/T
    while(c!='='||opr_top.ch!='#').UgKg,G+p*RkWu
    { s.NY.g3T'X2H e
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/HSf7?M HI
        {+?(N ?)Nj&R!g'Vb
            buf[i]=c;
'J!t2S/j0PT             i++;
!u]+X `? V             c=getchar();*xGN`1wP Lrk'D9I
        }4KO:H"Y0c!S7R9W
        else /*是运算符*/0TY MSI+eB8n&w
        {R/\8~W R3C+I
            buf[i]='\0';!Px$dMP
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/j4z2~ w'S4R I
            {:ctxW |g
                 opn_in.data=(float)atof(buf);
7YPh$m5J&P`_                  Push(opnd,opn_in);u/h9iD4y
                 printf("opnd入栈:[%f]\n",opn_in.data);
,c8K4p p?;}.](i F                  i=0;%R0w`T.l @G*\
                 memset(buf,0,sizeof(buf));
x3VMox o]             }3N/][iwQ
            opr_in.ch=c;h1\cQ[1H
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
E4A$m)XB0by)f             {
-a2V{"b,S Aog ?*K                 case '<': /*优先级小于栈顶结点,则运算符入栈*/g*u Y x!b)l:lp
                     Push(optr,opr_in);;S u&O"T&H4R_ySZ$M
                     printf("optr入栈:[%c]\n",opr_in.ch);
2b*~It-K?2y"[,W                      c=getchar();
Y3d^)U.G8^3^                      break;F1{*Z;r%\ [Q
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
Wr^K `;a|"~t                      Pop(optr,e);
!\.X-l^w2]3C&V2t                      printf("optr出栈:去掉括号\n");
tVY-t}([Cnl(}                      c=getchar();
'`Ssb/K-tw;E7z                      break;
Z,Dg[n`2A                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
T']Q)kU                      Pop(optr,opr_t);
teQc)Si:d                      printf("optr出栈:[%c]\n",opr_t.ch);AE,l(c${2D7xoq'\7T
                     if(Pop(opnd,b)<0)U$mxr:[Ph I$_2y2a
                     {2OHn^&O OC
                         printf("Bad Input!\n");%q ii&}o
                         fflush(stdin);
E%F-gU+rd W"Du"m                          return -1;
ag |DC3{] ^/S                      };jnI(j!le
                     printf("opnd出栈:[%f]\n",b.data);1r_akK8V
                     if(Pop(opnd,a)<0)
$w Ev5FV3e&Pc p                      {2yr8qt^
                         printf("Bad Input!\n");
3aV)Sc v                          fflush(stdin);:t|R2e4c.gC;Z*\1q
                         return -1;
d[^v f(dc                      }#M+p9p6W5sb-X A)A
                     printf("opnd出栈:[%f]\n",a.data); J1F!H%lPQ
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/0Ha;eh Jd3tK
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/~7Jm&g h"X$j|
                     printf("结果入栈:[%f]\n",opn_tmp.data);
gcqFL(i5^                      break;
.n(Sa-d$aF\             }dY Jw#n
        }
Ug9u5B;X2h+?/KN.H A         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
2X|GH \I0Y$k     }
e~/q3W i OB     GetTop(opnd,opn_tmp);
jP*J#zi     DestroyStack(optr);(J m3\!U[ g
    DestroyStack(opnd);`(e8D f~ `?B2z
    return opn_tmp.data;
8P2`q(t&I"@ U C(QZs5Y }8~$f:g5}]N5a
z;`Mh[.~+Y(DtX
char *killzero(char *res,float result)
4S9z)Z2s-O7Hm0} {
0g,b M#Q%?n     int i;
r5?fM$^/p,r
(wc%i5r]6B     sprintf(res,"%f",result);
(tb~)c%eq$w:O Y     i=(int)strlen(res)-1;K$\G1g1D?w
    while(i&&res[i]=='0')
r)Y$fT.c9O6fa4T     {
$p+fJOT%xJv y         res[i]='\0';n;jI{2n
        i--;:|JT6Xsc)@o n
    }
5]4a7]I%^n0G     if(res[i]=='.')
,^G-`9w)ad-O         res[i]='\0';j L3a*EhE3I2S
    return res;z @#`dSz%G
};R-aO%BL*N%]4M

3nXCX9WSm int main()"n_g{0[k
{HuL4M j%Z n
    char ch;
aI'c7U ^Fs _B     char res[64]; \5gk:i9^a6U~j"ep
    float result;
C`;BzuY[     while(1)
OU;ThH6^Jt7r1lqP     {o"ZR2ZKNN p
        result=compute();
A:}5hF:oV         printf("\nThe result is:%s\n",killzero(res,result));
U'j(i:x$lR,F&T         printf("Do you want to continue(y/n)?:") ;
n?[&Qi5[!WM         ch=getch(); }Ei5L]&g(n
        putchar(ch);
~k(hl-m,|N,q?         if(ch=='n'||ch=='N')C%U P0Y| k-R([C wp$q
            break;
#f/z,hDd p!T$`2Z"R F         else4{4X[,lf%o$O
            system("cls");
)o0[B J(J x     }
&rd1`tq*|YD     return 0;HAnB%A/o
}[/i][/i][/i][/i][/i][/i] gn yp9R L
i U9JV ptg
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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