捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
*Ji|5bna)onp 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
x:EK$ds;y6f8N /**************表达式计算器************/ E+y:t!dvgz ~'h/L sk
#include <stdio.h>
,_%z3n)a Q1C #include <stdlib.h>'g9^9]n%Ya
#include <string.h>T'F`1ly^!za8p
#include <conio.h>
Q{9J+P)u/J*m9i #include <malloc.h>
UjU!otw
#s!V&^Q]"~ z \ Sv #define STACK_SIZE 100U)~ ?*ud[
#define APPEND_SIZE 10:I YE0D3i}1k

}o'W.DM ? @3|O%y struct SNode{ @.CJ M$^ j!v q
    float data; /*存放操作数或者计算结果*/
/[*_+m7h*Yd8k*o+tl     char ch; /*存放运算符*/
oh tZ&V };F\|2ep-k8e-|

wa#_tG vk$GO struct Stack{
?6J8jO Ud1v5wO     SNode *top;a9~,g j%m_ h'N;T&b
    SNode *base;
4atLv IR.R V     int size;)y"tX4|N~E@K
};
U0B)`u'y.vLD
,M LZmmAx{ i0f /*栈操作函数*/Q.FI+bYQi+k){W ^
int InitStack(Stack &S); /*创建栈*/
fbUS*t0P int DestroyStack(Stack &S); /*销毁栈*/,^S+k"Aas"A6_
int ClearStack(Stack &S); /*清空栈*/
`jXR\ab int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/%~-H&r&gy3O$U:}l)q)E wZ
int Push(Stack &S,SNode e); /*将结点e压入栈*/x1I*r;L \
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ m,^6e.x4c r.gk

]h"f.ik{cY:zw /*表达式计算器相关函数*/
co~8q4_W+G char get_precede(char s,char c); /*判断运算符s和c的优先级*/hK y q|eo/Hr
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/Lv GC2[zK$Q K
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
h2U D}9ERo float compute(); /*表达式结算器主函数*/
2j c6f2U%sb char *killzero(float result); /*去掉结果后面的0*/ ceSE z8~2~H

3a9`c4|aG [js int InitStack(Stack &S)} Cr+E [Z6Mc'q
{
6d2?c-C3}!]Mb/e     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));g$}PZ `.X}/~'C
    if(S.base==NULL)
{u hFxyAAz+OX-J     {
(uB@*k E:[%@ ^&bU         printf("动态分配内存失败!");-w#dEKq;HTlm;E
        return -1;.JM:wI6K-C
    }c-C b'B.}G8`+W)bN? p
    S.top=S.base;
n}-rdz     S.size=STACK_SIZE;#L'a&Y~+u
    return 0;2vM7Q2Gq3[ {0} Z
}
IeK"i^ X7e] _ts*Y0k3Z.YW
int DestroyStack(Stack &S)
P)rZi#Uji@7{ {#{6X D&IvI)[ Xx%l ?
    free(S.base);
X[)XPD_     return 0;
,?N#nx,KI6eZ%R'tS{ }
[z'U3n/i'`Q
.~1S{ { {PPW8_ int ClearStack(Stack &S)
3B-VH7sun2JSI { Gz4U Ko
    S.top=S.base;U)c#GEy"q
    return 0;
N ?"M{b XGVi }
,U4plbS'W _y e:@/_fF9]w
int GetTop(Stack S,SNode &e)
a_.GK!`iN6S {1bI zz/B'\;r
    if(S.top==S.base)
'nVJjU     {E ~ h+Zt U"k
        printf("栈以为空!");MD*BD^Jc
        return -1;
4BJV7h+G.vU     }
2TY2e(ud&['rPV     e=*(S.top-1);
P7T~1}^#|(hvv/E     return 0;
t1xj4w tY5v }
5U!y G(au4d4N @3s~#N n*WC,g
int Push(Stack &S,SNode e)
K3D6J'_'\@)f]s {OT1Q'X \XC%jy
    if(S.top-S.base>=S.size)v M*{1wc)aM
    {
_Rx(~ fq R         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
v w*lw%s&?-O         if(S.base==NULL)
C\B Mg5}GRH         {
UbYzzs q @Y             printf("动态分配内存失败!");3W#lQ;q0xBgPZ0j
            return -1;,Q1}G0Xh4c\9f\
        }
oZ#L8p'@         S.top=S.base+S.size;
9nh1~OwvfO-_0h T         S.size+=APPEND_SIZE;
blZ a Ql     }6O8f2c{0fd;er
    *S.top=e;
/\GY:_ t     S.top++;(p$kW v9AU*z%n!X
    return 0;!V;l6E_|f
}
c0zE2dAF
[? H*puXeg!ehV B int Pop(Stack &S,SNode &e)a1UAuA.l(@
{
.M7`7FUBM*l     if(S.top==S.base)-EX"jC j}
    {AwM V!u
        printf("栈为空!"); e:R xcK
        return -1;
r'[+gB0Cv7nld     }
(H;M9x%D7[     e=*(S.top-1);
uH:t1I(Z-DR.Cf     S.top--;.CO8n:m)HN_g
    return 0;
J&C/bc.T }
`p2x|3Z|$V"G~
2N5y6^'s!i @_ char get_precede(char s,char c)pX!Aw{T
{
ID&~2lFID3Ww     switch(s)q;uo jV Ts9~ YZ8T
    {
Oq2r V X         case '+':                 
`HS)h/L'|"Yy"a         case '-':m8JCt{![\I
             if(c=='+'||c=='-')
b$j? G$q+JS                  return '>';nz0ZT u{{
             else if(c=='*'||c=='/')b)z$^#y-`;r!\
                 return '<';*Zj2n9up7NI1`}
             else if(c=='(')
:~*d:fAYb^'Ha                  return '<';
i w"t8zG9m|FEM              else if(c==')')(^5tU+u2R#h GZQ
                 return '>';
^-vr*d(~(F              else
9J:_CJ7nO'H5vOD+w2A                  return '>';4x AP0q.R:Bt
        case '*':3zu.q7nPc\
        case '/':i)I0E$G2h~%o
             if(c=='+'||c=='-')
]xrK%Od'ge"b                  return '>';C1tP~p#UJ#R+CT)v
             else if(c=='*'||c=='/')
'{4Fw8kQ"cs                  return '>';
0R;f_dd6EA {,K              else if(c=='(')
V)[M y?;X[[:|n8d                  return '<';y+Z`z ]3Ui u&Dt
             else if(c==')')
B.|#nP*@$eQ#A7_ J                  return '>';Cdc|[%P
             else2Mh!B&^!Ql)w9I
                 return '>';6a%d;N hME4I
        case '(':
(h;bm L8qG              if(c=='+'||c=='-')
P%u4YR$\4T-k7}4L                  return '<';
e_txQ$C3o2w              else if(c=='*'||c=='/')#~)LI4@%D0Q#`)g C
                 return '<';]%K(E?T
             else if(c=='(')
cIAc+X1cZ2?sS                  return '<';cWFbxSA
             else if(c==')')
2p&d1c!A d5O2|A'M                  return '=';O&w)b$tP {%V6U`
             else
nAEo a                  return 'E';
6g kSR;}Dg_         case ')':Hs+L%P3IT;SR
             if(c=='+'||c=='-')
t'Z}+raJkk                  return '>';K7H)j ftB
             else if(c=='*'||c=='/')
uZ8L:L[$w                  return '>';
(E)?WpH i              else if(c=='(') Arm%\:U}.C
                 return 'E';
'Uu.p]j!r G}\              else if(c==')') dy2ReSKWYHX
                 return '>';f^/y9k5kt L@q
             else
5[b~2{ dD                  return '>';8c!kd(O;Qg(K1] i
        case '#':,Y-iGz6o.g'T%j@
             if(c=='+'||c=='-')
4}+Uh}.[!^RqZ                  return '<';c? b8Wqv)y(F @
             else if(c=='*'||c=='/')*S$anr,G
                 return '<';:OU*G*rIV
             else if(c=='(')
8}l-|3Od                  return '<';}*_-GS2P7q}(]
             else if(c==')')2pU:?I\g sro
                 return 'E';)yb)p_*w;R"z _9u+l
             else#u'ce5@|3_
                 return '=';
c'j0jc${         default:.d{ T/HGwmh9Ki
             break;9z#_%h[w _2Ek0l:q6A
    } f)acfY/x[
    return 0;   
.}#q6P)^#E/I9?)@aVM }
2bC/g!l+AlZ-s4e sRxl pAA(cm
int isOpr(char c)
%t#w9z+Ih&[$o {
-j:V-PGX8BW'u     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
I4w[H5?1|2i*Vp3F         return 0;`"L3fc:s4HV)?
    else {!q-~vK
        return 1;TGv0Y,Q3}
}
R8_$MV)EoK#kP
;z~bK c_ Z float operate(float x, char opr, float y)ax@B9nH
{va[!V0c
    float result;*I6Wz$XB#W N:u
    switch (opr)*ha6{]X-H
    {?uVf-c ]%\B
        case '+': i*I)oA_
             result = x + y;
H)Sw~X4B{E|              break;Pt Gux'\hZ
        case '-':
4R ZG {C2P!f0]4o])d              result = x - y;FYf] BN
             break;1\%G'd x.jk;Mm
        case '*':
5|m3Gu*ys:`gN              result = x * y; M5{| B+x
             break;
N5g.ip~         case '/': !U6w c2S;M
             if (y == 0)
\MgMB;|              {go7PuQ@J3@
                printf("Divided by zero!\n");2O$W!L(O o|
                return 0;-S1BXd7H+I Z
             }zNk7x#B(Br'i:j$Pm
             else
1BV4d.LB}O%ID              {(t8K:@X*H7qR6{
                 result = x / y;
be!i5|`AD'[;`                  break;|}*Lu(E}sV*p
             }y:w8Mll0U qa`f
       default:
#r\^"?hJ(T1O              printf("Bad Input.\n"); 9Du6V.f YcF
             return 0;
5{}f7`0mZ     }v?~7@c4C
    return result;*Js;]X/i0BO2B-c;U0c
}   
6^+L)S qT _ QR`
^)v)E9mM8L? float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/)X)zw(t U mCg}%vL
{
0a4\^ @F,K     Stack optr,opnd;4kN~]0v NP
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
7r+Xd \,pK     char c;
1rw8L+l"x.qd     char buf[16];y-LL&KVCi_0n
    int i=0;{ AmF}
    .@F,_u9n*Q4v
    InitStack(optr); /*用于寄存运算符*/7Bv6RbwP;F
    InitStack(opnd); /*用于寄存操作数和计算结果*/
&NF-EcM~y&l V     memset(buf,0,sizeof(buf));6k8z+~C8mX/y z
    )dA+RiFR"a8Yly:Z
    printf("Enter your expression:");*}/I_'G9`S
        
9qI$TeE     opr_in.ch='#';qJQ7DO/}xm
    Push(optr,opr_in); /*'#'入栈*/
3I*\*S9@ TrS     GetTop(optr,opr_top);
;?aO.Ne}Z~+f     c=getchar();e*t3x'mp)r[2RN!Ed
    while(c!='='||opr_top.ch!='#')o({N8_/]"C |b/hD
    {)h"s%xKiG
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/)_j,j?r;Il$L
        {{B lXb9t5{9ni)d
            buf[i]=c;
.J5Kq xDvU             i++;i n8Pgj ?Qb
            c=getchar();
b C$b1n6b0M         }mQs/?ACl(tD
        else /*是运算符*/SMhc&T
        {
'|yy HD#}H(\B             buf[i]='\0';5MDS"HYM1lO V4o
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
3Q-GkIK+c             {sY g#K(^DFo
                 opn_in.data=(float)atof(buf);0K%oj:\xHq
                 Push(opnd,opn_in);
_!AD!@ G^0V*mG                  printf("opnd入栈:[%f]\n",opn_in.data);+nh%K6K+c
                 i=0;
5j"H9WI!j"N2E _                  memset(buf,0,sizeof(buf));
\ @ O#H0]u9Nc             }
:`V/Y$pP s/gl(]]*x             opr_in.ch=c;}8Y^7F:j
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/RU2k.O~5]CR
            {%peD D3ov9bl
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
o&| WR0R J+n                      Push(optr,opr_in);8NU&y)}XL"r:JA3Pq
                     printf("optr入栈:[%c]\n",opr_in.ch);3X }rm"pRC7N
                     c=getchar();RYC5di-Qget
                     break;
Iv1]:C4bD                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
Q7?%a3iB"Gn_qcP                      Pop(optr,e);}] O*L [-~*v"i E
                     printf("optr出栈:去掉括号\n");
6X/E-B2XAg!\ro                      c=getchar(); OV5x1nz/g4zTQ
                     break;&rW0d\~3_
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/z-Eo'U'N%i I p
                     Pop(optr,opr_t);?4P&m|s%\fY
                     printf("optr出栈:[%c]\n",opr_t.ch);
R!b3q-k'{                      if(Pop(opnd,b)<0)
FG%G'bJ                      {
4nw p&z!fA9r#H                          printf("Bad Input!\n");
i,R!T`&Yo7m!}d                          fflush(stdin);'}"`4e(m0b!k,C2a
                         return -1;
6^u6w-b*F.H8t"X \)g                      }
A6U h+X*Y BY                      printf("opnd出栈:[%f]\n",b.data);oldr JT2V\(j2Q
                     if(Pop(opnd,a)<0)~ {,J;Y+| _[h
                     {
-S%CtZR pN6u}                          printf("Bad Input!\n");
SzEA(T                          fflush(stdin);
u'QhgN{                          return -1;D a(J2f.O
                     }
E4Rvs H"z1d$S9c                      printf("opnd出栈:[%f]\n",a.data);-~Id(YVgAQ:g
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/$K\K zr$J
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
$?u:^y'zLkE6}a o                      printf("结果入栈:[%f]\n",opn_tmp.data); mK J5z0P!_ l
                     break;? G"oU a,}\!W2u
            }
;?r(M,A4cgfwq         }
/h3q/KOR iV         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
0h-T+reSy1rpa#CQ     }7F%\]-?%xu
    GetTop(opnd,opn_tmp); \H.FiaHV @B2Z l
    DestroyStack(optr);
2Znk%^\s%v     DestroyStack(opnd);
u`gBv]'b}     return opn_tmp.data;
t?6U3j3E8|r }PU"q^H2|Y:x,j%ZH

5?(t%f5V T P(p*~.} char *killzero(char *res,float result)
C g,|B#K|"jX^4D {;G V]&lL.k
    int i;NocfiD!}m

L5vp!pTQ"p     sprintf(res,"%f",result);.d$~u;`Xx {7n^
    i=(int)strlen(res)-1;U2X7nIJ](mb
    while(i&&res[i]=='0')
|7U9a+M,q+@TO     {
+Y [gbE:T:@;LwG         res[i]='\0';$Zv,k7\"}#qqo:}}
        i--;
$a xMD\(t} j     }
3Ct_)sY4V \-rI;iB     if(res[i]=='.')9CA1R2|4J+y|
        res[i]='\0';
I%M8Z?(va     return res;
3j%^|"P[3Q#T } s)_y"Dr$[F6wi

:Y5CV7s4\ int main()
#X Zc U8I9J {
+j Q b,l J0J q;K     char ch;
-W2H6W r JBRs-Jw     char res[64];;I.GjY:`} g3X
    float result;`G1v6DU"n||7E
    while(1)
pt5f_-|s$s|&c;cN4C     {
&E;P`%yq)oy         result=compute();
@+?3u+})Ki w         printf("\nThe result is:%s\n",killzero(res,result));
F?:sn Dsp0^b#Sl         printf("Do you want to continue(y/n)?:") ;
"c W6p~jJS         ch=getch();%[ p1v:z0dL
        putchar(ch);(ZF\/@V
        if(ch=='n'||ch=='N')
bR$a HV'GE7WJf&|             break;
%_0tM/OC;X-N zgh1L         elsep j)p@P1t;H]
            system("cls");T[d8g\R r
    }
B)x ?-hz oH8\     return 0;s4|m&oo'q]-qC
}[/i][/i][/i][/i][/i][/i]R-VZt q:hIq R0K
'jG:rX,Y?
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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