捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
}X$C9S8T$_ { 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=D;rNv!}^X3^
/**************表达式计算器************/,q&J*LLcY
#include <stdio.h>
X"m/o8C0jr #include <stdlib.h>
8B i2q1lu$Y;B,~Z3UnB #include <string.h>
4OsR:~.]"k`G1g;QD #include <conio.h>
+e;szY O-L #include <malloc.h>
a m/]S&~*w %b1]'g&LH
#define STACK_SIZE 100
@BW@.P]4C #define APPEND_SIZE 10
f.P%B8{/t&d1s.SB
9Z2e+R+kn)m*`;D struct SNode{ZOF+mNRb.PFY
    float data; /*存放操作数或者计算结果*/'IbV.p,r4l&F)mz
    char ch; /*存放运算符*/ D5qZ;X4Jp
};$nds _ Sp

kZsb;cN7V struct Stack{gAO.yO"d"i`
    SNode *top;
2Ox Pr:o^*k     SNode *base;
L4Ys!v&{ LhF     int size;G+[0V.v2esh!gsD+Sq
};1hI1V:wR2x N+o.j \8[ge

.\)jhS7Gxq /*栈操作函数*/
0e4^S$X]`.?1l5h!["P int InitStack(Stack &S); /*创建栈*/~k.b(t b G7h
int DestroyStack(Stack &S); /*销毁栈*/.])| O"f4G/UPn\
int ClearStack(Stack &S); /*清空栈*/4MN)qT0P p{
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
F.w il$aX ^;x;DG int Push(Stack &S,SNode e); /*将结点e压入栈*/6vfg"M7b
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/8JL0YLji7M2K
7K{1N3a6r^
/*表达式计算器相关函数*/
8f q/A9tn9o:p char get_precede(char s,char c); /*判断运算符s和c的优先级*/
`UG.l GQe&{xm,D int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
4Mj%tUgM1p float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
%Y7cM_-Xpqgfl float compute(); /*表达式结算器主函数*/2Ty4F pB#r0p @dl
char *killzero(float result); /*去掉结果后面的0*/ k%@5@a,D1a3|

f;p7y FY-lit int InitStack(Stack &S)1}2oo'L(o
{S,\"I kP
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));j7Y;U*lH~2\
    if(S.base==NULL)jZ z;J$aCu1k5{
    {~"m e$D!e v`
        printf("动态分配内存失败!");
]f3y&^Z.S3r'M         return -1;k7uMok
    }
8pZll9r)Ol     S.top=S.base;N?A;b!z
    S.size=STACK_SIZE;[7xG.J{-Kq
    return 0;}t)LE!S6v2Mu
}
-SR$@U Q8Q/v~W 9Sd6w.\:P
int DestroyStack(Stack &S)AKF9Q h-Z(a\
{
l&R FA _7Kn     free(S.base);:ra3L)V'N
    return 0;o-o;^C q6Lot
}G5E1| q'T \ZAZ
Oj#S-E D;\ |Y
int ClearStack(Stack &S)
"erl@"l {x&O)J#V^ I,A
    S.top=S.base;
8|4i \4V'sY3h4N     return 0;
D W[;k)} } |}{JI#Hk
9U1u{%NB'z
int GetTop(Stack S,SNode &e)
Rd^"uf6K-y7G+v y {7|b m0rQ8] q1p L
    if(S.top==S.base)uPgHAWsLt|
    { S;s#v2~d bR'[w
        printf("栈以为空!"); q;O"Z1["{y nd8|
        return -1;
nMF] t.TFi$z{     }
nu DP:ZV*g     e=*(S.top-1);
+ps*Mc b ^     return 0; { t3rk:f _K
}
7l(KMa} E $YTo(p0z8i,L/Gj
int Push(Stack &S,SNode e)U4{1{7Y$tZr:b C
{2X9fm}5HE:r
    if(S.top-S.base>=S.size)
bX:h9~w     {Nn)kwCfX)Q?
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
I h"yC5Lzv         if(S.base==NULL)n6h p7M C(H
        {L{w*WF|,FxI
            printf("动态分配内存失败!");6`,Mr*?5D q:r
            return -1;}h,p'k:Xb/rE
        } bw:Sndt z8V
        S.top=S.base+S.size;f*@g*O4N9_([e(j
        S.size+=APPEND_SIZE;?5E,ugL
    }
+o ~ F j)|!Y?     *S.top=e;
2N][8r b*Q'IA Yk g     S.top++; c}N;t/v
    return 0;
3k~aK` }
YaK+_,I!gd8\ G1} BB)M.ws4c)x] d
int Pop(Stack &S,SNode &e)
8|MmNNO {4wD m3X9q&t-t
    if(S.top==S.base)
9P9l(_h`"N.Q$f     {Aib#n/r7`
        printf("栈为空!");
.ZB `lO @:O         return -1;
I&`5|'T0X;Fa!SJ     }%P c3f"L C*E:I l
    e=*(S.top-1);
:VIv.t|0@Aru4|Z     S.top--;0J1C'F4b9YmjXa/L+m
    return 0;
:{n#]9o&|W"Q#q }
2}U9_!}kFu~2H g,|7M5cV4K@A3k
char get_precede(char s,char c)
u(b/b wrqx [ {
P)I+HI {1e/@M     switch(s)^h$dF"i"v$k
    {
*R8a:gs T;M         case '+':                 
.X:k4t3OVRW!P         case '-':b&G3h;j PQ
             if(c=='+'||c=='-') i9U w};kSEA"[
                 return '>';&jZ] x/Zr
             else if(c=='*'||c=='/')
^!N+rz&NF4h1i7|                  return '<';
@*}x^yu`u              else if(c=='(')Pu'X||O%mT
                 return '<';&m m Yp [E5h.b
             else if(c==')')1Ts\(^8t$s)f.V
                 return '>';
/q~6`*vk8N#Bb6o              else .e.K6O B j?Q%]7e!b&`/N*~ ?
                 return '>';
z/~6O(hg+qvd+e.Xh         case '*':8^v%N,O*I&Lx
        case '/':
9Us-oKy^#p              if(c=='+'||c=='-')
VUtP cs^-P                  return '>';
#T"H'kZ.a!o#a              else if(c=='*'||c=='/');K?#B*RR XI
                 return '>';)s*bJ3Q'O+`g-e!\j
             else if(c=='(')"fUoWP^ ^
                 return '<';
$L { S\ S-o*W:C              else if(c==')')"f6TRD&zGa6K
                 return '>';P {\m oNz
             elseRH6Gs(I.ns#P
                 return '>';`/T bY D(`,b
        case '(':
g]6E8SIp              if(c=='+'||c=='-')h g;i-@OXp[*P
                 return '<';:M'['s8P3L/kIi/HM
             else if(c=='*'||c=='/')+@#A+S-Re%N`(X
                 return '<'; JJ@,@2iKN
             else if(c=='(')
%@-X[*A5r\                  return '<';
u%IM0I,feg              else if(c==')')L.S+fmV
                 return '=';Amr2[ ix3V
             elsec _g5jw U
                 return 'E';/e$n^ULX9S
        case ')':AD1Oc%T4@
             if(c=='+'||c=='-')
)ASF+m w1Z                  return '>';/~S af#sF@I
             else if(c=='*'||c=='/')1J1K }7US t h\DP
                 return '>';Ekl&OI3W
             else if(c=='(')
&r9}P N1v                  return 'E';"|^#w'hb_
             else if(c==')')
gd {:qu.S?F&d_3I                  return '>';5e9^/A*I&_
             else/^ z-z4v*Gl%w
                 return '>';
4fd@.G~*RV2uO         case '#': |^Jh+bW
             if(c=='+'||c=='-')
FpE;m|h;g3a                  return '<';$g8c wH#m.i YF
             else if(c=='*'||c=='/')g,@2xsDojT
                 return '<';.l8F|H'O?
             else if(c=='(')
3tF-G6K],G/c                  return '<';aU uK6v`1IW/i
             else if(c==')')
/\}(_]ULf;D3J~                  return 'E';
,LW _K-bP~6]&O              else
J(jT!?U0[;p                  return '=';DVT$E B@CQU
        default:[/tz lm\f%D1K l
             break;
of-ep-Ou     },VZb(GuK6Z
    return 0;    1o E1I:_*NED XWO
}S.JT"pV&ci+FTi0Zi N
Mi@"o;z(q%Y{:|
int isOpr(char c)
:o"v+V'lWUQKv {/^~ XJY `
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
7o,\DpJ         return 0;
SZ^+eO8D     else
Xeb7}"y_;K         return 1;&HB aXti5y/K ~/H3W
}
dbUzqT*W 3_e,V'zt
float operate(float x, char opr, float y)
:Oc v3u R.g1J0Xq r\ {y!O(I.iEW:}
    float result;
PaoQZ'w     switch (opr)
"A9cJaV     {
7I6N"^|{4S,@!ol         case '+': q4i'qGW%m;s
             result = x + y;0sN{z1L[A
             break;cx f X0N{I3{s's9rQ
        case '-': ]#K3F*i},l
             result = x - y;
r5L#V+Z([R&U4P M              break;[9aHT"CD9[2aI^H[
        case '*': lkT)wJ$BF*]Vz
             result = x * y;
:` u LzcI(Xf              break;:Y7go IWLkl
        case '/': gg$B/V#S:M3@S i:IkF MD
             if (y == 0),HIQ[onO ?
             {
-h0~k+I~[2{                 printf("Divided by zero!\n");.u%?z,E*Sz
                return 0;
&G!Q1WshnS E              }t9^ i(m,P:T
             elseR-Z/VS)W*T D/o&b6x
             {&WO(ck+KJ X'Tn-I
                 result = x / y;
Y md:L'C4niV7A/D                  break; }'jT7r;pg#N
             }
`_w?K!Hj6N lQ        default:
wXOy%F?              printf("Bad Input.\n");
d?8bo](E&ld7K0YI              return 0;
nKu;F5tr     }
m(T5h(v5i Yw4g;J6S     return result;eFjOIL5V
}    ;v7z*F_+HElq*`]

h`smS_"t9@#V v float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/-vf#i)X9X-g)T8|
{
AD/qA+`:yw!\;^     Stack optr,opnd;
b(e B"Ft     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
;`8@w'dT$?     char c;
;I)?*Sx2V}({!uQ     char buf[16];
uHmj2SZ w     int i=0;
o(air@!np#Cqd     F ^@E5RLg~z#{
    InitStack(optr); /*用于寄存运算符*/
C+?`lS _8w     InitStack(opnd); /*用于寄存操作数和计算结果*/a9Vd HgE
    memset(buf,0,sizeof(buf));
%T v5S0pz    
o[ [_\gh7a     printf("Enter your expression:");
8Zs[%Nn'\         )cA#Sb }/U,QK.k
    opr_in.ch='#';
4ed:h }-O(\5y     Push(optr,opr_in); /*'#'入栈*/
U){:u)OaU2X+N     GetTop(optr,opr_top);bX{*[/I'{5Ttb
    c=getchar();
Z6Tgjj!e!iq\     while(c!='='||opr_top.ch!='#')
{`,R y@     {1z1I)p!~$`!M?m/e^
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
5F1Q&F\#@E         {
9j&b7v4ayo4\N             buf[i]=c;
6v F }DpH+P l"U1V             i++;
9Y y,Pp4I9N             c=getchar();
w0ZGy uE;i?         }w @4kTB)dD)q|m
        else /*是运算符*/!h@9ff^'L
        {:hqX?F j
            buf[i]='\0';
ukPd {P#f(Vq             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/ U1@)r?[/fN6OA
            {
Mx4D@1k-P,C#f]d?                  opn_in.data=(float)atof(buf);c-EDG J4z a*LP3O
                 Push(opnd,opn_in);$\&uZz:i6r aw
                 printf("opnd入栈:[%f]\n",opn_in.data);
M#K O1[kB v)|7c                  i=0;q2^#W2I.F/D
                 memset(buf,0,sizeof(buf));
p3N uL!k)tH             }
H-T*An-`&xB)y1^             opr_in.ch=c;
TK9R&R LdO             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/4}(q)l9N$k-L?4p{ @
            {v-g'Sd ~I?g
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
;KI?${ ]1w\5s4L v                      Push(optr,opr_in);
B@eF4VJ3{                      printf("optr入栈:[%c]\n",opr_in.ch);XaW%hE0X| B3\
                     c=getchar();
1m3T5a/KN;}l2r-]l                      break;
!o1Mlk i bx                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
4eZT!Zi/Fq'T0G-D_                      Pop(optr,e);w2~#Nu*@W~ I)bI
                     printf("optr出栈:去掉括号\n");rD ewd?J1R
                     c=getchar();
v:^"|F!}:s?                      break;u7S$z3{n?A'N~-DT
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/!j,G3{ E n8b,kRv a|V iO
                     Pop(optr,opr_t);C&| ~$~'N
                     printf("optr出栈:[%c]\n",opr_t.ch);
v7Q#}{s3fZ                      if(Pop(opnd,b)<0)
9B%hC1{"f[B                      {6otHs/X*X KE~
                         printf("Bad Input!\n");C7r A LFm r9}2B,M,b7w
                         fflush(stdin);6}7uC[ t E
                         return -1;1GK@{:gfoA
                     }
@}:c!V$s]0[sC                      printf("opnd出栈:[%f]\n",b.data);
M$N5Oy:{7oT                      if(Pop(opnd,a)<0)i,M$\"E8qx})G4q
                     {u6DQw`y$|X]V
                         printf("Bad Input!\n");
V!s"U&y L;hv#v                          fflush(stdin);
V3T-FW%i                          return -1;
]n~"s@                      };i#Jd,C3{
                     printf("opnd出栈:[%f]\n",a.data);
u)WXjh'\:Tc&Q8`                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/G0Qy8~ j8x q}o
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/hd(Na2`pf/O k
                     printf("结果入栈:[%f]\n",opn_tmp.data);
t/Ctz0WTH"S|$YS                      break;dp:xH zW o*R@ W
            }1m#b m:sj5u nO
        })E'v!{ Q+x
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
D!WL$Sv+wgb p     }{t/eRtto |
    GetTop(opnd,opn_tmp);*MU#~+Wy*h.`J.Od%Z
    DestroyStack(optr);
dA+tc'~wx     DestroyStack(opnd);%Y9okE \jp
    return opn_tmp.data;y]n r4tD G
}
p"nG1~WX f9]G$^Xt 7Q|*_j X:yj-p8O(\4i
char *killzero(char *res,float result)
7r*ZF3V/H [M(L { N1WR}+I7K#t6tf
    int i;7b1Rpb,kw9F7Z%{ g

0G"P {ya QD'R!`     sprintf(res,"%f",result); |_Zc5I^!Ol`Yc
    i=(int)strlen(res)-1;.V(tAX.k*Cs_8Y
    while(i&&res[i]=='0')A&K vD:~.D C6[&V
    {2xPj LZ6P7x(W
        res[i]='\0';
*RrR`K4fFa [K         i--;
I*x Jh1NY ^;ol     }
3\ zd!@.H2q a,]G [     if(res[i]=='.')
B4x(B5m.v         res[i]='\0';!IbE'g5}{H @3nvX
    return res;
"KdX5r@-Z[R }
}9^;aEO0D w-g
MB ap+k+R]B\8Tqv int main()
z i SOGf~t {
g%UC-Sx;|~+L     char ch;]7Pbm:d g
    char res[64];Sv4~'c RV
    float result;6M;J#zT S0k l`A$M!b4m
    while(1)
ls P#e0k;u     {
hU)N,LdU2?         result=compute();:^GjqodK
        printf("\nThe result is:%s\n",killzero(res,result));
OqG9mE5O         printf("Do you want to continue(y/n)?:") ; PO{/qw$T2aP;l
        ch=getch();
"Xqq,q n/JeP&GKq         putchar(ch);
E)[um9bJ1r4m8c%c         if(ch=='n'||ch=='N')eM8u'Op
            break;
-bYG7Aw         else
W+dX/@.wFM#h.J             system("cls");
'G Tn{ q'P     }
.o9Xfo1mTq%I     return 0;
V7fQw5Z[z] }[/i][/i][/i][/i][/i][/i]*H3T0P!g D Z

;Jg}h U1T R [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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