捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
*@6P!T'\xmeoGr[? 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
sh_Jc {;yp"F /**************表达式计算器************/#y d0z9}/^#?
#include <stdio.h>
3{/B&te$Sjh7Gko4| #include <stdlib.h>
V*Y@&K+n z$xN1} #include <string.h>
9i+D4Y6W r@%Mrz#J #include <conio.h>
R})GqLC"\ g@8n #include <malloc.h>
2p*uzO-L1T5a o~%\
0_!A:s!zx7W o5Q)EWa #define STACK_SIZE 100
A+G {,o4Gai/M O #define APPEND_SIZE 10fg'z ~UO@x,_ z
o$U^O:E%@BT6D V$\P?
struct SNode{
y5s'k(}A P7\     float data; /*存放操作数或者计算结果*/
Z/l }l e5w,IIkMS     char ch; /*存放运算符*/-f{ zV @2r({
};
yY&h[8xb,mY? S N"H6?}t.H
struct Stack{
^R N EwX m*b     SNode *top;
MXC {9]b Dcw     SNode *base;n'S~ s|Q*e\
    int size;
$\e%y+|9o*{5m };
lQ+O%S_tp4C l 9ok0Wog
/*栈操作函数*/
8{a-`&]#VV;qK^ int InitStack(Stack &S); /*创建栈*/
jz2m*J2pB x~)kz int DestroyStack(Stack &S); /*销毁栈*/
)h(Y&d1uv$Om&n int ClearStack(Stack &S); /*清空栈*/\"Tek8^D
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
%i9wEQ4_dw0Z*l int Push(Stack &S,SNode e); /*将结点e压入栈*/
JC-q(vv int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
k0l/_4o!jW 7z4H0rP(we`pv
/*表达式计算器相关函数*/(Kvz8tuggQm
char get_precede(char s,char c); /*判断运算符s和c的优先级*/XKi0g%I-I/yE&H
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ `? b7e_\/{\
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
-}v4af R float compute(); /*表达式结算器主函数*/W9G N T2I6v k
char *killzero(float result); /*去掉结果后面的0*/
T:j2rT6_ kF&j@
9Z9RUFv/_,C~s int InitStack(Stack &S)
"o9Msj@0q.Y~ {
;~L ~ed     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
q5K"U9T!V'R     if(S.base==NULL)oV/Um~zd*`
    {
6BQp{RY         printf("动态分配内存失败!");6A!u-w {,sn
        return -1;EfKl*b^ XF
    } ~6tM(XZbT Ns
    S.top=S.base; S p2Cu0O+u"C
    S.size=STACK_SIZE;m;L T*c Y%ui|
    return 0;
(_.PO5~3da;A } j~ bZ?!f
7iq4I7FZ6p
int DestroyStack(Stack &S)
)i.~RUK|.G {
~ anCM5O'm2l h     free(S.base);W @6C4k`#ny
    return 0;
L/slD X*V e }kjsKu8eB
"O#wynZ6pWB/Q
int ClearStack(Stack &S).u5MAH C#Sj-|M
{
C`3q P)V2\     S.top=S.base;
1@qc1E9KC r'?     return 0;9X$k3HGFk,G$D
}/xmF;G'm"x"Pa"HOz
5_ OO_0c ~"\
int GetTop(Stack S,SNode &e)
d7Oi nyC {Q cK:^ A;tS
    if(S.top==S.base)
]:X1~ \ U1i4X$r     {
4NCd(B3?9Q(ao:c         printf("栈以为空!");
9yk5EYc G         return -1;
D*@q(PYx?t     })}*H5F:L B Id
    e=*(S.top-1);
~EG MT K%{&R     return 0;
e#l,pj3b+Z)gB }VD:X1B0y
Vkr$y1Rz
int Push(Stack &S,SNode e)
_!aNZ4u(D.X&l {6G+R\F4AX5Y5M k
    if(S.top-S.base>=S.size)!K9m8v6p z*w2cJ.l
    {ktntbuM
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));yV:I2]Q7}
        if(S.base==NULL)
'|,\u*A+W:R-MO         {
NPP,dA+p             printf("动态分配内存失败!");
9^8E6N6Ax w7N@ W$j             return -1;;w#iR+@&lC!s
        }
$B9OGR:xM         S.top=S.base+S.size;h/Y5H-NtLv
        S.size+=APPEND_SIZE;
t'{/v&X-y LS/?r     }
m6~2A(My     *S.top=e;f1u;US`D%b1bj
    S.top++;
t8u1`*UQ     return 0;
Q-W Y8U5d$m3U }
;m'yxt.h4j-p_'`m ]SM,C*k8f'X ^H~p
int Pop(Stack &S,SNode &e)3Ub^ J O3S3_
{XUqR+w0O lj
    if(S.top==S.base)NxR6fZ\'HU ~p
    {c8z6GK2p1V)yK([3L/p
        printf("栈为空!");
|x1|t~q&f,o         return -1;W4U-y'c @C"NB.fmM
    }py*I.hS^:?r
    e=*(S.top-1);w:V&A&w,YX(V&fZY;q
    S.top--;
)P NQ-C _p(i]+v     return 0;
G-D Ol3d _M }F M9R FkN L;E-~

|)X$vXBvv+Eq \ char get_precede(char s,char c)TKs'u;IbK
{6Vs!QUuqyk/y l
    switch(s)
2u0on9A[|;j2T#a     {
3yP#i)Co4U2Z1i         case '+':                 
/gn0_9? X lcNH         case '-':5N/]R@ jc7[
             if(c=='+'||c=='-')
5Fb{j!R]P;cl                  return '>';XASX9y4[H&@
             else if(c=='*'||c=='/')3ct'V:K2}2V7|N/C
                 return '<';(mFKa8T
             else if(c=='(')
8eY*B#W2K1id                  return '<';7I&OXg6aR
             else if(c==')')'tNFH;V?3y{1NyY`
                 return '>';
)C)~/}.oc              else
)J2].GS {,A&TN0T^AG                  return '>';eG"f Q/l
        case '*':Mk!n bsf#H
        case '/':
s ~2Vxq:P)~              if(c=='+'||c=='-')
nn!X+w8h f!P$g tL                  return '>';
v:f3~v n`ofC*P              else if(c=='*'||c=='/')4n6j:g:b"|%Q&f0f D$f6@
                 return '>'; H"l{ h i8h8l6KJ/K0K.j
             else if(c=='(')
X#t@oiSv                  return '<';
,p+VJ$Z1T_]              else if(c==')')
'_b0Zl z.y!lN tr                  return '>';jU"sb@/C#|,Vy9J
             else5D cwk2_-P0H
                 return '>';0t;HkB0wXmn
        case '(':fngOr3E%A6u
             if(c=='+'||c=='-')xZ4x0oq,~0}U#Z
                 return '<';,j_.v)C1?P r
             else if(c=='*'||c=='/')eq}7Cps4[ U@"[ f
                 return '<'; K YG y O3[(K Xe
             else if(c=='(')]+D ]]6uk8W2A
                 return '<';
-q] D F({M2_!a              else if(c==')')
:x'H:v:znW/c                  return '=';-v8Y.`-v%o,A-?
             elseLP"HH8n!d
                 return 'E';
U{u v{o:L         case ')':1u/C(@Q r
             if(c=='+'||c=='-')9wh A2W$uq c(Q#Q$J
                 return '>';r9t]4^!U$Pil$C.DA
             else if(c=='*'||c=='/')9xa9~I0F2d0FR'o
                 return '>';.l|k dK/w+[
             else if(c=='(')
g0d p{0N;K                  return 'E';e T}F%F
             else if(c==')')
/d8RJ3FI,og;{e                  return '>';
9A&@~)w o*b0ow-qq7M              else
x,|(M7h w ^P                  return '>';
O0l v DYck         case '#':gQR2fG0i9Q
             if(c=='+'||c=='-')6[fMt{:hwWQ
                 return '<';DOSrANJ.~#{?v
             else if(c=='*'||c=='/')*i1bD aZ/j$m$c
                 return '<';
(X3hW*O8P              else if(c=='(')s.Q8T l0L.Ha
                 return '<';
A%S6iw(oX4l              else if(c==')')2oG"R{+p
                 return 'E';
7n(?,lB#Is'X7w              else
eV YG'U%z                  return '=';4O @U!TI)o
        default:
n y/wO a p!rRN              break;9j8Y u5zG+o x*s
    }
C3d cC8e5xg     return 0;    'y;Z6]5UMy}3Zf
}m _L^ NI b-i7u1{O o

.?'l }na3nBb,bT'b int isOpr(char c)9UV*uW5z_
{
3WFX y8D%l)gfY     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
2`9x$m5_RI+G-O         return 0;
GX/?0WKO!H#Z     else J0z'crL\9a)@f
        return 1;S5EA2Vi&g9j
}a!D$L[8QPI+U"hS9S
Z ?/uK)Gxt`#_? O
float operate(float x, char opr, float y)K R9h U8x[7y/H
{
\7X`2i [Q&Cw     float result;/Nn!?0D+e U
    switch (opr)&t1W7m*O4?"e/cd
    {
r{7h@,~H zh         case '+': %V lZT4w1g0T
             result = x + y;gY5d S.dn&m
             break;,`X I6p.SQQg"]B
        case '-': X$tX h@J @DAq4@
             result = x - y;
$Bj$V(qT2~JT X              break;
/W/\Rk,UC1I!K         case '*':
u(iR&kM3FiPY              result = x * y;+D#|C@C*`
             break;
@ Ia i Py         case '/': K&OKj ab1s'a:qt9Z
             if (y == 0)
%B)sd@.K@z6l              {
7Lqd R"{3_q6B                 printf("Divided by zero!\n");
#c2a5h7^rX                 return 0;)EX*zdhp
             }ps Jo([s
             else
v.b4B-o S D["sz              {q%Ut g)e+v
                 result = x / y;
&b2gqZ6|^                  break; ^;F({o"rpX{ I
             }#|j:E+~$W(V a
       default: *uFC/Y[$D1E?'b3Q
             printf("Bad Input.\n"); $RCa |cHk*cV+e
             return 0;
+?PP-UQ?     }
klf%vMT x     return result;
N.['uJu9cW2h }   
p"t'`yH:F
3uh{Ql\,O5b float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
Tw-I rVeN {9\^K5JV1~4f
    Stack optr,opnd;["@3n&Z.S-R!C0k
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;,tT-tu.SfR
    char c;0B?)tTwe&dt
    char buf[16];KsP Z8H
    int i=0;S%Lx h D b.i
   
.a0_*}Ys\     InitStack(optr); /*用于寄存运算符*/Q f,Vp,Z6y
    InitStack(opnd); /*用于寄存操作数和计算结果*/
uP:{d^(]     memset(buf,0,sizeof(buf));1?P^ BaWr.U-zk
   
e:L#AyR5VQ~     printf("Enter your expression:");
[&BD8X4j         %`)HGL4YBrqt
    opr_in.ch='#'; u(AT9Z|p#e
    Push(optr,opr_in); /*'#'入栈*/
y_ q,['OA     GetTop(optr,opr_top);5liPa,a[ r)A
    c=getchar();}8WJAM+z@
    while(c!='='||opr_top.ch!='#')
k([0j4a.b }5Q~ BQ     {[0MQk&B.H`^/d ~KM.m
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/y~Dx7C w]2mt3v/d
        {
Ed8k4d!f6mt2qb#su F             buf[i]=c;
%YzF*\C,@s@)O             i++;
&W VD!\Fr^ I B T             c=getchar();
]m:}"|}|7[:b1e         }
X bKdH,Q         else /*是运算符*/
x;FaR*E ]_l         {
#q0o IpNd3Hd!u             buf[i]='\0';m%LO V!O
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/gR@2d$BKB w
            {.~:i!@C!P
                 opn_in.data=(float)atof(buf);H'pA |UQ2d
                 Push(opnd,opn_in);I*r:J:|t5`O
                 printf("opnd入栈:[%f]\n",opn_in.data); KFb9`2b D,~
                 i=0;1eEm2^8T5E
                 memset(buf,0,sizeof(buf));
6{(g:H*rT4B             }
mN.e:C2aW oD^             opr_in.ch=c;(bBrYkp?
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
?-^!h.A @;Y             {
!d@ [o#H&T f                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
8u8a {IA Bx B w F Ox                      Push(optr,opr_in);
C+Jx;te]                      printf("optr入栈:[%c]\n",opr_in.ch);
]'s Xmz9VH|                      c=getchar();3x5}n7T~;Y
                     break;!K1Z(M/o0|b0p
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/"YTRow/GX;t~
                     Pop(optr,e);5v,b5P)U!e4x+}I
                     printf("optr出栈:去掉括号\n");-vG9^/Bt&L x{"F
                     c=getchar();P se+[-a)O B`U#p.^j
                     break;s2Qh2DRi,M0Ff
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8[*J;|JF5p X#B
                     Pop(optr,opr_t);+o$}S/} BU{&pH
                     printf("optr出栈:[%c]\n",opr_t.ch);
K qn K1xG                      if(Pop(opnd,b)<0)
w!as,?o.n7z                      {
ktl8fh^#^ QQ3D                          printf("Bad Input!\n");9}?0Rg3s2}
                         fflush(stdin);x0I2t@2]M1z;`A
                         return -1;
7_%\yG;E9P c,nry                      }-o PAv-b8o7s8T
                     printf("opnd出栈:[%f]\n",b.data);
+ezTG4cw-X2M                      if(Pop(opnd,a)<0)-z%G1Y{CI BX
                     {
l\;zPuID~                          printf("Bad Input!\n");&r3dI Y3Vf
                         fflush(stdin);
LpQnH^$|                          return -1;P0A)L(c#o,x1B'MnO
                     }
#N2A%}k"sH6O(@gE.E                      printf("opnd出栈:[%f]\n",a.data);
s+y6OXa4sT                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/*nJ!C)j_a
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ Tx7|&w~ q"r7v&_
                     printf("结果入栈:[%f]\n",opn_tmp.data);o3xhlb1x+x/]
                     break;
x'\)M3`Xn#M             }WE4tN/]A7R
        }_2t3p@WO
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                k3\"[_Xr+R
    }
anoXYhW     GetTop(opnd,opn_tmp);
(ecu Y,\0e     DestroyStack(optr);k;l E;|I~Yw
    DestroyStack(opnd);
+nw-V[/I     return opn_tmp.data;&i$qgxA6mW
}
E1i6Fq7ys.xMh
zOiz a7`9ey*_&p char *killzero(char *res,float result)
}$QZ.?,?x#@ {
gY8F5xo5`"J     int i;
4GhMF4c i V.M'R6Gu/A#|
    sprintf(res,"%f",result);
#F+b zop \3c |5T     i=(int)strlen(res)-1;1vd+zUY1B,F;I
    while(i&&res[i]=='0')
uO[mA1N#N2_c     {N/\U Gaf!g W!K%G
        res[i]='\0';
9JIaD]$V{s|         i--;(Dz Zb6RJp)Z
    }H.k.`$~6Nh
    if(res[i]=='.')
C"Nb|B Um;A O         res[i]='\0';
e5}%GG/b*ub6qc`-s     return res;#O5I"f6| t#G?
}
2U?#Iava`Y hS8O9Rmy3I)[y(q:Le
int main()
)_-?P1x bH-B m {
q1taj8nG^-C:J     char ch;]&g8]1wKL?f
    char res[64];
[y$M R3xB4j#C y|     float result; O j5wO!Tn c;K3k
    while(1)
:Cn`#eZA     {5EeH)z#@A6{ ?
        result=compute();+K*z-s!`Mr#U!T
        printf("\nThe result is:%s\n",killzero(res,result));O0g/OMt"i
        printf("Do you want to continue(y/n)?:") ;d:H coR+}!z0@Bo
        ch=getch();x0K^ P&m5U]
        putchar(ch);
DHUL'C8R         if(ch=='n'||ch=='N')#D"f;v'QVL h
            break;.N.|&G.|l9q0s`
        elsejR!I#a[D
            system("cls");!c(VLm~Ip&l0S J
    } ?Ao[W:A/V/v(@*n
    return 0;-T3NS*_5DA
}[/i][/i][/i][/i][/i][/i]q"d_c;ExL3E5C
}c-yx/mo:OG
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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