捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
[MT%b#R6b,|x 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
}N Wf*\ R(?"l /**************表达式计算器************/
,F`*};s&`&NAX #include <stdio.h>:_&} ~6m_o@ S
#include <stdlib.h>
-N0_4B0F&JP #include <string.h>
L+K6qIEk3aR #include <conio.h>EeZk2q)ME
#include <malloc.h>5~1i%\xt,q?kc p

b2\q_#X #define STACK_SIZE 100
.z'K[`3f%p2l;I #define APPEND_SIZE 10 Eja"La]%v

a"G0Zz^$E{i9\/D struct SNode{)dq&J%N `3x
    float data; /*存放操作数或者计算结果*/Z C"[0FF-D
    char ch; /*存放运算符*/
W WIF)m%T i };
$\4E@ [%u &]ZHmY5]#n
struct Stack{N!o9ics Sd
    SNode *top; c`JWI
    SNode *base;
HO7H3z0VE(pi9V     int size;*H6lF4C5q\ A
};H0h-@AW)`h/i
b0WI'm+K+iB
/*栈操作函数*/
FjAs-cs8v int InitStack(Stack &S); /*创建栈*/
6jF0gW?,S3ts int DestroyStack(Stack &S); /*销毁栈*/i&O]T[_p
int ClearStack(Stack &S); /*清空栈*/hPu,`.a_v{
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
5\)aJ!ogC int Push(Stack &S,SNode e); /*将结点e压入栈*/Fv\D Z*|K7] Bz
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/v6E4b7`f!]

6T9M]a-h0]6`:S /*表达式计算器相关函数*/'ss6c Up5Jb rK
char get_precede(char s,char c); /*判断运算符s和c的优先级*/ O-pG*Cw&B c
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
jam~y!M ])W float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
"v#jmn,Y$[ float compute(); /*表达式结算器主函数*/P }*X(P\.n9\4L
char *killzero(float result); /*去掉结果后面的0*/
'FFH"k&B5Wf+T
0B6G#U/Y Q'S T int InitStack(Stack &S)*c#V{9s-uown
{s-K i4G0L'@
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
ZDZ|r|     if(S.base==NULL)
3D\!E.{@1r,O     {
7h;~'c%KE&A3O/p5Z6c         printf("动态分配内存失败!");
'x)rI.pyA%P!U         return -1;
1v5U ^ eS4vx3Y     }1YsB&\ DNJ
    S.top=S.base;q@K5|D*R&V7Ae
    S.size=STACK_SIZE;
D}9I(? K-Qgwp     return 0;Fb4t.R%f J5E
}3h1KW9qR^0L
(Yld+f D
int DestroyStack(Stack &S)
0r?4dY9npEXkQP| {
lNfs StOU`     free(S.base);#U&h_zUY E
    return 0;?W8DX T(}
}
H_1ird.` UK/`
$a zwA3x5u&S@I int ClearStack(Stack &S)
$\6zI(uQuIX {
0CE8[Ll1]^     S.top=S.base;(t'm8\)z U5ody0a V4HB
    return 0;i~n*}x'FK+q
}
{B2K?5l!m']#I Z'o@DAe
int GetTop(Stack S,SNode &e)y-tJ&nXCZT
{j)X [T,p;|b(Je+{ C?
    if(S.top==S.base)'v.WYe#VGc'[5]
    {
$a/fd(f^)tq1Y1L         printf("栈以为空!");&GY{-YBF&S0V ^|
        return -1;A#?V{9u.m
    }
#a#P tJ MN Z%cy9O0Q     e=*(S.top-1);
H"? nI6pV-a     return 0;'xH e*n lQ5w7]
}
cK hc$l d(W5g 8k ]M?+T_C
int Push(Stack &S,SNode e)
t]C2WP jX:W M {
3H|3P~t+v     if(S.top-S.base>=S.size)YP @h'U
    {
~ Fw1^g&k2|5RU         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));v+`R qy&p
        if(S.base==NULL)
5w `p/]#Os         {bG;a*g/j+M
            printf("动态分配内存失败!");&mj,xY2vQ8U_ H0JV
            return -1;V*t6h];AJ6l
        }%x*ZsAJ*z,H
        S.top=S.base+S.size;v]t ^jk3x
        S.size+=APPEND_SIZE;
-f"fB[ Q%` } {     }
.og&qebv.~h     *S.top=e;V-B-Y#ZL*wk%A,E
    S.top++; Axm+S&W,[A]
    return 0; e w(pm` L
}
a2X^YD'q)?0J
o N4E"L [7Re&q int Pop(Stack &S,SNode &e)
|3]yw&W2Xi%f*zJ {e4s aKgZ3Vp
    if(S.top==S.base)
4j3Qh(h.X$O~     {O+X#^,j}pB
        printf("栈为空!");
%L fd9A y?fU*[         return -1;{fS&b |K(}'I
    }
9V&etPq B3C     e=*(S.top-1);
E o'GY ~%g     S.top--;\6\)Af nRk
    return 0; te&GQcDX3s!z
}
c4F*B:?1j b
o HyDg9Sye0I char get_precede(char s,char c)
(Pe;C6i(Z {V"Z)q#lk"D|h]
    switch(s)
{C+M+R'x*_utt     {
%L$Rvc)P/fF)|F         case '+':                 )zMm|t%U.X8T&J
        case '-':
V c5G9^*rh ony              if(c=='+'||c=='-')
y|%nvzg:j1X1x                  return '>';6pj?.C,M'A9L
             else if(c=='*'||c=='/')
D'W"po!S&`K                  return '<';xy!vJq8d b Y b
             else if(c=='(')7Sm(D1u5X}U
                 return '<';vc/L~5J
             else if(c==')')
:U'~GeVfs]                  return '>';
+]asY1tjJ              else s&S:}#D9o6Wb
                 return '>';
9_/|+~XHB`         case '*':m y["yF5y!K%svo
        case '/':
"I/NL|D]              if(c=='+'||c=='-')
]C'Fa {6F} W                  return '>';#Z2I9n{)sD2L y RN
             else if(c=='*'||c=='/')-e-xAc7h4Oj.z
                 return '>';1Llm'@Q l
             else if(c=='(')
S4A Pd&`0Kd)q                  return '<';
F OHNhN[g              else if(c==')')YsZ6}hs
                 return '>';
+P$PP5}!IV              else
U$m B6V]3@                  return '>';{"CL2e Q]i4t
        case '(':
}sUW#tvd Qb              if(c=='+'||c=='-')JldF)Wo
                 return '<';
V lva$| \W              else if(c=='*'||c=='/')#N;m3h v*VCp
                 return '<';
8?` B D'E              else if(c=='(')
3E1u0w|.n Y                  return '<';6KhLO&E l,p2TV*q
             else if(c==')') j tyrT
                 return '=';.}Z%_$BX/k,kM
             else t0`\,L0n+P.N/Y2kif*V
                 return 'E';J'Zqb [C|6w
        case ')':
hCQ w5E@c/QynjM              if(c=='+'||c=='-')r@0Tb!@"h5G|}&|3{
                 return '>';
kE FZJEL#A8J6o              else if(c=='*'||c=='/')
eQ$W#|C [ k0\                  return '>';
.yE Bjw{.vx?cJ              else if(c=='(')
7r[*T7[P+?                  return 'E';+X+i-J,\|K-@
             else if(c==')'):N;GD4nV
                 return '>';
LRg#~R]~a*F              else9r _4] s*u'Y1Gb] O3v
                 return '>';G6K"b#J*Y
        case '#':
8^6v;QT IFyAh ~              if(c=='+'||c=='-')0B&v)p:D2V'l(dj"QM,D
                 return '<';
,Cx _|o3z              else if(c=='*'||c=='/')
y.t}@y5r2\.y                  return '<';
q&C3hgE.~9[5u              else if(c=='(')
ZX\.mIC                  return '<';1m#heB#DDvY5y
             else if(c==')') sWrp9eqN
                 return 'E';?A%s4r1|w2?
             else+G%F}Tn&X0} bY W
                 return '=';
"OCu P(lNi         default:
TJ? Y[ s2M5P              break;
!?DF/sP*v6^7YA&Sa     }.pJY,V0T$z1g$E
    return 0;   
)^{.r%z8cq i/my3O }
^,AH7M:`r@\ P$yup~t
int isOpr(char c)8U6d6{;o!w&R,c}
{}7xk#l_t
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')1g8b*P"iNZM4xX
        return 0;
l4lk7]G9Z6J^yw     else
VH/S:x)D"su:d5R'y         return 1;
'_l_jk/t+V2d2P;\9m }
.B9o@$PM? h:IzT
o'b5g*T6C!~ float operate(float x, char opr, float y)
3JJ vvaGxX5XA {(e-~v8IM2m(^
    float result;S#Or6EZ2r^
    switch (opr)
#nX1U&oVq^V     {Y,~ gN w5y^0P
        case '+': g4~}*uMf
             result = x + y;
~{ BR[b [              break;
)?Q7@ [a         case '-':
jI}5t4C:z              result = x - y;/nKijs
             break;
$m%N7]1j~         case '*': ,_T!HV^9ng9c,l i*U
             result = x * y;
W1{+Tn0c C;M              break;
-gm B.f?f!o2T#r8j         case '/':
!X}(Y%GM p              if (y == 0)
VsmY7s$oI-]&E              {
kV!mrw%s-Q                 printf("Divided by zero!\n");
@A p+Q!k#r2p                 return 0; F"`$_Pp6Kl9X
             }F}I sgw*J Ku}4uH
             else!Sd#E6DT c3s.`
             {9l.{S-wg/n$N9D(sq.Q
                 result = x / y;
-xF6pp~y                  break; n!N"V"C5k
             }ev$DA2YJk
       default: 7^u5XBDxF4SBs
             printf("Bad Input.\n");
pv%cn1ghL              return 0;
1l/O wG1O9r     }4N:I$FF f d?[Lu!p{
    return result;
!l2vfOM }   
:{%v/W%i`| |$w EE )GI5t@4T0ZVcfG!{
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/Z2D/eb"Rq7Al m j
{.oBDt;DS2x
    Stack optr,opnd;
En:AIB[y     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
5sXH Q Fo     char c;2b}6|#_~
    char buf[16];
[2s$wK4X0pp-d     int i=0; r6Qs.?$Y
    HL[0gR
    InitStack(optr); /*用于寄存运算符*/o.O0R woMd NU
    InitStack(opnd); /*用于寄存操作数和计算结果*/
Ae%iX,l!h b W)X     memset(buf,0,sizeof(buf));
'IZ(N9Yk3v     Fv8?q o4_
    printf("Enter your expression:");
5p3Q.{e(w9C!yN0d"C2i         
dCn }K!l]     opr_in.ch='#';$p3jG+j%}v b lV
    Push(optr,opr_in); /*'#'入栈*/A9tV [} ~N
    GetTop(optr,opr_top);
Y K4Y/j MY:T0Y%Y     c=getchar();
9c.Zh5hd s^)L     while(c!='='||opr_top.ch!='#')
L6\b7K4TU"L[ O3on     {
"Q7X e @&f3?`2S"z$T         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
g|4q.h`$l@%[         {
3@WpFrs(f h:jX             buf[i]=c;
ls.h*^$i E             i++;
z$Q w0^+pxM:g,b             c=getchar();(S9yuX2U2|
        }[xmI&[c*p8RR#Y
        else /*是运算符*/'zWkSM6xW` K
        {E"?&LZ%hG
            buf[i]='\0';
?E7[ k9V)K`!l             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/JuMl Mc
            {
%Dy O.j6y                  opn_in.data=(float)atof(buf);
y0vS^ z.["V                  Push(opnd,opn_in);!y7nU/[+s5[ g,t
                 printf("opnd入栈:[%f]\n",opn_in.data);2B!I.Qd2n"[cj_
                 i=0;+CY$Q q%MK
                 memset(buf,0,sizeof(buf));6f\L]h5vSz9s
            }
NJ\Yfv&Q+rT             opr_in.ch=c;0M,`zm~I8E |
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
Z S T f;g3`h*O             {
(x3id _5I:q)KR                 case '<': /*优先级小于栈顶结点,则运算符入栈*/k9VMw9Cu&b2Rj3S
                     Push(optr,opr_in);^m*W+{aR-u{:l
                     printf("optr入栈:[%c]\n",opr_in.ch);
0qnv~ z                      c=getchar();
L)eG)c-K9P                      break;hT6p e.L6i
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/X'l,ER-}/gxj
                     Pop(optr,e);/U2ZY+M0ZmsM
                     printf("optr出栈:去掉括号\n");y(z:cL@f!v2u
                     c=getchar();
e[yW0|*`v                      break;
/_OLW_                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
1|1O(P#t(V~.K                      Pop(optr,opr_t);
"Q?&@:gvpI^n                      printf("optr出栈:[%c]\n",opr_t.ch);
+q5j_.MFm                      if(Pop(opnd,b)<0)JW:K6?p4e [ h
                     {
1s!CHk t#c3H)n {                          printf("Bad Input!\n");8ak?0? |.u2^n
                         fflush(stdin);
!eTNE+T                          return -1;p d mj-x
                     }
GY9F m\.nS                      printf("opnd出栈:[%f]\n",b.data);
XFuJU{4ds                      if(Pop(opnd,a)<0)
{kv)Rx!CWu'EfSP                      {
-k Fb5y)L9w8VT U8\                          printf("Bad Input!\n");wa/? h%r[!JI%}
                         fflush(stdin);#M9\s2?H"j+a
                         return -1;:p|z!y:KO
                     } ^6|n LS'gI_
                     printf("opnd出栈:[%f]\n",a.data);
[i/i-?%[%TJc!C                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
7Jx;x,q P$BY                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
([$@9I] wH0u                      printf("结果入栈:[%f]\n",opn_tmp.data);A_6J1Y6G;Y1vb
                     break;
2_9F!g zqj+x2M             }Ee1@)q~
        }B!hO?%[Nt5hw
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
j%w}.VJF X#s c     }
"dp(Mfc2W |4j5MS     GetTop(opnd,opn_tmp);5l1x4K,~$LBT wM;w4l`'t
    DestroyStack(optr);
hB,] D}f"T     DestroyStack(opnd);4hKv%~j:F Ei1E
    return opn_tmp.data;
&OSh q!Q }-e?$Eh#v SH

!v P}P'S:h,V }6I3IP char *killzero(char *res,float result)
:a8TXU{8s {iJ0\g Ibz5H
    int i;(ff:?1X*U7?(djS
](f U~1U&@
    sprintf(res,"%f",result);
#`;G;Y dHpWa,?     i=(int)strlen(res)-1;
{\RM!g/m e     while(i&&res[i]=='0')
7Y2r:jvCo J9dAHb     {
1qy3K4~X]7t         res[i]='\0';2T ] Q+` qT
        i--;,d:P9NDP3Vc-[8n!U
    }'K.p6x0I1\(l#^T ^
    if(res[i]=='.')s^!yAi2K.W L2^
        res[i]='\0';"q!CD h9l_M#p Ar
    return res; }Q.YIa:d-W!}
}
'uXT%gip8l%Bo8I Ma+Dv S)F$I!?9K,J
int main()i d,exE(i^pzEi-z
{yO5d d1s7F;L+D.~
    char ch;
SII&z D `5bW     char res[64];n6U3gQR BH:f3t0q:y
    float result;
r#SBzz uV9a(}1?Z     while(1)
'j `n,X2{ AjJ5n4K8`     {
Gr5jWJ-N         result=compute();
d:U-k9l+AT`         printf("\nThe result is:%s\n",killzero(res,result));"h,l%@+R^
        printf("Do you want to continue(y/n)?:") ;Y@+U'P8X){_6_
        ch=getch();
5Nm~(N/G.s         putchar(ch);0XeHGE1q\xS
        if(ch=='n'||ch=='N')q(?m(eC yewN K5y
            break;HXL^4z-w `]
        elseY/G1u"j.p\3nI
            system("cls");
)@ Rb)nAj     }
@m0f/pCf9V}9xn,` Kw     return 0;JA N6Z i7S
}[/i][/i][/i][/i][/i][/i]
xRSXHQ!Y%ela
]b.h7MB Q+f4m6}-xm,} [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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