捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.[G1N$N7|1yPJ(A$|
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=0Bu?~6P V E p
/**************表达式计算器************/+_ Q+Ai/b
#include <stdio.h>`\1k&m1?k7Q#t
#include <stdlib.h>
!zqf#| \v%{ du #include <string.h>(iV#T6xl6d W)`!J
#include <conio.h>
4f9kM+T NF?5b #include <malloc.h>6uU2Q3V"J*h4P

QU`'dH #define STACK_SIZE 100
Bz0tY/yS Z }%J O #define APPEND_SIZE 10p_b4b9oeD
@b8P^6@q8ZjZS
struct SNode{
snj-IJ ~7^$C"Ux4bQ     float data; /*存放操作数或者计算结果*/r6kHUB%^ C!y
    char ch; /*存放运算符*/
Na q(P*^p0ud };
!FegT;YF2?)\i ,Dl z6GJ:|P
struct Stack{
6w6?4o i^ p T9i     SNode *top;
!U4W ];JQ*w     SNode *base;
jDu[,L E     int size;
#[zVl%Unn&^R };o*q ?MP^ YP
&JUxzot~NhV
/*栈操作函数*/
ZigE"LhT0j int InitStack(Stack &S); /*创建栈*/f$z#b$rt
int DestroyStack(Stack &S); /*销毁栈*/)SI~&SIC o4f I-fpS
int ClearStack(Stack &S); /*清空栈*/#PX$P P8Y1nV g
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
&m0j%wu%]U[ int Push(Stack &S,SNode e); /*将结点e压入栈*/
'J@t9K[ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/:Wb-c9R'y1[R
Q5Q;j$FR
/*表达式计算器相关函数*/(T{D'i0@;T"J
char get_precede(char s,char c); /*判断运算符s和c的优先级*/3aT}rg@-A]
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/4up|VM"t$O],c
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/ [ ODY*g0`i$B
float compute(); /*表达式结算器主函数*/
fPrsr char *killzero(float result); /*去掉结果后面的0*/
"Adwe1w9Z2q
uc?`4M+bF int InitStack(Stack &S)
8i:|o-rz)M x6[.L Q {qJA_.kc'K ~
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));m7W w l&x4W|1Z
    if(S.base==NULL)0E!k'D)h8H:?~
    {*il&B&qo(LbJkB;m
        printf("动态分配内存失败!");
]3up@gG(W         return -1;7O3uT1a_A-Kg4n/C9U
    };s*L h5W#q7b$~#n
    S.top=S.base;
x*^'kP qZ,cb&czP*Y     S.size=STACK_SIZE;
^X:w[)~Ci"E     return 0;:R'|'ZQ"NZU:l0]
}N*S GrT

r'A^u9Q int DestroyStack(Stack &S)
j'y`E3Q*~q4l {5V ZO[+MN
    free(S.base);A"d__%aM
    return 0;
Z e Y.{&i0ZLuy }#Ht~;Hb)BQ,[
^&hu#V$_['H$`4v)B
int ClearStack(Stack &S)
K _paQU { _c{H)t;Pd
    S.top=S.base;
,lx1xR(a^     return 0;
-L$S2T uT @/@Z }
F\Vsjsl4o} _1| ]{+_!W
int GetTop(Stack S,SNode &e),y"X:?B h9aZi3T5I
{
]d&f!RP["Y1s     if(S.top==S.base)*E}JC d(O"@"t
    {
"? y0r$\iRk;N C         printf("栈以为空!");
7{.@9zR5`         return -1;
+|?;|7QI     }
]g-vqXG     e=*(S.top-1);0{Mv `S-t
    return 0;
z;U {-z#le }~5sHnx'N+Z L P

#N7{)R@)y L@.q*g rW int Push(Stack &S,SNode e)
YWQU!HD+fM'j {
y,uZ},{     if(S.top-S.base>=S.size),y,y$_)P-pW7S
    {
8A/g9TQZ6{N         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));@:M9P?[,a.A}
        if(S.base==NULL)
:CL%@ v1\ F:L         {
eM7ju QD xx             printf("动态分配内存失败!");
1r6Ay ^9r'il^             return -1;
-ta*] Q `Q-r6G         }
i h-ZL*Px,H         S.top=S.base+S.size;hP{/u*@6F u(U
        S.size+=APPEND_SIZE;
R'z-mt+T0tq     }
/K Rk-lq2J0H     *S.top=e;
RtX!Z8t%C0?m     S.top++;(ni h(\ p
    return 0;
_mcNm0?+JWV.c }
j p!] g^X9Y.h
sD0k,s6S+wq1On int Pop(Stack &S,SNode &e)
B9A2G+J7{P\]c {2vh3w8z-C H
    if(S.top==S.base):n)Wd:G]&EX8VJ
    {
:em9K:Id.j!|c         printf("栈为空!");/\,s yd8hU uJ
        return -1;
|*q"e3_'b     }
2psR8V4e6|:l |     e=*(S.top-1);
/qM&m q%dY {     S.top--;
3z8Wck!^     return 0;"B7GY2YN k
}MLi:a~1ycIVt

Y9m*\$C6y:_R!e char get_precede(char s,char c) c]7@m&wf
{,g @w%me6J1y4DZO
    switch(s)
/pm'O4k3` zk(S     {
Imt~0AA         case '+':                 Fp X'wdk.h
        case '-':BIT-KoI+WAW
             if(c=='+'||c=='-')
tq$h XA G                  return '>';:|'J}0_.ux y)w
             else if(c=='*'||c=='/') A{ cg2o%] C
                 return '<';
1CpG I&e\3A              else if(c=='(')
H-c g&j~EM,\@                  return '<'; E;H?&V&}.S
             else if(c==')') P,i5_+R\+J
                 return '>';
[sV,j/HS              else C-J%b{p5A
                 return '>';#RKf$ykQ[
        case '*':
*i.C1}d~         case '/':
\^u&]k'el              if(c=='+'||c=='-')
is"c| OB;e                  return '>';L cPVl;w1G
             else if(c=='*'||c=='/')w}xd,O}^hw
                 return '>';[f a`!sZU+s
             else if(c=='(')
js Iu.Y\4o ^y                  return '<';
$u5M.N*TEUq7K              else if(c==')')
!_I4NZe-xX                  return '>';r.j;r+i y8FS
             elsesqfGi
                 return '>';
]A Vq os0vx$T         case '(':f?/IQ]4Q|'qg
             if(c=='+'||c=='-')i4S)mL/w&^Y/Gj
                 return '<';
\l.Y9HM%B              else if(c=='*'||c=='/') ytU3`\V
                 return '<';(s*A[:|/Cu*~
             else if(c=='(')t?uB\
                 return '<';KT.E]u7mB2w-o$Z
             else if(c==')')@kt&w^%g
                 return '=';N+e!w%?Q,a$Z
             else2E l ~t(LwS
                 return 'E';,TxR2~)x^
        case ')':
#JV.A.t3RN              if(c=='+'||c=='-')d sj'`@
                 return '>';pL(iE5\ P@0n)dv
             else if(c=='*'||c=='/')J!e{2ZzTv4M_ ?
                 return '>'; J:y:m-T+b_XO
             else if(c=='(')+E7jq0E DQS?%]
                 return 'E'; N|/e#U6K"]*Ni_L"q9_(D
             else if(c==')')
rKH%fP];\ R                  return '>';
@F.k'b m c*m%|              else
+b)I MwK                  return '>';
E_:w| PWR$P         case '#':
agN9YHuz| oB              if(c=='+'||c=='-')
'^.GE&gi)XI                  return '<';
rwH:N)ol WicM              else if(c=='*'||c=='/')8f}'W.l'D.J%T'd
                 return '<';%p'q.m;vL#Kr
             else if(c=='(')
2?.p;Ox!b2g-e`6}                  return '<';
e8?$x1yXu IP5{u-r              else if(c==')')2O1}vAY+I
                 return 'E';TH(D5gCw/Y
             elseQ0E M\0k;Q7t
                 return '=';!}"K"hG6C-Y
        default:5{_ Wwy!K
             break;oKZ$A:w+K9^
    }
U5N7r`.A EzH     return 0;   
~6G/P3j8x L x$q }VL"B`$?{[+~

rPs,L S8w(q-no,D5R int isOpr(char c)
4U@ \Fbt5y9E5DZu {
OI$Af cby     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
*|#@(K[f"G.h$ji7X         return 0;
U+wp9pN5f     else
8A,Q,xN4w\jK!vy_         return 1;3U&U3H#d[&tY2[S(G,?
}
k*|0jX2lE!tv
Q/Z9ck'T @D7p\h float operate(float x, char opr, float y)
y v)Xh N`b j {HQ#?Es+L k3N-z
    float result;re~1q4N
    switch (opr)^ S]f/g W5x(svgd;z
    {/M*jNGs
        case '+': k.?l5T&d,jNR7a
             result = x + y;
%wmY7^-G7e$A~              break;C N3e0ppry:i
        case '-': 6f NR$~qY7r { ^
             result = x - y;
hj+C9ZF!y-MZ'v              break;
K+U{0g&{}l}o         case '*': n^ v.P1IDb
             result = x * y;
x4C&SY_j^/{d7H              break;Or y ]x.[M9zVhi
        case '/': !W,^8n;g)u6p7v2fvd
             if (y == 0)
\_(HpQF| Y~0aU              {|`&v5p bK8a)p
                printf("Divided by zero!\n");
jn!N#ivR(u                 return 0;6EGO'tj~5l ^{g;H
             }YxC3~&tW
             else
K+H)b Dq w              {
gO8]G`Y a                  result = x / y;6r+Zh,Q^%FB/{
                 break;
.S3Id2m?{ go_              }
2g%T SC\B+{(Z/{.[        default:
-U#_#p.IHo              printf("Bad Input.\n");
6z.fq6W jK@ G              return 0;(q!z%K_~O M$Z
    }
B.`~EEt+Wl     return result;D9p%}/rd@"h
}    2pS2ey;]f
~Tp6x hf ~0p
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/O.X/_'P*sJ0c
{*sV F4?,l"|1AX
    Stack optr,opnd;
Tn6[ E L`_5d~q ?     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
-Ibw1jb.t     char c;
UK9i-v r+a4K&}     char buf[16];^d rvM4U"g
    int i=0;
-ecG5h |E?w     Q$s.\r5F|
    InitStack(optr); /*用于寄存运算符*/
m-p.zoi2ryyx     InitStack(opnd); /*用于寄存操作数和计算结果*/
c^_9Fq3a#sh5|j     memset(buf,0,sizeof(buf));
L~y(t(~U3N     h{;@bh.lI&V:O Z
    printf("Enter your expression:");
$Np{@*~aL.]d)@A         
)R-K6V/~8W:O     opr_in.ch='#';F$~S] o;M |)eV0F#w
    Push(optr,opr_in); /*'#'入栈*/
(U1e3kxR!g,iU4R     GetTop(optr,opr_top);
;h*Kn#B0v BM1zv Q     c=getchar();5D|X[yTC
    while(c!='='||opr_top.ch!='#')
-JS!RH }     {
g'Ba9wLTJ`D+j!w5X         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
!F DH6}r$`#k H;`+L         {
5] x m(@(r;UGJ[+P             buf[i]=c;r+Bv{dg1?
            i++;
QG] ki,u/jr             c=getchar();\d0S-Ut1} K1`6J
        }
8B0r3@5H^@ M"[-P         else /*是运算符*/%]y`3_O0KUP
        {
J:]/J)?I4l6S m             buf[i]='\0';
%}F&R'_$}'~S}             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
(^/hJ:Cr\O7c             {
L_o`q                  opn_in.data=(float)atof(buf);n*wt V K$E]$T
                 Push(opnd,opn_in);
/Q ]2\7q|6r                  printf("opnd入栈:[%f]\n",opn_in.data);
5r5N+w"gH#gD                  i=0;
C s4H(X8q v                  memset(buf,0,sizeof(buf));[ S(o%w{1@3T(?
            }
6?jESgJP$Rr             opr_in.ch=c;!}(Z)[ j-jH
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/Gcq9BwMx*mx
            {
M4T kV/[                 case '<': /*优先级小于栈顶结点,则运算符入栈*/3OxKL9t.A;K2g
                     Push(optr,opr_in);"{.b8c x^2w9D
                     printf("optr入栈:[%c]\n",opr_in.ch);
1FoL5l7L9zp|l                      c=getchar();%q4{'b#j4B)_G
                     break;/b\;D4b!]AYYU5k0\
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/7SY,@mY:f8J])E
                     Pop(optr,e);(U l(|:Z$Ck-b:\ IJ
                     printf("optr出栈:去掉括号\n");
m^{f/E[                      c=getchar();*J.r/~k3P?_
                     break;
gA6`&Yip/uM H                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
+X.I~K9@.?;oX9s                      Pop(optr,opr_t);
(je#uz n                      printf("optr出栈:[%c]\n",opr_t.ch);#[ar6VT2Z0q&BU
                     if(Pop(opnd,b)<0)
s3j K4xoT                      {
/f CP(SUbew                          printf("Bad Input!\n");8BX D*Mi O:}TF
                         fflush(stdin);qKINC;Z
                         return -1;sb5e}x |X4u$k J
                     }|%n3P(ehe@+p6A
                     printf("opnd出栈:[%f]\n",b.data);
A ~'G'{%Lk                      if(Pop(opnd,a)<0)
bQ5t5phAw                      {
.Sa'?O.u_!m.V                          printf("Bad Input!\n");q3]!hEYqr5o&Vda8O
                         fflush(stdin);
e;`"Pn7\d2Uj/Z#I                          return -1;
'Dmd$k/]AZ$y                      }pn G h mA0|4l
                     printf("opnd出栈:[%f]\n",a.data);|[N k(IF+|a
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/:vnJ9Z2k{MH?|+v&E
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
9SM0P DE\t:Y`                      printf("结果入栈:[%f]\n",opn_tmp.data);
J(K(Am[D                      break;"F,M[-B1M!B$v
            }7\d4X8FFT e&Z;Mcl
        }
/d r{6{,Orh~(l$d         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
J+bv6KTx2j#M-r     }&v PI6HJ&Q
    GetTop(opnd,opn_tmp);c1]/R.^%Y
    DestroyStack(optr);2X&x|%~*D6_U'k$?
    DestroyStack(opnd);[-QmB4d^W+v,M'f b
    return opn_tmp.data;
h2b-s'd.E9X }
;~rnN[4p gi_,p
.Gg$m"Ml char *killzero(char *res,float result)
T4jl0R{ F*P {
1Ly/X;uoUa4u$j*M     int i;
4c~:x6{H oO 1{9x ]:pR&v1a S,sT"z&p h
    sprintf(res,"%f",result);1MIQ@,c?k1c h
    i=(int)strlen(res)-1;-I@y6O+TD
    while(i&&res[i]=='0')
F-zJ%Hc%sf     {
\?'}%ce2a[#v         res[i]='\0';'m#N^&H2Q"v
        i--;
2D;Xe;@S2Nm+G6e     }-d4dz-K!G$Ea
    if(res[i]=='.')b(M(pO-r9q
        res[i]='\0'; QaP#{E8PyW
    return res;
7GRB1n2l*UcGJJ }8?m8Z,\NCb!lz
|3Q-jP%y%^/y
int main()
-w0tTA*Q ? {%v}0[}NT_6Q
    char ch;
OD ?C5ec4z&B Oe     char res[64];
-KU5S.j_d8V-c V{     float result;
z qo)[?6Z Y     while(1)b#W4X!g)W6Y
    {
&j9_Cf?         result=compute();
}Mx5g I R/`9Q8A'\         printf("\nThe result is:%s\n",killzero(res,result));'|2g JdcZ
        printf("Do you want to continue(y/n)?:") ;
Nhc6J9K^         ch=getch();j8d"f&E ^"Ge
        putchar(ch);
e En/yF%bBT         if(ch=='n'||ch=='N')
:{3^G m6E@6b*F             break;
+z&~ Q O5c4JA$F         else9|-I2p2UF8S @
            system("cls");HY2s.hz]yZN
    }2aQR M)Q5q;f(S$Q
    return 0;
y_%l`N+Z }[/i][/i][/i][/i][/i][/i]
9v8nei E;]
wa*GT%`1P R [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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