捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
f7`2A(Z1C#eOx.I 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
g xkv3Z.`|5a /**************表达式计算器************/
$gGMX w #include <stdio.h>
7G']#E&O;uH]%g |j #include <stdlib.h>%n+F)O IkV}
#include <string.h>&[CWY:s k#nz{"R
#include <conio.h>
&G;Wz@J!? #include <malloc.h>
Y nIaif.d
/aCy&s!lt:q #define STACK_SIZE 100
B w-r5hJ~6o4Z3n)L #define APPEND_SIZE 10
UlI)K.m6|c%J:B {m 7A?C"u7frq
struct SNode{
'q*y4t`fu     float data; /*存放操作数或者计算结果*/3^%J&S N"Q
    char ch; /*存放运算符*/6e1p_5]+@"f"I t"@s7e
};
6cJ(co wteFd'L
JQ d4Bn struct Stack{Y,QB Xd"s
    SNode *top;} V }?+}|OS
    SNode *base;
5z(kll0T8`     int size;@Eq$R\+L
}; _!d@ GP d@
Ll2eV&S&[ tZ;V-j
/*栈操作函数*/'z/Q[:_v
int InitStack(Stack &S); /*创建栈*/
@[L3y ts0~.|'a int DestroyStack(Stack &S); /*销毁栈*/
Q ^.miY2z Y int ClearStack(Stack &S); /*清空栈*/
s4h0Ts*_.xkt int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
d;N}m8\#^ int Push(Stack &S,SNode e); /*将结点e压入栈*/b2U o_y,G
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/%vr W!tX0oDz?$s

*Z `H|&X[0n /*表达式计算器相关函数*/
7QZ5U9Ve;P:C!^ char get_precede(char s,char c); /*判断运算符s和c的优先级*/$oR2tg.}5| t
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
dY V@s-k&S float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$w8q#J#U9a\I^9Y
float compute(); /*表达式结算器主函数*/K$A'ru gh6|5^t_
char *killzero(float result); /*去掉结果后面的0*/
p/lIr+a*t^$I {
B/Yr@-~+Js^ @@ Y int InitStack(Stack &S)
5|P"NK {:?/~|)s7@ {Tr5g_]'lm:zP1Q
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
Ap&?"kY     if(S.base==NULL)7JNL!LuX#n
    {)d t$F z{W`
        printf("动态分配内存失败!");
2m9R@ OCrRH;n0I,} J         return -1;M*l`8zhm!U
    }
[]g"Q~     S.top=S.base;
.l%k6H0iV&}     S.size=STACK_SIZE;
:gu};u$G|3]j+Y     return 0;,r)SV J;xc"^7dQ
}
%n*gNB Z(m/axZ
GX8I4w-N8n(R int DestroyStack(Stack &S)
IG s a%G,n Y4^ {
M[sfg&H?"f     free(S.base);
*\ W/W:YgGwXV&F     return 0;
U5]q2Vn ^ }|$Jeu6O/|L!SVE't

3A)HLoL7U|lF int ClearStack(Stack &S)h/W&M1O h0_b/H
{r#UM7Ug }8gJ!S;W8Hv
    S.top=S.base;;W` iI#\b3\~
    return 0; ss?r?~:_.dG {
}
`olb]+f [tMC&E l"b
int GetTop(Stack S,SNode &e)L(FN&t8m t.c4{){
{
"g mf[U/h"A\S k     if(S.top==S.base)r z1yd:TTu
    {
f6e'C\;MF}         printf("栈以为空!");
X0m7R*^ `0[ @3F8gg         return -1;
MM7l,|#AVX+v     }
ehQp `f z I6S     e=*(S.top-1);Z_I6L$O/qig E
    return 0;
1H1?&Wr-on!n&r },Nb3q(ZNKU0J*A_,j
5L7CO$Jx)T'W~
int Push(Stack &S,SNode e) G3P*w]0a8t
{
/e1Y ?2O!p     if(S.top-S.base>=S.size)
S-G+q3SEt     {
#gd4Y!l)~8RV?         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
n6m siUQCt         if(S.base==NULL)_`\ OjVd I+TzO
        {
-w4jQ([+k$o9i2q             printf("动态分配内存失败!");E5R8dz~ j
            return -1;
(n7KA0Fgf i"k6OD5f%k         }d2c4o!{ H7GUdS
        S.top=S.base+S.size;(BT5FmU:C]-|fxz
        S.size+=APPEND_SIZE;'f`3fzL^#iI"x
    }%r;o@P%Og$u-E g
    *S.top=e;
fVS.n Yp^3q:K     S.top++;
o,Vm1F#d| FAQ     return 0;9o(P'{#r(o0W4d
}'E5r)`?2yMX
e2]H:U2n|B"s*R
int Pop(Stack &S,SNode &e)
~ [1V&F(l {
m%H4d*Ab/PW B"a9Z     if(S.top==S.base)
%ww!c0`z^     {-x9s|9U/a(b9I
        printf("栈为空!");D.D oQw;]c(I
        return -1;I TfpH3`u/Bs
    }
k$G f0`w-L/j%Z\     e=*(S.top-1);
[(T @Q!hkj!J     S.top--;[`P)Qd^s
    return 0;N XW:_7RM
}
9a!k ysI.m!X#JC
0OO6fhC \evd char get_precede(char s,char c)*`,U5x&c,ia6K9s
{\ cL;q2V`b"E/|/i
    switch(s)!`)V$[~(b
    {
bWZ\ p)vo4Ld         case '+':                 
mot[ci"E,h$V         case '-':
q.w P&[4P SD-V d              if(c=='+'||c=='-')
X fNN:s3i                  return '>';XClZ1jy$|7A
             else if(c=='*'||c=='/')
!I0BY6q N~/cX B                  return '<';:@!l.h k${o,g
             else if(c=='(')
4uj_`y3NiG                  return '<';
qP'|ac"VYK              else if(c==')')
;t^$D|9q(eP)o xv                  return '>';
q_9F Jr              else 7I:F[UKvsP/A#x9O'c
                 return '>';
rQZ;L&?         case '*':
:M j3m|)P5D         case '/':H2`Q?3M3X
             if(c=='+'||c=='-')
|vi ^'Qj r                  return '>';
7pp:ms%f$CWx Z&jm'[:}              else if(c=='*'||c=='/')
q5eU5~(r0xiu?                  return '>';
aD s#PGa HVCe8A              else if(c=='(')
_-Y:tpt3^                  return '<';
4sn!|H v,Q6k'n              else if(c==')')
S6| Qlo                  return '>';II JwzW
             else"q*`|VY bFP8T
                 return '>';
o4Y,]i z&xIKO         case '(':
*w,wtNH)E              if(c=='+'||c=='-')M Q [VV r:U7ZP
                 return '<';Q"@8]+r._+S@ z"|U
             else if(c=='*'||c=='/')
uL0p NE1n!U Wg;w$t+[                  return '<';
QSTmyKwWq              else if(c=='(')
(b!m(tC2{p8X                  return '<';
z#[1kB6|0^g7`              else if(c==')')`6]jtdt UM%H
                 return '=';
}t'ZM,V,`a mO              else
Vt`^U;W)z                  return 'E';-_o2z"_s.T?1Q
        case ')':U/h%t#y,A_t4~3I
             if(c=='+'||c=='-') @/n0f4_l+d
                 return '>';
N"u3F-vS \ R[{              else if(c=='*'||c=='/')
p;a]*K8cK*O                  return '>';
WPg {#K              else if(c=='(')1U#?bd+ewce1EI;E
                 return 'E'; w} Vr9Xa'eha8Y_ J ^ e
             else if(c==')')
:h5Y Y}7k8fM                  return '>';
e~SQ'g@              else
\YM(\{(F)J                  return '>';| Y;d0` r3v
        case '#':%|LA[)BW|"p K
             if(c=='+'||c=='-')
{&c2sJ;R6UR3ai                  return '<'; [1Z}j5Y!_1]F]'F
             else if(c=='*'||c=='/');YL9mZ&d
                 return '<';
H'x+Vk0|Q }X              else if(c=='(')
(vvy*U*UXym                  return '<';-t)U,T?4Er0Z5{;~
             else if(c==')')
1R~OU!P'U                  return 'E';D4_WI\3Z9m)?eB
             else
t^3\"N-AO R                  return '=';
UTV/ApV5w%_ w1t         default:"P$Eyz f&c
             break;
4G(u*sl%A)G9f4[}N     }
?~^y#eQ Pi     return 0;   
C%O%CmF3R]9g }5aR]#I?6h)D4r:O
1W8yv:x7_N zR
int isOpr(char c)
/F,].Y`? A:X$L?K*u i { ]-i5|7Er
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
*s1V+Y(|G5s5FyS         return 0;%vlE9f[~.aVc/t
    else w)|?+y:L|Ka"D:B
        return 1;u]/qj~9m
}
;t[kQ-O/?r QjK2v|$U-F
float operate(float x, char opr, float y)I W Sg+D'C
{6?La.J'kO
    float result;;eJ"f'N8v8gI
    switch (opr)
D8u7Z/b(w#Wn     {5A4JR5Q:n
        case '+': 0z/T I(dC ]
             result = x + y;
bg4N$l }8?1xI4o5Y              break;
c|!p^ b }`/R J         case '-': PK[D-T7?,C`
             result = x - y;
q^5]#A1KPHp+P$B              break;
2K2|zst.j         case '*': _3oDW%Ay4yb ?
             result = x * y;*b!Gr [8u"JpM
             break;
d%G%Va B8@ z){4a         case '/': #e#\7kx1JH
             if (y == 0)
.A.x-QJ&a+n              {P"x SH\}6X3Ka
                printf("Divided by zero!\n");
| G l n C;a                 return 0;^]FxV0L2g/}
             }*n6dR f"i![
             else
3az[G![              {
+ak~ E/k:zn                  result = x / y;0yf5?i!w
                 break;
mX!RF ^~^              }6O;\0^6K @4sLl
       default:
VJ Wy3Y0C/}              printf("Bad Input.\n");
9A1w;{%U8a w0~              return 0;
n VT-|3c2s r     }
6TFu2V7d {     return result;
P-fA)T-j@3W:R }   
~\N+]1o%Tg1Q5Zs M i^B:V3l;SK
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
E?_C!z$gJ {7N$H m(S y])V
    Stack optr,opnd;C3F{^N3@
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
jg(ep e0U     char c;
c[+D2A g     char buf[16];.ccg#gVm
    int i=0;8QtM2HwJ
    #S+ATl+f3mt!|
    InitStack(optr); /*用于寄存运算符*/L},LmP@{ c G2Q"k
    InitStack(opnd); /*用于寄存操作数和计算结果*/U.L X r!E9R/X$a
    memset(buf,0,sizeof(buf));
3X(P:^!So~w(jt    
R)zE`{     printf("Enter your expression:");
~Q&XI!W         
/Nl.vPB4D     opr_in.ch='#';ad"xs5f8Q#@^
    Push(optr,opr_in); /*'#'入栈*/f j{*T$\&|Q
    GetTop(optr,opr_top);
UKro_3J:b Tw/W     c=getchar();2EI^1n"m` n
    while(c!='='||opr_top.ch!='#')
(P;o|(t Ss M,Q F-{;Q#sI     {
'}ZW-Y/z         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/+v q6\)oGX%t&M
        {
BzlTIu1|'{7Q             buf[i]=c;
ujkzJ$F+S             i++;+^I,z4K6a@4I!Ku
            c=getchar();
a4f0n `*Pw%\"X         }
w&s r;WSu ML O         else /*是运算符*/
B3q"`.BU dT         {
^s'a _x7n8t B             buf[i]='\0';5Ab U&EskE'k;a c$L
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/n-T$H4]3A1O(dS
            {'lm6I-q K2H x
                 opn_in.data=(float)atof(buf);
$YQ5D|6n;rj0d [                  Push(opnd,opn_in);z @.ht)Qt
                 printf("opnd入栈:[%f]\n",opn_in.data); ^9LrxL!n^2a+E
                 i=0;l-H*@5RK \O QE8g9\3^{
                 memset(buf,0,sizeof(buf));
3dAR5q g;@             }
WpurJ/Eq0^sk/N             opr_in.ch=c;(B.Zgj#Q*W`b'^0P-_'R u
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
%DY$_M8i'E1?n             {
S:In'\7gL b                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
0K?7bt7oK!r}                      Push(optr,opr_in);
3_)_m Fq'^ @'L                      printf("optr入栈:[%c]\n",opr_in.ch);"C6].o6HG Z7Xt
                     c=getchar();
2^(P D%_*c/e5S                      break;
)i"w*}&XI*_.C _ K                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
:C/})A4I+G\ i3`;K)K{2x                      Pop(optr,e);
*p MB)@k)Gliu[                      printf("optr出栈:去掉括号\n");-a;A+CB9m5]#k.Uon
                     c=getchar();6f5b%M oW$@$sH3AS
                     break;
r Y1F0@1feO                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/4HwiI&J4y%D$yM
                     Pop(optr,opr_t);
3z9Xx4e`2h                      printf("optr出栈:[%c]\n",opr_t.ch);
'KN[.da3`m?4M{O                      if(Pop(opnd,b)<0)1W%CdAQ$b*`N
                     {\*k-r1c|"u)j'm
                         printf("Bad Input!\n");
g%D.uG-D9s                          fflush(stdin);
[5v lV#ZrY4@                          return -1;vk{q7NgY
                     }
;c@4Dv-JA~%E                      printf("opnd出栈:[%f]\n",b.data);
\V7edz#RiTd-h)e                      if(Pop(opnd,a)<0)6@.CW2W q8L9EB5@
                     {.ryX)K/X\N
                         printf("Bad Input!\n");
+T$~ t,F/R6er                          fflush(stdin);s:L0oyxkLl(z;hQ-w6?
                         return -1;:C _T+h.@1z(em
                     }
BR-KOuj                      printf("opnd出栈:[%f]\n",a.data);
9fR(F t;\ wz                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
vZWn%U {O                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
U,q*\D+fj,OB                      printf("结果入栈:[%f]\n",opn_tmp.data);$co T o#A~
                     break;$Q;qh/F Y4v
            }|U;?7lT]
        }6jQQ3}ow
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
lmo3V x1dV     } F t@NK
    GetTop(opnd,opn_tmp);(e?F'Ng
    DestroyStack(optr);
coa9}Kl;n     DestroyStack(opnd);
)F;J z LZg[#D$L,pY     return opn_tmp.data;UB3G oj0D%Mr
}
U hh@.VKS pr*m7r,E1CT
char *killzero(char *res,float result)+n2R5i*O,i6iZi'\V
{_~^:sl
    int i;.Mn!{.Y/q

1X*U$` n2Q `| C     sprintf(res,"%f",result);
nr@ RI     i=(int)strlen(res)-1;
0t5c'G6J.}6r(A1Ma     while(i&&res[i]=='0')
#`A6{z&T9qO     {Rj;H l4Y+It-g6}E
        res[i]='\0';]!yVHH7t(I9x:p
        i--;
6{;l1f2](z:b     }4y6U@ PGq0J{
    if(res[i]=='.')
HK)uc!G8n         res[i]='\0';
\'K C7P5b.h ~ [,E     return res;
$s(II8|)X tE2AD0z }
3\:f'fb fS ^pn1? A!arx
int main()
q%P@5`%KVh {z:{!R)sl4o,nM
    char ch;
;Y_jZ r/m     char res[64];
'KY#IF&hCK4D3[R     float result;$J7r};`$r9V8@6f4s
    while(1)5z:q"@*tv3CW'_E
    { B9f8_"esQ4[0X]3?-S
        result=compute();0oJ Z.@:J)m N Z
        printf("\nThe result is:%s\n",killzero(res,result));
7crT$r;lLzx!y         printf("Do you want to continue(y/n)?:") ;0u D#G`c |lrLzs[
        ch=getch();
6W:d'EJ { C         putchar(ch);V YA`-T ] X&x2i
        if(ch=='n'||ch=='N')K BF_$K
            break;
'U!hK4v8uV1MUY8Y         else1T3nQtjK[2W9P$o
            system("cls");
9be#F2yV6D yk3g'i     }Cv};x.w/W
    return 0;H0A_HN+U
}[/i][/i][/i][/i][/i][/i]#FTk:y1c

6{T*P @:Y6Qr-x [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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