捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
Bv!pp h:@dj#^W 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
K] C7`8m+W,[ /**************表达式计算器************/
j:Z+i}Jm-? #include <stdio.h>np(]x \1@xA"z
#include <stdlib.h>
2pVJSnDKG6_OU #include <string.h>%y[k/s(`N
#include <conio.h>
{#Y'|q.} sgz #include <malloc.h>
],ZDXDn
+~;pK:f O8] #define STACK_SIZE 100!B(O i?$t5`}
#define APPEND_SIZE 10 ie&wPe jR
2qS9I9S+p'dIC
struct SNode{ l;\7cS.x
    float data; /*存放操作数或者计算结果*/
IVTlS3h     char ch; /*存放运算符*/
V;M.Go8d!g };L:z8rF~g
8E_ Lk1Mj E8z
struct Stack{&Q%Y-{TS x1TBdB
    SNode *top;Ya[ {RY
    SNode *base;+MOc&mv
    int size;
U1K/U7t!MAd~ };3? z8[x!G&O
P0m$T+X|I(A
/*栈操作函数*/
3X)e&Usxz7t3IK int InitStack(Stack &S); /*创建栈*/
um`1^.LV int DestroyStack(Stack &S); /*销毁栈*/
~ X1x-j p{ ?'b int ClearStack(Stack &S); /*清空栈*/
#bL1B7DwK8w8` int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/7vw|9I1O
int Push(Stack &S,SNode e); /*将结点e压入栈*/
:P9?,_0X1Tu)[j5O int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/D9h F*jT

qBC,Xwu /*表达式计算器相关函数*/
.v~3b,d @ char get_precede(char s,char c); /*判断运算符s和c的优先级*/
,W JxD!D |B int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/Q3J-XV.`)`
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
M*Zj6Hq*cw8o'CB,\X float compute(); /*表达式结算器主函数*/8B l!HoA u D'}h
char *killzero(float result); /*去掉结果后面的0*/ i6_3Mgw$P/z7I*Q

:MI8l g"e-\E P.BY int InitStack(Stack &S)
?/tV)OSv+qy {
&h J!^fT+]!IS.^6KR     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
)F(~GmM&piZ1Z     if(S.base==NULL)
9O k!y4?&K     {
1z ~Zy.r         printf("动态分配内存失败!");
-|+Y#l!r[7tU!uR ^         return -1;b'{zOS
    }U^ c].x2D
    S.top=S.base;
[C;Rg/}0v[     S.size=STACK_SIZE;U+g2LPkqA
    return 0;@4W.K"B1gB"a }e.X4z,N C
}b/G"R"k@T
!X*GG;z&HWoq
int DestroyStack(Stack &S)%S"q:^/p'[E
{|W#mvXxH*Vz2w
    free(S.base);
ip?"J$j:nBok5g}H     return 0;
0Mk e YO zZ[,d }@7[CQm@

&P%@bK!`i int ClearStack(Stack &S)
&k)Ug zj:}&XM {
2~k1a1D3YoQH     S.top=S.base;
1S)BF2N W"d1U     return 0;+L9G? ~ M|
}`!y8S8E/m(Ee

!f$~3\9b7B6x int GetTop(Stack S,SNode &e)
i|(s~Ih {
$a.p(vC\ K| ~7n     if(S.top==S.base)8e.a0F9|/YH
    { U*[+[ S[+M9a ?
        printf("栈以为空!");!E)aI.xX
        return -1;Ba/M7s'z]wK
    }
F;|lnV u Xu*V.y     e=*(S.top-1);8?l qa0rPZp5T
    return 0;
(n"gd eP }NYMeH!\;@
{:Z-y7nSp
int Push(Stack &S,SNode e)%B7xl3G!aRe,k
{
hr`h1o`1Q'}     if(S.top-S.base>=S.size)
b-UB,X;SI     {,Tb O\\YHE
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
Xlr}0A}E         if(S.base==NULL)r$@['VE T`:W
        {
)O0DH:D9k5h6Eq             printf("动态分配内存失败!");
-m&r!Cwc_6K             return -1; k Y+X"GP*Z
        }6W)I'IqmPM `%m
        S.top=S.base+S.size;
1I RC,e`{1I         S.size+=APPEND_SIZE;
2D@ Vz6{     }
6\J.Ga R     *S.top=e;
+W,K$ZY6^I|1k/o     S.top++;
7F8v(V'mo l_     return 0;
&l,_8wK j\i2n }
5f%b1lWpb`l n"k1a;p$ds
int Pop(Stack &S,SNode &e)
_b2XH2M3y+P {
`"r2iJ7Yg ]'K     if(S.top==S.base)
3qxc*x AD$O] ti^     {
lmNl,~IM         printf("栈为空!");
:`+e:Oxe`         return -1;
8V#rk4p2{"s     }
(O4G*].E:I}     e=*(S.top-1);
3F j;x\3XJJ     S.top--;
X6J(H ua]     return 0;
(?J!I _ x-R }q8]2KIi G6c4q

J6fU5T ].f char get_precede(char s,char c)jM5Z5xO5J
{!PLkeuzW
    switch(s)
\X5]9R(I*m{     {
R]P2M/Sj8]+Cg         case '+':                  S d7R!d*Hy
        case '-':0e!p)i]S4j
             if(c=='+'||c=='-') XR-Lbak6L0}X*E
                 return '>';h:nc~ X F
             else if(c=='*'||c=='/')
4DH F(LC:k2vV                  return '<';
9Y+H#i,bE1F2m K;S              else if(c=='(')9i X?,la#j~Y
                 return '<';
}+?6Wi~K7}0B,gb"G              else if(c==')')
-Pl1ka/|H,kF)[                  return '>';9KJ^ C%r6bb a
             else l:m+Xvptcg
                 return '>';.ZYi#qXP&^cT*y
        case '*':
A*R5j&d;kWZf         case '/':
.HoQ)k JhB~Q6C              if(c=='+'||c=='-')BI-M]m
                 return '>';6F@4y,|(q:N(m!`;? C[
             else if(c=='*'||c=='/')
k!jQ!FK4c3G:V+m                  return '>';l Sd)S|
             else if(c=='(')
n IYrw[l$I[5k K                  return '<';
s txGid              else if(c==')')j9A,ZEF {9HqOK
                 return '>';Y.j-{8a'sNh/i*H
             else%A*XT]6p8E
                 return '>';c?h$kJ3WN5Yk
        case '(':!v2v~SH)}B4M;C
             if(c=='+'||c=='-')
7xM\5woL r nX                  return '<';
/|;Ds i+Q(t~              else if(c=='*'||c=='/')
a#[w(V1I1F} sC3WR0u                  return '<';G|EFZ
             else if(c=='(')
4Xff"P#U fu$f                  return '<';Vf Uv:~8`0E;A
             else if(c==')') y&``7BiDDO+Pc
                 return '='; BF_l3HKN#z
             else
Q&CW'r1z*O#S;~'X                  return 'E';;^ {(ra7Y oD9H
        case ')':
7w/Zp&JG[X              if(c=='+'||c=='-')7|k|/y(ih}*g%p9|
                 return '>';ny:k2UUn,O%i3f{#u
             else if(c=='*'||c=='/')
KTb;e2Pv4UC3j+gg                  return '>';
Pc ZjgZ              else if(c=='(')f't l:L(u@D'F
                 return 'E';
5Y| H R_              else if(c==')')%wE1E"wLr U{
                 return '>';@_t#d;J(D
             elseI*f(G/X,J'h,I,^
                 return '>';
a4SP5@DX7u*{jJ         case '#':
%z C"g/t1YM"r_#S              if(c=='+'||c=='-')-Qg qo9xZ?Mk
                 return '<';V-`)t#C?f tkF
             else if(c=='*'||c=='/')
%{HD }AU9R                  return '<';
6P Ewky+}              else if(c=='(')
qe'|pA t!t                  return '<';
,A D `(VC8i7P n              else if(c==')')bz6E$`.H.{
                 return 'E';V;|V&b"}ga!U
             elsePH7f7Dk
                 return '=';7g~ T~-C$pZ
        default:
H"qIzM2Lu@              break;*L.n F4mt7\/[o/zf
    }[ zx#I&H/{VmucY
    return 0;   
/wR-^)w+S[D(P }7k-zd D x%o&\,NE

4}A^^N3rQr F int isOpr(char c)
9p)Y mu-OW4| {6qDfbe{5_6O d
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='),S}b$L8x!rf
        return 0;
9@,pUVv%[t/v     else ^g H2F`
        return 1;
s I(Ff'd0e }
)Z2u5cUV
Gh\]0\7Y float operate(float x, char opr, float y)
2vW X5|? { M(z9Wne/rx
    float result;
/}U]6U2m$^     switch (opr)9w*_2`,zC
    {
q,KYa z(S         case '+': ewLnm1HJo pV
             result = x + y;
o$YFRck8qg U0d1U$m              break;0L4Z'K!B8D#\J [
        case '-':
*q6]1R u*i-k              result = x - y;
dn!fd\$M              break;
S0ZTsW         case '*':
4PT7e_ WJ;a              result = x * y;
\(?LiG*A7VR              break;
c\,]4l2WgWv#s;z         case '/': c)m;v6tK'e G0z
             if (y == 0)$b!b0]6l,VI
             {(C&^1N$E!bw`%GW6c
                printf("Divided by zero!\n");[)J;D2r-Kq
                return 0;\0[YWUe*B.j hr
             }7Q7E?)`}7vR
             else,m1`-a V/Dr'`l;|
             {
$X'KDBd]Xt/AU9i'S                  result = x / y;%sy^I+V \Nx
                 break;
T;pUdT!l              }
vJ/U"d2B'Q6pg        default:
;P|.]$Yz%u              printf("Bad Input.\n");
)M4S1HX}\%d*`] Ic              return 0;d{#]PfJ|
    }
]~ rpNf3x     return result;
nd1Yx6A4r2v@ }    'e L"rx*o9t#zb

?3|:_$gso/h float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
~l!v5V&E@} {1iC;y9a"Ff
    Stack optr,opnd;(^xP1Af/v8c
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
,p5@A[8I)v,@'|I/N     char c;
3kf3Rp-uDS*VS y     char buf[16];0vDP{1^T;kRt
    int i=0; ecbJ$f6f m pw6O,c[9?
   
c(`+_1K}     InitStack(optr); /*用于寄存运算符*/\8J*`/o$C3q(U)A8lE
    InitStack(opnd); /*用于寄存操作数和计算结果*/
x)nAN%mop     memset(buf,0,sizeof(buf));
&v"k#t&oh     2z:Boj1V'L
    printf("Enter your expression:");L H,_"I&hA
        TEX$D8RY9J!o2`(mb
    opr_in.ch='#';
U)DDhX:??     Push(optr,opr_in); /*'#'入栈*/
|ctZzO:| @     GetTop(optr,opr_top); y7cH5_gt3q
    c=getchar();
p(bOo?1hs7WF     while(c!='='||opr_top.ch!='#'):m&B x)b t6S1P8~Z
    {
V['_3p'R.^1~pGBt         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/&Z+m'^*u7z9cRp
        {
9mzgE\             buf[i]=c;
m` Zjs gw.o             i++;
+D9d:Bl"eVK*}*mp(F             c=getchar();
|(D6?AB\c k         }w0S|.~Q5X
        else /*是运算符*/6bmCeY.s Aa6i5[0k
        {
M8D T)S| `G!s7y[d W             buf[i]='\0';
1\!hac+`,]             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/&K R&@y s;U
            {
8Qgx7S4Q0ku z                  opn_in.data=(float)atof(buf);
8k}7R g8AHr                  Push(opnd,opn_in);
mu4F^)q,E*d `*qNU-g                  printf("opnd入栈:[%f]\n",opn_in.data);
j$B6Z{/W(`_-N'N |                  i=0;
E7LUfBI8J                  memset(buf,0,sizeof(buf));
^0Oz2AjG             }!z2v~4Piyynsr?
            opr_in.ch=c;7nP(I2VWa-Xi\5s
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
P!RM*u,R$mBY             {vn!E@ d4nn~r
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
i:l/}$q]^2Hw                      Push(optr,opr_in);iYRn*tRw
                     printf("optr入栈:[%c]\n",opr_in.ch);
0g.N7Ra5v                      c=getchar();PQ,{6bQm9G
                     break;E1E%XvSs@%E
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/0VRFp1f2W r9A
                     Pop(optr,e);dS7w-s!tt5H S
                     printf("optr出栈:去掉括号\n");6MUM,Z3HS)jW
                     c=getchar();
.JJ3Ml.G w"Ag[5j                      break;
2K"y0W&\5u                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
%DAii Z~                      Pop(optr,opr_t);REFF|{-B7a$G"b o)P
                     printf("optr出栈:[%c]\n",opr_t.ch);
o[.?]!h|v                      if(Pop(opnd,b)<0)6bM3?y2H8AfW
                     {1s*Z(uCm0|im
                         printf("Bad Input!\n");sGp%D3\h B&Xp
                         fflush(stdin);u f ?X r2|!f
                         return -1;
G8K%qZ/Y3Xy5iYe                      }!W+kC&B/h"w X
                     printf("opnd出栈:[%f]\n",b.data);
,xY|h%d,T E5O(`                      if(Pop(opnd,a)<0)/X)n?1rk fV.I1x
                     {j"@2of8ha!e6W!H
                         printf("Bad Input!\n");
znhlf~w_Y                          fflush(stdin);`f.VE!Q
                         return -1;
h5RU8TV^$Z2fl"E                      }
vpLj;a0Y                      printf("opnd出栈:[%f]\n",a.data);
*\4]"| Y*cKP7E                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
.]t iV"y                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/'I+YM4e7p
                     printf("结果入栈:[%f]\n",opn_tmp.data);
i ^:[4Q;v9oHrAh                      break;.L{I BU `h3{
            }9cCu+K(WDg+z`b Z
        }md%]:PA8z/`
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
8O"@fW A     }
;CP!bLd5m;S_ _F;m     GetTop(opnd,opn_tmp);
GX.X8Qk]-u({     DestroyStack(optr);h1}cS5ax
    DestroyStack(opnd);Gfb&g {"R
    return opn_tmp.data;[#xx`)D;C"t
} gbz(V$B

AnT4e'?'h5OV char *killzero(char *res,float result)^T.B ?4x"|
{
0Wh*E)I?7s     int i;$m4zXM;x'|3avJ

4w tq$rg'NhC     sprintf(res,"%f",result);*V"e#EU,{0~ i6u
    i=(int)strlen(res)-1;
T?uAA9F     while(i&&res[i]=='0')
F;CQ$H5A     {
O.N2?F7g+dVp Q wF         res[i]='\0';p p5AA+PcV"m+Ei
        i--;}n7l9z4LI8Y}
    }
_$WI dT o(Zc*l     if(res[i]=='.')3sY|X,o*O
        res[i]='\0';9yS&av5Wg&WX
    return res;9m-Xg$[Ua]
}
5ie`)pGK#IvW $T J h9y"c4u
int main().~0lG` n J,x f
{
w1OP_;Rsc0i     char ch; bJLY-hL
    char res[64];
sr I.Hgv     float result;a @U|l
    while(1)
i0T;\/zV;r [     {}9S nt.E8eM;g
        result=compute();+K8`X8CbxX
        printf("\nThe result is:%s\n",killzero(res,result));
1^tK \z7E         printf("Do you want to continue(y/n)?:") ;
gtb[Tk"uH!]3S K-^         ch=getch();
d3u6S2C/HAi!?         putchar(ch);kB-|-[R#R f
        if(ch=='n'||ch=='N')Ia DA[K+a
            break;@F Z](YP
        else
Cn]Go N_ S;_             system("cls");?zv@U;g
    }
AJ;M,o.A$g,M     return 0;v [k2a g]l
}[/i][/i][/i][/i][/i][/i]
k;?j[Ha~5N *MJ'qjd1D4B
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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