捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
{/M6xVF(ol.wW 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
^*N5F7cE /**************表达式计算器************/"`,?C+nW]
#include <stdio.h>e/Vj9hJN
#include <stdlib.h>j _#d'sf[!k*a%QT
#include <string.h>
?"Q^'YE!V%IVS #include <conio.h>
R T]Dc*CB#Zo+J #include <malloc.h>
c5i y;l)kx&kY/O2? }O(|9sj
#define STACK_SIZE 1006C N7d4O5K9F-o
#define APPEND_SIZE 10
*Zlx/J-\(@9MP*V ~+Q*W+G ^+Lh
struct SNode{
*W(CH,i$O5^     float data; /*存放操作数或者计算结果*/*M-T6mHdt }
    char ch; /*存放运算符*/[[eZS2` dd
};
7Q&_e3p:|-n;f%y &Y8?9`(I3[ F7r$iy
struct Stack{
5h4?2ra MT     SNode *top;
M&^G6]we X     SNode *base;g1ou!Yb+T&o
    int size;
p'n5{w"cIj(q };;el3t8]_C
/x!KC9a v,Z
/*栈操作函数*/Q7b-]"v p8F
int InitStack(Stack &S); /*创建栈*/
F8E/][2Met int DestroyStack(Stack &S); /*销毁栈*/2G&v,F*bu;Nb{
int ClearStack(Stack &S); /*清空栈*/ ~&o:q@4h$w#~{
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/A/E\VEo-K?;F
int Push(Stack &S,SNode e); /*将结点e压入栈*/l)k cTl4Pi g+K
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
.A9iHY!n `$GP P ']M/X |qu
/*表达式计算器相关函数*/N ~"V'^%H \K
char get_precede(char s,char c); /*判断运算符s和c的优先级*/J+{fG&QKg
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
|q hw7wd"l float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/@o vX&dQM
float compute(); /*表达式结算器主函数*/Y B,X.S6\0~Z
char *killzero(float result); /*去掉结果后面的0*/ "p!XSvu3n-t!SZ
R [.DyX&Jp
int InitStack(Stack &S)p t&[;|1RR&`#V9G
{sT;~kp
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
'^+R0M ]4\Bc"E$cW-D     if(S.base==NULL) \%}*Z/f a:tYPG
    {
$h%`;FR4c8q!ZO         printf("动态分配内存失败!");
#Xh$reM1Yi"}         return -1;
^$@ _?.rU     }
`'EZ,ttL     S.top=S.base;
$z4l#i+O_`~'sd2S1qM4G     S.size=STACK_SIZE; `i4LZ7} F
    return 0;
G7LdCkNn }
MI;f dtg
:aF-H @ugK gD int DestroyStack(Stack &S)'Z!{ }sD*~!@}
{ i y1M)IE9Uo2O
    free(S.base); j7jY/ppk hZ)i
    return 0;
ZLEJ4cT;X }
V"]u evl] j
5Io.~8JM ^N.}0Q}RH int ClearStack(Stack &S)
0O3J(GnARU {*RW'wHVQ0k;X
    S.top=S.base;
:OzoGr#x1y     return 0;Zy_L~+ra7j
}b] uf&M3t[_
9M#Qr3Bn|
int GetTop(Stack S,SNode &e)
cC$XkR \Z%[/j {
M!t;i8N{!k9VV y     if(S.top==S.base)
eOo o#QE     {`O&?.f-h|9^6jg
        printf("栈以为空!");T[;NZ!C3\A
        return -1;
N{$H*Z r\ Y5qSv6D     }M Gx;RBc
    e=*(S.top-1);
v3Oib8_Xo/G|     return 0; Ya3{w,P:plq
}
,fq3a&aN5|n V}:M+c c `5R F&p
int Push(Stack &S,SNode e)
x _Y'\"xs9B {
_G/s N4lsJ#Tj1_     if(S.top-S.base>=S.size)
tco8_D     {0_0w0b{.Ggg O
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); x#y$a B#f]%W?
        if(S.base==NULL)
%U#HdaG6B$U;q M O)W         {
EWAo d             printf("动态分配内存失败!");5|+BKYQ\-O3b
            return -1;*w-f4I(]G^1EL']
        }
se HE"NhS rf         S.top=S.base+S.size;
8]I%V&ce Swl'e         S.size+=APPEND_SIZE;
hTVy-z7I     }(WRm.M6A6p N
    *S.top=e;
K!e!_ sXx     S.top++;wI-gY8q;a6Gy&c0H
    return 0; {t6X0naM
}
^-RP5Vr
8P0m|&K~ y.D int Pop(Stack &S,SNode &e)
!{QbP{*~*Q"H8Y {
3uL#a pfKj     if(S.top==S.base)
6w4b!t$Lzy3] { d~     {
l)Yf'IQ.nX3lm         printf("栈为空!");
!Hw|%H8q,H         return -1;Zp$| k3SR
    }'Z'_}FEk5~#`
    e=*(S.top-1);
0rV4p4ltl `^     S.top--;
'_ Kiv;H \4I     return 0;
4^uE:bn }U [ |"i,\"J/|m2iG*p0O
#sL.fY5m zv
char get_precede(char s,char c))~Kn c&i^/c,L;t
{tYa0u;FkRT
    switch(s)D4I+Q z0@1i'hu
    {
6x].vAq8kt'hA.v7|         case '+':                 Z3Q1n(P+Y/Uh3YO/[
        case '-':
_VM'g.`&p              if(c=='+'||c=='-')bCc r4H
                 return '>';
{lwk O!z!S G              else if(c=='*'||c=='/')
nZ8TA0}/K                  return '<';-vG UZHv7Nxl
             else if(c=='(')
6PI!g"J:M$le#p By                  return '<';4pQp9}P3G V#|
             else if(c==')')
{,z&n.R7\`                  return '>';R ]+XbX
             else
%V({(N7d3g'D                  return '>'; I_*o,GM m
        case '*':(o.\x5\b
        case '/':}1pRY$X'Ya
             if(c=='+'||c=='-')4bB.xC#H(q;L6i*{
                 return '>';B+yt:fCPa w7}
             else if(c=='*'||c=='/');{mv^8]
                 return '>';{XhV y
             else if(c=='(')
7e*q"AO Qs_?                  return '<';
.R6J8I'r3J              else if(c==')')
9B~I1oJ                  return '>';
Ai c)Xa#Wex}(jA              elseyz*u Bm
                 return '>';o&n(N m"bG o${ B|
        case '(':
y'y-^"c#~8@Li              if(c=='+'||c=='-'):IWlZvj I F
                 return '<';Dt!P0LrJ
             else if(c=='*'||c=='/')
CuTwGe%?x                  return '<';|/O+JS^3L%|
             else if(c=='(')
(Za J$g8k.x                  return '<';
;lAD8l4b#m"CE:x              else if(c==')')
fEm`2m/F&[ J }8|x                  return '=';5g A O-F | qq ]3D
             else:A ~'X.Y YA |,G;p!SH
                 return 'E';
:E5}Yd MrHv         case ')':_I)lt!q u"N!A aY/x
             if(c=='+'||c=='-')
R({ v1q.]b2~                  return '>';o$Z s keg
             else if(c=='*'||c=='/')
)bb N$rC5I r                  return '>';"[8w'I.]4G EjW1]
             else if(c=='(')C&E#}1zIV"b|uq
                 return 'E';e7a"R N6m
             else if(c==')').|K3dme]$V M
                 return '>';
dB `fo'C              else
j9X^2p.W V                  return '>';
Bv+A Qq;Srx)z         case '#':.J acuRh }B
             if(c=='+'||c=='-')
'n]%];~8_ xj9p A                  return '<';
_%{4q8mE?0Pm              else if(c=='*'||c=='/')_/oWuK"|
                 return '<';%D|x+L V
             else if(c=='(')W"x+LU,etXh\
                 return '<';
F?H EUi+y#[O@              else if(c==')')I{(d+L j ~(U'p a/F
                 return 'E';v1r1\+v/K7` s"X
             else
7h|%Wf!KE                  return '=';
.S r!|&Eii         default:
pw;l]!t ~3WN'a              break;#i$Ap7Oi2X,w/f0l
    }
[0i9K.eT\C)V     return 0;   
ldi,N c1G }
c}%~4n)K4rBB PWy%t/iG{fK}
int isOpr(char c)s2s.pz0S6t
{qF@:|$J2nI
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')neo H~I;~4b
        return 0;
.F aI6ZAB@R     else
i1Z'd G m&F         return 1;
)KS*?3` qB } O|m@ m;SsM-tr"Y
!I Rv'w!{(k#H!A,G~F
float operate(float x, char opr, float y)
c*Osq\|&YdA {
?Q M3p0L`[Y d/B     float result;*p?.K*eO$J"g
    switch (opr)7H-WJ1i-`#[E
    {
k}!reN A lN T         case '+':
^Epv{*X              result = x + y;
!`B9}7XT8E+a&e              break;
:M(C,d*?W ~*cP L H         case '-':
2_ A"pV6k5k`yN              result = x - y;
sT)k0Us              break;j3H E;DC"G z2S
        case '*':
"[#~1I^.K              result = x * y; mL6f,V.n? B|x2f
             break;
M)j7` F O#|C"b         case '/':
6o'aHC9bG^&lEd              if (y == 0)q~"i:MBMv"C;d
             {W zJS+O Yo
                printf("Divided by zero!\n");z3[k5n X so9Z ~
                return 0;7rI;d5e#T%x
             }
/a$b$uz1r O_              else#or/@m,w
             {%g-th_ SZ'pfYR
                 result = x / y;
)h-Bh#W,EJk                  break;rWL H)q8iW
             }
PA/~"g:G| U        default: 8J}iX.yH#X:Rr8~!o8X
             printf("Bad Input.\n"); (\+k{1zT#gV W;m|
             return 0;
'P8H.S!u7o4e.uH     }M(e(`of*WK K`q
    return result;6P#aSU_6Z%xa
}    haQJe1{"I

5f I:{R!e-|s `,_ float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/~N b r@2{$TYr8s']
{
(V$|7sXGKQb;]     Stack optr,opnd;8_+S^'qm6Q
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;#z6Y,BuOu'g
    char c;
!N-mc$JIRi8aN\     char buf[16];
RBE9t{0q"a5q     int i=0;.M-preZy m2l$E
   
}Zm L.D_/l     InitStack(optr); /*用于寄存运算符*/
0W{(W$T7q ?~W     InitStack(opnd); /*用于寄存操作数和计算结果*/!G(~B lH
    memset(buf,0,sizeof(buf));*zo?]O
    U"f } COCmj
    printf("Enter your expression:");s|T3M2x7?
        %@x5C$x~Z A{0E6L7O
    opr_in.ch='#';h O_)P2L%bI1OSJ
    Push(optr,opr_in); /*'#'入栈*/
.m"DS zaME/E}     GetTop(optr,opr_top);&u%Dq,E D4r%v-VIi*n
    c=getchar();K L*h$i[C6hRY
    while(c!='='||opr_top.ch!='#')
/jT+E.Fq-lQ!g2^ i f     {
a^Uo)Hg;J         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
4Av,n^H         {NK ~:lw%xL#QA f$C
            buf[i]=c;
slvt+p1]Y B             i++;
@VM)x"E             c=getchar();C5VhBr+BNf
        }
Ys)q*\ml*|B         else /*是运算符*/(gG)H~P,\
        {
T&]1X3p#Y:iV a'Hd             buf[i]='\0'; m%k P(R)N)L
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/$I T$y5u;p
            {
'{F,bo6I]H5^fO/F                  opn_in.data=(float)atof(buf);kO [ J O]/jz
                 Push(opnd,opn_in);
N8g"o7z2Z;U                  printf("opnd入栈:[%f]\n",opn_in.data);
![S%tca%c                  i=0;
1Qm!LRy v@0k                  memset(buf,0,sizeof(buf)); d e+wd/SS'R
            }u S @q;m%l CF
            opr_in.ch=c;,A$A-yP.u8Q$c
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/Of @ roG
            {+D?O| ` oG
                case '<': /*优先级小于栈顶结点,则运算符入栈*/;xhTFIU
                     Push(optr,opr_in);&[H8K8I Hnm&h
                     printf("optr入栈:[%c]\n",opr_in.ch);
#V)^z1@D$[vw                      c=getchar();{7R4Gw0|
                     break;
v,d'{YUm                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
kP4KJ2}$W                      Pop(optr,e);{2d,kr C+N+G
                     printf("optr出栈:去掉括号\n");
rHBr&DR%o+i                      c=getchar();w:vB r8co
                     break;
r4_1Z(EZ n                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/1eN,HD/eK
                     Pop(optr,opr_t); gO,Dx&j?
                     printf("optr出栈:[%c]\n",opr_t.ch);R'_HJ/U}Yq
                     if(Pop(opnd,b)<0)#LW!d NP \d#c
                     {
5j7b;X)i-][0m]:J/?                          printf("Bad Input!\n");
k d\4OV                          fflush(stdin);
)oa4l^Uv1v                          return -1;II&j f(T ~&I
                     }
H'slC W`fL6{                      printf("opnd出栈:[%f]\n",b.data);
N? _@}MBb6g(R                      if(Pop(opnd,a)<0)9]T8i2R%}'g7Dc1^E
                     { o*P cUUE;M
                         printf("Bad Input!\n");
$fD{{C8O M:zG                          fflush(stdin);
(Gy4{_,\w'A7i                          return -1;1tx?b unU
                     }
%t0v'Q7A{ |*N                      printf("opnd出栈:[%f]\n",a.data);
{\v)c&N W-Y                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1o0F2{ orAR?                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
%R)S._3D|h|i-gi                      printf("结果入栈:[%f]\n",opn_tmp.data);+ftWCB/S*c7c
                     break;
2Ux?z:A%FZ             }m.v d'a&A+t9Tw
        }IQ;v hX
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
'p8LZJR0B5lC     }
%JFF{6@oQ     GetTop(opnd,opn_tmp);
0r6w:YLx     DestroyStack(optr);
6bm;Y]sI$x     DestroyStack(opnd);/XC%ao&U l`*o
    return opn_tmp.data;
BH%GWO+b|%I }.t"zv.fCi

2p s(c0@&k ca char *killzero(char *res,float result)
8V+^Bya5]I&a6p{J {8B|0@+D B%WYIJ
    int i;/\3| |\3NP_?"Amao
JDq-z(eJ9K0X
    sprintf(res,"%f",result);
2M]l%tZ/c({:A c     i=(int)strlen(res)-1; }*bW;C%r
    while(i&&res[i]=='0')
-sav`XEHd     {gB BL(K
        res[i]='\0';v {"IT+\
        i--;
f#l@!]Ti!` |6}     }
}%e `$i9m-l5E     if(res[i]=='.')*IZKj xf]
        res[i]='\0';
%UTy P@,n     return res;1e`_ Yn
}:^5Dj'je$GT v1SJ%Ci

i m5c k5M)N`xS4V int main()
IPP&y+~i ] {
1n5nNr@L8W     char ch;2x;|2aTsBN-X
    char res[64];
gB.I]K/{2AUi     float result;
i ? z.P.Z vU[`;S     while(1)
J)F"BQImY     {
5[*M3nH5j Q [k P         result=compute();
*Ac&Loz E Z]         printf("\nThe result is:%s\n",killzero(res,result));7d Ef#aQd.h s;y8Jv
        printf("Do you want to continue(y/n)?:") ;
(K/D.d$o(_^z         ch=getch();
m P4b b n%E         putchar(ch);
`&{-Z2K4BEM         if(ch=='n'||ch=='N') jQ7kp(i6[A5sRx:a
            break;
z2i{-` n b%l.x#C3r-og         else
"j r,jO*\)Suf x             system("cls");
5^#|j(sa1e     }
%Yhob e&\]L Q d2h     return 0;5a7[?U i!|
}[/i][/i][/i][/i][/i][/i]8aeb"l HXc
h4m)lb_#al.q
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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