捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.*LrpoaHOl
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
egXvqU jL /**************表达式计算器************/
"]8pQ[)|IK #include <stdio.h>
k c+N-~-zv+} #include <stdlib.h>
]!cp`-cqJD/e5Z] #include <string.h>
!zDN:R6{ #include <conio.h> Ei?i5D\XE}c
#include <malloc.h>
U;w$zr|op$x "yMf#R_s0M
#define STACK_SIZE 100fOx K;D|
#define APPEND_SIZE 10
!Z!k@'S3V9Y6S:k hB VK'u2BQ2Y'Sd*X%O
struct SNode{,mDZ#J8M
    float data; /*存放操作数或者计算结果*/
[`N|-ix     char ch; /*存放运算符*/
K:vOs}Q!B2s };
&Q @W9k+k2r f /[0ywQ0g.ck"Q
struct Stack{
$@G a/Gmf$fo9m     SNode *top;7e/r4C&^$K[r
    SNode *base;9iJ{X.M
    int size;[*ptIQ4u;yxcs
};
2el1a8p#UyV.}bf4N y%zm+Y+Q#~
/*栈操作函数*/
!xH@1z)m)w3G K int InitStack(Stack &S); /*创建栈*/$c0k$S `8b.H6xT}
int DestroyStack(Stack &S); /*销毁栈*/
~3p/Z2|zlgA"s int ClearStack(Stack &S); /*清空栈*/r@J2s7f Qm t
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
4WG9B?lx:p int Push(Stack &S,SNode e); /*将结点e压入栈*/
o1r0hKW M l int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/I^YMtJ

O/| Niw\ /*表达式计算器相关函数*/?$TT9CF1O'n&qH
char get_precede(char s,char c); /*判断运算符s和c的优先级*/0\ ?E"FX
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/9mX1I B|
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
9Hm+d7q5s x@HR float compute(); /*表达式结算器主函数*/
+HcZm-KlL5Q s char *killzero(float result); /*去掉结果后面的0*/
\m%KV-n:n P El,_9of
int InitStack(Stack &S)
%\?%xSc^Pa\!KB O {
/jt4K hH vbg-t!s     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
5d pb PVg     if(S.base==NULL)
LdM&^2y2c,rb,x$w-oY     {
wA-]U2O0_ Z%}         printf("动态分配内存失败!");
}E)wl.S/e         return -1;
-YQ(m2O#P r6DI?%?9k     }
Q|BY5rl     S.top=S.base;&]j#J hL}Y
    S.size=STACK_SIZE;
i6Vba1KH     return 0;
/eQl:v0P%Z }.O"{sS#QY^

HvX;sq0oO4Q1x int DestroyStack(Stack &S)euYY][
{
P1ZJ[0I"]&FJ5}     free(S.base);
;I-Dp5q;V6YgNf     return 0;CS"Xl!O8r r,e
}
'G@ W3ns\4L4`
eH%Bi*b int ClearStack(Stack &S)"ao@a Qrc
{
(u0h2pV{5{0~z     S.top=S.base;:c] KCw
    return 0;
,JX+Z-CO,Ul"H#L.o }
7lE|Kle6L&r!Lk TYZ1M$`
int GetTop(Stack S,SNode &e)caH C5}1aQ?
{
8Yq3y*j2Gb0c5P'G*n     if(S.top==S.base)l TO'[+W%N.[
    {
r?bM;q {]@:b         printf("栈以为空!");1]!p^i{G^
        return -1;7Aqp(?"Nd9LV
    }
\|;ef%q4eU&m     e=*(S.top-1);
LM d dh(r Ei1\     return 0;Esv,fK4x`
}J'~Y*| s

N#_8r.We$Tz*m }0t int Push(Stack &S,SNode e)
eC3k:W|R-Z1_ s;w(u {.oBP/juq9j
    if(S.top-S.base>=S.size)!o L3K'] b [$zPZ!A+D
    {
/k;M_;i$^bj         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));-V(fYO F3O Q*[
        if(S.base==NULL)(|k9v/qW"\1mB
        {
\JU Y&o&i3~             printf("动态分配内存失败!");
)]VcZ'J.x_(|%dX             return -1;
~{(uy5kf}         }*qhb/_\*b)c.G+H
        S.top=S.base+S.size; V0cs P5Pe.p U
        S.size+=APPEND_SIZE;
Slb%vs     }
;m!k7]v&S+A5ne     *S.top=e;
g0s~ p/J'c] k     S.top++;I0pZL/Ad+[i1nn`
    return 0;i F-M0g+w
}
[4v bD X+} H
-FA/c)p)OKZ? int Pop(Stack &S,SNode &e) W@uCPyb e z
{
~ F5P`$^V.{     if(S.top==S.base)8ZJ T}DpK2j6B
    {Q\n"v-r
        printf("栈为空!");A-FS)]`Z Y!q{
        return -1;6F2Z_;j V*x
    }
#zm[Nl8z     e=*(S.top-1);
$D@*F dI#{3Fq Nf     S.top--;gh)W"f la
    return 0;
s|B\$g5@ }
&w.F:S3[%D
o I4g&y I(tR"r@ o t char get_precede(char s,char c)
3jhhR`X3b.U {[ t]*}][hHc
    switch(s)ox"CW\
    {
2cU7Q@H;Si/b         case '+':                 
f9tf|Tk(r2T         case '-':
?n go_.@              if(c=='+'||c=='-')
#P*Fi"q2U@ zk;w                  return '>';
_m2K0y4Xps T @              else if(c=='*'||c=='/')
&kO,W7i Nk3g _*bG[                  return '<';.P$@T2M4uf
             else if(c=='(')|2`d};q S
                 return '<';
EI6M+C!T$epU`              else if(c==')')
mvP bN9k4G,M(n d                  return '>';
2j1e&}{v{              else d&w/F@7p
                 return '>';4V8] n&[l3L#Z
        case '*':
4AO(B'k Xl         case '/':
ru&r*W&h?-]q5eeHC              if(c=='+'||c=='-')2nG4zgKQ-wR
                 return '>';,O/ku,T&r%x_
             else if(c=='*'||c=='/')5oam_Zs;?LYg
                 return '>';#p5U)T/sW&ZpL9rW:L
             else if(c=='(')4Vf{ DQ|S
                 return '<';
e:o,_"e1i0b(fx              else if(c==')')
h:sVvG a$G#h                  return '>';,vL.c0C'Y7o
             else? ?S}h;?{(X9s
                 return '>';
t1q#A#A O+Y         case '(':
$B\1dT5F M l2G              if(c=='+'||c=='-')
9qIl$^:_J:H                  return '<';
},eyE\8J+PQyd              else if(c=='*'||c=='/')
9ou8x6G@~+{                  return '<';iTO6MXx
             else if(c=='(')^auBl*Q
                 return '<';iy _X2Um7V t
             else if(c==')')_om5Ws7gJ
                 return '=';
*o8BYm*ZL:e S/Q              else3^$Di~l5o"o Hv Z1{
                 return 'E';nX*K]U'W
        case ')':o*m-cT| _.c.y6A J
             if(c=='+'||c=='-')w~K&g }'^l
                 return '>';
q[K7|8y t0n              else if(c=='*'||c=='/')%G4nm;pa7^R|
                 return '>';7E&v1~`O5U5B2@
             else if(c=='(')
7RI3d"|2KK T-s1yju                  return 'E';
bDb R2A              else if(c==')')
y'W?t#@]4d r                  return '>'; Y2cG7b(LU
             else$S$t%[2rU1G8nL
                 return '>';
\%W9Jwz^         case '#':b z p(O A3{ k2kR"pA
             if(c=='+'||c=='-')].P[IZ,lv.g&XYb9i
                 return '<';
$H%tN-~ZJeF              else if(c=='*'||c=='/')
'An9\9~9~v:T                  return '<';
!~(B8}.[tt&}1s(f              else if(c=='(')]:s}O"G @
                 return '<';
*k ]uu7FuPn/[              else if(c==')')"G4_n\kVn E3NK}!p
                 return 'E';Ef4[1|Lv&p;V m!V(n
             elsegl)f'J-O*lqZ;U
                 return '=';
F0j VO;^_rT         default:
2q R f%U3pw UX              break;{Ye#fY"p\
    }8El&Z8A8B]mo4H.c6h8q
    return 0;   
koa;^T4C3b y&] }
x5c8k$f.N`:DX:F9n a0COoLe s}P
int isOpr(char c)V;I]s-B5?E
{
ngb4np*S     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
ddZ+MArt4K }         return 0;
c:P2s"H;rwTe     else
%V0DB9a0Jg6YP-d         return 1;
%HYM;Y+vu e B }[1n9P;|Z-P0\6C

'b;uGv1o$q float operate(float x, char opr, float y)A{nE:R5Z(g
{:h(BN"vv m9a TR Z
    float result;
PE-R-g1q'az/_/?P     switch (opr)G Up&M2q No Wa6a
    {9q)Y{y"^!D8D,Q}
        case '+': kGJ"I[ I
             result = x + y;6A#M2W DD
             break;
&|%ZB+K-O1N P         case '-': w9kq EZ2q%tx(T*|
             result = x - y;
I5t?$Sj,T~              break;
0K"mm@ O3c@7j         case '*': S!CElb&`
             result = x * y;
*Lm/JEs E:S              break; rU0\HG]%L9Y/FyY
        case '/': z[$Bbv5V8d
             if (y == 0)
8V E6F5p%h4I/{M+q              {
*M J8i({e"TY                 printf("Divided by zero!\n");nzo!N~#E,D#j
                return 0;
k2@1d%Tj              }V3o#a(|}
             else
qr R!o1cc(L Fb:|T,q              {r j%J6pb&[
                 result = x / y;]`{o/i xv
                 break;
8~[+CQ NACi              }OmTyL9d;y!W
       default:
y7Cb&Y%VL              printf("Bad Input.\n"); _W r%HD
             return 0;8Q^b ?.|
    }
t:`%O4{&g$G T     return result;'Y O[.o?X8Pj
}    )QwQ w6Ot
6N5R_X:}
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
^!XK5V`1`,[ {,Eh`,@+QAQ5QM&`
    Stack optr,opnd;i.pf5Y(Z
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;d9u&sZl'wKF"aCE
    char c;
Z9BL Q,})RU ]O     char buf[16];
.Ok*x P!Q3G ns/a     int i=0; }#g5c e;gL"t
    )f \l!Xm@+\e ^+x
    InitStack(optr); /*用于寄存运算符*/N mTyK!G1jW#D%B
    InitStack(opnd); /*用于寄存操作数和计算结果*/d`];y1v u$aJ*k
    memset(buf,0,sizeof(buf));vESt)}AM%M#v
    N6t uF8`+G
    printf("Enter your expression:");[o6w Pnm)i
        
2H \7a lw!Y     opr_in.ch='#';
-RwY"?:u$n.T     Push(optr,opr_in); /*'#'入栈*/y#Bk-kn[P@S
    GetTop(optr,opr_top);o;RCCD
    c=getchar();\x@gfS9P
    while(c!='='||opr_top.ch!='#')
q'[#Vj\!w/wcD     {q6O-yz:AwD7M{
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/o zu*?i;{+kC?
        {
A|-B&a9R j             buf[i]=c;
"qMl f\D!D]!n             i++;
+I T8l\&R#x+l:z             c=getchar();
r/J4Tr(zZ&S/{:wz%?*ib         }
}F+h)d,e I8s0d8|2H-p         else /*是运算符*/
7s;[sX7R!Y^         {P/r4`4Chm d&i1b
            buf[i]='\0';
i0z3sS8K|te             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
5T(J7r&Cv|^l             { t Ftl$SSF|
                 opn_in.data=(float)atof(buf);;a6[yU1I/A8`Y
                 Push(opnd,opn_in);
6Y'g3ob(oZw,I!l                  printf("opnd入栈:[%f]\n",opn_in.data);gK~WQQ
                 i=0;
#vXdnY b+P                  memset(buf,0,sizeof(buf));.kp8TO(S_q}$Bg-^
            }
(m$oE!jL]*z7S0b6e't             opr_in.ch=c;!M0[ O-U"C"Onc5j&|Q
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/.gz.`Qz!O8}%wT\4V
            {}d)xFa
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
K"A6c1L*bW/f \                      Push(optr,opr_in);l8[:E']C0J
                     printf("optr入栈:[%c]\n",opr_in.ch);:mZ3w;wh7jx?
                     c=getchar();9_J@aK_
                     break;
]a3Zd,Qnf-L                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
u$b/LSLJ)lD                      Pop(optr,e);
7hYK j&V8P*]$Y                      printf("optr出栈:去掉括号\n");a9K;Q$l_1xxl?
                     c=getchar();l,h;HH+o:oI)h)\
                     break;BRgj5[t-f&j
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
r]_ImXM#t8A                      Pop(optr,opr_t);y(v q){$RbP
                     printf("optr出栈:[%c]\n",opr_t.ch);
%^;m:F] { fGP&W                      if(Pop(opnd,b)<0))l:z%kjv{z4}
                     {*la&C\8t d+}
                         printf("Bad Input!\n");Gu6m?7@.\4@2X~8aW5}
                         fflush(stdin);
Z'NT'|j                          return -1;
g J%xgrM}-J"y&ws `                      }c3v l3b4EE Im;u
                     printf("opnd出栈:[%f]\n",b.data);
XL lM0mR2Hm#G1N&i                      if(Pop(opnd,a)<0)
+w#PBy6F%M_e U                      {
I!~|V\8A})A9Mp                          printf("Bad Input!\n");U&lWf$A.a
                         fflush(stdin);/] Y-d9l^}*k
                         return -1;
{*lE,Bl }? _5\                      }^'Xn _@2}(DP3T
                     printf("opnd出栈:[%f]\n",a.data);
Wa%t(Ez                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
lU`x6t8ER                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
^ kO4|E?                      printf("结果入栈:[%f]\n",opn_tmp.data);
|6S@W|RQ)@py                      break;:U;s'kx([(en6L[{
            }
D&q-SA(^4mm         }
i#F;}gn cM         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                h],?;?;h4P-] D
    }
2E_Uvfi~:r     GetTop(opnd,opn_tmp);)mT&@/aiQIo
    DestroyStack(optr);rp;CE8b/Z:C:B2y4CE o
    DestroyStack(opnd);
m:\W fnB3rqQ/R E     return opn_tmp.data;
V@(b~%HD:I }Hk b \z!A$o

WH pFHX.b char *killzero(char *res,float result)9mc_A9{1etpO
{9A&~0VAmR`(@aj
    int i;
9RFL4C;i7e/R ;F,R!htq@
    sprintf(res,"%f",result); F*oj.q;Y"gN
    i=(int)strlen(res)-1;j8YLr\ I
    while(i&&res[i]=='0')y-X N1Kg3Rx
    {
b4K_E4?%cW         res[i]='\0';
G.giY,e4`-]         i--;
s't9jcQ|     }hS_9L4{!gHJ
    if(res[i]=='.') r4k_0q~|!N
        res[i]='\0';
!Eq9u|#b2j\`     return res;r!e5`3`$fL*Jd
}
:N4c4x&G-~6l} d
9J7s!f@Z int main(){ m5v ~hM/Y
{
8^jqE#zN{&q     char ch;
&T,|o6s v%G[     char res[64];?;Xq~#}0P
    float result;)Lg&pc%t^m
    while(1)$Ck8R;P }U_
    {n!SNB d m _'k
        result=compute(); b e)Y zV/cp
        printf("\nThe result is:%s\n",killzero(res,result));6c3| MU\ g
        printf("Do you want to continue(y/n)?:") ;
}u8w4a?CQ Y{         ch=getch();J3nQ[a
        putchar(ch);qm;[+J Z|RT2p:i
        if(ch=='n'||ch=='N')
T2Q S9Z.d             break;
6\-D:Ax ^o*S         else
,aU$l.[*L6n)b             system("cls");
6|'b:q8JbmL     }D6U(`9HH A GS/Q
    return 0; On8s%G]Q Ia
}[/i][/i][/i][/i][/i][/i]S'E1P8?C"E"F sb

sz"kQ |:r:zh [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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