捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.*\ n*W g~+Lk&D
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=5`AUZIV`
/**************表达式计算器************/b#mJDC _G
#include <stdio.h>
qX.n0f!Ux I #include <stdlib.h>;r#V8F3Nnm
#include <string.h>
i$u6D yO v o #include <conio.h>
K[N#nf$e,A6D X;S #include <malloc.h>
Ee6J8xqW N;~/bDY7CB}i
#define STACK_SIZE 100C8Q%GO9I$M/{
#define APPEND_SIZE 10
8\_/nI9B%M'Ky L-`k L_(v v{r
struct SNode{*kJt:~s/C
    float data; /*存放操作数或者计算结果*/
h)[*n[l.V Y     char ch; /*存放运算符*/
/D'HG5K$N y1J2H5` };JtzlfO ^?
zdR9J/k7`#{{T
struct Stack{
zB#S,j!V-R     SNode *top;
.r%~ y[K;l\ I,v     SNode *base;
i hg i)i upe     int size; gKj;~vTa
}; Ai;| TKy }l

JBRoV [K /*栈操作函数*/W'L,RuFX.N(S
int InitStack(Stack &S); /*创建栈*/
P:u qR Pp;b} int DestroyStack(Stack &S); /*销毁栈*/
K5Vi+a@-Y m int ClearStack(Stack &S); /*清空栈*/#f U|s g{;` aE(Re
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
M i6x8s(fq"s int Push(Stack &S,SNode e); /*将结点e压入栈*/ G7N3G*j]B\^-Z
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
8nP\K3Y2V e!zgw O.q2D H
/*表达式计算器相关函数*/
a9F0]7F%lYH%B,dd char get_precede(char s,char c); /*判断运算符s和c的优先级*/
W&\ n] G4d int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
Cn Cd X Z)u f float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
x#ms"B8nlB"}} float compute(); /*表达式结算器主函数*/"g Dk$n%S Z\9X
char *killzero(float result); /*去掉结果后面的0*/ E%Cj/Hd"a5ZVb3n
6k1X[a!s7i5B\"IkWq
int InitStack(Stack &S)
;hu @t^&{,~ Y-Bl? Q {9A@1V,G}
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
U1Q3Q(BcSGTL2n}     if(S.base==NULL)
#M$b1EO2T     {
H:j5O-e5gl3V[uK         printf("动态分配内存失败!");
Q c8t#ed;S3Z(T         return -1;
6d0r:IExm*c(oy!d     }
FE#Og+W [ c     S.top=S.base;
l%~x%C u ?w1q3JT2w a     S.size=STACK_SIZE;
a7[v(j~'won     return 0;
7G Dp1HL }
6s9}ea*hbk2|7Iz M;vM^8|l ]DI6V/r
int DestroyStack(Stack &S)
3JD~){,m`t M-{X#] g q { tT P].|5X,n(y.M.c
    free(S.base);
g ?}^S O$[s@~     return 0;
6wl,e _&A W(A$CJr!q }
:k _7J}S3A "G\r"x!n&Nt I i$\.n Kn
int ClearStack(Stack &S)+V6Iw5Dm1` L9GY
{Pfy?5X9^,F%LoK
    S.top=S.base;OS5}5P5t3X7QZe2\
    return 0; UP^!CZ'tw
}
&P*K[*} r/e'b S1V1WH|9f
int GetTop(Stack S,SNode &e)
D6GR9m.cX {
R!|`9vjz]     if(S.top==S.base)"S:g&t!s9l}^0RK
    {9gs;P6u0]u*[}C*i
        printf("栈以为空!");n})L+a#_c/[
        return -1;3tjq%F9mQ R#Zw2F
    }
PY8ra mRo     e=*(S.top-1); bhD I+CK?
    return 0;7Woz{2B:~h6J^
}}lf P d K&A3m

F2`;QR(f\.^&U int Push(Stack &S,SNode e)3Ocz sx.o
{
P|$X6w+|\.QM7\I     if(S.top-S.base>=S.size)f7qU&x(vuG4f~0Tt
    {t ]o2s\-{ _
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
.meBQ.A4V UMKO         if(S.base==NULL) l:~ e3R3l$lAu"n(`
        {M@+t7pl$` te
            printf("动态分配内存失败!");
,q'D'o~#b"Y7M"g4p             return -1;[ tO!?"s/u
        }T'z*F%B4Oz:qp7L
        S.top=S.base+S.size;
%ue'Zm$G6Z5K         S.size+=APPEND_SIZE;
5BkNS(f     }
eSI"L'K     *S.top=e;
gB`X-A5Q[     S.top++;
)^zG0t6e{%?/}     return 0;
OV5_6W Uc }*j qrY `gQ
#j6i0c&Hu/g R'I
int Pop(Stack &S,SNode &e) j|d|B?"x+@-R
{
Oll)]k2b ^2l0R_)^     if(S.top==S.base)vq5[`)u4N.W:X
    {
@;IEfT%bC2|5[         printf("栈为空!");
z)D&L]R*b#u         return -1;hJi:c~ Kdv9X
    }P6I@'S,x7r
    e=*(S.top-1); PP5sN:Q8N
    S.top--;}Q-~^(OLG8f#Q?
    return 0;
B9N(umV#d5x'Q }*CB#z^,dV:{(ZT
!TV+M)g)sh+WQ"P
char get_precede(char s,char c)/Q1Ijw#S] B
{
*]x0ml8PPcNA     switch(s)
7g.j9hw(i9N \e     {
A2qC J-o j_6\G0\(b         case '+':                 #g#Tb#c q"fCy0E
        case '-':
3FX4iA\3r              if(c=='+'||c=='-')"S+Z$| l5sT
                 return '>';
O j9~]ql!r*X              else if(c=='*'||c=='/')
7tnV d9@                  return '<';,sf3v `ok r
             else if(c=='(')
z0q2|4Q+V6W                  return '<';
.C]o1Zi              else if(c==')')*vaX K3bD8u,R [
                 return '>';XBp3M%}Td)@
             else :N-v1t xw*n#CQ)Gu3O
                 return '>';
4frS@ T$d         case '*':
@N,t YP.J'}(H7Q z^1L         case '/':R3Z(dJHk
             if(c=='+'||c=='-'))X/mFt k`Ds5S
                 return '>';P(d2I!Q1}AS{.h&r'`
             else if(c=='*'||c=='/')
XYDQ"T-CKL;?b                  return '>'; c-RAc%AA#j
             else if(c=='(')
K9n pz,Y\                  return '<';(V(WMI#`gvzE
             else if(c==')')
? biS\!m?` A                  return '>'; nE2Gc1WK
             elses:R9Uf O ds
                 return '>'; OxM&U(nt @
        case '(':+m#oGsg
             if(c=='+'||c=='-')b,eM#ezpY
                 return '<';.~ b`;u(@6i7F b%|
             else if(c=='*'||c=='/')KpU9dx9d%A/sLZ v
                 return '<';
(tC I$r,j a6? b)J              else if(c=='(')
9m2u(I%x+ZV                  return '<';
6W@(y$NT+O&m              else if(c==')')
4n&A'TY @ T+Yo                  return '=';*^KL*v0gS
             else
xu:bhxFo'Y                  return 'E';
Oq4b5R;|u]|QZ         case ')':1ru:@N1L O
             if(c=='+'||c=='-')
t&z6y M(k                  return '>';d$P7}+?.\)M
             else if(c=='*'||c=='/')
R%E&EY b4U|                  return '>';
1[9^LVV7sJ              else if(c=='(')
E$R3l{8nt\d.i                  return 'E';gg"^8a M\
             else if(c==')')Ni_cc
                 return '>';4PS!y9n E:hg
             else
5{8V} LiE                  return '>';
t RDx4sjN:SiU         case '#':
;N,g,\/x:| Jr              if(c=='+'||c=='-')
by&?h:HQS,r-`                  return '<';
j'R$a0WsaZb2cV              else if(c=='*'||c=='/')
W;XwOS'U]X                  return '<';
2~f$Fi Azn              else if(c=='(')0C-V ? Fm_
                 return '<';
I ^&?"i(s{              else if(c==')')
:iAZ#{/\{J;E#I4U~                  return 'E';U[q:kBOyP(q(Y o
             else
(y.V3}YqeM| I                  return '=';
3H MaVW0A[ U         default:
6T7[rh4DD9f7C&]              break;
(tjc^ne,}     }
"pR9~;No o(uqu     return 0;    tA6o6hx"[X@
}
0C j3p+]_#dS2K0@:`d
6D!m(jX E6zQ${ int isOpr(char c)
q*L6k6|$b-v,k5V {Keb#D-xy8zd
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
e] b(o.Sk         return 0; Jr3im^&h-`
    else
By"~w+V*?T.`         return 1;*J*R.iT-zbxF
}u,Z6vfn)Y)M

2@{-\ `7t M Z0l float operate(float x, char opr, float y)
;R [8g)A"~(x {0B np @Z#J5e7Le2G
    float result;
u]ng8^4G;I%d     switch (opr)f/C;}|J#I#Al'r.B
    {
8R4k!T`"DZ         case '+':
%@4m(n)YQr\D              result = x + y;
IL H%F5zs              break;!Y:t qtk-A Z*e_
        case '-':
7~J r-m"~ V1Q              result = x - y;
!U9o,[U.T:y              break;
c$}I3d r         case '*': 'vuREbT
             result = x * y;
#M X b'\N#FQ3q              break;8q-QOj^O8J
        case '/':
L}9yy1P4G `              if (y == 0)._w)v'h B H\I
             { R q3w \ wD
                printf("Divided by zero!\n");4M+f f+@V0RKs8`V2x
                return 0;
#`EVxc e;W              }
WI@R.pX              else;q/{I-R8?!T
             {$E\j:[)k)K j+a
                 result = x / y;BlgE Ew O
                 break;)VLz'}N mc$zqI
             }
1[9A wA5?fo        default: UW J3U a0v$a'V
             printf("Bad Input.\n");
w8B+ty T,OH              return 0;$U Q*?2fg,S;x
    }V+QkL+b2Z
    return result;
K*\L6\uTGgt)o }    !q4cf4@q

;CtJ^ MyLu(Q float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/,|u c*aOP9wb!M
{
]V!ph3_ B     Stack optr,opnd;u)ad&xM!I4y_
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;/u2n.I \3{2jVhOZ
    char c; oy,y1B4r
    char buf[16];
X9l'~,zF%[S     int i=0;0x0H!T~"t!\!L q
   
@*N;X,gyc     InitStack(optr); /*用于寄存运算符*/9U^-fIH8USt~
    InitStack(opnd); /*用于寄存操作数和计算结果*/XFY:@4I]t
    memset(buf,0,sizeof(buf));
3o |5MQz     !P&@v-tD_
    printf("Enter your expression:");
m @#y Q Z0~Hu         -e `7o*f4g B
    opr_in.ch='#';
(R8\D8yfXUI     Push(optr,opr_in); /*'#'入栈*/
gHyz6T1BG     GetTop(optr,opr_top);
^"{[4?h,u     c=getchar();
$I!b'oCJef@     while(c!='='||opr_top.ch!='#')
v]b;UU7~8[vCO     {U1V#}kzI0q
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
T/p2jq~%qq5P         {
PRr P EHl2}             buf[i]=c;3@^rYB
            i++;
/s$WJ|3E vO+sJ             c=getchar();
c/la2|8L5}         }
ht^.p,l${j*b G         else /*是运算符*/
u-}$qtM         {
"Q']Cv CT` IrTi             buf[i]='\0';,R*J1L3Kf!zf
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
!GJ{2nI             {s"V@+X)S0AWPE
                 opn_in.data=(float)atof(buf);
$O-oI C[faja4cm                  Push(opnd,opn_in);!ZEX JU} {T:G#AlU
                 printf("opnd入栈:[%f]\n",opn_in.data);3|}_&}2p
                 i=0;0SQ8[q+d'@T$u z;j
                 memset(buf,0,sizeof(buf));#Hbnj r;w l:Z
            }P,DfL }o
            opr_in.ch=c;tQo(HREk|7ds
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
"wupz&ho Ru:] [e!o             {#d#Q6n,mgZ Q
                case '<': /*优先级小于栈顶结点,则运算符入栈*/5Ba*I@Q']
                     Push(optr,opr_in); s0jor7\!X Qg
                     printf("optr入栈:[%c]\n",opr_in.ch);m)} F4n"vG [Y n
                     c=getchar();
AyQJBb i~                      break;
&zm?{(gz                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
9CKna3? A_;Ei1f                      Pop(optr,e);
HY"_5J2d"n#g ]$N(bDi                      printf("optr出栈:去掉括号\n");(t&i_c1i |Gt+~ ]1w'p
                     c=getchar();"b T6mP;B1n0w6G!_
                     break;
!ZPc|cS                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/1S/tX\"u:f3dg
                     Pop(optr,opr_t);
+DX#FC'?hw.Ra                      printf("optr出栈:[%c]\n",opr_t.ch);3L;g,{&H(G4I
                     if(Pop(opnd,b)<0) o+Z4_a Z C(K
                     {#dyRV7\vR4bv j)x)[
                         printf("Bad Input!\n");
.moB t}0I,z;h                          fflush(stdin);
f?-ho Z1K                          return -1;)Z@ql1KM_ q
                     }
G!fpHr5[3d                      printf("opnd出栈:[%f]\n",b.data);
*Piqw$hy*{.B0_}                      if(Pop(opnd,a)<0)
3S*|c"n;{+Y/S[                      { xJ`'x(i+\ d
                         printf("Bad Input!\n");2V5aR]1M:V
                         fflush(stdin);
k:B W4k7U7Z                          return -1;(~sO;x8ur.o i9yX
                     }
B,A\8K-A V                      printf("opnd出栈:[%f]\n",a.data);
(@u\QO+g0[                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
el N/S8U~                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
k+c-{iT j'Z%b                      printf("结果入栈:[%f]\n",opn_tmp.data);
lD-S*{["[5a                      break;
(U)GB!n&KO             }c3?bT.b@~6}
        } ?)su(g?;c"P
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                B'` ]6oK7A ITe
    }
Kg1S'Ue     GetTop(opnd,opn_tmp);
-\2B*X6E,FE s     DestroyStack(optr);
;L(tdyv*N$zhD     DestroyStack(opnd);lh/kw8]#l$@7S
    return opn_tmp.data;
iDe:O5P:f`8zG du }
q ]!b#ay k I7mr.T XDJ\NBf
char *killzero(char *res,float result).WFNge2i
{'i-YhG6l+D}iX`
    int i;
TvQEi M0t F,t
J$[7_].q ~mg%e/T     sprintf(res,"%f",result);eJ(F9n"S m
    i=(int)strlen(res)-1;
*j9|x!sOF @]     while(i&&res[i]=='0')Y7wYFp/\b
    { E9dX{ S{ g+|
        res[i]='\0';.O'C:A6HTD+f#Y]^Q e
        i--;;K7b|iXN#FcT
    }
_![v.Yg1zY&Mt     if(res[i]=='.')b7N0KW2|X,p.GE
        res[i]='\0';oX$q}$@j
    return res;(`pz\C)x^p8}t2c
}3I&`F$`5[!X.Bp8k E

:Op;\ g`b b_ int main()
8`UdDp K'EV {;RC,e'\-iZ-H9|
    char ch;Y0N$VwH7~!yD
    char res[64];
!}MTa*U S     float result;&hmPh&W.K(Q#S'K-I
    while(1)
6Sy2O1?~u4m/kK)}     {|&F)Gj^Ovri^
        result=compute();&I*^Ys*s7@vQ5O
        printf("\nThe result is:%s\n",killzero(res,result));"~uMYpg
        printf("Do you want to continue(y/n)?:") ;
D&`W#rfKk,t2W         ch=getch();&h?'B%@D
        putchar(ch);
Mw}EH+J1?/Zl         if(ch=='n'||ch=='N')0L)QM-}$I
            break;
!iJ}C&w         else
:T7Pv"l2F)M}y1\ u             system("cls");;hl \!X9M+ui"y e
    }
T\@%F$I9ZF     return 0;7I J.sm(kA!EG}
}[/i][/i][/i][/i][/i][/i]2zR)B.\iXt

Q$Q S^:XN [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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