捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的._UDuVh L qsf
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=K$d}4^/w)^
/**************表达式计算器************/i AA!]!ok
#include <stdio.h>
Fu Su*j/l #include <stdlib.h>2FEy7T5l4}
#include <string.h>N:nU\ u
#include <conio.h>
s @/E+P@)PHe #include <malloc.h>5A)p d y.zWs

K~|uD/O.X8yi #define STACK_SIZE 100M,MIS(|
#define APPEND_SIZE 10:\Yq4do\~

\HA%~1fWd%fh struct SNode{"s7F:c2k%f,yE\%S
    float data; /*存放操作数或者计算结果*/ JZ V+n+mGv MD
    char ch; /*存放运算符*/
fy5q U;AQ };
.GR-K9\*QOI'gB p~n)m0S(PS%t+_
struct Stack{ o/CD |/AL f
    SNode *top;iI` tvk.W:I)f~
    SNode *base;
tP1xrz+{"B     int size;
8qx"t^ x6N+A };
2@\URqq'kR
VB4bl2VbP/yfN /*栈操作函数*/
4e'vQ8]C\#RC6l int InitStack(Stack &S); /*创建栈*/
/A0XA a Sy int DestroyStack(Stack &S); /*销毁栈*/
9`cZ Df8r{)nN,c int ClearStack(Stack &S); /*清空栈*/ ca8GlaZz|
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/(jr on-o0|O2D
int Push(Stack &S,SNode e); /*将结点e压入栈*/
\%`*[*`4[c int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
9y&u8f/[X.m"L#l
1nJ\'L6t /*表达式计算器相关函数*/+Wu#t }(Wq%^4~n'W_
char get_precede(char s,char c); /*判断运算符s和c的优先级*/,n!tj,t$f fC*{O~I
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/3T$q.]R;R\hP5`/z
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
)` tGZ6j(?#m%p.t float compute(); /*表达式结算器主函数*/
&\6Zb @ \$CqC char *killzero(float result); /*去掉结果后面的0*/ *vg3h@g}pH"@^hn

y2jeeKP&n4n int InitStack(Stack &S)
O$t8jq1E$si v {?.K_ ^'V;AZ
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
5q8G!zgm:bYyf     if(S.base==NULL) q#t v]${'T w
    {cqNj [
        printf("动态分配内存失败!");fB5z]8|
        return -1;
CI R:hVh     }
_ qn cjQBi%{7]o&O)K     S.top=S.base;rj5sA?4E_
    S.size=STACK_SIZE;
?G![ U/P     return 0;
%ghI8Rc+poU#J$z }3l#I'N)DX M2]-U
c$g%[UWq
int DestroyStack(Stack &S)
'U-} TbxXt,b}U { rPV7Q!a`w B
    free(S.base);
Ic'J-X;l1U;M     return 0;-y4xGvW*lJB
}
vM-[4Xl5go(y'a7U }$ba^(\"]4C!kCl
int ClearStack(Stack &S)
AI(BvTM {
7z;v3{a[M vJs     S.top=S.base;
L5n ~)s TfkTK     return 0;![M9ZD(P:bf9Oy
}
Z3Z:d:n2A?
3y~ga'g int GetTop(Stack S,SNode &e)
[UR Oa'bx7J {
6G.t.XN8qN.E*@qN     if(S.top==S.base)3F:kIvu'E1@
    { w&f7ukU#t
        printf("栈以为空!");
;SeKgi         return -1; t'c;_B(l"dS0n8q/W1q
    } YE%u2\S5E#j
    e=*(S.top-1);A3G[:SFl3\A
    return 0;
']t9Z qQ3q~aE } n-U#NQ.c0D
H0J h$K } ]9sE2e
int Push(Stack &S,SNode e),o?o:D |K*c4c
{
M2j\U5U*}tTQ)x+`Y     if(S.top-S.base>=S.size)
6g_c$r~-c DmX     {dn$f%X$i9C$]$I!U
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));X0u v,XrOsK
        if(S.base==NULL)
2w*@:j;m#ZgR^C         {
ND7w#c$mnJ             printf("动态分配内存失败!");
Z3XuG'^nbV             return -1;&BW o$car
        }
o1[Vqt2l         S.top=S.base+S.size;
WX a huS3L         S.size+=APPEND_SIZE;
6R+TB2?5r     }UM^]Z U2?D;V
    *S.top=e; hk6fZ5\f*H!s
    S.top++;
%l8g:~.a2W{C     return 0;.mt8}%t1[o^
}^8q~GGEQ*F&V
1`t*CpKC:I x,w
int Pop(Stack &S,SNode &e)
$DH[b3h%^:C {
N+]4ttJM     if(S.top==S.base)
O~a@!i3}6w     {$u1b2B&j$`| p
        printf("栈为空!");
$t,ipwAD_         return -1;'Yt,{ D(AT~;N#dvk
    }
!N,[,X,Z$S].t!x     e=*(S.top-1);3Xtf.i^G_
    S.top--;
'~qV.n/k+U ^1~9k     return 0;
?f B*f&em'E }L7uaF3Z9e&W^)G_t3k

.{c1ax:}M;e char get_precede(char s,char c)
b9F_-c%I)f?"D {'Vg/cB#ke$hv
    switch(s)1g R{#k`*jp8|T_
    {
Y3O+V7v:z kyS         case '+':                 
:AH&q9j0n6J         case '-':}d?$@L0Jd)p!}
             if(c=='+'||c=='-')
kL6`5?*a-H&B,MK|6y                  return '>'; K{~P,oEm'@'K w a
             else if(c=='*'||c=='/'),h.VO{,z;\5u }
                 return '<';
F;|_R5Ak.n1@],e              else if(c=='(')-^,Eq'~ ~FG~
                 return '<';Ra5B.|7x%L g4x
             else if(c==')')4Z!O W)r]pL2{kP%C
                 return '>';
A/G$Td;m(h8G              else
6x,`q pQ_aYQ3F                  return '>';h4RC_J"e*I
        case '*':
t|9U%K5e I6If         case '/':1]/b lE2P`R8d(c
             if(c=='+'||c=='-')
bd'YzAaQ                  return '>';
iVA4aK e-W6E `              else if(c=='*'||c=='/')
*p)D5~1lqij K p4su                  return '>';3g3f.|d,o
             else if(c=='(')6O}fgrDp
                 return '<';
u!S(c @K              else if(c==')')S:[7C8nbWuK
                 return '>';
5i/}\$A xB              else u)^lS%KC
                 return '>';
2jOfJ%WJ1Ggm         case '(':1jwT"o-M1}
             if(c=='+'||c=='-')c.~)jnN
                 return '<';
X5I.U]$WZ M              else if(c=='*'||c=='/')$d&Z8m,\:qb
                 return '<';%}j/C ?+LfNkn
             else if(c=='(')
&Z$F-t*|T[                  return '<';xsT#F2O%A$Ug0N
             else if(c==')')+jiV6?7WY
                 return '=';
p(SZn1w&v$b;\Hp              else~)m+T%\L7G1g2E
                 return 'E';"`/Fo*~R%d|
        case ')': W-fP3[a~._
             if(c=='+'||c=='-')
*^;[3lmv)x                  return '>';
} B*Z Da^A              else if(c=='*'||c=='/')
T4t(mTY                  return '>';
'T!s-q(at              else if(c=='(')
A{"A`7\L&a/mx3D                  return 'E';
h![ nmZx&Z2T9E              else if(c==')')0g2G9?g_"n!v
                 return '>';
:w'Nnxf\{ M ^              else#Ja0fJ$c9KH
                 return '>';.iM1S G S+S'L
        case '#':A [ qg ^ ~(O
             if(c=='+'||c=='-')G#ELnCho5t/K9B
                 return '<';
&R!K^ wN2|$r"q7Pc_              else if(c=='*'||c=='/')
6j i x@1rus r'I                  return '<';!{8B_u\:pq:sgY
             else if(c=='(') I:R5z*J|$Xa1f K
                 return '<';
9@,Ye#X%_ {T8nQG              else if(c==')')9Px v2Tw
                 return 'E';
Y%d1NR G`ny              else
9Q%W0R&wn;Z#];}K                  return '=';U4g5d#o.I ]IS't5c
        default:
c@}8\#X3Z ~              break;
N?M [5H2f4x A^8j     }+h8E8jM0v&Pb
    return 0;    M"Qr,qw
}'L']#f w:ZK9akA3R8Ep

!WCk.["TTw'N int isOpr(char c)
t P#X d+c'^ {;F-Qh/d'u Q
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') |N%R,n x)Ylhb{
        return 0;
;Fj}`%yZ \)o     else ;Q*r4m/{ gf.Q
        return 1;
QfhA#o.t4J7yw }
{Y(zL7J%X2?
$nt:k].oq9T float operate(float x, char opr, float y)
0hx'j:{0u:_B i {
HFI*{*A     float result;0w(z(ytB;L+c t
    switch (opr)
7Z%_0W0b;HaUM @     {;`d)p%C0` Q:c
        case '+':
)T-D|[O,ND~ X:A              result = x + y;&kq9h_3h
             break;W6k-\*]!{+iD
        case '-':
I9i1HX_5s              result = x - y;6h5srU.yX1`En
             break;
8U,?e?j         case '*': 6nK L_J/dd\+z
             result = x * y;
i__4b!l              break;(Z#p%Y0mKH9A'o
        case '/': `#aM j&~G
             if (y == 0)7`#l+A6b;M{s8P%N
             {
rJq+Zrd-jf,]                 printf("Divided by zero!\n");"~;Yf^\T-J!b
                return 0;
@9j_ B%v)V z_y%g]              }
T0R!cm9TR              else
U8Q)N9T5wb0|a              {
C K4V m~c j                  result = x / y; teT&x%|#H!X H^*_5G
                 break;
*Vx-@VdH9N              }%iC\&ST.`cK
       default:
Bs:]/yw-eqrO7UR              printf("Bad Input.\n");
d#LAAA|              return 0;z}7TS^7m r
    }/Ul)fVX:i
    return result;
+[ Y-z&T$rc)OG }    5O}A9_g:LN$x

L,UO-i2V+{H float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/ESaKl\'HW
{D Uo+M`|,W4B4]K
    Stack optr,opnd;
.V3F xRxEh[-S     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
f4X&r4u%Rv$G     char c;p7bdttd/y
    char buf[16]; LnP9Rw+ZH? j
    int i=0;
A[7TP*B)O9_@     J.iMz zc+xZ vi
    InitStack(optr); /*用于寄存运算符*/
&@;y%cDA*b+s%Kq?     InitStack(opnd); /*用于寄存操作数和计算结果*/tU+n`Ea
    memset(buf,0,sizeof(buf));z2z%GQ!_9R;^+@`
    Y7H#f:McTG!\Qt
    printf("Enter your expression:");1q$\A@_0[{ Rz
        
n^|j:j     opr_in.ch='#';P-u {6v DPN
    Push(optr,opr_in); /*'#'入栈*/ hMW)IzqKd%M1D
    GetTop(optr,opr_top);2YFm @ q"U)`5_
    c=getchar();
!K0i$M5Cg     while(c!='='||opr_top.ch!='#')ECK$i*d\
    {
?R1FcH_Og J         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/8A5u8\2a*a5t
        {+g!sv+y|
            buf[i]=c; F4U)m R\Xo7I n
            i++;
X*z|1N;YZX             c=getchar();
)a6I?E7G^8K q         }
n9]z1e as         else /*是运算符*/
R` s|/O6M}a         {8Z`fub5MJ
            buf[i]='\0';
1[_8s9c[!DDQ             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/#JQz.L sz)~-S\
            {$]uMZO"o
                 opn_in.data=(float)atof(buf);
_ Ir x3W H;@                  Push(opnd,opn_in);
;xB7H Z)q:]                  printf("opnd入栈:[%f]\n",opn_in.data);
b;E v"BN1w ^-k3D                  i=0;4Y Bk|m Xd7\
                 memset(buf,0,sizeof(buf));4WV6b.wtp
            }jQ6_yw%E
            opr_in.ch=c;
H6fx5}0H^D~oUU             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
[hHmL#?K.i$X*|g             {5{k:fnB~7{"L`U{
                case '<': /*优先级小于栈顶结点,则运算符入栈*/$t7|7V8[&|Q
                     Push(optr,opr_in);
ei ^BkCRC                      printf("optr入栈:[%c]\n",opr_in.ch);
V4_,g0l@Xd                      c=getchar();
X _:h iL9Vj3WB                      break;
e2Z XY0TL                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/6flDa%R;Db1h
                     Pop(optr,e);5gC kF%h
                     printf("optr出栈:去掉括号\n");
R#~L6\8Y#a6t[                      c=getchar();#No(ou!Fw
                     break;(Y"nD3AvF[
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*//R:}*T$T"^O V
                     Pop(optr,opr_t);
G@f Cn/F-{                      printf("optr出栈:[%c]\n",opr_t.ch);"YWsX*UGJ
                     if(Pop(opnd,b)<0)
p6A2rpK WOO7O7w,r                      {
joQ+X?W \h._                          printf("Bad Input!\n");TW8a E&^VI.b
                         fflush(stdin);
)MGy)d:\)R] h*Zs                          return -1;
o1G"M O Q(vU-S@`                      }
M(DC"d(Gi+x m'X                      printf("opnd出栈:[%f]\n",b.data);CC'}Y-f e1e}u y
                     if(Pop(opnd,a)<0)H,kX*A%V z;I7h I
                     {9@Jqi'L
                         printf("Bad Input!\n");
i%PR4p:ZnES                          fflush(stdin);
,S4k9a5\})eH?#R                          return -1;
${l?;N N2{                      }
#ol8A?0z9SrW |3W                      printf("opnd出栈:[%f]\n",a.data);2VD4Nh^&R5w6m&x
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
&~&]l!Ql5|-U5L|                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
9hI E/Det h3n p                      printf("结果入栈:[%f]\n",opn_tmp.data);!E1z&I4b;P*vBE
                     break;
"L8b!@9Y R             }
"I&O5V sI_         }\oT7TI
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
Q{ tkv [$O(Iz0|2Fj     }'\#^Gu;w%YR
    GetTop(opnd,opn_tmp);Q*hN P3`G a_#v
    DestroyStack(optr);
0}(M-L%L@6O3[(}R     DestroyStack(opnd);;o J YZ b%E.G*tevf
    return opn_tmp.data;
{#M fH MVT }
F8E EH^!y9l)l
8[,lb M'F char *killzero(char *res,float result)
)]!~+J5v _"\ {
A0W7j_t$Q     int i;
3K;N)aa7V2GZ
(JLO2~:D,JG     sprintf(res,"%f",result); uYi Y'[-HA!An
    i=(int)strlen(res)-1;
dW|ec/g8x'n zu     while(i&&res[i]=='0')
(w|.h+WC!SS1y"u-nj     {
zfqt|UT:y         res[i]='\0';h)H QbJ)_*Ge~8v
        i--;aor)Rv1U
    }.DcG7RL8Y4B)s
    if(res[i]=='.')
'K i(L NW4Z         res[i]='\0';
)a"_MrAts$|     return res;
:j.^5e^+}/f }g0I+o(G$U O7Y
t8O+r6S Em'F\
int main()V-J;X U7^Ug
{
h%j4}A*c.m2etU;iY     char ch;
e:oN5M;l3O3S     char res[64];e*EON0r$auLL(G
    float result;2s`fi P%y;Pa
    while(1))`[OMA+H)|
    {#|QZkI/o!G
        result=compute();
C#Ta9k"[5\Y]1A^         printf("\nThe result is:%s\n",killzero(res,result));eb7NR5G%q
        printf("Do you want to continue(y/n)?:") ;
if[ J_vf         ch=getch();8|9Z*t.dy1O$|
        putchar(ch);,E#P7R4r6u7h Q
        if(ch=='n'||ch=='N')
r-mCv7D6T             break;
!z~PU.`E~ YP         else
.v4FV:\-I3M#a)x.I             system("cls");
GO/Ab.zL.z#iB     };y]:N1W ~*X6n5z
    return 0;|1aW*@&I&^
}[/i][/i][/i][/i][/i][/i]FY(ZQ-?Xn

T(UC4L0A*E'G [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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