捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.7Q3n z:\S [U+s!W
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
l)^ F(N0r5yJ /**************表达式计算器************/
C S.J3`#r4\gBf #include <stdio.h>
&r*kk e P7}s$P #include <stdlib.h>
3J|)l4j%|.l ]R:^V #include <string.h>Vh&Q H9q;b
#include <conio.h>&{}d9x'la$U*~F
#include <malloc.h>1g:{L.cS\w C1v

)gDm6S3KY*k #define STACK_SIZE 100!x`_3}^+k5n.w
#define APPEND_SIZE 10
&Mzw+KDV,e
/rk-r k@E{ struct SNode{
L3]i'xr[-[A     float data; /*存放操作数或者计算结果*/
5q#FGkBxI     char ch; /*存放运算符*/)|$kk5@ DF7y
};DL#y(_ \8s&x
R+Go Wea3s
struct Stack{gP3V-\;w:?*^)@^
    SNode *top;
;j5p9ZcbL-?Z     SNode *base;
{/]i&M*e     int size;
Rb,T(T%wU\ };
6hz|5JNz2d!G0d"W C!vj~6g/c^L&{)TS%W
/*栈操作函数*/;S*LcMB5X!Im
int InitStack(Stack &S); /*创建栈*/
N9XC?HP int DestroyStack(Stack &S); /*销毁栈*/
EAB R+i3g"? int ClearStack(Stack &S); /*清空栈*/
4D LN}u0vA int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/8j \wa9A*H7X;{
int Push(Stack &S,SNode e); /*将结点e压入栈*/5z ~%zmb"N _CxR
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
K:u7]6J!X :kN/z&f9_v
/*表达式计算器相关函数*/
6ZGQxD)qH y9Fv"]*F char get_precede(char s,char c); /*判断运算符s和c的优先级*/
8~8Y`||7k6nX int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
?t)Yf3j#W float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/k5JvF {rW
float compute(); /*表达式结算器主函数*/
O2njyi-cp? char *killzero(float result); /*去掉结果后面的0*/ 'xFT'|/Xb

9X1\"U@#n@ LnQq ^ int InitStack(Stack &S)
zq@6j*l8V {
ts&E#ld'}     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));Z q+hw5S'[
    if(S.base==NULL)5B:aY HuV$K}d
    {
]2D4W%D2rnx D7L         printf("动态分配内存失败!");
_^8okn QTM?         return -1;(l c.zaEl0B!a
    }
*aa~+kh TvyF3b     S.top=S.base;f7_ O*CN.\ P@
    S.size=STACK_SIZE;{ Jwz3A.m&?"~$t
    return 0;wM2d!s7CYxE
}
lBN&~se`&z 7F6@G w'i:\KH RC
int DestroyStack(Stack &S)
a'I-V:K`7^ {$gGx#l3W
    free(S.base);
9VTMV.r@ZUs B0Go     return 0;O'_8?5k CzL
};K!god je z
E$n+c8r_ `w@I
int ClearStack(Stack &S)
k w\Pj'l|._ K$k {/^Q+B^3P:N.T Ht6|
    S.top=S.base;
,HJ4B)m"z"_]     return 0;
SMvV#f![ B-c"lq }
'PAn.~:S `h'{ZD+P )C6JVN_"O5`(R
int GetTop(Stack S,SNode &e)/t4MIKJ f:B
{ }b8fG^ C`Z
    if(S.top==S.base)
VX%\/JW1K@     {
q1OqFAB1k f         printf("栈以为空!");#z;Q!Iq'x*c|
        return -1;
_'Wn0v2ds     }0P_%D2b0}*Yeo;J\y
    e=*(S.top-1);
a%Slt1S BP+T     return 0;qWpA3{)pI3Q
}
xRWs JtE8z@ Z *N7n R\ r f
int Push(Stack &S,SNode e)
$t}Q"@*\ {.FqN'P'R!j$[
    if(S.top-S.base>=S.size)
9Z4KC4aW@2k     {
Tu:MF j[pr~J         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));S'~)gq6k
        if(S.base==NULL)]K-?MJJ"q7q%o
        {
Q |L_ ]&v%u             printf("动态分配内存失败!");`(y\2}!Q+G+y6f
            return -1;
EpTj^+YB         } IY Joy c_C ia
        S.top=S.base+S.size;U2B2f2lP
        S.size+=APPEND_SIZE;
Wym^CZk     }
#gcWQ*B ?     *S.top=e;U$K \M-Z}*OXJhx
    S.top++;mPy }*gl9?
    return 0;#s lz:q7jS
}
c f:h/uHMC0@
@r CN9n%pq int Pop(Stack &S,SNode &e)
,b%HND$~ {
)rZ8N"Z q p     if(S.top==S.base)dw.t6Q ]RfK']M
    {
OZ~$VSq? R         printf("栈为空!");
!PZ'i e,OsK         return -1;
5Y V9a/^#zrm     }
zB7kH:mc9dI     e=*(S.top-1);
k%Kp m&L;t A     S.top--;H O AP-z
    return 0;B |0z1P7kp:Y'c8^
} XO)v'[;c

Dhv7Z+w char get_precede(char s,char c)4m#ql _^T
{ya,N iV+lU3uY
    switch(s)
Vw C&B8oT B1Qj,}     {Z;|)aX^ `|e
        case '+':                 g(E E5jK6Z4Nvt
        case '-':#SG M {ys$N(v_.?/cHO
             if(c=='+'||c=='-')5c2Z&}*KH/q K
                 return '>';,Z}EQ%eB1[$t#}O
             else if(c=='*'||c=='/')fw0G1P.}2y
                 return '<';.aD.v]#SB9X3{x
             else if(c=='(')
E.N _A4sAl7uY                  return '<';}`9T$W.cS?
             else if(c==')')
1CD$n{;U                  return '>';sjqAT
             else *^C l B @7K.z`
                 return '>';,E X*D$j;e
        case '*':
(f+S"jA#NSz Nt3t Gy         case '/':
,]+V!lpk XGj              if(c=='+'||c=='-')
tQ)DD}^-W                  return '>'; P+]5h%IZu
             else if(c=='*'||c=='/')
A+Cs,a)o&t                  return '>';
qWE!\3hd?              else if(c=='(')0d8nX!Ug:z
                 return '<';q9e9s z1o+E
             else if(c==')')+r[#X6tU5[
                 return '>';7] s3LMqHhW6t
             else
%~~%?S]{                  return '>';
#y!QWUx7y$`$XdJ%{         case '(':'A Y'D2Xw c#XD
             if(c=='+'||c=='-')
J#L(A}^Q                  return '<';$oQ$roQ"uh
             else if(c=='*'||c=='/'),VA*DABZr
                 return '<';
0xr qLj              else if(c=='(')+d"Z*L1CeQ
                 return '<';
]:k{w\9f\n!{2A              else if(c==')')$e;Y9yB)R
                 return '=';A;Z? ?(]
             else
)p1G Av,C                  return 'E';8hW5S4O2pL\*u
        case ')':
6C7IJ7]\Gs              if(c=='+'||c=='-')0etV4Y1pB Tc
                 return '>';
B }p!mU              else if(c=='*'||c=='/')Ix!]vu#YL
                 return '>';r3Sv:RGoUmt
             else if(c=='(')
} Ry*pr&QI]                  return 'E';
xo+W.kqKW1mY8P              else if(c==')')
5?*T:oU;`)m!o&V-y Ib                  return '>';q3W X#Cc
             else-{*Q2f:z5|y z^
                 return '>';
}-A*[9U/f}8}         case '#':
#s;T$u0syu,Yvf#V              if(c=='+'||c=='-')
0TyaD o0m#yG                  return '<';
g$z"HGy;H]              else if(c=='*'||c=='/')
K LN @%Ty%M~                  return '<';{]9H(e(v*}"K3vZ
             else if(c=='(')
mDm9Q9UY)@E                  return '<';hP.[I B
             else if(c==')')
![p5nfVSp                  return 'E';
CYf&~kz N              elset}8rS!}5f"Kv#y,rw%j
                 return '=';
q~:ue a'H)U         default:
bw"@IX8T              break;
0]J'i$cJ]     }I%N8leH]/P4}U#u
    return 0;    %B/U(O|&ag{5r
}
!gr#c#]HX
3ks`!~Y1OT|4]J int isOpr(char c)
|[mk X`ZmV8H {
.l'HhX:PH7]     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
~1aq%kszc         return 0;
9d7cg,y&^;}     else Xlm'U}a@
        return 1; K8F9mvdq/O2`
}
aa;Z&P|hC@o%fQ6w t k-dy_;\~S4o _
float operate(float x, char opr, float y)
F%q ^W5RA `4S {@8FDS m dM]
    float result; [#`Np"x\;|
    switch (opr)WH3{]b J9}
    {4W4y M.p N
        case '+': h"U5S.DDQTa:w&A_
             result = x + y;
^+?F&N1X+B              break;
%PR|"}$G'h9t(u         case '-': s3QdDe)GN({d
             result = x - y;;Y*UA ]^x bQ
             break;#zoz4C'jV_
        case '*':
jt+r-u8t B,[/o              result = x * y;
`|}L'x,}M              break;
+O'^$m9MbJ [N+Zd         case '/': j_&Cj_(kH4^
             if (y == 0)DrrpC,V Wkv.Y
             {
m.t TO-eP7v                 printf("Divided by zero!\n");
)z.[D]B.`                 return 0;
xA;b,[A&}#~ i"M              }&C PGWh(B"l8Bpk
             elseZ uw2m\[ q8f$Pb
             {j+VM;fPc5d2p8eez
                 result = x / y;.?z}Z0R
                 break; ^ Mja%f{6BG
             }
"BewP:zT,P#e        default:
U0z8m6G(C4Dz              printf("Bad Input.\n"); }[4y \X0k*t1y&\0Y9c
             return 0;
v p*k xc%|     }
?'Oq2?YY     return result;rC5@G.iXZ-M
}   
u Na:J @#P+M#S-f Wl*@-K3f:a0zH9V
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
V~A,F Zv {
P b dTX%P8GW^Y#I     Stack optr,opnd;4f5RrY(l4]
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
/RzI"PS3z.v MD$g     char c;In u2E#M'~l
    char buf[16];
r(S#]G1G'I.W6g     int i=0;Dw+TiB8dNm{
    &OQ Mp6S't:X
    InitStack(optr); /*用于寄存运算符*/
w${:ZY.Qfh)Fj9E     InitStack(opnd); /*用于寄存操作数和计算结果*/
j"w f\X"avY     memset(buf,0,sizeof(buf));
zG)cK*qj.Z:t    
~1S*a r7k;c9vB     printf("Enter your expression:");~a jdx.J1[S
        
i Be\P k)?G4f? C     opr_in.ch='#';
W1Ju:BM%h8m-p8Bv     Push(optr,opr_in); /*'#'入栈*/
x}:N$`,?P     GetTop(optr,opr_top); B+B;L/t+xb T)M`7l&~\
    c=getchar();
:rlQ {*|2mw     while(c!='='||opr_top.ch!='#')Rl*{F%i,V3w4q#{
    {
}e4R+mM\~0L.l         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/c7D7]D#}
        {dO \"d+[k)H3C] c%cBi
            buf[i]=c;B[2W&go8m9]['H
            i++;iETzx V8g6E
            c=getchar();
,R@#Z!Qh)L         }
)\H4\&lT         else /*是运算符*/4V)O'f O8Rxu T`
        {
MY1bS8A"{2M             buf[i]='\0';vs k_~4E;SR[
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/H^ `H&s"AE
            {
} I;qHlQ@                  opn_in.data=(float)atof(buf);'y Rw q f
                 Push(opnd,opn_in);
d0D:A,?}3j                  printf("opnd入栈:[%f]\n",opn_in.data);
dfzs^Q`@O                  i=0;5\`0I5f6cK^f
                 memset(buf,0,sizeof(buf));f Z!RDe pU
            }
Z+?eu;g$eB             opr_in.ch=c;0}CN`qL)r'\O9g
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
7M"H*X3uq"v             {1dy6y1IZT
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
_lSl!CLui/IQ                      Push(optr,opr_in);De^ta4o k
                     printf("optr入栈:[%c]\n",opr_in.ch);BQo0l9i j-A*S*`d&k
                     c=getchar();s Ci)Sj;F~U
                     break;GG| O&Gh'E;i{|7dc
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
us1t@([.Z w%a"^                      Pop(optr,e);
@SO.} f1F                      printf("optr出栈:去掉括号\n");
7pu)uz.yjZ                      c=getchar();
;qt)XmG                      break;
%V,U2E1xZ@R;`                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
*rR(l+X;[B!A                      Pop(optr,opr_t);
e*X.y"o}MU [                      printf("optr出栈:[%c]\n",opr_t.ch);Ya;[XthC[
                     if(Pop(opnd,b)<0)5g&k}g%LR F_
                     {\P-T.r`^
                         printf("Bad Input!\n"); a2xIc4}/V
                         fflush(stdin);
V g'u5}U(e1M                          return -1;
u;i n Y$z]K!uN                      }$W\"hm:d6bWq,r
                     printf("opnd出栈:[%f]\n",b.data);&a@/u:\tA
                     if(Pop(opnd,a)<0)7`:l8_U R'}:{ Q
                     {H+I.~E |_4U
                         printf("Bad Input!\n"); X0B1jfH { v
                         fflush(stdin);9z+WU x5d j2L\
                         return -1;,~Vq1HhZ$F7vj `M
                     }z dMh:q${
                     printf("opnd出栈:[%f]\n",a.data);B%b&`;__r
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
w6vv v5qb-v#~                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/v*O1Vqwv n
                     printf("结果入栈:[%f]\n",opn_tmp.data);6J.[3w6D5I)~d
                     break;
'iT)a*{'G1Me Z             }
aVx6w8Q%uN1F         }V*Xg^R k
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
/a7E%[&e.kE     }3}5}v6QX;CO3f
    GetTop(opnd,opn_tmp);B9v^8RY#Z4Q
    DestroyStack(optr);
r)a:v^$[ P7@     DestroyStack(opnd);H ]7_h g/|0b'D_L
    return opn_tmp.data;8bX]2_ men
}wV t3E\.n

,IOB}P1|1x7cM char *killzero(char *res,float result)
1VX5}D'Y,suc;t6H {
.`G1`w)M1L!D#LD i     int i;
5A*fB X{5}
?1}rK ai     sprintf(res,"%f",result);
6o"DhaP4e.}f     i=(int)strlen(res)-1;
6?~v@-r"s _4m8A.X     while(i&&res[i]=='0')zu"H6Y U
    {
lw;px'E         res[i]='\0';
&es#q E e)?PKJM J*@K-o         i--;\Z$zP \Q1@~ G
    }r5v@x(p
    if(res[i]=='.')
"_&V,A/w(i5e#t         res[i]='\0';b&B+P1niq4H
    return res;uY+SxG)t
})K:JO4jK q3O3PWY.^

*MW SaV/X int main()7Z1m(D:Q XI+Fy
{
5C H;y#}h.Ie     char ch;
&X.e;s Nu8c&o`     char res[64];&{]"N%Tg%im"?IA
    float result;
,ia7K#dwM     while(1),u/`%zjg'e)M
    {
z:uOEH!L"v         result=compute();
} o${8t MsgK         printf("\nThe result is:%s\n",killzero(res,result));y7m7_[!Q&A \!WX
        printf("Do you want to continue(y/n)?:") ;
9lE{-}aM         ch=getch();
3Is k0R-ca"Q9qI         putchar(ch); ^bgu.uUC
        if(ch=='n'||ch=='N')
hI oR3f             break;
,wqr!w;i;_%K1q         else je U'e%n4P+Tq2b1e
            system("cls");
6Ec*];VhR     }
jk.H"Hjst     return 0;o,m#C*A["Ik'S"tA
}[/i][/i][/i][/i][/i][/i]
Qt"z s o-B:A N`G 6]/c I*uC DD
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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