捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.bLhn-e.O.rv
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
6a9}y p @6n /**************表达式计算器************/ OwZuX\'[
#include <stdio.h>
yG+Y'{9Fzn #include <stdlib.h>Y"j2K6f N.Ka
#include <string.h>(H,W1e/p5AGN`2r
#include <conio.h>iN N jYt'mU U!QE
#include <malloc.h>
2o2A:~#J:}C q
\"o4]/F Co #define STACK_SIZE 100
zv2L4Z.}4s/?vp #define APPEND_SIZE 10VD\#A(H

[(`f@*h struct SNode{1w*B k.aUL&U_
    float data; /*存放操作数或者计算结果*/3Rw^ |kyx$Cw
    char ch; /*存放运算符*/
4}rs ^ a#z$^*h dA2n };
#DWJ k"C'S?e
(W(F \~y2aO struct Stack{
(uoDHj-j)q(E:S6V     SNode *top;
]{s#O1q     SNode *base;Q`(o[6IKf
    int size;q5r1M`8jD3Y
};
%ep&O#b5C1~ )F/QE*d#e6v
/*栈操作函数*/
Q$?mWn\ int InitStack(Stack &S); /*创建栈*/"f"I2N:t p+V(k(Q
int DestroyStack(Stack &S); /*销毁栈*/8B6O#] xI W_Lh
int ClearStack(Stack &S); /*清空栈*/v*x5S a3Jx6X
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
(X;r3R"mLy3w;AYT int Push(Stack &S,SNode e); /*将结点e压入栈*/U Cv~zw3H
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
|1yk)r+u@m `M.~
%B2bXC\!B;[&|R /*表达式计算器相关函数*/{$_B,o#jh4mAR/z8[
char get_precede(char s,char c); /*判断运算符s和c的优先级*/@4HMdf%f~9h%{-KX
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/1OehgMl ~
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/ fb\ ]6T
float compute(); /*表达式结算器主函数*/
~*FV_9p!g0C+m char *killzero(float result); /*去掉结果后面的0*/
N VQMs;K
O4k3d*r_Q int InitStack(Stack &S):@2}N(H6F^ p%~6Or:p
{$gv#EQ._2Nj
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
:s0li yH @4J^)?/Iq8n     if(S.base==NULL)
p/}2D'K[5}     {
1}aDAR$sO         printf("动态分配内存失败!");
o$IEt0h^qZs5a Y         return -1;b SUFFW
    }C;E8F/n%i
    S.top=S.base;
9}"q @3E^`9nq z4i1c     S.size=STACK_SIZE;
V#S|l.F-T,Q)J     return 0;
Dc7Ffw/^2s![,O }
g3f7Ko.EA5}b Xe:`*Tq
wr$Y&jY`N int DestroyStack(Stack &S)
aV.a7}U@)U f/EF {
9e3c(X Q\5Qfw     free(S.base);
bs^Q$X`     return 0;E h)T onL {
}Nj,|x7N$X.y.p} V
5Q.B"yR'g|
int ClearStack(Stack &S)
K/{*BW7C&w7o0yA-v {
3`Eqq;x9uiB)V     S.top=S.base;
&S D hyk/D     return 0;1]:LISh%MCl/I
}
/X%m4okQj
Ow2E'|)K~+@#I"K4| int GetTop(Stack S,SNode &e)~3?\/W:oa
{v.|-L5j(G QI
    if(S.top==S.base)5o W Z lO} pY0Z
    {;pd6C6w0K-X1q
        printf("栈以为空!");a%QG;L,b?I
        return -1; X-FK{] Vu!l8f9j9V
    }/{ ~Ce6b)y
    e=*(S.top-1);a*J m|+L*Yn"F!Q
    return 0;#my&A7R!_:K3c.f}{
}X3Cvi%U1xt8H

nU.o*{0[WWV.e$k/C-R int Push(Stack &S,SNode e)
;C#cy"K;UI*g {,U(J.W&s1H
    if(S.top-S.base>=S.size)j:y"lr D2a
    {-s9o#s U)H2y K2Y/?}
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
^ D&tBh3t         if(S.base==NULL)
y&`M.l2T         {
*oTi,h7n CgGZ             printf("动态分配内存失败!");
_4bY/I.bz*Y!o             return -1;
:@4|T srL/V+u         }
#@W;Y@,n5q         S.top=S.base+S.size;
x,HPv!~Zh0gM         S.size+=APPEND_SIZE;Wp/up(ac+n
    }yz9k+R P i1|U{
    *S.top=e;d@?1LE*Zd
    S.top++;
~ v)`ro't s     return 0;S7|M` J([m;^c
}6Ve \:R _ Cuy$h

2P%Q8V?U int Pop(Stack &S,SNode &e)
5_{w-ihW7x {B.CO"N2{'y~|
    if(S.top==S.base)
7VX@[u.A9d0x     {
n|%?E3TA-^6g)V         printf("栈为空!");
c"plUY:F&B!We#Z         return -1;8RIc"K` T
    }
MG'\ CB%{ r,U_G _ y     e=*(S.top-1);g$`!us&T'i
    S.top--;'Poi%EI#w
    return 0;p$~R p3] J{
}G7z5`!q+yb1b2M ~
%dSY5BW7J
char get_precede(char s,char c)L~!{@#N3o9r
{ H m&m j k0^dq
    switch(s)7VQy.dk X|n
    {uh3u+oJ%zc!C
        case '+':                 zR&P$i | Pgm&{[
        case '-':#Kz{ hZ SN3R;h
             if(c=='+'||c=='-'):NrEB%hm
                 return '>';
A(l|{k~Z              else if(c=='*'||c=='/')*Z/{o:ea7OI-Y$r [
                 return '<';c4` oT;G
             else if(c=='(')
"O ^{j)g+t7T@8u|                  return '<';Vk Z%E,a
             else if(c==')')r-rb}6UO
                 return '>'; n:I`,h/ov`
             else
~Q:j6Qi%Du2y                  return '>';Vr{)s ^8KF k t:a
        case '*':9Sl:n&H+fl
        case '/':
2V+EaHl5Uz              if(c=='+'||c=='-')
$i+| Ys7X                  return '>';9F/V\"bhy*QBPV\
             else if(c=='*'||c=='/')x7^ Yt0tz&\aB
                 return '>';:L-r E*a9lfG R:k#v,pt
             else if(c=='(')
t;T8u^ h                  return '<';/ez4G O6t
             else if(c==')')
I4|jr5O                  return '>';$H&Oz/W'NuU | T
             elseNJ4c5Q7[U I7O(o
                 return '>';
$I8R.p;F.N xl         case '(':
5p8q-[;r2gI F              if(c=='+'||c=='-') p4ac$vF5X sG5vP(S
                 return '<';
\Z5c[P?7u              else if(c=='*'||c=='/')
Li8| o u                  return '<';
rRW H3v              else if(c=='(')
FWz3JHo~!k                  return '<';
+[+p9p&Xz i0x2I              else if(c==')')%S~8q'q?VRz9d
                 return '=';
8} [t7lDv4`1}NI              else
d L/{!A)[~                  return 'E';wpE#YGLb9X1K
        case ')':Y%Lz g3?x ly
             if(c=='+'||c=='-')
8zrQ\S6U                  return '>';&C9~ p3_#CR
             else if(c=='*'||c=='/')j3?wH~ Q$J
                 return '>';
8PA+XU'\G TOyD              else if(c=='(')
Z!P kCO M"san                  return 'E';
&JE@ l} P]r              else if(c==')')
!^!q2S}{ |%aQ5U                  return '>';.\"_;]!r2s+w0Q
             elseGJ] }:\5H c4vi2],K#h
                 return '>';k@A;O,@K1C)J
        case '#':(m4Q4T^U5t
             if(c=='+'||c=='-')$tY}R? K
                 return '<';
7q6n6oqR8hL)?              else if(c=='*'||c=='/')
YMG.mL,XF8B4t                  return '<';z1T ]O5o1xJ
             else if(c=='(')
2kB,d;r1OxW i|                  return '<';ocM+x2L#o\(},[;m
             else if(c==')')
#Q4wn7q8|u%|^                  return 'E';M+dM} K^)B
             elseiL8cl2Czz7MI
                 return '=';
?;T SbQM4VW9@         default:
{:M/k!~ ob4O6b              break;
M6e _ez.q3SV     }"Ii/iwc`paoCi
    return 0;    oVP``
}yK.ohm8{c} I
0[J$h je ^TF1]y
int isOpr(char c)
:@:`4IT0]O ^8_ {
1Os TqZ)M     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
3V5~erI9N         return 0; Q6ZDqn L qB}
    else 8m)z:sgj P5H^
        return 1;#{2ApF|D;U\`+S5z
}5XiWET"yCM:l
"yT9N8e*a9@9p
float operate(float x, char opr, float y)
dikfr3SX g {
P1V:}A7]8Y2_'c_o`     float result;)hq}&M8S
    switch (opr)r?+x t4| wW s
    {
4A\g-b$_         case '+': 3sd/mc%q F$U A7qu
             result = x + y;
4NTE~;x7]-c.~R              break;
Wz6q4]&@f         case '-':
9EAX(i1Pm Zt],A              result = x - y;l?4m]"^ Kx
             break;
(W#a;N|,}+b9l/_m         case '*':
a^ P&t!B-a.B3T/y              result = x * y;
h` `hf0b TZ b_Lv              break;
(z/^WJ,H"tLC         case '/': H@*?C`o#b
             if (y == 0)|N?\e]5A C r
             {
.[[3QF;K                 printf("Divided by zero!\n");
j-XV+MP{.~aW W1R                 return 0;
+{-z(Zt+KK              }
+k E5MP~d6_              else
+^ ljFB'Z7Q7Z\              {
P*w0A%m t                  result = x / y;
4|&JS])Li                  break;
-uCh!a7XL*S:g              }| HV0^z Q;Q'c A
       default: d { Z;jEbRz U
             printf("Bad Input.\n"); QO%]8H Fr!p.\6X
             return 0;B*F:Y:_u$K5~9_9]
    }v/YDlu,@ L-d"G
    return result;
;V|!m p G`)C+D }   
-~X0I:o8D _*\)?q7Q
R|$w!v2mio|+@ ] float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/#o*ALJed8C q
{+?r)F^.?"t~k!Rk
    Stack optr,opnd;Y r:Xv@'MPP[Q
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; QbAC{3b^w
    char c;
!n8Us1l9m"n]~     char buf[16];
g;Y^nr!C._;A2_     int i=0;
/|3I ^&E3GJ(N4f y    
TX ~/OtK6]v     InitStack(optr); /*用于寄存运算符*/
%G]:G'|/G"okX     InitStack(opnd); /*用于寄存操作数和计算结果*/,M"Rx|_:E@
    memset(buf,0,sizeof(buf));uFt6TJf&qq$B joK
    $y#A@$m"\
    printf("Enter your expression:");n5n)W)N)} ka ?Sd9s3Q2f
        
%BF,?y"[Xx w$F     opr_in.ch='#';[AFltw.`
    Push(optr,opr_in); /*'#'入栈*/}/yx8N-]axK!~U
    GetTop(optr,opr_top);9]E'WL~\bh)B:W
    c=getchar();!`+PY YBlYV:q-B7_
    while(c!='='||opr_top.ch!='#')
0VA2TA3J1c     { |6wR/E D C
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
L:dT0^1?1z)Wh         {
K$n`W{             buf[i]=c;
QI1wxiL             i++;$Y;O{B'O:A4q9L:?,T
            c=getchar();
D:h M-l q9C)iU         } N8w:P/OL ~:vZ
        else /*是运算符*/
#L$I1Hr$]7g|         {
L9m.K]_Rf             buf[i]='\0';
*DO ES]3}$b             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/#e%K1A eA
            {
{}i*V V _                  opn_in.data=(float)atof(buf);
]4O1r/RU v TJ0}?                  Push(opnd,opn_in);
rr2Xmk                  printf("opnd入栈:[%f]\n",opn_in.data);*qIN c%}8V
                 i=0;/n:?3` u#Vy3z)q
                 memset(buf,0,sizeof(buf));4w+X u"scJ$w3g-JV
            }
+[`%BIN*\             opr_in.ch=c;0W9ik e ?&r8}:?
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
k X V+}6EC             {j2j*X`'S.H
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
|)~Qu@0Oqj3E,g                      Push(optr,opr_in);
5D3HZ4e"r,oR                      printf("optr入栈:[%c]\n",opr_in.ch);
4i,d0a]cj.J8b AM&w-}$\                      c=getchar();H%hy"[F4Bxu\4J"x
                     break;
6[0lb+D(H6H                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/rr.bZZj4h(R X
                     Pop(optr,e);*Y G7~vhe-nT [
                     printf("optr出栈:去掉括号\n");#}+W]5B'^H%gi ]f`
                     c=getchar();
v&qi#o%oo Jt                      break;~ m-?Z5V3O(P
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/y)x(jiP8^7[6p"X
                     Pop(optr,opr_t);oT~ Nj OnF%X~\
                     printf("optr出栈:[%c]\n",opr_t.ch); PH0aW p(K
                     if(Pop(opnd,b)<0)^JE6M:w}+u.v
                     {N%P3`&C5n1U
                         printf("Bad Input!\n");
8{` u4ZS:\                          fflush(stdin);
?_\*HP!U:]                          return -1;'Y+u,hFz_O5c#AsC
                     }
sU@iyZ Q                      printf("opnd出栈:[%f]\n",b.data);7dh0j5_+Q2Z@2M
                     if(Pop(opnd,a)<0)
.o!^$B1z'y%d#nBw                      {;gG ]\ YeXS
                         printf("Bad Input!\n");
|9i7sc"z&L?+}                          fflush(stdin);
6A T$\;PU                          return -1;9x2e$C.Ux
                     }*?h*X$[*Vki'f
                     printf("opnd出栈:[%f]\n",a.data);
+d#r$UXnnx*OJ                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
lrU:lPG                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
X"^8~QEb?.~5_                      printf("结果入栈:[%f]\n",opn_tmp.data);-b7tz]*}7N{
                     break;$]%LnMx#hH$j4IEh&E*O
            }
PH ZCO\%T^f:_         }P2t*eP@
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
6TX*Ih&q2xLK8A:}%b'^X     }6H7[/HHU0g W
    GetTop(opnd,opn_tmp);
5M2W8Ojrq-@r3w S3n     DestroyStack(optr);H8^$[0G6BZ1R@
    DestroyStack(opnd);
cD%e7F/T/F{     return opn_tmp.data;*[ uG#t'm.{ u~ SI
}
gT]hq%]8w+R !xR-dJ ^/d+\Xh
char *killzero(char *res,float result)
8}R,xzN0W {
@-f;_\d_e'Ns     int i;6D#O U D7?JW pj4\

j \'UL#mbX?$P     sprintf(res,"%f",result);5@$jwQ#p6v
    i=(int)strlen(res)-1; Y}+\Xp:`
    while(i&&res[i]=='0')
OJ F{!~K?A0j     {
X;pD Q z#`L0K         res[i]='\0';
&i*TIg2eBlz`R|         i--; K0Q?4pz&F
    }
X9L!cW,pb     if(res[i]=='.')
8F$CG.J7k)E#dB,K         res[i]='\0';
h B L:X3k     return res;
7Z*e5~x,ht,tE8u1} }
A{XwXn*]
!G _'JgnS4o[ int main()
1v3}l%T5E9] {^NLwAG
    char ch;
#s4uSxJ [-t"D     char res[64];;bZMoh(g?9S ib/N
    float result;
$f7_4Z*j,u$Ku     while(1)
o7MPu!ZO C#nRq h     {
r:D }l t6f;\ k         result=compute();{M-o UdI.zm;k'P
        printf("\nThe result is:%s\n",killzero(res,result));
1I*Gk:D W0|$l*xq         printf("Do you want to continue(y/n)?:") ;
E)^M_m#m oH         ch=getch();7R A ]NH(\_
        putchar(ch);
oKk6]`;|jG         if(ch=='n'||ch=='N')
r6\JCPp@(\5[C             break;
to$p6uQb\         elsewgY+H[9o6N*mIt
            system("cls");
aFI^g8n [Y     }
\*w4ny!q     return 0;5R G*m\j.l
}[/i][/i][/i][/i][/i][/i]&e:?%iT/b4l,u
+\@'VQf ^9Z/QkI
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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