捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5b k/eb @*p*lr 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/VC sMTu:GqN-} /**************表达式计算器************/Z-N@D,? M3Pz7_
#include <stdio.h> lb%b NNj)\$T@$\
#include <stdlib.h>
z)y H6_+M #include <string.h>
p f q s6WnM:@G #include <conio.h>
P{| o8H,m T\ #include <malloc.h>\6o ys-r9o

"R'L-Wl0h k6rb #define STACK_SIZE 100*W2i(d9h{"K)h5W
#define APPEND_SIZE 10
/MqmR9}.V
cm-G6a#~)P4O y*e[,e struct SNode{&S!HOb|
    float data; /*存放操作数或者计算结果*/(]f@ V(Be;\5u e_
    char ch; /*存放运算符*/E7R P?f'L
};
x;BN{}4PL*M/b.[
1r9^U#s K3Z"\{~ struct Stack{
2Z*hV2MSM     SNode *top;W~-RD0Y7p cT7d
    SNode *base;
0fB)S2O#jD     int size;
^&m.L3@|2_S`3F/ct };+oy2wb"P;}

_X1W(jK0xE%msP /*栈操作函数*/'{A)X8Zf} @&x%N
int InitStack(Stack &S); /*创建栈*/
I}RldBPK int DestroyStack(Stack &S); /*销毁栈*/
s7zs^ u/dU int ClearStack(Stack &S); /*清空栈*/
9M6ue V P&E int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/.mnmq/Z O}w
int Push(Stack &S,SNode e); /*将结点e压入栈*/9z;u.P8@ I$r3rWT
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
_-QY8bGrG x O
#T:d7[2P+H4W~S:p /*表达式计算器相关函数*/
t+x(A"b5A'M6i char get_precede(char s,char c); /*判断运算符s和c的优先级*/K.f4{ c)E
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
3L @ o4hO float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/:uOcq9t&E
float compute(); /*表达式结算器主函数*/
fWl tN3bk}g9eU char *killzero(float result); /*去掉结果后面的0*/ )H4Bl BH:p
Ar n0_J3xy8P,?h6[c
int InitStack(Stack &S)sK'mwD
{
)GE y8Z'wo(Rg+r     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
wKSJ9c;Tmh%m     if(S.base==NULL)
Qc4q9|:J/S.j3}     {
H*Pc3d*j:vG a         printf("动态分配内存失败!");
2Qs L9A"Q X!p         return -1;
F]Q6he'n     }
E;F0Q0}U w     S.top=S.base;1_%]Z\Z/eOj"Mv
    S.size=STACK_SIZE;7ePr)z$?}r
    return 0;
ju Bj$I$[O } K#Cd:QW3y(pb3w-V!ir y
n}j Z~ jZ!S
int DestroyStack(Stack &S)
,z;TB7dLiT {
!Oa4Jx4cILH     free(S.base);
o&P-W [/nHP!w     return 0;
D.IAB]]+P9TH/S }
y:x'x8\,Zx;`
2Y![sFW int ClearStack(Stack &S)
c3v"Y z!_ {
(k|tD| X{9n-P,x     S.top=S.base;
6ce"A0V9k#n ll%pM     return 0;2C8t'kb/cE-_"N
}bp$j(h;M

vL/R1M7Z%v!K:P int GetTop(Stack S,SNode &e)
`bo h5U7fJ {+y1QO4w7TF(L8f
    if(S.top==S.base)
t8~5eQ,Q]sz&?     {E+r0a.d8|"j p'Q'Gi[c
        printf("栈以为空!");
%i0aI1Gdl         return -1; qC@%zH,f:C
    }
e:OR"y-I     e=*(S.top-1);
|#{A-@!~-K2kn     return 0;e&\8Oy[H/p
}
3C4?f Y*U,V 5Kv6O-q3Lq
int Push(Stack &S,SNode e)E#U I5J/S_W G-h
{
}Rg*i8_2x{     if(S.top-S.base>=S.size)v4jY3IG2F
    {|C2Y'q;La/c
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
P"g-}_h^sx         if(S.base==NULL)
,l&Z:d6d&Xa/I         {-P Z0J4|0I u Y
            printf("动态分配内存失败!");
d7y`y,a&o N C             return -1;
(J|C$N!n[#}8W         }ua*X{0U \Ki
        S.top=S.base+S.size;M/x3}5L&}P
        S.size+=APPEND_SIZE;
1s$u+aN:s     }-DT*TZ"|q K*Oj(d
    *S.top=e;
~)f d CYV     S.top++;;z+tkIx;T Z
    return 0;
'h;RY%A1{F } Um;djYn.p
^`\'`*|H3x)o(FLP
int Pop(Stack &S,SNode &e)
N)Ji"{7h0I)J {JIF K1QQ1y,v
    if(S.top==S.base)2djP(aF~m
    {d&s-`F*J%V
        printf("栈为空!");
kSxH+Q.Wk4O(f         return -1;
'IZj o#d     }
'B^ F}&W,uj     e=*(S.top-1);H4n.v#~G4\ M
    S.top--;
Y"Ua-H.^#A:y     return 0;9`"zb$q3^S
}
Q+NYI2R X
fT/dRE char get_precede(char s,char c)
7jd `wbFr {2c(w5K k~0[z3[
    switch(s)
J2_JX"F$w     {WS+D3f6B/{
        case '+':                  IP&~}x!j7T^
        case '-':+SfNH.pe'H0ap,_ RD
             if(c=='+'||c=='-')
~ s!TJ5\,stD                  return '>';5|\"o q.u%g"cOK
             else if(c=='*'||c=='/')
5v6p#A B-| o(YJP9M                  return '<';&WF-V'O;[j
             else if(c=='(')Ha0wnL-[l5G
                 return '<';T.BP|we*p
             else if(c==')')M2Enr? N4?B
                 return '>';
1HzZ B{7p              else j"W+jby SX?.ac+d.F
                 return '>';
qW3ML K8vS         case '*':
BqV[PPo0[         case '/':
wZ*k~D#G              if(c=='+'||c=='-')
qT!Pw`)d)H{Qi$Ou                  return '>';
&V(u6a {%U!`8hd              else if(c=='*'||c=='/')
j {j#j3og.?                  return '>';w(Kd"gQ{v
             else if(c=='(')H:u o0MJ'T2|]L!w
                 return '<';abKHb0f
             else if(c==')')
1z ]Bk{;\                  return '>';
7e;TY.j3W              else
(B2BGqY-W9d}1p)S                  return '>';
WSblV(F         case '(':_z]:~+zC*F F
             if(c=='+'||c=='-')
!\qGh%B                  return '<';
M P3dKe @J@              else if(c=='*'||c=='/')
zq xh|:Q                  return '<';
7rF3FO%U9{              else if(c=='(')
6b Jfp1E#v:r                  return '<';dt.ql:{~ c ud
             else if(c==')')n6fq(]d(A
                 return '=';
]bAB,GVlWz              else kT[o Q O
                 return 'E';8FN_C;R-`#U
        case ')':
tA"@%|[ _.?_              if(c=='+'||c=='-')
/C xsCM`6`mX;B                  return '>';
I!Mjw4]HW!o              else if(c=='*'||c=='/')
Lgh0k^,]                  return '>';
(OFIG%~h)u|              else if(c=='(')Q*s5Y&bzP/\)c
                 return 'E';
l?1Bv/}/l              else if(c==')')
Mk&h YeY                  return '>';|G5Lo5?}
             else,sK"Kf:]*F4IJ
                 return '>';;xR T p%?&~4qJ
        case '#':
E{H:f ?5D Q`Q              if(c=='+'||c=='-')
E:B!E |$E o                  return '<';
gmxfc9r5h'p*W^              else if(c=='*'||c=='/')#Y7W.d$`0V+K5J IW)Vw0y
                 return '<';k_*q4wX%g|\
             else if(c=='(')
Q(Lg?$W C&qE                  return '<';
u+C Zbe5E2n              else if(c==')')
I O8Fw3w TU2u,L                  return 'E';r;oT1p,l7Xj
             else
`8Dh,BiW M i                  return '=';m ]V,bBH!UA-NP
        default: oC,n@L
             break;G5@-l H7k,C;R{
    }
:i&o3X9z@%V}}Q     return 0;   
{fl/b0@)n5s F3i }
&x(z,e1_BYv&Z-F` K1c
QB/r H_0l-MV1A?`O int isOpr(char c)9l:d'z[F.K
{
4Pc6ck3v%np mR     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
_P:y7St}x'K         return 0;
y6y!q#r? Z Y |     else
Iw'k#[z#Me-S         return 1;
5Dc$T"p#VeX }
2IM8cP3S!J
Xa(_;X8Z(Y.tN float operate(float x, char opr, float y)
d:e;`:o+Cs }#{#U {
S3u ?/WOPSY     float result;
L%iKC R,^ I     switch (opr)
'UkO\ZR_     {
T'|in9i$wMc [ b         case '+':
Q8tvX M|+Wm Lv              result = x + y;
i ef3i'R'w"_ d              break;v7Z6ZZ)}O
        case '-': w5T1|P1w.K
             result = x - y;
&[ vwu"_x4E"m7|)T              break;;}:x#H'}c(r:v8\
        case '*':
1eCX%Uyw f#CO              result = x * y;
E4v;e|p@#z              break;"d|6s5Z^b2Y'X([
        case '/': ;e{4L(Ty8Iy
             if (y == 0)
$[+GL9N#t'?dB              { i9b/T'[2\z ^h
                printf("Divided by zero!\n");4\2LgA~/XV
                return 0;
'E#@#RTH              }
Mz*\7ta#T0Z              else
$|*S0uo U              {dc^M"M:{
                 result = x / y;
1oc tl7AH8eR                  break;"P|j8c%W IT
             }
b Sb cv1Q        default:
NN1wP8b              printf("Bad Input.\n"); y.La u(@h3U&}(z
             return 0;
CZ3Sx3J9E Eg P'o W0Z     }
+P9dK"z8M&J     return result;
c ^mu7n }   
SS({Q xV2| IZ _O h1cM$Y
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
j*] n&[4P1BRC*S {
9u*f,niZ B     Stack optr,opnd;{"`7KXO{6W
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;@ C,k6BV;L1l V;C
    char c;
pn ma+{8b     char buf[16];
*AwF4H?     int i=0;%VQ%Gc,_0r
    @]\*ch.R
    InitStack(optr); /*用于寄存运算符*/
q&fT CsZ ux+BP6C     InitStack(opnd); /*用于寄存操作数和计算结果*/
e|7`?:B     memset(buf,0,sizeof(buf));
Q'L7l/lR     y&HR;P+_
    printf("Enter your expression:");
^I cK)tCX+LG9n;v         8]'v3I9{r m!m0j0`kj
    opr_in.ch='#';Pzol)d bt*A3\2`
    Push(optr,opr_in); /*'#'入栈*/2Pb KC C3VO,yoB2s
    GetTop(optr,opr_top);
4AN;n3vpt8qk     c=getchar(); s `8j"]L{(a
    while(c!='='||opr_top.ch!='#')
.I,IU4c;uM BZ6tD     {
k ~!e/X,E7HQ,f         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+g ["IMm#oX{$}7E         {
+w'P s)Z(u!E'ev$O@             buf[i]=c;t;^/Z4g^z
            i++;,mP!|!cd*GG
            c=getchar();.p&y Y_ R q8z
        }
V$N%o a2y@'w         else /*是运算符*/
7u;} C$SQ)x         {
2vH@.il9qK             buf[i]='\0';
u;NMCE_p             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
K,sgu(wu%Un6}!J&v             {
$Xfy"b4[5g{?X3G                  opn_in.data=(float)atof(buf);
iwynS&vz                  Push(opnd,opn_in);H6~Ue0I0eP D[U]
                 printf("opnd入栈:[%f]\n",opn_in.data);Bl9A{'XCX U`
                 i=0;
c9V2E?u?                  memset(buf,0,sizeof(buf));
*g6L,[p:t`^             }
V'\G.P'o!_Xdv             opr_in.ch=c;
3f y!N y `.Adp             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
NFb"Xx)?8hy4mwD             {y!owN pI
                case '<': /*优先级小于栈顶结点,则运算符入栈*/p kcV3aq9k;OV"R
                     Push(optr,opr_in);
;NcM-x`dh                      printf("optr入栈:[%c]\n",opr_in.ch);7G'{4a8ig5c;T
                     c=getchar();
ve`"[4MWI6t a                      break;
;Zp+ak+rN4V M-s                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
qE\E;Gbzx                      Pop(optr,e);
%Ut1zKX%X                      printf("optr出栈:去掉括号\n");
*k;[EM!G/VZ                      c=getchar();&U"] x[h T|2j
                     break;
N xX%[ r\Iz                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
0@ OK:[:am&j!z%V F                      Pop(optr,opr_t);v1hQkU+q4j&q2I
                     printf("optr出栈:[%c]\n",opr_t.ch);4d\0BZoO s _\O&t
                     if(Pop(opnd,b)<0)
;RUqHg{                      {t h/l2]:lh#dK
                         printf("Bad Input!\n");S N)bi_z/S3L
                         fflush(stdin);
)I;m(F!dTX"cw                          return -1;a3Jm DC
                     }
7PrV gK,P"f4{                      printf("opnd出栈:[%f]\n",b.data);
#Ig$j4ME Y/Xx                      if(Pop(opnd,a)<0)
6f)j M.Kwk                      {3N B(q@^4l"}f
                         printf("Bad Input!\n");`3C"\B!@:|.Se
                         fflush(stdin);(HzrJ zC,o`
                         return -1;
S }1z R xPk~/Z%C                      }4F)iD!Vbe x5v"i
                     printf("opnd出栈:[%f]\n",a.data);
E A-jkO[                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6U7`TVJ ^                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ Vpg k0wCn
                     printf("结果入栈:[%f]\n",opn_tmp.data);
kT MD].U:@3W"p&w1N                      break;T?4J%g(u@
            }L^s7O^%eS;@mK5wT
        }_3Q(N4q AyGy
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                $xD5|2d3f
    }:[xF^8R9d%Z
    GetTop(opnd,opn_tmp);P9xeDL't)T5g!RH
    DestroyStack(optr);(T@H]S.Bh
    DestroyStack(opnd);i0fno:K W*a5G0A[
    return opn_tmp.data;
O*L1~!QR*GXJp }4G1x/u&pIQ0u

5|]pO|L sn char *killzero(char *res,float result)5BDf(u zHPX,a
{
jz C#w-iNb     int i;'R+g[&ru
2s2uJ^8q0O#zo9ar
    sprintf(res,"%f",result); o)R | HY
    i=(int)strlen(res)-1;
7?)s`gW|'O     while(i&&res[i]=='0') | r(g,G3S IG
    {,b Hl\E
        res[i]='\0';
dD k!D KQ(B         i--;
*j&W`4w$g'l5X     }
#Cx SVs(dG     if(res[i]=='.')e?)_x0Cw'f,x
        res[i]='\0';
K#x_,K+@9Da0{     return res;D%F5C$y(e*Y
}
Bq(@JCtw
,S}#?*[ c7FU+h0Q)? int main())y4K"{_tT/co$pz
{
-MqP"u1e_     char ch;
u6Y g&h!UDW     char res[64];*wm lP*X4vbjp
    float result;
0\.dN,om7t@X     while(1)
3V:o&j |'m4dx-vA     {0_2No['Z0T-}T4u'T
        result=compute(); eJr*|3|uh%[k
        printf("\nThe result is:%s\n",killzero(res,result));
t?0cu/G9{         printf("Do you want to continue(y/n)?:") ;/L4cft#Z
        ch=getch();
zh/YC&x+f.b         putchar(ch);
;x ^,m6kk-B-k-FD         if(ch=='n'||ch=='N')!n[D#AJ zmWD
            break;9Q:t'rN2l y;[/Z
        else.m-t+v[T_3J3m$g
            system("cls");
U E&E%S6uo     },_8N0dG#~7\3UH&zd.G
    return 0;
2Y IyF`w }[/i][/i][/i][/i][/i][/i]@:tM^9R-B$e

+BR8T.TV^|n [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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