捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
ks(|1q5y 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
ah}7X9Y^ /**************表达式计算器************/
p|FK%o.W2S$[%T #include <stdio.h>
m/D2zSlOp4i #include <stdlib.h>
|3`y/]*`#PJi"v{ #include <string.h>
%I|)Z;Z S$Ik W-Y #include <conio.h> S?)b3y xGn'j
#include <malloc.h>,}E7R-y#w&h5mV\ Jz

-Z1v u9[V)M'e:Rs #define STACK_SIZE 100#x8| wF]8k$\,P
#define APPEND_SIZE 10O%[5PV:] J
Y-GN8a5Ga
struct SNode{G ~ n L3^/\g!]
    float data; /*存放操作数或者计算结果*/l8sR#z x/m2J
    char ch; /*存放运算符*/1cK @3N)m;n K#hm
};5?3a(Iey

Mg2v1\g8K%Gt struct Stack{
mT ^#\5k3L     SNode *top;7I4Z9e8SPR
    SNode *base;%_;L |1pj7S;T*g,n R/V
    int size;
N+vFN#E|fP };
/VC&C+[ t'@ tF$C4neS
kk5|O~Ok] /*栈操作函数*/
X|pl4c4rc0] int InitStack(Stack &S); /*创建栈*/
(K?1m7C$vN int DestroyStack(Stack &S); /*销毁栈*/e9SsO3u7u2WV
int ClearStack(Stack &S); /*清空栈*/k]M#U-N!]Ok)Q N V
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/hFu4]@)s
int Push(Stack &S,SNode e); /*将结点e压入栈*/n2~ a1D.Hmr!S:[ A
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/$x^kxr Od
ERU;M i,J'O:Q9l
/*表达式计算器相关函数*/
bYrSq b P3_rQ char get_precede(char s,char c); /*判断运算符s和c的优先级*/
X.tKJ0{W5Q int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
'\-}$Tnm)S-p float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
2dC$fi:U g0j'dg C float compute(); /*表达式结算器主函数*/
plKJ iY9d char *killzero(float result); /*去掉结果后面的0*/ CHJ"J s
7R U/n#|'] ?B
int InitStack(Stack &S)
E0v]^ B L(D'aAJ+E {
T0VT3hQVFG;~H     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
1}Vf`V,P5z     if(S.base==NULL)*Ye-m"N3?'vr}
    {m+Rn1Rqi#h)ZU
        printf("动态分配内存失败!");
)w[J9D7{t_         return -1;
fl2dU Q$}\fy3a#b     }}#DH4@iB,~:]"s
    S.top=S.base;
-qs k4zF~r5z     S.size=STACK_SIZE;
%HpT,jk9t`     return 0;A-aBi'Y:w.{
}_aeZU^:TE

Dbw'M z-uG@4k(Y5i,? int DestroyStack(Stack &S)
E1Tq9wV ?c {
R$R-BW ]l$x[     free(S.base);i&\Dm+a
    return 0;
1@["_#v`d }9`~8ak zQ$^B%^

D7r%v(o n&Bm5Ip int ClearStack(Stack &S)
qR:[ pd {
D$Su/C j#Mc     S.top=S.base;9v'T%f(xn#[:b v
    return 0;/Ik;f2]/`j"K(U$U
}
9p^i*[r^|\W ,P4vv&X\
int GetTop(Stack S,SNode &e)
|k.~ n!bW+h7@2A({0l {
;?J&jF1bA!@Z     if(S.top==S.base)
5tz0h.wN o \`     {
-fqEz0ITN0m         printf("栈以为空!");+E$G [/Xd;S$i {"u
        return -1;
1iN` z:{%_`     }4@'`1V/NOW4N
    e=*(S.top-1);
7`Yt9B&VKF     return 0;
o?[[I+{ l }
yVf fh4JcDq \ [siJP(G;~
int Push(Stack &S,SNode e)
d'[2Yem+DG*A {
9X y#Rz1dC9W_0c'k     if(S.top-S.base>=S.size)
Q7hs:p$fR}I     {5e0MHcNf+~!`;h
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
%v`})IZ j"~z)`         if(S.base==NULL)4X#jj;tUBd9a,N4`
        {
y,wn-l:fea             printf("动态分配内存失败!");.Q h&zV`7A
            return -1;"l]6AUlw
        })ab:u1e/aH y3T
        S.top=S.base+S.size;,RuY/Vz r'L&| r
        S.size+=APPEND_SIZE;
"t(lXj6FK@     }
*Qo}|d/id']bji     *S.top=e;%X~-n#V@0L&f
    S.top++;
/IK _\$j     return 0;\ O(A#Ea,j(PK
}0WU7@%`-n

] G(x/mdO&R int Pop(Stack &S,SNode &e)
BRk*^s#bXQ {
C$iZ2iP7v!O;cz     if(S.top==S.base)
4_F C!j6vt     {*Lx0YC i)T E
        printf("栈为空!");o-?1CCy8@
        return -1; a(N{/X;g
    }%\a J/T;ly
    e=*(S.top-1);I/? mD"p rI-e
    S.top--;
7TV9@FN q C     return 0;
s'GYIlm!O LX } Z C$hR`l8r$~G

M~i8FJe/W6w char get_precede(char s,char c)
ww:YM? {
c0Zr"Qq N     switch(s)9F(c-s,u+yY
    {1~ h_n9Y @
        case '+':                 !C!t)@FH#`
        case '-':
3Jym2UwB$T;o              if(c=='+'||c=='-')&i NH F-VzRY
                 return '>';-}!M#R~pD%P'GM
             else if(c=='*'||c=='/')
x(}$A,nb                  return '<';-Z(D,XWJ|"x
             else if(c=='(')
P7K(w~0Go~6X                  return '<';
II)Z4|Y\              else if(c==')')
0a$o}!Ni`Ny(h                  return '>';
#o"l7Vp}              else 4i3RSh)m6m+kU
                 return '>';
7{ @6?)[VZpr5pq         case '*':v&A7Xbp2I/f&q&Lb;pY
        case '/':
`%p'e z{              if(c=='+'||c=='-')8Q1v0Kc.X#J8vL
                 return '>'; enx8kT u
             else if(c=='*'||c=='/')
0s1q'W7Wi0h~                  return '>';
+B5D K"YLgW k              else if(c=='(')*c(P4^{8NP E
                 return '<';Si*r'D[y%s
             else if(c==')')J$e/O(aK}i
                 return '>';
w wAh!E z6KLsK              elseil+J.xC_
                 return '>';
0c0| ?0]9w5m J"~-~         case '(':
.Uj6M#x3Lt:xL              if(c=='+'||c=='-')
+I+k5\*UTe` O JF                  return '<';
TEx4I@0k:ozLi\              else if(c=='*'||c=='/')1`/u8oM.{3u|
                 return '<';I,[6WY(J5e;oN.| }B
             else if(c=='(')
AWd,RK"f                  return '<'; oB?'F f?+R5f W
             else if(c==')')&]6J3mZ+JyF `
                 return '=';)J~'E7BtUv-W
             elseAo |)t gk,z.m x2c
                 return 'E';
MC$Mp y*p/^         case ')':
L0P+n2HL}t2YC gR              if(c=='+'||c=='-')z|+F d"NmpZ7?
                 return '>';
#g'M}Z l M(S L              else if(c=='*'||c=='/')
2i+?&V afl s:K                  return '>';0{!R3sxR,cQ hV
             else if(c=='(')
(u)`sm/w.K\5F U                  return 'E';2tt3SSO6A,D[6E
             else if(c==')')+oOV$O-c Z+q'P/_9H
                 return '>';~5Va8K:eG]
             else
nA/[A%x                  return '>';
S7n4J,A5n4['v         case '#':
-wz.Lf qJ j              if(c=='+'||c=='-')U@B)LS4X&@
                 return '<';2Nd5K"c4f\u&s
             else if(c=='*'||c=='/')
.{ \)nod?4p.^                  return '<';
O Li-wwPLn+b \              else if(c=='(')
~8[e#RuR*U3x{                  return '<';+S}6\Ae,]
             else if(c==')')7xhl%g4t0m3L ITV
                 return 'E';R{R;]`T
             else
0X.cGK3G-y                  return '=';
E T*IcIR5i k         default:
m3gQS xW N"g)RF Y              break;8nUE#IS.w FF
    }
1b)b8y ntLyE     return 0;    E0XQ,x-|w W`
}\U3w-|Sb

n.If]6E5q int isOpr(char c)
~kO3qK:| {D E4d;u%wk`
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
2?!tV S5o!Fk2nv         return 0;u\gkXtoV6L
    else DA6S'^!Do
        return 1;
mg8q'M2cTl }5o3t'T7v,b
b Pt7x&X;|`
float operate(float x, char opr, float y)(tC!M lzG{'_,L
{.S:P,R%u.}_q%y
    float result;
pPlz&Z&q     switch (opr)W?y0`z3p&mD
    {;JU2Co3I-c1b;m^
        case '+': m8| jq-]2M
             result = x + y;D?z\m
             break;Xq:T9t:t7x7|5BjPeJ
        case '-':
.^,Ih8_%BX/O4_              result = x - y;
hm7@#W)[(~f Dlg/v              break;E)X/y&xwH7l D
        case '*':
Uqb1f!s"dGQ              result = x * y;
/QR b7i ~`              break;+Fmvul7~a#I6c
        case '/':
0L$Y)y.CW              if (y == 0)
&A{8U|$ABXgS.Sa              {6VdAm7T0xJ
                printf("Divided by zero!\n");
7J6T$W DT+Cr                 return 0;C%c@%M~JJ
             }4I G` l\.SO.\
             else n)oo.RkR}/Sds
             {
;G ma(f/B#op(q7|                  result = x / y;
1@+oS V6cF/SY"i)W                  break;]i6V+ih Qu2D ^
             }
HrV[#Pr        default: R8_w+oDM{d"{9e:I
             printf("Bad Input.\n");
_VZ I-^              return 0;
8|;BuP-`^uwP     }
1B`V.fw"a9e f9C`     return result;b sZ6G-M8nm$h
}    ?N.\8x#Ij!w:wdc

K;F {n7F6q float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/9SQ/J.de3S
{;dwXb.D/yX|
    Stack optr,opnd;
h+MJ {?+Iql!D     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
6{Gf!_N     char c;;Rnq,J}(`0B-r
    char buf[16];
`8B8IK"F)`!g~     int i=0;
(l0I-X~@Ua0P%s)d    
1owk%Sz TA0D0v0z     InitStack(optr); /*用于寄存运算符*/(L2o:I0{#VE`8{
    InitStack(opnd); /*用于寄存操作数和计算结果*/H2Q7h5a L
    memset(buf,0,sizeof(buf));X6Fwp(l k/chI
   
'wl4j3Z0|^K|)CN     printf("Enter your expression:");
-g3J8l PC[ c         
\NSIqSg dHX     opr_in.ch='#'; MO+Umx4S_4@e0Y
    Push(optr,opr_in); /*'#'入栈*/}2_S He wt:s.}*j m8Jx
    GetTop(optr,opr_top);
u{\rIUF     c=getchar();
uS\6K0L2NF     while(c!='='||opr_top.ch!='#')
D{ f/K5k     {
9s$z6@hF8w         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/YUN1\T?U+t|?}
        {
!p:}Lf}5b.Ig5w+|7S             buf[i]=c;
'USn+Fq C-ZMR             i++;2j&M)V S?"s`6~
            c=getchar();
r*\S1aD2U$I1S i/`:U4pbK         }
YA ]0X6DNb4`#^K g\         else /*是运算符*/;Y$M{f)J%]x4u2b
        {4z7\%T0Q5K
            buf[i]='\0';
^WIi0\Cp             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
*m8IF.\9Pr*_5`6rA             {4^q_#RB*m"Z @ ]
                 opn_in.data=(float)atof(buf);
:u"VZ,F6Y&oa                  Push(opnd,opn_in);
J2NlS(@&l#L1z,SZj%kKP                  printf("opnd入栈:[%f]\n",opn_in.data);
\ w,@*l kW                  i=0;
W2b4JN$V%j3ow                  memset(buf,0,sizeof(buf));
|*b3@ Q V_#\p*t             }
V4V2v5XoL0L0]             opr_in.ch=c;
)P%@)V2ajj             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
H!x4w*J-W CP             {
(R/nk Y;Q ]                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
'K?$m:nK-`                      Push(optr,opr_in);
D(X bQ$S{                      printf("optr入栈:[%c]\n",opr_in.ch);Q,I,~f\8|
                     c=getchar();
MV0nx%rJ                      break;
*_%t3HeF*_                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
e B;VIMuN4\;UPD                      Pop(optr,e);Nt)SS6u9|mQ
                     printf("optr出栈:去掉括号\n");
3Sg3cm;bv1y,|                      c=getchar();?gA6T` Z X
                     break;
Gw$[CxL'V8\                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/(|Hzpq T6`1c
                     Pop(optr,opr_t); P9_A-G/k L{o7c
                     printf("optr出栈:[%c]\n",opr_t.ch); u'fEnS:~
                     if(Pop(opnd,b)<0)-y!T8X;q(qE:e
                     {
!v,|u7B+t P i                          printf("Bad Input!\n");
[b'Z3A6L y                          fflush(stdin);
1GR&Kq.O                          return -1;
9sL+T+y#?U1a                      }4Z`y.u`/]]
                     printf("opnd出栈:[%f]\n",b.data);b:n/n*?'ewo D.c
                     if(Pop(opnd,a)<0)
s\E8dg ms&\U                      {
.z]ss?*\y3O                          printf("Bad Input!\n");aGcYC#F4[,J3mEtw
                         fflush(stdin);
4R:Zdu.Wr                          return -1; rA^!Ad0r!F
                     }+J*v8T(G1g5|0O
                     printf("opnd出栈:[%f]\n",a.data);Hl!?P:I$`9y2y
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
Sd0OY/FIcMH                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
f Dcw'E}`n/`Q                      printf("结果入栈:[%f]\n",opn_tmp.data);
g8`;g'a\^$C2b\I                      break;
S^*pp'R+X!y             }
.AEJ;OidP         }T)})Ld4H]7mO*u
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                *a$\\;L[.w.J"^;l
    }
rEVo2~C     GetTop(opnd,opn_tmp);
5u0YP7|$b'J3a NJ\     DestroyStack(optr);sy5ELh
    DestroyStack(opnd);V!fa?!T8YWAP J
    return opn_tmp.data;
gsq3A:HN:j(lSl })J9n1_h([OUp
f#f@d mi[Q
char *killzero(char *res,float result)
X?4?;GINo*jy$UsJ1S ] {Vx+Rbr {m
    int i;
e"F!CR'I{K q 2nY.K0bt"[ k9U
    sprintf(res,"%f",result);hX%Qa%Fn KY)B
    i=(int)strlen(res)-1;q3Q3eYUE
    while(i&&res[i]=='0')$nLd v]z cB
    {
$G6e#\"e"G(Il5qmE         res[i]='\0';9dd/I7b5En;| R
        i--;-\kt q}dIx7?;c
    }EV,ZpZ
    if(res[i]=='.').u/u(?7o _O1s q
        res[i]='\0'; S-hPW!] na
    return res;C2w6H+x-D(e;h e
}
5ockpR!l!^Jvy |L:]/Q)ou
int main()
2y(ICfc0p7X;UN {TU w/XZsqv
    char ch;
Lt}E#G4aZ     char res[64];
@^.qf,MN y     float result;p+QX#wCon^
    while(1)Oh^|X"CR
    {)s3`#Q#l\J7}
        result=compute();
2o"|/J?.`1ZO:ut         printf("\nThe result is:%s\n",killzero(res,result));
.G9|T Yd&p"J![&u${         printf("Do you want to continue(y/n)?:") ;
qXHav6g0uK]p         ch=getch();X b~q VKV
        putchar(ch);
w$mBSN3bL7Lk!w9z$T         if(ch=='n'||ch=='N')
-u y U'\~n1}}-G \             break;
L6YuKn|~ {+^         else
*xHfnyp-p4q"l%uMf             system("cls");;{q}M kQ,_cE
    }F&g+gy/P
    return 0;
sBtFK3D k5YQh%p }[/i][/i][/i][/i][/i][/i]
H#O.?:az:z~ jYay*H5m*K
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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