捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.aw8\G@,xD1gM9J
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
PfH)Inlz U /**************表达式计算器************/3n}F*i^;|j5M5@
#include <stdio.h>
+E'\6^w)VW+l { #include <stdlib.h>
1FMWB/q[]MDa #include <string.h>
X0B ~#J7Y+oC #include <conio.h>
-bP{R `o&kt"l #include <malloc.h>vQ2~TEl/X9X
R1}*o&axm5|[`
#define STACK_SIZE 100
z9a]!Xr #define APPEND_SIZE 101U+^S9Y5D8D3@2R

y-CLR7]+j struct SNode{
:X_(j'?g4~i4x3Am     float data; /*存放操作数或者计算结果*/?1N'z"t D4S ?
    char ch; /*存放运算符*/KMP8Ce&BD7E
};p LFNA3X.M

"Pat R t9\ Ri*S2?;W struct Stack{
2G(MG~r`m     SNode *top;;C%e|.?d1E'`R3`4Z.W
    SNode *base;
:T+w+wJ,L"~ O     int size;
o}V.y6]hc y };JFG)V b,a3T Z4f _

Z^9d Q:F /*栈操作函数*/ mEG9wd8C
int InitStack(Stack &S); /*创建栈*/
%` o`1bF"}o int DestroyStack(Stack &S); /*销毁栈*/)vm)j5V;f!w
int ClearStack(Stack &S); /*清空栈*/&Z*x$uA5H4buK
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/7O-]){6H*Y@E9t%c
int Push(Stack &S,SNode e); /*将结点e压入栈*/
v4G6V| L int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/"X%zpJ q#f |L2o
#F7ajw0w8FR
/*表达式计算器相关函数*/C-P5L6?-F
char get_precede(char s,char c); /*判断运算符s和c的优先级*/9n6nU/tU{(j
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/RnFF'}
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/3nfJ{ja^ v~
float compute(); /*表达式结算器主函数*/
5j ^"y RJ6g char *killzero(float result); /*去掉结果后面的0*/ ;B'F;Lj0Ci8|pH4b

Y._^:d1w\ vi int InitStack(Stack &S)%{E,Q!v3J$qv:c
{%_GOo},aEF R!E6r
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));J Rg3] {ih
    if(S.base==NULL)
i5eT,W4X/Sq g `N     {v%m2F'n x#hu
        printf("动态分配内存失败!");X"eL6~5B;~M
        return -1;
TL}[L9G#Y     }
|{| d8r     S.top=S.base;rXB G/TA T0pM
    S.size=STACK_SIZE;X8T;i }qM2| C2bh
    return 0;
J.y2K#`-M7i)G.B }
hF$Ym,~5lY y K`W4iD
int DestroyStack(Stack &S)Y4cy TjTX]&w
{8n3b"Y.xr/pk%h
    free(S.base);
X_~ESb$x     return 0;1rH3u'KH$Yh
},X6ca0^,^d}
,k*F.JH8e(u`.I
int ClearStack(Stack &S)
0t![Xl(^ {
W_.Q*zsr[     S.top=S.base;
!_sH&Da2M!|     return 0; yfB jk ?a6c
}+M\;@N O,x
b(o(~mI
int GetTop(Stack S,SNode &e)fIv [/z6]h|9]5m
{
(D1R^Cc?     if(S.top==S.base)F,qex*V d_
    {
(B*PO8p-S%Ql         printf("栈以为空!");7`$q~]1k1[K
        return -1;
!h3fFbAh(Nb     }
h:]xj9}S     e=*(S.top-1);
7LQ @Ks6?jL}     return 0;
w"Q+CI J!Vc }8a~s:X&oCG
s$i)N i2a6Y9_
int Push(Stack &S,SNode e)
MSL ]c R6v.cDv G.S {
(m'E~~ RO U     if(S.top-S.base>=S.size)
%t9d:[;~} L4h     {
+ap d#K[`w2j9M         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));.{,c1re?3~/S
        if(S.base==NULL)
VD'a W8N[X4K         {
\;mG O7s{             printf("动态分配内存失败!");!M+cky/\.r
            return -1;f wt*`*t(d c2A+M
        }
jyk9RX7v.G         S.top=S.base+S.size;
i+KDcM1E         S.size+=APPEND_SIZE;
$K xZ z!DzU'Y     }
n1V#O$z? TPq4Je     *S.top=e;
Hw2Ky6c2T     S.top++;
K5^xOzqE     return 0;
(E9ZcSzEn }
)u/i?*DmU|)S-j
;kTq2O,Y&L^d3LU:W int Pop(Stack &S,SNode &e)
A0h2`7`D E T {
;{ Pg K0_m     if(S.top==S.base)
mzn+K!P5BiBx     {
\ B OHD }1Q&A         printf("栈为空!");(UQ Vp4o+mko
        return -1;
Lh#o}EnV4x"O     }m_YA*^/G
    e=*(S.top-1);.j5m&S'jV$A
    S.top--;
4F.|c5jua4X-Q     return 0;
Cno'||Q }9G DcdCSu t0unx

(hoTrx$U char get_precede(char s,char c)
vq1^c*V2y4~!RPN {IA}`3?(X0O
    switch(s)
T2v3bxt$P \     {
b,N(U8N#Q6k:xm(D8qU         case '+':                 
^1t{N9k         case '-':L?P {4UH r
             if(c=='+'||c=='-')
JFE3l_LRqtU                  return '>';+i n`G:PH:h^
             else if(c=='*'||c=='/')
&p-g ME3h8K0a                  return '<';
0Fd2p#yB9L2qp              else if(c=='(') X e-?"Y*P In4AGE
                 return '<';
:f;nF\t!n              else if(c==')')
tjX.nbb7lr'`%F                  return '>';%Un0KSL j~
             else
7uO9^%G:D M                  return '>';In3IL3tn7R'|4[
        case '*':
:Hg/q4iE+g!j         case '/':U`'Uu-Y6xN+YP
             if(c=='+'||c=='-')
E4yW``j                  return '>';
A^N"} \4[s%Q              else if(c=='*'||c=='/')
o @^LP3L-BW D                  return '>';
&k ~#m+xS,Ku @ut(@D              else if(c=='(')
)f-X&b"c%o m-`I/O                  return '<';
#K`6_|;]%uOg              else if(c==')')
0xxD+g4TM                  return '>';
S"XH,ZH]w!h              else'O4wV;Z:bhQo
                 return '>';hJV.E"f*tc
        case '(':
Y,Yn!e\}#h              if(c=='+'||c=='-')2Kc#h)z7L;I0t f(q
                 return '<';,z BF-IG
             else if(c=='*'||c=='/')d\_ g^ZZ5_,B&H
                 return '<';
)[&M*@*b6Xb              else if(c=='(')
|+B e I I$j:HUM5V2J                  return '<';#AaFWR9X4sx)Db9o
             else if(c==')')U+{\$I(grnxc
                 return '=';
v&BFKNg/[3O f              else T!Q7JSqzR(B
                 return 'E';R/\~H!f[y$l!V
        case ')':+Xy)g'{5ARM\4RZ
             if(c=='+'||c=='-')
wt9j8|:`*l:[*P}X I                  return '>';r0l4]rJcs#U
             else if(c=='*'||c=='/')
7D1fxi+pM3nM                  return '>';
:kQjw+y`              else if(c=='(')
(U'qaDS6s*JN:sb(x@                  return 'E';,g.C5z*a7M3O sf
             else if(c==')')g7ve]hN7K
                 return '>';S3uPoy E:sek
             else
/@ w9ES`2L7a;N"Z f                  return '>';5BBS9lZ d-q/J
        case '#':G,Sf;L3wK/l$n:tZT
             if(c=='+'||c=='-')A(F)O\,~6vM
                 return '<';$C w*x4|-T)RHL Y
             else if(c=='*'||c=='/')
.Kn\Q*RgC                  return '<';-C(\(e,\^ Z5S%w.z
             else if(c=='(')3Bt4P3t x HB
                 return '<';
pE4J#r-q3Um5_ S.q%?              else if(c==')')r hp9U\O.z| J
                 return 'E';tOny}
             elseDA2a^%cT,f
                 return '=';
n8h b?;s,e @         default:
4oQw5ew#|P              break;(i@-X&TO2E0WK1r+eZ
    }
-jGi S1V5}     return 0;    R/s2o e4F)LB!_.T
}.Hn-AfZi.I
*]]%_2sb:rj
int isOpr(char c)
p h Rq2_ p/N C3p {
4ci1` f$Or*}+E:Q     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
U XfNl         return 0;7u!WU Ee'x@`7f
    else gXx'eJfLjx
        return 1;
'j#]qE s xV8M }7z0ib'vgT`WP
$RjT7O)T8sFm
float operate(float x, char opr, float y)
#p+k o pP E6P!I%Y.m @.~ {@/ZxQ0i-Z%@6M)\
    float result;B/~hIN[%Y|0MZ
    switch (opr)
,w@'n$N9wUh     {$s8{cwDG
        case '+':
I-Ne2a @L ]x              result = x + y;
]4e%X*BI"T              break;
a N&CRH Q`]H         case '-': WsE8s~Q
             result = x - y;
#iFR_S6@)G8r\4s              break;%{0\y8o'r
        case '*': 3H4O u1vv Kj
             result = x * y;
r'd#lSg4Im2^,}D              break;
A{2}&Vo$Q         case '/': #lBs!EO SL
             if (y == 0)J2x,V/Gm%X%Sn
             {
\_"\1~ d)kp"c                 printf("Divided by zero!\n");
6Zc0c6m!_Kl.}n)U T'{~                 return 0;
2U&nLw?bQ m              }F-R:}7`9{
             else-QoiWC?,g)uV4R2E
             { Rg!}-Fhy*F
                 result = x / y;
` k{W;yv'w&i k                  break;.a"HA,I'U
             }%w,nBY.f&L_+p+`
       default: 5C8jM k \$]"r,y
             printf("Bad Input.\n");
!TNNgs o              return 0;e2l OP? A\
    }
*cm"{&?-I8Xl     return result;D^z;Ss#|:Cs
}   
D"N(Jx7_'eT'E
3d`j F0?~'I float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/[ YTvf%DHX*s"zz _ j
{*q xb2ZG
    Stack optr,opnd;l,tu%qn
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
v i*_!{tM`E.|     char c;
ih~.}{{     char buf[16];
u@7QX*C2t`     int i=0;n wA{q.bbva
   
,TA_3i9DK&\#N.{o     InitStack(optr); /*用于寄存运算符*/-e)? A6nl0[)U
    InitStack(opnd); /*用于寄存操作数和计算结果*/
:?)B*H Yk3Dl     memset(buf,0,sizeof(buf));
F IR2yI;N%_     o+YE/^4GL
    printf("Enter your expression:");$@d I|d)A0f
        
dC l;sw [HS     opr_in.ch='#';{i#pZs{
    Push(optr,opr_in); /*'#'入栈*/Oe~9x IJZ;C
    GetTop(optr,opr_top);HhvwB9G$K!B5I0{
    c=getchar(); q9? _$Is-v
    while(c!='='||opr_top.ch!='#')-a \cH%Tv4t!s
    {v:c(ls)R*FG[P-d7S
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/}@r[xD
        {
:{dX[a C             buf[i]=c;*iF4HJX,\ TP
            i++;3|"~qk2c Em5}r*jM
            c=getchar();BC#k UhQ V
        },ve*Thx~w3v\"w
        else /*是运算符*/0R \WdXu7mN3Z
        {#h }*D?2D:C~c
            buf[i]='\0';
_G ^0N7].R?R+N             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
o7O5fAOp*_s             {
fRWR.c[3Us&A                  opn_in.data=(float)atof(buf);f7f,N7x {"u
                 Push(opnd,opn_in);4k.IDcj I-t#U|;Q.c
                 printf("opnd入栈:[%f]\n",opn_in.data);
-Vy0Y ? vUv"F                  i=0;
DK%r-_4Z ^V:F.\                  memset(buf,0,sizeof(buf));
7Pm\%Z/C9?#b.n}             }$I @v0R%`~~i e
            opr_in.ch=c;|5i'G [w
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/*J*]!bg3Y0Sa7NI c
            {
;Utt%^ixM&F                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
KC.~'QD                      Push(optr,opr_in);
r%l7Y-H `N8nS8?O-y(]                      printf("optr入栈:[%c]\n",opr_in.ch);
o N!|5s#sX@3N*^v                      c=getchar(); J(R$TPSs"G
                     break;
VNU"ZW DkG$]&z-H                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/b] \S NJZ
                     Pop(optr,e);
J*\We n$D                      printf("optr出栈:去掉括号\n");_;h!nu7Vq
                     c=getchar();
kIHt-C7bXs&S6]:G+w                      break;n` M_] qFQ
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
4CPsY [ q4}0bH                      Pop(optr,opr_t);9G_ q%d8J!W
                     printf("optr出栈:[%c]\n",opr_t.ch);.s!o3LL \%RqJ
                     if(Pop(opnd,b)<0) m,J|`$|f m N
                     {
\d+Nw1Zq4f.sr,v                          printf("Bad Input!\n");b$O x-w+t!V's@%s
                         fflush(stdin);YdV:^,d:rN _
                         return -1;
y3~v9uN"u-W                      }
(uD[M4O4hd"Z6^                      printf("opnd出栈:[%f]\n",b.data);D b sr4Y:?q8e&F
                     if(Pop(opnd,a)<0)
dH(g ya'Pc/wZJ                      {2fxO5@3x,EV4w}
                         printf("Bad Input!\n");bD9}lKr(C
                         fflush(stdin);
eDK?yS K1}:J                          return -1;
EDMz6gH |m"K                      }
Y&H|,h0^Z                      printf("opnd出栈:[%f]\n",a.data);(o hO [r%D.MKJ
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/~m8V Y'Uq"m'L Q2cy3o
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
^ PF M c                      printf("结果入栈:[%f]\n",opn_tmp.data);
+?XAK z-Q_j o                      break;9J#A/LyR;}-| |
            }6p9\2D#Sh;a6Ec{n
        };q2hsN D'x3Lja!S
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
v!?KBK:c#n1V     }
o7g0ga0aT+bzf     GetTop(opnd,opn_tmp);5a I8_$mlj d
    DestroyStack(optr);g4kp1Y] R7N
    DestroyStack(opnd);
Sfhq{8Uv]     return opn_tmp.data;
L(Q3L*w:o }
&ti(e.h[zv
A+{:Gg8@q.Q char *killzero(char *res,float result)
h9a^ze9Ro {
(X1g^:p#n`a)A     int i;
/KV#E&h5A#Oh(je9IU Xir4}1Z*AC\CJ:]
    sprintf(res,"%f",result);
t5s8oA|C2t1m,z     i=(int)strlen(res)-1;vK;q:Kl6\
    while(i&&res[i]=='0')
2Xs5Z-y+cRT M n     {"m-}7@,B,O`7s4roW
        res[i]='\0';
~u%y9K0r`2P         i--;2go!w$m4C)a\X
    }
r8r V q#O n k9?^c     if(res[i]=='.')
NFmDL'n}!H         res[i]='\0';
zLv`"T     return res;K"rHMy^#P
}lTi1My1I
j8A:BUKCOoB
int main()
e'N @X&_VA,? {_mT!Ac
    char ch;/zj/T!Feo.AJY
    char res[64];
5RVSO;\/^5^t;n     float result;
B*@ v)k _FH;yk     while(1)
'A+W+J'Z t4gkO     {7~:g&P"v;M
        result=compute();Mbl{a L
        printf("\nThe result is:%s\n",killzero(res,result));'{8f(@wF \:n~#c
        printf("Do you want to continue(y/n)?:") ;V n$j7h+fN
        ch=getch();
HO6E\hv*C'L         putchar(ch);${wnV9PY
        if(ch=='n'||ch=='N')
}0S$kw.lpG             break;
Er-o+P2r'D/\         else9K\7g+Z[R+}v
            system("cls");,fyz#Z/uq EOC
    }? M\{7Vi:E
    return 0;I {WQ+AX:g4u
}[/i][/i][/i][/i][/i][/i]
N`:X;yMP7ZY
J+f#^fhx [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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