捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.b;I^fb^Nh~5W {5vo%sc
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=m1`+]N1~J@Y
/**************表达式计算器************/mt"I#dRl5LS6|){(i
#include <stdio.h>E$Bt'^&XM
#include <stdlib.h>
R/o&cFi1c #include <string.h>
#pSaT!O&Q #include <conio.h>*b Sdx"gw Amr
#include <malloc.h>
ZGJP [y*wI Ww{8t4^9BY6L
#define STACK_SIZE 100
| ?2\#[6O)lp #define APPEND_SIZE 10
*b)`-q.q:@)c6QW ry%~ jSed-~O0E
struct SNode{
wcF K1n p|     float data; /*存放操作数或者计算结果*/&HA0q"N}n
    char ch; /*存放运算符*/
Su v x/aF };
Y\#]s)U"Zl5k (}o7pR,f
struct Stack{
{WNQZ7H*T/uk     SNode *top;
;c['Eg2|"\7h6zE     SNode *base;.Y%}%cRE4p yr
    int size;
n4`6eh1[+t hy };2ml4N*hN6oGO
P&x%|Hk9}a
/*栈操作函数*/
\.LxUO*Fh'tP6L int InitStack(Stack &S); /*创建栈*/~,`5JjH
int DestroyStack(Stack &S); /*销毁栈*/
x]9|4T)V6i/^/` int ClearStack(Stack &S); /*清空栈*/ q?,OI.KP%]
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
*Em4GdP-t int Push(Stack &S,SNode e); /*将结点e压入栈*/
L9S | S)y mE int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/x]IhkMa,Q/c9}

-fEw8m2H)u+V2t /*表达式计算器相关函数*/Ur)Jeos9j8C
char get_precede(char s,char c); /*判断运算符s和c的优先级*/Te0JKL2E l)a`
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
J8m1F,L$c float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
Bl'pb1D]4I float compute(); /*表达式结算器主函数*/v:RTr!JB\:~
char *killzero(float result); /*去掉结果后面的0*/
DOW"v)JO
_r6MK;|~G!s int InitStack(Stack &S)U"Z0n5E!h/g
{
:?~4nt(mF P     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));"mK:V)qs
    if(S.base==NULL)
&w1D\3h+Vk af     {y8MR4|J8`2V
        printf("动态分配内存失败!"); s/G*f9wT"K"D:pB
        return -1;4^wX,^#V"b9A
    }
{5MG^7@8r Z     S.top=S.base;A+d3~ ~3v I#B5J
    S.size=STACK_SIZE;Bp@;dhS\V w5M~
    return 0;:Wc kmxT M'Sm
}Y4F;{2i9_2?&qE:Yf
Po|0O-Wbg
int DestroyStack(Stack &S)k l B1]4K9[:\
{h#e{9I[6x!BC
    free(S.base);
O_;t-QP8f IE&k     return 0;
{|J7B$@|+~,U{&? }
cc+wuw;O
+xs7N4F*s!j"K int ClearStack(Stack &S)
gR6dQ4mjp {(R \ Q(S#\#f,jS"o?hR9i
    S.top=S.base;3I!n*iVQ^r _e1x
    return 0;
on O6o*n E }
]!_h@T@'k C"{V%P xW? i
int GetTop(Stack S,SNode &e)
2HQ#_n1E!k%C"[M {
KrJ SM     if(S.top==S.base)
-M$E"]R V$B c     {y-B-e_]FC/p0G^
        printf("栈以为空!");
X(BHz%g2M}h         return -1;
6r,tvo,R$n'~YX     }q&D q0Y Ih;H
    e=*(S.top-1); v@`O[o je*P"]
    return 0;$w/~#h$o&k}-aT!k0L
} g'D7]-`1^~
"ne2{:n2?F ]
int Push(Stack &S,SNode e)0y;Mj&x1a
{2fER:Hd&E
    if(S.top-S.base>=S.size)1T9D'} dE!E2qN
    {b'o`*Ci5t}!A}
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
T.ES1~(G.hd         if(S.base==NULL)(Nn_Bb{ M1b~
        {l0_ mW\C E1A
            printf("动态分配内存失败!");
$?f7Vpw             return -1;JI.[x5nI.Ey_{K$?U
        }7[ a ]+c+K `nB
        S.top=S.base+S.size;Z B5^m z%a
        S.size+=APPEND_SIZE;
:Jpy8lq:t?fff     } CO"D%q2B1x0o
    *S.top=e;J8J#ispl:D6}
    S.top++;6r(emC0nB
    return 0;
,V,tX j Y }/cs}&OI U)h9L
A5@}lny D/lG{
int Pop(Stack &S,SNode &e).K W kA8fn6DR*i2g
{8Yp/E,@? J S_(^
    if(S.top==S.base)
8HI|N-?XD{     {
d9}&ou'qoI         printf("栈为空!");}1X3qB
        return -1;
!^:O6ZB y&]M&S2[B     }
J0Hwr O6mL ~     e=*(S.top-1);
(Q2OM x"Q:V6_4u     S.top--;RL SZ?S
    return 0;
3rW%WV2y;`)k }0C W%gR3us,y

|?1g*i5C!w+D char get_precede(char s,char c)
}B&}zdox$^ {U_%@~kb(JgX
    switch(s)T7D7EP9Ks Y/M
    {#d4ez;N"b
        case '+':                 
;q&O8?5[5wh K         case '-':
JP8^A5R0z#y              if(c=='+'||c=='-')srf~DG-RTt
                 return '>';/gal)LS4Mp
             else if(c=='*'||c=='/') v{ AAXM[
                 return '<';(j g q;W!d Epe+t
             else if(c=='(')SjB+|`'W Bw(rF
                 return '<'; }"Bt3tW
             else if(c==')')#C6_1a9II` ~%?
                 return '>';
y|6sZ x,WB5r i              else
.jn?FzS e&uQ5Q                  return '>';
h-N0m"}X         case '*': Ej t V%t yT@k
        case '/':
@.s*_*Q`$[,D              if(c=='+'||c=='-')
K a ^"xt?:r'q                  return '>';
leWzc,i,h)w(V              else if(c=='*'||c=='/')]V^"K^$aS/E
                 return '>';
P)Z%o3O(B uY!l&J-z              else if(c=='('){2B pixS
                 return '<';
i7~2P9Fe3bOL,sr              else if(c==')')6P8c7c3@!wtZ
                 return '>';3Ym[?6x:h3bR
             else
3aP ElOKmLiv,Jj                  return '>';
.yc` X4Kw7w9j         case '(':2OEp4JTv?
             if(c=='+'||c=='-'),y{rYX6T
                 return '<'; O.jlUs`"x
             else if(c=='*'||c=='/')SN'UZ3cBc.k6z.I
                 return '<';*Yk|3_msv
             else if(c=='(')
%ov2Wu(fz6t Y[L                  return '<';
:o0u|g[U*D;g H              else if(c==')')k%IT1^{D(~|
                 return '=';(k{ q6C Iu$O
             elseVS9sFv J9G0_
                 return 'E';7Qv0hr0n
        case ')':
bc3\S#apK              if(c=='+'||c=='-')
'?}A&o[Zu[                  return '>';
3o Y'S+@"A:c7x(f Z1W              else if(c=='*'||c=='/')
+isw_LkT uH                  return '>';
!sD8Om6n$a:_              else if(c=='(')R"mMEs@\7`4@ l
                 return 'E';
$_(Oq-dT(n5hL VR              else if(c==')')
&f(k7B!mU#G.a                  return '>';h,s2N?A I\
             else
Uv\"D?[Ip&}                  return '>';
)oD9w~,c7H         case '#':;G vK F{8Q
             if(c=='+'||c=='-')__+Yjmv7~+HPW
                 return '<';J-B,J5j;n-z1M
             else if(c=='*'||c=='/')-pH#~@7W8[ ra
                 return '<';
hmf2]O C              else if(c=='(')
.@4E*V ^$` P                  return '<';H'tE*w3MuG@)S
             else if(c==')')+[/y\,L i K0f _
                 return 'E';,v9~|(GO!j+gw
             else
^`Mv7OX                  return '=';
`0~,XA/YXP         default:
@ W?3g;R q'k              break;
V5M-[/{iW^ h#n,Iu     }1T t;xV r-s4tz a8j
    return 0;   
c8q*oH j S)lU }
$peU:auAF )~2?p r C*S%c
int isOpr(char c)+XHb%SZk;Z;`
{
BL*@m%h\     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
%I!ZY;g]-^)Gr         return 0;5\WX!w Aes
    else
utkDQT(J         return 1;
9Sr'm$b;g;ys'e_ }1o7ebq s _
It5CS,]"x8nj u
float operate(float x, char opr, float y)9ZR LfR/U3xz/h
{
z-kO QSQ     float result;{(yum,r0X;UA
    switch (opr)O-PN3M.Tb A
    {
h ^ Fp'h%TvuTr O         case '+':
2EL$T/zXf7^D[              result = x + y;:hW8b X/^(x
             break;
pk#f0UO"lf         case '-':
b/Oe;]{&gy$Gh              result = x - y;
$aboSx X~2f,h              break;&jb(@$V(i}~k
        case '*':
/B{Q"_Nx @              result = x * y;Ya x&Iw`
             break;'q,a$kf)L
        case '/':
MP#d-IhnP6?              if (y == 0)
_8?D F Cb              {0qI;o/[WxOT
                printf("Divided by zero!\n");
}pemr0U4k)V                 return 0;B$b!g*q8lv
             }
.AL@qU;B~7e              else
2hu)y*tf }              {
q,u4_CX?^                  result = x / y;:c#h1Jm l&_4D(^*M n.`.v
                 break;
d X ~6P6{H              }
F([(}M a~(c3x/S:C]        default: -c$}-TK~
             printf("Bad Input.\n");
Q0vX]5Jt              return 0;
~6b$a-|F     }
/x[)]h6^ C:l*W7W     return result;
P)K})D%`JFk }    W!JVW$QX'I

y(kZh9@7D2xE float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
$d s2R+_8f*Pb&^HOf {
?mN8{{)mti     Stack optr,opnd;
(X ^.E~;@ t"r     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
"bv ChnozVcSP     char c;-kkZdR sdi+|'_)m]
    char buf[16];.^LrLh
    int i=0;GTI.f e2D
   
*b(Wx}/qKz!C     InitStack(optr); /*用于寄存运算符*/
M*o/f%\~)M     InitStack(opnd); /*用于寄存操作数和计算结果*/~r%Ll1iG
    memset(buf,0,sizeof(buf));3Uk,l;]+p+A X5AB9Y
   
.lrY#}q     printf("Enter your expression:");
Ac`8Fm3}g7O$e2X         
.v S2@_;^r+|     opr_in.ch='#';,OD.c9Qvx4Wa'H
    Push(optr,opr_in); /*'#'入栈*/
$q f yIr1G;]z     GetTop(optr,opr_top);
5fM4}ZOf ki9M     c=getchar();;p }0[ VA3aj?
    while(c!='='||opr_top.ch!='#')4B`{| M.|
    {&S\b i%lY+Zs:c*Z
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
&M#W G |P f)]9ZE;h         {
6O*[ n%ClP kl h             buf[i]=c;9NK v5{s5j |np8g?
            i++;
}#r;r;@cQA,E(I:G             c=getchar();
JK#`a4s5X7W[1FG'n         } L,^_g+yW
        else /*是运算符*/
7w k N.d |4PR f@~         { Hf3v uq Cas:|
            buf[i]='\0';
gl4mQuEM             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/|v8H:?Sf)\)`.jh P1t
            {8c Wo7iH P;l
                 opn_in.data=(float)atof(buf);'e/A}e%C^8O M
                 Push(opnd,opn_in);
P7p[G'Ba#uk                  printf("opnd入栈:[%f]\n",opn_in.data);
5h}z(XFrM)K2v                  i=0;
H)IE Az C4S                  memset(buf,0,sizeof(buf));
Q2B)S.~j} P0Y             }
\*}/Fr'Sb             opr_in.ch=c;?+a l*`8a}5EO qx
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
]:O W:u/a(ZvSi             {
;l7uIRk'X                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
+f*hOy)H;}P$]8mv l                      Push(optr,opr_in);r d1c1\c jp |X
                     printf("optr入栈:[%c]\n",opr_in.ch);{zg)a tq H/L
                     c=getchar();
\8a1@/U ij ]| Zi q                      break;
BVE)ij}R                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/OPHWr
                     Pop(optr,e);*^)N v:Dm~] IE
                     printf("optr出栈:去掉括号\n");
+q&iT!x b.d                      c=getchar();f@F,X;~
                     break;
r)B4et(IR                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/\~S#v6p4om
                     Pop(optr,opr_t);^`(OkF qwU
                     printf("optr出栈:[%c]\n",opr_t.ch);
Vl2]FD&}+p|W                      if(Pop(opnd,b)<0)
8Vvy*}3\*l:N N}-}J                      {
XNed#V`8K                          printf("Bad Input!\n");
@#bULe'B                          fflush(stdin);"Vuv/zhP/Zp$Q
                         return -1; ?7Ny*h"M
                     }
E(nra8d-wvB                      printf("opnd出栈:[%f]\n",b.data);
hZ!y.e~oh/JFN1hKF/U                      if(Pop(opnd,a)<0)
$p/s2J+B0]J x                      {
SAcJ.{2J CE                          printf("Bad Input!\n");C e:D~L3K.n,|d.P
                         fflush(stdin);)^0z&@%r_-w5\
                         return -1;TW sD%X/Y;G+N.?#]
                     }5b3}*n ]+gVHT
                     printf("opnd出栈:[%f]\n",a.data);N1R5Dmw,y
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
K#ua+O+n+gPk                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/X#Alm%\
                     printf("结果入栈:[%f]\n",opn_tmp.data);ihfG6_/B#@&b.A
                     break;SC?;bCkl*U
            } d'Y+i3Pa{k-K
        }
fgU'o$G&A         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
8ou*XV5hh'b8q],Y     }+Ks5X5}$V9BHS
    GetTop(opnd,opn_tmp);
W5] IPI7{5e     DestroyStack(optr);
G%}Yr6`     DestroyStack(opnd);
YbQ[n @c!IZN']     return opn_tmp.data;
;hf8C7TZ&sG N+D$a }
y8wk WRa
tAgS3RGH _/? char *killzero(char *res,float result)f$DvU,q'f
{
9krD ?2\y&j     int i;
rPbp&^^h`~m
\h c2` ?d*NW     sprintf(res,"%f",result);,ol7c~CO
    i=(int)strlen(res)-1;3l"nW5I6ZW,dPf
    while(i&&res[i]=='0')#O3s#~6?`W5e
    {h*Z$MXHNL7O3](}G k
        res[i]='\0';
\ y$k N5Z*h         i--;
%O m#K1T&BT:MX     }
+F2w$I M5p-hj8IX     if(res[i]=='.')
CfM7ZP         res[i]='\0';
#@L0p#Jm0`:R+k/R     return res;
,C1yQ5A.w8{ }
;v9z6T!G"\$g B3X)XUmm
int main()
UN#Xv^h o;y6Pz {
7n;?5x.kC     char ch;
Vm~ h qL2T$u6l     char res[64];
(s6a(O A2V2Iz&H     float result;B4W5J*s7Za@
    while(1)
2F!x\ p9CB/}.f2j     {3Yo$}4^JyX?G*I PZ
        result=compute();
/d)nt,W['EUM         printf("\nThe result is:%s\n",killzero(res,result));
[(v+L]i,v3r         printf("Do you want to continue(y/n)?:") ; F.]"z5G8lS1J-WD8F
        ch=getch();(db+{P4hO m
        putchar(ch);
o6dw e+E2q         if(ch=='n'||ch=='N')%x#k2@?$J%Sq ]SqA
            break;
f8rG2bJrg2XJ         else
;[.Nygr             system("cls");D v.G#u;~8z3K{
    }0{ps1g{
    return 0;
|(K/V#\0BC#ql,H X6c+h }[/i][/i][/i][/i][/i][/i]N3Ts7p~ Hz WQk
5U2UWD(i;kl!E
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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