捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
LMbg tfU7D;[ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=0DKf0c_\2jT)DK"N0?
/**************表达式计算器************/#na2C$FF*[
#include <stdio.h>
vLNRKQ,a6Zn5u #include <stdlib.h>_Ac:I3K-`
#include <string.h>
_ oc-}:eqO #include <conio.h>YJ1EC0R9\U_ Q
#include <malloc.h> vS|8kh

I&i(x:aJ VBH #define STACK_SIZE 100
w8|2};IE(h L!V0YLL #define APPEND_SIZE 10
_1}J0zT+T.t|
3zG0G5qEtm struct SNode{
B b:YHI     float data; /*存放操作数或者计算结果*/
G+Sn[B%c!T     char ch; /*存放运算符*/
N;G JX2XA;` };
YE+L{_ t.}c O x@LiN,@[$T
struct Stack{
Zv8T j9Il     SNode *top;@ |+I*N5J
    SNode *base;7s1s!V0P$BCh:e#ui8[
    int size; _d w:aYQu&t
};i N(b7] Gq

:\rI*Fq0i /*栈操作函数*/
C*IrdNVit int InitStack(Stack &S); /*创建栈*/
]8C'IY#~:UQ int DestroyStack(Stack &S); /*销毁栈*/
S _Q{4? p0?.V&` int ClearStack(Stack &S); /*清空栈*/
$^5Q&lq"B7Du{ int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
1plO'U~5Y`V int Push(Stack &S,SNode e); /*将结点e压入栈*/ Q }BO-`"[} e
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
\zt%Y5|y3H:RN 6\0cO9bZ2H`d5L
/*表达式计算器相关函数*/`8[k;DN(POi!C
char get_precede(char s,char c); /*判断运算符s和c的优先级*/1fn J r8gH#O
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
$G*EDc*g2pF5G8iV/| float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
A\X:w ~m float compute(); /*表达式结算器主函数*/+P g9G.]+ZpSD6h
char *killzero(float result); /*去掉结果后面的0*/
+x4kFQ!tH~kZ
z3~2k3YrI g4z int InitStack(Stack &S)6RLctQ,]}XJ@a
{
3P!`W9m'I     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));OiA.c9\
    if(S.base==NULL)
(vp;bc+Ru ?%\ Ib     {
!c@wj ]         printf("动态分配内存失败!");o8T.]zn M!y`
        return -1;5?5\.}t&@h+w8i4_7x
    } X^xu$OP2c7@
    S.top=S.base;
5ueN;QB%m Ku     S.size=STACK_SIZE;8h"H%sU\ QoQ
    return 0;
(U)A&N1lF&Q` }
I1j4l9KL S.{0Lb 4VR gWL3FO,_
int DestroyStack(Stack &S)
U x;Tv"O-B yZ6FI&m:o {wR8p7{S3n7`
    free(S.base);
a-h1}E'w0f@5^&`     return 0;g#I5cnO{
}N'D&UYc4`
'{H0RU5LH5g+A
int ClearStack(Stack &S),M ]2V!K-Fc5N
{
aTu2b#GX8tz     S.top=S.base;'h/hhq p-S
    return 0;NY ph"Q({,D
}R-]W,k1JRA(?Tf9h&g
1a1}6V7\H;F
int GetTop(Stack S,SNode &e)/V n H&sMR ~F
{!vczn^ u,db]
    if(S.top==S.base)~7eBc[We
    {
? Sl _ p         printf("栈以为空!");
;SS.p(^2Y&x1nW         return -1;
w-T8P'P ` pL%V     }FF0Rt1C9J{V8_b8F
    e=*(S.top-1);
)YV7oK![f2P[     return 0;
zi:T W^5h0A }
i^:x]_ q9eI!p 2|6l-]S"y-B
int Push(Stack &S,SNode e)%^&@2X1y%~6_;G
{
DRT0e+]0B&J%D|     if(S.top-S.base>=S.size)0Z4la3W{rNz
    {
2q[q+vj,m         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
-c2ImQ*l5P8_9{         if(S.base==NULL)
,B#[&r:F)\_         {0}'j Z Y8N|1A
            printf("动态分配内存失败!");
5i#[:i.QK4t             return -1;;c[4e`#z+jS'Y3BM+_*K
        }"C+Rx%Q H h k
        S.top=S.base+S.size;
%t'{X)P/]6Q         S.size+=APPEND_SIZE;pwS y'g:MHK%q(o#O
    }
7wI!f)j g6O~L     *S.top=e;
_F#^!t(jB-r?[     S.top++;0fXr}1P
    return 0;
n/ozZ`#^ C }*f2|3X`T.M4s~
Mh8d tFb4X,OK
int Pop(Stack &S,SNode &e)G?J&eLv/y_
{ v c*RL O5c
    if(S.top==S.base)
/XcL1`7j)@"e@%z:qe     {o5N~+UC\8P
        printf("栈为空!");
#|(Zp r6@0d         return -1; L z:G(Y&?1o
    }
EhV6o*fLj     e=*(S.top-1);\S2W5RT
    S.top--;
1R|%Tw_ i9p     return 0;
H5Wg;BHl)?m } {WQ}.A5CZG"M

d6tN W3K r*c1n;l$c char get_precede(char s,char c)
%w[em~ZyX {
1g'[%\D/X:~C7}D?     switch(s)3w }+O)\"vZJ
    {
&FcS6R.ZGi){[         case '+':                 
)Zep)QA(Un"~p         case '-':j2OQ?D s
             if(c=='+'||c=='-'):O([e,?0t9su&\
                 return '>';uM_T'd S!i[F
             else if(c=='*'||c=='/')
nHg#{W?                  return '<';
2D-ED#x0e              else if(c=='(').i!W;\~!ow
                 return '<';
J*A9w2L*fm.Y:w              else if(c==')')
1MZ8W+M8pS RpA I/}U                  return '>';
]1SaS0q_s              else
mMRmT%bX+~.i                  return '>';p*sh(a,hPz
        case '*':"G c!V#Uv
        case '/':W-}T+hm+l&J?
             if(c=='+'||c=='-')+_(tc5z| T|%n
                 return '>';S0e*|^c'R,t
             else if(c=='*'||c=='/')Q'cjfZ`'N-^7L
                 return '>';
!G/O2H"msy!M              else if(c=='(')&BQ-ZB,y!N9X7@vw
                 return '<'; h)ngv XR&?
             else if(c==')')Y WEF WR
                 return '>';
Kn)|7\e'F&^              else\N9|4S:uT5K
                 return '>';.m1b7A0~9`:bd
        case '(':
+G8p}A&`1p)fm              if(c=='+'||c=='-')jxm$}s"[g6a k S
                 return '<';
D&e%Z4^1~"L1uX              else if(c=='*'||c=='/')f+MY&Q,q8E&@8m,A8R
                 return '<';
qf0L(| ci]Nj K              else if(c=='(')
n\f'j`#G|y/Ue?                  return '<';? W4{)U0h8q&?
             else if(c==')')
+GE? e ]*e_l                  return '=';
%eUM8C.e&T'r              else
"dwc |&~QbR9m                  return 'E';
Ctm)U,CR8h6L F(_         case ')':/N0c8c_DrM q3O
             if(c=='+'||c=='-')
U(oV/}U`NT0n                  return '>';*jW Oqt e6\!R
             else if(c=='*'||c=='/')
_ c wPk{|                  return '>';m@!R{Jh
             else if(c=='(')j3YsK5y OPo5_mpe
                 return 'E';3{1k%{:sq0cX
             else if(c==')')XB2~ h5x8An%Q
                 return '>';
&bRaBCRHs*sSk              else
4d?8rkgI"Jb2?)P                  return '>';
NB?te/SbC L g'D6T_         case '#': TS CX j[/N
             if(c=='+'||c=='-')
;Iy c~IJ                  return '<';
Dq'w+C!f9KI              else if(c=='*'||c=='/')
)f}1di6Jw~ oC                  return '<';
q+`{8] f,]eR              else if(c=='(')
CM'ni%Wk                  return '<';
P d/L;E5E)B4tTQ              else if(c==')')
#KYB#Iz                  return 'E';4_1?'c#E/f
             else
v/G$o;`]                  return '=';#A Vc,sv Fe:l
        default:
U0w!yR7Ti              break; { G0zz"B
    }5|ke}6H)VB
    return 0;    &Th%Wv2`b*M)V @
}
O^Oov\8E Y!R N )O MP3`b)I Q;].G
int isOpr(char c)
`GB}d { U;{6cn {
~xNKgUVEQ$|)f     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')oa\A5g5}
        return 0;
Tw.Kt-F[ b;hWF     else
KhvH/`+py;_C         return 1;
5RZ&h$zoN` }
b%D!H6bL8m9[@S"q $A.PC P)nqBO
float operate(float x, char opr, float y)
$JC E$} f {
%pK1iBb$R-w     float result;;S WN5A)KJ"OL Z
    switch (opr)&Bbb/|s)h(?5E wL
    {
"rH,j;s}$d}v         case '+':
haW/~D8Yu Tf!o^              result = x + y;
.\2T/L*PAt0J              break;(MA z5w umma
        case '-': f0KF&f i5k
             result = x - y;(s$wQyY US1q,MU
             break;
:DV`i VTt0T         case '*':
+_N:m+^V,n/rG              result = x * y;
yy ydh              break;
`fO+J7Z }"_+j         case '/': ?V4Ki7?(p_V'`Q
             if (y == 0)
%Mq!T P k lm6dc;M[              {${ H9qI@hx s"|
                printf("Divided by zero!\n");
i*U:ef2_*x                 return 0;
G$e0h#~ j              }[ YW)Aq'J E
             elseAi$VM`q
             {1j+@+oO,[.m6mB4fd5I E
                 result = x / y;
?9\6`~8t4a9_                  break;a E'\^$X#|#g,gX
             }
!@8f5{*_r        default: ;A)SA%PGOW4d+E
             printf("Bad Input.\n");
3I2B3^:c]_:e7cy/iClM              return 0;,v5UT~)NQ
    }
]/y.q"{9W5}v$q~U     return result;
Hc1Rqq,Uk }    3],C g,T#{'XtD

&L'] c+Y?-p float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/B)q A$W;R%{.Lvf
{
|7r2W/n o e"P]     Stack optr,opnd;.KCm%HmH
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
3Af}5X4BI-~0a     char c;
.O7n7_9RL s     char buf[16];
? z$Va;ZA;MN~6| F~     int i=0; Y6w!Yt;Z]
   
2TR O%uL E     InitStack(optr); /*用于寄存运算符*/
1`0Q m0}*sX;n'X     InitStack(opnd); /*用于寄存操作数和计算结果*/ @`mD(tYfG4\jR
    memset(buf,0,sizeof(buf));Uq]T8^/D
    _x2hD X,qn wa6R"E
    printf("Enter your expression:");
`c0][%RvR0Z         
9sO|!V}`4smH     opr_in.ch='#'; o R qjq/~
    Push(optr,opr_in); /*'#'入栈*/4r8t!isv5bU!wP6VZQP
    GetTop(optr,opr_top);
(dU)niy B T'f     c=getchar();
q$S2\S6w(IJ(J*k)o     while(c!='='||opr_top.ch!='#')4}5]qZ:H7N
    {
S&H{?7Y ?"k#H         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
`9Cy4Y[cG2LB         {
*cdbd,Z1G9n3G             buf[i]=c;
Xb3u$Jk_PQ _             i++;/[/QwX;U HA,a ]!fB
            c=getchar();
`P-]|q1\k F|         }s/N#l*h W
        else /*是运算符*/PJSr|V!S5`?rI
        {
z7P'n8b!^$^_]&I             buf[i]='\0';
4Y \EWb?6rT LB             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/*J5C&dx6s(Y8]w,|
            {
C9Es }%V                  opn_in.data=(float)atof(buf);
%W%Zm0k2k5O\A7h                  Push(opnd,opn_in);
M0Q Tk:\;g/^(p7Nj$LCF                  printf("opnd入栈:[%f]\n",opn_in.data);J?3djna+b
                 i=0; jq'QG+K'e&}#uZ
                 memset(buf,0,sizeof(buf));8ALd`U fgs
            }1YmE'c Xe4pY1eA
            opr_in.ch=c;d/QU]U1SO(US
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
qg7mPWU             {
b+kOTCT]                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
!o r |SQ%j.Ed                      Push(optr,opr_in);
6P*B6hj*V Z2|7K                      printf("optr入栈:[%c]\n",opr_in.ch);X-TX.@zC3W.o l6Y
                     c=getchar();"yI ?G] h|B
                     break;GO$}8Z"B8f&Ol8@ ~F
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/xc I%y9afO
                     Pop(optr,e);d%`!nU+H
                     printf("optr出栈:去掉括号\n");C;EO,^}0?;J`
                     c=getchar();
(}!PD*|0n                      break;5wpvo^1_ ~
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
:Z@7E to;U-X8T                      Pop(optr,opr_t);
:F+~0o'U6SnF2m#Ao                      printf("optr出栈:[%c]\n",opr_t.ch);
'K PA*_/N.@(d#EU y                      if(Pop(opnd,b)<0)
fk&s] |J1yzM*i                      {${P-CD[?
                         printf("Bad Input!\n");
(z*I.j7W:X'zKk _Q8w                          fflush(stdin);/t3Rn;JK^:u-H!Y
                         return -1;
-n!Z1c:S`u!A(Q+`R                      } v S kk7~scE
                     printf("opnd出栈:[%f]\n",b.data);
GoF z@&B$M ~q                      if(Pop(opnd,a)<0)(d.Kl(DDO*mrQ2h9z
                     {p{!i2u{!P
                         printf("Bad Input!\n");
GW`k4_                          fflush(stdin);
'B.IIUd6Gbu                          return -1;
A8^ m8Jy5K                      }F9E/s5ha+D%p2?
                     printf("opnd出栈:[%f]\n",a.data);
(?+] R,\#o9_                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/(dM H H GF];lb
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/Aa z-\"Dw
                     printf("结果入栈:[%f]\n",opn_tmp.data);
p.{?A.Xc2A Xr                      break;O[5z6RqBm.q
            }$V[7rrv2O
        }!i3a(]w \
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                4["[2Vi&s*k,wY
    }}0An8RsAw
    GetTop(opnd,opn_tmp);
bwW&~y#x2}     DestroyStack(optr);
0e5UUV6d l ^0Wj+t     DestroyStack(opnd);
]9X0kq4Mf#i     return opn_tmp.data;4})]&B)g+f!y
} A.xBl.ItC9JCU
3JPi?T'|sV
char *killzero(char *res,float result)G,U] A1lZ
{
iIy0zZ     int i;
%zK.L,g H,hpL 2l(m#D:}&{Q
    sprintf(res,"%f",result);n?`SQ.]
    i=(int)strlen(res)-1;Ht*G_!R$J'C4B`
    while(i&&res[i]=='0')
P.}r,MOdV     { z^]D wS$jz Z
        res[i]='\0';
1i)h:`9le!Te         i--;
Bw7Hd`%Q     }.a R%Rk;f~
    if(res[i]=='.')J)H$@6R7Mit
        res[i]='\0';RM_~ yp%S4B6q
    return res;
0vk&]BGe }1p"}+Z0C&H$eot7`
Ms`kLT,Y2r;g
int main()
?r$D;}X2u z y;r {
I.w1GA1EuF     char ch;`RZ K7^+_
    char res[64];
H T1a&y1~9w6J'TX+R |     float result;.m$pBh;r d!o
    while(1)
5A*K-tUV3A1gs     {Ws8nK*P-o v T
        result=compute();
Iq@CTs Zg8J         printf("\nThe result is:%s\n",killzero(res,result));$mP#WgS/D
        printf("Do you want to continue(y/n)?:") ;
fD8s1V N{-J)s)s         ch=getch();'En%y/J[Y*^
        putchar(ch); |%LKG/N;KE&v5PZ-N
        if(ch=='n'||ch=='N')
X;?7@(q#d7yy             break;
o/\ \8Kd*A         else
5k+w3Rr"Y7~             system("cls");
Q6zC-_7P*A!{!b.P t ^"v     }we'Y,qD It
    return 0;
!O ~*L f-Tgj8[ }[/i][/i][/i][/i][/i][/i]
-c3_t1pC eT|3q
E+g E^~ [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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