捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.)er+}4|Mt5C$l3M8Q"i2L\
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
qYp"bi /**************表达式计算器************/
1e h_R4t3V #include <stdio.h>
M H?A~Z*E3JU #include <stdlib.h>
w#H9N:xHW4I/z #include <string.h> S$X{ C/p`'O$}
#include <conio.h>
M4V7^ZMX7oW #include <malloc.h>
pH!I\ij\,E8Z G}
2Z ~V^iT c #define STACK_SIZE 100
&ny6@5R%W #define APPEND_SIZE 10s#e,L+q.R5A

v6WgJG0E/@ struct SNode{ ksEW/W~;BY1z
    float data; /*存放操作数或者计算结果*/iE%pNj
    char ch; /*存放运算符*/
&\w0Db4Z q ~v;h#d3} ^&\N };
D"} ] P5R~f Qny+ht;Ix,dw*c R
struct Stack{ a0k#tK)z!Z
    SNode *top;3vBY LT Uy"\
    SNode *base;ytG$\DDr G
    int size;
QEx%Y#\3Y;t[ };
!s$OI3@4mM#~,F]4n xm5?s G{ g/P!v
/*栈操作函数*/e&Hj8b d.Uta
int InitStack(Stack &S); /*创建栈*/
7hT*P/rs!N w int DestroyStack(Stack &S); /*销毁栈*/
.Q&xw0JSFT${ int ClearStack(Stack &S); /*清空栈*/b m.iW4KC3qE u
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
%ZH _%N n;s4b P*_ int Push(Stack &S,SNode e); /*将结点e压入栈*/
Ka e7I"EW int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/fQEI9^2I.w8Q

-m6e"s*Fto /*表达式计算器相关函数*/(}#S{ |~#{1p
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
rC e_[9e1C int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
-D7l[N mxexYF float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/[r#cs&{
float compute(); /*表达式结算器主函数*/
G\:Si0m char *killzero(float result); /*去掉结果后面的0*/ $d!A0X-f"d5?xvIIv

s;v4c&qNE+Zs int InitStack(Stack &S)
C#Ob fM6?3Z6a {
l{0d3Y i _1U     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
tRM:AN*p4c!yJ     if(S.base==NULL) Ec}6h&^(Z h cP%Ie0Mm
    {-E5ZMZO:fJ0[
        printf("动态分配内存失败!");%q!\MO0xC/p|l/w6]
        return -1;
cJM7b0{@H0p"w(^     }*Q+T+b8YHe1q
    S.top=S.base;$pR'E T7n {H
    S.size=STACK_SIZE;Np-sJ^/R
    return 0;a*At!S+f0M
}
!bi N3MSqL;Hb.KW *}#I5Iaul;rUY
int DestroyStack(Stack &S):kF*A^6n
{
6N*i+l,e0V}     free(S.base);;c O Qd1b
    return 0;
%bG L5_7Xx\.r!Zb }'|*dN9a'I
lW9Q(g#?O"H s%ik:D ee
int ClearStack(Stack &S)1u L4Zcwez
{
j C*Sm \3O     S.top=S.base;
V'h(\3u;v^     return 0;
D R8CJ$P(VhA!] }
~fSj0A G"w vl e?
int GetTop(Stack S,SNode &e)
.o Y0Vs3L5q[y/J {+xCpad ?
    if(S.top==S.base)
5DoK$hb!C,L     {
Y3sA P9sPf@         printf("栈以为空!");)a7E+H4hm~*od
        return -1;
G.P d'P:Kk     }
@a!I.U;K lX     e=*(S.top-1);
&Rlkv#zt'_a     return 0;TCC[h
}nKa/_:{G
E^LC,J'yj
int Push(Stack &S,SNode e)
k+hY4k Lp9G:x {DT1]Q$^
    if(S.top-S.base>=S.size)
kg$V+h2Ft'?@ ~c     {RTf2B6Y!g3Q
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); BP FYH yb
        if(S.base==NULL)qO9S ?;b8C(}
        {6\_$Le0Suf X
            printf("动态分配内存失败!");I|({S"g4P
            return -1;
?k ck/C Q9HI @d         }
1@JCZ`M F         S.top=S.base+S.size;`D;f6rhl@w
        S.size+=APPEND_SIZE;
jEzQ4_     }z*Ai _'WA
    *S.top=e;
@ ] c6z5w8o\D1D/c     S.top++;Xm&I9Y G
    return 0;)Dgx*tT0e D d
}Ln"rl)i e

+N)ms }R int Pop(Stack &S,SNode &e)
G"i Z~#M)d {jNts6^
    if(S.top==S.base)
*f w/VyP     {;w*fh;m3OH
        printf("栈为空!");
SO4LeS         return -1;?%I F)wDS#w,r8E
    }
rWwN}5b`,K     e=*(S.top-1);
[ cV[!y%h     S.top--;
P5v}8ara     return 0;
2Zsy)P4D4gX }T.d8JZ&Ul?4C-X

9R+XW7p@e/VF({ char get_precede(char s,char c)R8MP0Uxp
{H#oSn8Xw
    switch(s)
(dX3g%upt"B gW     {Y dbN |n
        case '+':                 -qK+^ZI/q fd
        case '-':
7o1?o3Y,RB_              if(c=='+'||c=='-')
#c+XU E%U                  return '>';
{ w F+Y'Sms$^RQ)t              else if(c=='*'||c=='/')4]FZ%C+L'b3L~yR
                 return '<';/bH"oXM2Zj"r?
             else if(c=='(')
3{kPQ!bE                  return '<';
#PtvE6fGF&W a              else if(c==')')
8wq's{t                  return '>';"I4k J.}8U5I
             else L/S.as8kA ica[
                 return '>';$KaJ E"K9S}1V:N
        case '*':Iw8Y+|TfzQg
        case '/':2x}&`umv
             if(c=='+'||c=='-')
;V!?:I!v*_8G O j                  return '>';,h+a!^1y?Pc$G
             else if(c=='*'||c=='/')dT jS2h-pM"f
                 return '>';M$lG;Tn_X?
             else if(c=='(')(x9~/Y2SB(l_
                 return '<';(y-C%J.F)vzR
             else if(c==')')
2{F'o|l8ih                  return '>';
3kT5W ^'JMW              else"?:[}/BU Z
                 return '>';
1D AG*LS-WJ xjN `^         case '(':
.K,hqL)L C%zp              if(c=='+'||c=='-')
5k4p q1R-C7k                  return '<';d5jY,@FB)p
             else if(c=='*'||c=='/')
-\3o%`&Q(Q)sJ*T*c                  return '<';
}d-G#MjKE0L,]&j              else if(c=='(')
RDWR-hI9t                  return '<';
YC(h,Vt r"m              else if(c==')')
lD |1v#xO                  return '=';
xrWh:r6@/x              else
(K+B5nr$}R                  return 'E';6P ~ t"KUX`D
        case ')':w K&xoP
             if(c=='+'||c=='-')
c+n3L+|'J                  return '>';
-B4p$S*]wav4R?&R              else if(c=='*'||c=='/')
!`X0R4lS1Vw                  return '>';"T1Hi,sb }$GR u n&|
             else if(c=='(')
4i%S8_u.\&TN                  return 'E';"y*|v$a9ga-G
             else if(c==')')
m1E |*Kn                  return '>';"OeBGJjjc
             else EB's+n0k n
                 return '>';p0H2EBH
        case '#':
y` m{ Y              if(c=='+'||c=='-')7i q+~-] [Lx6F
                 return '<';wfV0zD@aI.iBR
             else if(c=='*'||c=='/'))q,^TXdv1Z?Yr
                 return '<';
7~&Gc,@"R%Qy              else if(c=='('),JEK.}6gXXf&u
                 return '<';
(e#tVH'k              else if(c==')')
r(m$Jk^o5c/_                  return 'E';
dt7G,N,Ayq              else
u9R9NF] y K ] r(?                  return '=';
NG(?%B%W/^sR         default:
A-F%O,iW)a!Q4P              break;
{qo!x4M)t:@l9]     }
k1ck!M*R&Mx     return 0;   
Z8uy$M"O0{9W H,O }L&^ gsU?8U
l"EUC/cY X:Si!~
int isOpr(char c)
j:b's"F\? {0w~/oE R\&R
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')K4Y6E.L"n3@4S2`
        return 0;4e5JhI @+KBO3lsQ
    else #G0?b)RiE3c)w_)L
        return 1;cu ] g4Y1IZ$`(\1vi
}
%Nl5pus%R6N
nwCf+n2Z float operate(float x, char opr, float y)
N6WJ1Q*vaS {#n C;D9{lP8T[Z~
    float result;
yu Qc6MQ     switch (opr)
Es azap)f     {8S%{z J6rmE[p1gR
        case '+': )s1JS,]R2`
             result = x + y;
|W+h'U||4s B              break;
L;{B D)GK         case '-': r/T"h4f odo ^ K.q
             result = x - y;,Y$JXtk%?
             break;
8s%~a~;`K(O         case '*': 8i+q5hI7x1f1r&z
             result = x * y;-bD_SQ%T
             break;PZ\h3C7f)G
        case '/': u8fY2k `;}!r? |
             if (y == 0)!B$wi9U4dQd#`I
             {9jaz4r1vM.~d0c
                printf("Divided by zero!\n");
N/Q|.ZMj                 return 0;
4Wt#yFu8wj%t+Pj              }
!H,_TA3X`Z*WN(g              else ftrX.W-yd*_
             {
y NY!z%p-WuS8rR m                  result = x / y;'D \R"tW2wr.K
                 break;
pR3e7v!R0n              } H;Qp+O"Qk&UOkl
       default:
.n bX1W/aD$E iT H              printf("Bad Input.\n"); t'~'ncEt4^
             return 0;
0kXx-?$[ k     }Qu-}+nIvsKur
    return result;
#ZN Z~6L)F V*l }    9}"k1cv6oH-Ce

1a1I-](F'{0A-o float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
kOP6w9r!V2PD {-q2C X&ii\ K2~
    Stack optr,opnd;/M ]3]q8d_{
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
o"s%a+`T7HY"U     char c;
R+P YB B.Z1lK     char buf[16];B\9xOb-`j
    int i=0;
F,zO]"H1~n    
8i`'W Qf9|v     InitStack(optr); /*用于寄存运算符*/*sV6y B'^-P[@Q
    InitStack(opnd); /*用于寄存操作数和计算结果*/
V,oe&]1[ c4HA     memset(buf,0,sizeof(buf));
G+Ln XQ d+hkJ     {6iiL1q.uJY
    printf("Enter your expression:");!s/a4}[b)qx-u0C'o
        Fb(\3~3BQ_
    opr_in.ch='#';*{1w1erLesn8K bp
    Push(optr,opr_in); /*'#'入栈*/aI ` I(`
    GetTop(optr,opr_top);
Z%WkS J;A rb     c=getchar();
9n/Ic[J&eayX     while(c!='='||opr_top.ch!='#')
&b0b B'a2}9iz9lTn     {
oE)m+^9r$H1e gM5I p         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/Uh-SW7Oiw)s _e2@
        {7d)l.bS3d]-\
            buf[i]=c;Qu,z4q!wwEm5E)P
            i++;vi `w*D bx`
            c=getchar();-LibT\
        }
$B3MuJ5Dq         else /*是运算符*/
)^twb,u0p         {2rs.p+hm
            buf[i]='\0';$w6L)G vDZ)X p s,ZJ
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
M,[4e$y*?!VIm             {
$dD"hQ+{ta.j5jS                  opn_in.data=(float)atof(buf);:jl(p8yV _-b'?H
                 Push(opnd,opn_in);
U `![*Lt,mZ                  printf("opnd入栈:[%f]\n",opn_in.data);0|7ZV}0gg
                 i=0;
*ZtJ n9Sl                  memset(buf,0,sizeof(buf));7a7r&Ii`;N7w3h
            }
R4Y7J2k!@e4te(S             opr_in.ch=c;B7ut{+Z3doK
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
;g ? T+N:l u             {-z0W9W$\b N j
                case '<': /*优先级小于栈顶结点,则运算符入栈*/]8K#NB2V;g|?Mm Smc
                     Push(optr,opr_in);,pT1H%O$wS.E6jW nr
                     printf("optr入栈:[%c]\n",opr_in.ch);A fU;bG'bK&x3KX c
                     c=getchar();
u0P}XU;\V                      break;!W!n7S%G5\
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/-G}2Q uX6Digd
                     Pop(optr,e);(A;oYr7l-IE8~
                     printf("optr出栈:去掉括号\n");
$V-g2E(C(c^](Jz]                      c=getchar();4? FcNk
                     break;(N0p){*d9Y?&`
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/$[p W3Z[Uy-h'MN
                     Pop(optr,opr_t);\9E5k D']:H`\
                     printf("optr出栈:[%c]\n",opr_t.ch);
m)MIb.w                      if(Pop(opnd,b)<0)
aB#Mf;cN;Fdo"|                      {
w'G d(QI3?%V-p,f                          printf("Bad Input!\n");3|,_` p(v2X%j4_ j
                         fflush(stdin);
5{ \.B}6o4G,D1S1R                          return -1;
\k7w#~b D:XJ!Y                      }*TO#u/KX6WW0J7U'X
                     printf("opnd出栈:[%f]\n",b.data);"U)K^NCzv)D
                     if(Pop(opnd,a)<0)'h4gP W#S4T
                     {
6@Ed'h5v                          printf("Bad Input!\n");iz6Z6wt
                         fflush(stdin);
ZsM,}J|}:{                          return -1;
!x"ouUH;i                      })oT0rK"Iv B
                     printf("opnd出栈:[%f]\n",a.data);@X0V6N(] ?WO3c
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/)ZMy*dQH'@
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/2ce4uv'UpR
                     printf("结果入栈:[%f]\n",opn_tmp.data);,{*K?r3AhA
                     break;GUGRM$T0hs#p$ZK
            }
'TD%h H,\9^&b2k,B         } G0R#cF j2?ixy
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
+n"Y"l3p!V$yj'T     }
"Z?#e Q7Bj*T     GetTop(opnd,opn_tmp);
a$z~&rY2jr:k     DestroyStack(optr);#N"a's#RO:|
    DestroyStack(opnd);
6~w k5rD%M     return opn_tmp.data;+X La7U%znjOjL(i
},gB,Tih_
1j~!RV&Y-cSrl
char *killzero(char *res,float result)
3@)V0Y%\O!O-]kc {
3C F#[+{6}+Y     int i;VqELAX3A

BO2d~{UM     sprintf(res,"%f",result);
-V.?XI[-W/AD,s     i=(int)strlen(res)-1;
7f.i"L"[e j;U _Xn     while(i&&res[i]=='0')9q3b1}Ed0v
    {
2s*E7@&aw4M         res[i]='\0';(Hb;w3t%H N4pJ
        i--; N2W;@)]}'Nf
    }
"z/F2?5w3l6sD     if(res[i]=='.')B0GM1x'g/e*j
        res[i]='\0';.? I3Y8`_?NB
    return res;(`bm*b @4_,S3w
}
+~:Ze}I`+B%I
7RQJ [_be^ int main()F$xSyX q(r
{O`HJu VXD)oc
    char ch;6SpM\9i7s$Fm
    char res[64];(]|1|8^`3VXX
    float result;
8eB#`h%r9|/]2US     while(1)
CLQ'^M1n SH     {
:`gbS U0^         result=compute(); y8uPem DL#_3m
        printf("\nThe result is:%s\n",killzero(res,result));1oEA-b DP h5Q:t
        printf("Do you want to continue(y/n)?:") ;
G|(lC6bg F         ch=getch();
V J POy         putchar(ch);
6Kv7{&n;U&b+G,O`^         if(ch=='n'||ch=='N'):M1pt!X0pCcl
            break;
sQid)r$y$Du         else}3xU6VPe|'^
            system("cls");sGGD#@kXoA
    }
rm |g+h'{ t'te     return 0;
cpU&W.z }[/i][/i][/i][/i][/i][/i]'Yy;k1jo1cr$m C
l N#T P Ej)p(M
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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