捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.xu? Vc
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/Dj_2N&p9\T)P$w9Z /**************表达式计算器************/(^#X qld,j t9M$i_
#include <stdio.h>yk/e.Vw$YU:D5Zg+S
#include <stdlib.h>
!L*EHTEcZ-T #include <string.h>
s&B`7{D/hF #include <conio.h>
8u)^6~"L?{#qA2S #include <malloc.h> N'hxD~.]p
Yiw4[ [ a:g6}"O
#define STACK_SIZE 100 Y3D~*E l7Pm!P+W.Wp
#define APPEND_SIZE 10
} H&dH&cV%t.R
An)NLhyj struct SNode{
j uFb+o.} Hu     float data; /*存放操作数或者计算结果*/
)]0PhLa1]X3J e-xK@     char ch; /*存放运算符*/
kcj8cE].TL!z };.T gM+n9D7l3?

s O S+b*~)YT*E? struct Stack{c| sQXM3X!tL/bn
    SNode *top;+Yk+E;MB.z
    SNode *base;
5rl#_`8Yx$X     int size;
3\$V%J.V#i*O };Cv7M p2cQ
'W Vl;M&e4sIk _3J0L
/*栈操作函数*/
sN6W/s0}(o-Bf int InitStack(Stack &S); /*创建栈*/;y:j:g]VM8oD
int DestroyStack(Stack &S); /*销毁栈*/
's6J&a{"v4{i;` i;R int ClearStack(Stack &S); /*清空栈*/
$Z+Px0y9etH int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/&k5bkRpm
int Push(Stack &S,SNode e); /*将结点e压入栈*/:tCu*Dw0k#I
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/(G*~7v [Y+n/MNVx:B
?H1S,^0|([
/*表达式计算器相关函数*/7tR R\l8X
char get_precede(char s,char c); /*判断运算符s和c的优先级*/$vM @@"SR;q
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
dp8?.B*g6L;Y float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/'@ Sn\5V*TD h
float compute(); /*表达式结算器主函数*/x"f };nucBfS
char *killzero(float result); /*去掉结果后面的0*/ 'ytiwhK+OlF'W1f

9z5\H~#m7|BKc int InitStack(Stack &S)
gx4[3[FP {
V rex Y'TLB:N     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));OZovw V4t!a\3Kb
    if(S.base==NULL)
n&O)j*y.@,\ W+OV     {
!c*Wo:x'z&f ke         printf("动态分配内存失败!");_8f!Z gW4`
        return -1;(r8i Zr?V3[+H
    }Kc dXcqi y/l1`:Z
    S.top=S.base;
)F d,d2Fp H     S.size=STACK_SIZE;
|S&E8S%A |\U p{     return 0;&K3k:t0J SY
}
ae"U Y3x[xK/_ ?Y3GK5T n V
int DestroyStack(Stack &S)*y K7x8z)no O3}6@
{
+zL-ixm @ I     free(S.base);b!U.s'~h/u5t+E
    return 0;(f(IfP6NN+^:n9{
} Eu/OC-OL6c
&WT-~*P7z C}
int ClearStack(Stack &S)7Y/`G7|Zj0L0i"W
{
@G s8dL$fk!__R     S.top=S.base;
.n.Lrr9h,sW&[ b/c`D     return 0;
6NYj.c3l*p"E \ |s }"o9Bnf| d"s

-cK(p(uo$AB int GetTop(Stack S,SNode &e)8O%x5R5d4iN:X
{[:A)SV6KWQ
    if(S.top==S.base)
l"N9c&D N:c7q,FK${     {
q[4R'VO7`,k:S         printf("栈以为空!");{9n-w2t)v;Fm
        return -1;
+u3A4@L)y+XcT)I,O     };I }z$AZN+AI#k
    e=*(S.top-1);
7yQgW*M$L @K(UdF     return 0;
:dp`V4P}!rO }7_NA&N'ekZl R
2]^D$m+rE'i%QZQ
int Push(Stack &S,SNode e)
UswR DH5`_ d {G*g9G%i5y3k&z
    if(S.top-S.base>=S.size) dUi*P;ZD X| lM
    {
},Z |ZR [ XS         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
Wv"G(Y u;P({&Q         if(S.base==NULL)fpaf.[9H9?,M7E
        {
+l9v8x g$X(t             printf("动态分配内存失败!");
%n+G6\ xI             return -1;
3qCUv0?'I[0y~         }}ImX;p~,S
        S.top=S.base+S.size;
I7q%T$_0M{         S.size+=APPEND_SIZE;QHs\4E,r }
    }
BE3|WK k3S {M     *S.top=e;
c |6\v+vx'c\     S.top++;
].Um l2Mr Bbw3r@z"v*H     return 0;
!]M2t3P7~ }Yu1~s"d }h

/f Q'E.M]z S0w int Pop(Stack &S,SNode &e)4I(p Z(K A GKG$r
{dN"TLM] J
    if(S.top==S.base).S7B!dZH_Fz[
    {
8on[*}/yiL2P         printf("栈为空!");q,k$JPv
        return -1;
^.WW|;y2K     }J)F9F7R6q9^*{
    e=*(S.top-1);
3T }+?u1R     S.top--;
q Z#a)zbB}0D-r     return 0;
d*[ n5`d I Q H };yn%o;wgK(C
&~^Jy}
char get_precede(char s,char c)
f_{Z"\ {gm3bS%Eg*kRL
    switch(s) |,V+F)uK9pI(j-er
    {%k%RG%] H2@P
        case '+':                 
kg7?W8Hu s*e         case '-':
)G)HxX-t0J)pm              if(c=='+'||c=='-')"mR8Bh"`7MXYr6G
                 return '>';
:G1Li:x;\{t%ei              else if(c=='*'||c=='/')
V!@Cs}                  return '<';
$pw qz$jJ.o              else if(c=='(')
^4u4VD0u}{{8lU.\.Z                  return '<';]t,N#L0f7} W mC(`
             else if(c==')')
pv:Y%s5t CV s:e                  return '>';
?!D1BSZ W              else #Mz_5W%m5`F+h%g
                 return '>';v@6tfKmi
        case '*':H3g&_VV+]j$~1R\
        case '/':
Vo#u Cp i?Yw              if(c=='+'||c=='-')
-cN[Q"]k*bBz                  return '>';
[7I$rM]7Sz              else if(c=='*'||c=='/')%j Q0f2c*@RbpB DF
                 return '>';,HueNe3u?
             else if(c=='(')1U`h o C)l$?5p
                 return '<';mI&v E Ik
             else if(c==')')
x%tY j|c-Iq                  return '>';2tl,Qhz&R
             else
/gAl,P$qsMJ                  return '>';qgu5p9?i
        case '(':
H2^}sS'`,ye5}0Y              if(c=='+'||c=='-')
A ?0bg k$b`\                  return '<';
HK k+F)V9}!|,Bgl              else if(c=='*'||c=='/')
P#H2NY$@8\J9h                  return '<';w2]2kZgcS+J&F+ESK
             else if(c=='(')
2E Yoz*D6QP.^                  return '<'; K)sp W-vgrOm
             else if(c==')')
E^ PY)S?b                  return '=';
K%C`7~9L7S              else
9G4@v#e+uW A                  return 'E'; y.K*dG-h6v L4G
        case ')':
_a~e ? [@xdz              if(c=='+'||c=='-')
x1N+{er                  return '>';
Qv.nJ)s              else if(c=='*'||c=='/')
K.mm!ON6_`'T IA                  return '>';
2PHN7E tcs-NE              else if(c=='(')
'vD/sE4~                  return 'E';
3pGE U)]\              else if(c==')')
-@V!p9j5w!?@5WfUx+w                  return '>';*ExI/o!z*m*o/`K
             else'c{3?}yD$^4Y
                 return '>';
0oEI)aff&p7S"dm,d         case '#':[5N's(t2W%M
             if(c=='+'||c=='-')5Y#e)`6H6nN;y'B"o,P
                 return '<';
Q kO Pn/~*@ S3j5_T              else if(c=='*'||c=='/')%||nF]rV
                 return '<';{z9X-e\nLx b&V!\
             else if(c=='(')X.OmkzH
                 return '<';(D@n0Bq2N\R\G}
             else if(c==')'))tqL/t;w`O-NO
                 return 'E';
I4MgVL,LlU(b              elseb'Q ksM
                 return '='; ~0Tu4K/h `(d,[R
        default:
@!i/|5p4KUBp7eE*K              break;(N+r,q4hzYJ
    })N6dX#~'lQ2m
    return 0;   
&S `2hG ?;q }
U#b-E*I,Md&zg^ F2f,[&wL[
int isOpr(char c)A:e\/g-nlD-?b@
{\ A {-p M'~,O
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')0j0jE3F'Y8Q ^Y
        return 0;1W#\*S6~4jN
    else %uN7gFw
        return 1;
N.f#J&C-Q*e2|k }6V9iAG/f4o:gf
2gQ [:c }Vw*@
float operate(float x, char opr, float y)@ W+X i }S;^IkE6Tm
{?Mvo5}(s0s
    float result;
~,s[9P)QF     switch (opr)
V plu;A     {
h5B `0s4ox         case '+':
,a'a$t1A,l C              result = x + y;
\ R3S"V9GK              break;4C;Cy|o%?
        case '-':
@+tI |g0Z%V}B*R-nN              result = x - y;
*u xeB-}c              break;
O t/[[E         case '*': 1W7R7Ga.T
             result = x * y;A0J z UPk,w
             break;
K_+GgG F)S|         case '/':
']!x(VW3s^8f              if (y == 0)(hC` qwVr+Q
             {
wI9M,S+Tt                 printf("Divided by zero!\n");
JJ5f;S)D l                 return 0;
#s`Z dP Y zY"c Z              }/Kv FB-y$@G
             elseY/x D'pqj4QC
             {
j&_3Mmn-xuNj                  result = x / y;f)T;U{z5Q%Z0OWe@
                 break;$}#IAkkH&G
             }
#o9C.`jY%Y+fI        default:
[1{5aV0yq,Co$T              printf("Bad Input.\n");
1X9W_7Y~5w8` [#z              return 0; ]0P5HK\5Tn t!S-k8rLH
    }|vg#tp%Ip
    return result;Fo$_VG/px{2S,C
}    3l6]([/ayUw F
7jg*Tg |&fXWB
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/n,m!c ge4];j
{e:|V*b+y#W!O8V%LH
    Stack optr,opnd;8k+U[KIP1W
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;%s!F7vb/[_b tPr y)H
    char c; x"gjiC:Pl+y#L
    char buf[16];
j.N7U5F5yE$N.B|.[|     int i=0;JQ1GW$|c5\
    $l5H7ie)O$yj
    InitStack(optr); /*用于寄存运算符*/:T3_ ~Q7md
    InitStack(opnd); /*用于寄存操作数和计算结果*/#Bk;JwT!d` u$] lt
    memset(buf,0,sizeof(buf));0eSum^RR V4V c
    5L&hA3Jp(h4W
    printf("Enter your expression:");"C[y,u o8Gd2f^+YE
        
W.G)X+S9`     opr_in.ch='#';
.Jd%?.GH(v3kg r     Push(optr,opr_in); /*'#'入栈*/
iPhy0t     GetTop(optr,opr_top);
'L_:`)UN8~rXU     c=getchar();]V7Yb t(i@zm
    while(c!='='||opr_top.ch!='#'))nFJ;[4n
    {
4Y1_2N"F%l+] O"Rdc         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
og#`+RX"` XV,FF p         {
Hu*Onn6D0E             buf[i]=c;
]9D%U,Z_0i J%O4Lo,wg[             i++;C8wh(QR~,jecf\Y
            c=getchar();'bl:S!| Ek?0h
        }{O'@ D5bF
        else /*是运算符*/W:bT2G&i bJ8E F
        {`*u2n'\;Av?$D
            buf[i]='\0';
1i M;}6sM5g)n*O|f G             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/W@F+D8n3E@|Md
            {
'W#WN(Trk(G                  opn_in.data=(float)atof(buf);
W/lb'|-y0j'~                  Push(opnd,opn_in);&j e!nUH
                 printf("opnd入栈:[%f]\n",opn_in.data);;o0n j[/}+[N{\
                 i=0;Oy4B+@NB R
                 memset(buf,0,sizeof(buf));7N[E6b4Cq n0np
            }*d(u2ik Zm
            opr_in.ch=c;
R;d)Ww J)F ?T[e             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
e&Y2P?/K H*K IZ/c@             { s6z!Quu
                case '<': /*优先级小于栈顶结点,则运算符入栈*/U yv,e~VS
                     Push(optr,opr_in); O;u]+o,U,a!q
                     printf("optr入栈:[%c]\n",opr_in.ch);$C ^.QC zs+uzO
                     c=getchar();lw2G.q#O
                     break;)d+F5u8js?
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
wj!} {)I#frGg|                      Pop(optr,e);
3nh,lF0XP"N W8p                      printf("optr出栈:去掉括号\n");
#^5m'ci'Z                      c=getchar();
\^0Q#qNwl'|6^                      break;ZZZH d!eb+]q
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/$B$YcG |+M!\f
                     Pop(optr,opr_t);3]%K[*ta
                     printf("optr出栈:[%c]\n",opr_t.ch);
n2W7xA A"u                      if(Pop(opnd,b)<0)7UROX,n{ ylnZ
                     {
Z0sVrF                          printf("Bad Input!\n");Q]V,N|;w
                         fflush(stdin);o2sm.@yn"|5|
                         return -1;l`4To&UPY7nDH
                     }
lw v:G:@VXZs                      printf("opnd出栈:[%f]\n",b.data);Zm)qF&\Q3N
                     if(Pop(opnd,a)<0)1R]4CmI#n:n-Ko o}
                     {+Jy8Ap/S Ul*\U
                         printf("Bad Input!\n");
V-w)qP9p U7e                          fflush(stdin);
C!}8QX"NB Qz1F)Y                          return -1;
:ZyAa ^M9T                      } b~^X2r
                     printf("opnd出栈:[%f]\n",a.data);B'S3R"ZA;?w%{
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/}.U(MJl"OL A
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
TK k Ux`4izX0G                      printf("结果入栈:[%f]\n",opn_tmp.data);
'EB6Q:z!D2p                      break;9C tJ\HD0vJ(?ly
            }
:V'^1A_6i+W#cb         }&V@`1q?(}t8O(Ep
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                *Za&w.[dLF$~j
    }
gpi c;rN+G     GetTop(opnd,opn_tmp);
.d"uOE3UZLX     DestroyStack(optr);
N Hia3Lp     DestroyStack(opnd);
-C-o8f6A:L`     return opn_tmp.data;
L v.b7?!`,Xv }
T1x"OE'A
-Pr#}QE#R#C char *killzero(char *res,float result)~;c.mQt*wmG
{
bz*}Vg[!Nt     int i;H _[(c%|-M&_7xVK
rh[.TDT[ KK
    sprintf(res,"%f",result);8VOF/Ey
    i=(int)strlen(res)-1;'c |.ogJ?Z3O3N
    while(i&&res[i]=='0')WG1u!a~ S\E1p
    {
|t9]4}?-bCV0m         res[i]='\0';
4@5h/l$^9v~5`:W         i--;'qzw+q}"|Gi
    }
!e+z1Rk+}MSa(I     if(res[i]=='.')x5J!l;C"mCf
        res[i]='\0';
z;c'W2m n;|     return res;-V"P&W9^4n'@
}
oZ4l~o)P &_bf0Nz
int main()2IyfF!Y+~
{8RQ&S$@1zpa/T S4^
    char ch;
*|fu0MlX4b7C     char res[64];
\+}Q}.J     float result;
A(k*LyG+rx     while(1)"d {A&Zef2PBF
    {
'V8F)|1@-l,re~         result=compute();
&C*D-E6N:Q z4k         printf("\nThe result is:%s\n",killzero(res,result));
"A2_ m l2w.c*x/c         printf("Do you want to continue(y/n)?:") ;
({K.Od2W0@ gND         ch=getch();
_&Y'w.OiS         putchar(ch);
m/J!Ha4z7Q         if(ch=='n'||ch=='N')
!~5Hu ]h`$?             break;
br2F#H;twb%_i(\AH         else
0j.t1pi,B}2{5k x             system("cls");'?p!L\;d'I
    }
R ~ ]ehl V     return 0;
8G7Y0r HS ^Q }[/i][/i][/i][/i][/i][/i]p&NgZC.M$C

.q6L:[7p*m [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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