捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
:{#m*is5Rh+{:Lj 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=v ^t C g2G
/**************表达式计算器************/
(VX$m6Syx?4fl #include <stdio.h>
7n9X|eez&i #include <stdlib.h>9Em1Z/?x ]e'\ h
#include <string.h>;B7P0^A}
#include <conio.h>
/R5S4Y,}l*oh1K #include <malloc.h>rU{c C QD:SNIS9Xt

} AX }1l1k!@ #define STACK_SIZE 100
"p%nVT:hs9f #define APPEND_SIZE 10
Y#[`1} P2w!It
|/J9i@IgH struct SNode{
i m P S2N^o$fS-U     float data; /*存放操作数或者计算结果*/)` a,nd']7s_
    char ch; /*存放运算符*/
;l,]~8uK"K!II*|H };
,]*\#ev,Z8O6T7j
]4x n2@6Q struct Stack{2h#b?"jxGj7m Nb*L
    SNode *top;&hyS~*~ kJ
    SNode *base;
'~z!P |3q[ `!| Y&~'Qy     int size;
K ?;u9Sts\n };
f3w7Y^OX%~[@*g
`b*bS7z@"Lb /*栈操作函数*/
r2fj[G4RQ C1H { int InitStack(Stack &S); /*创建栈*/
-fngW*\2B int DestroyStack(Stack &S); /*销毁栈*/
ED/S4o0W7^1`@ int ClearStack(Stack &S); /*清空栈*/
]V*|`4UJ int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
FK.qsQg g int Push(Stack &S,SNode e); /*将结点e压入栈*/
4H}"K `)c@:d int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ Q!Z&A#B)@8e
r/t#Z2Yt0f
/*表达式计算器相关函数*/ s u)Am]/pd
char get_precede(char s,char c); /*判断运算符s和c的优先级*/H5z h'I$X~G~%R2h
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ir/J@#c9N0qcNp5XK
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
;`-o1dl#bUZw float compute(); /*表达式结算器主函数*//nQ H"t|co R
char *killzero(float result); /*去掉结果后面的0*/
A,\%~d%zU X!Oo%pmWnu
int InitStack(Stack &S)P;M+dZ0}F
{
+cI7x'B]!vC     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));-R:SVOa
    if(S.base==NULL);AL'Y0~/F
    {2s|;x;yw!U
        printf("动态分配内存失败!");
w.D/R+o o F'X-z6l         return -1;
;y?(y+S| o     }
4B%Q$C1HA     S.top=S.base;
]C T+?u6k     S.size=STACK_SIZE; K5^#bNpV:D?p%k
    return 0;
t jR` ?;aRJl }I7?fL$kX

[:Xa D6We~^ int DestroyStack(Stack &S)
TC~!Q,^+N8?'X T {
0]A CQjx ]     free(S.base);
WSW3]#s)p6ML     return 0;jzb@4}Y%vA;@u
}*iMqWt'p(Z
t4e U'Bi"~
int ClearStack(Stack &S)w9H*Iu$u|"`&y0m8x v
{uj[1} m&}"G
    S.top=S.base;0m6]5I+c7e?H$fo
    return 0; \\hjx6O
}4UB;~^q![x1S
^+y9p&TnR![6Q.\x
int GetTop(Stack S,SNode &e)6Q"o%}&J7QM
{
f"J~4@4x6?     if(S.top==S.base)
g C$ByE     {2m(}mV-Y4h:kY:yfE
        printf("栈以为空!");-D4L8Ya Gwh
        return -1;
6Hg$B r;g2@     }(z M(J`A
    e=*(S.top-1);
qC#x#O'~E0\B     return 0;ZB2r2^.emC
}HCr/Qj c:R
"w'n?0l)gZ3?
int Push(Stack &S,SNode e)k {U1Og-UNm
{
z)kk0@T'{pC     if(S.top-S.base>=S.size) v}eQ+b Ao$@ G
    {
kPfp%Y8\ Y*c         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
"m$LDn!J         if(S.base==NULL)
z+X D$@0h Q wZK:a         {
F NVXB | l             printf("动态分配内存失败!");
dtA5CLt.PP             return -1;
:[:el)`}^3DL         }
3F-Ga{ Q+`8G8b k d         S.top=S.base+S.size;
![5w'\1C,n&c         S.size+=APPEND_SIZE;Qjyrw\N
    }4c&LK K$|&M|]U'k^
    *S.top=e;9Dx4[1nr]!Ofd.e4yR
    S.top++;-{3m!e7t%OQ%u
    return 0;
4?[+o@0g P }9q4Ac(D9I4uBym

A,LD,[` z)s7N(eE int Pop(Stack &S,SNode &e)+E!Yr.^0]|7Hf
{"n%O`c:V
    if(S.top==S.base)"l_uc ao
    {
n+Nx)^Uf9Y         printf("栈为空!");M)}z%J ZF
        return -1; _(V ?fa%Y
    }
e+z1A6]pD     e=*(S.top-1);-_(F S7J~"\
    S.top--;(X*mC2jZD4_
    return 0;yY1Z@mIV)E9G
}
q5Is:Y V9`(^f0A /FbU'zS E i
char get_precede(char s,char c)+O-^H~GHF3i
{
V!bc)_Y)Dyc&g(o?     switch(s)gl ]k/n8SP
    {XQ6M S8}+e
        case '+':                 
:~6F[-DU:r         case '-':
[&H.Je{z4y D              if(c=='+'||c=='-')ij/^1c;xN"v'p5I;D9JZw
                 return '>';2s1Z(Id$WP:L W x5~
             else if(c=='*'||c=='/')"OW1PrT x e
                 return '<';
IV K,Po{,[1g              else if(c=='(')'x8}G3V6zJ*N
                 return '<'; de5Td Q)f?
             else if(c==')')3A6@G&B(}hO+H
                 return '>';t;yIRV*[
             else
mH,x-z$k&RJ+s)X                  return '>';
g`0x/zOoB         case '*':W g:W(C4we1Z
        case '/':
N*`*M%gB!@Zr              if(c=='+'||c=='-')
]g\4Nf                  return '>';
U(G+z+T!tC hL              else if(c=='*'||c=='/')8\&@E4T.{*c-r
                 return '>';2f`Q[1p'On;\
             else if(c=='(')
Sq&U{S?9YT$P                  return '<';2mw;Se+ex oenp
             else if(c==')')'G5|~Czu
                 return '>';
"Sv;g k}MY)D              else.`8s8v3RAk:u
                 return '>';
4tH6Q*~0R         case '(':#q,G N_ jC+{ X
             if(c=='+'||c=='-')8|Y a'y'U
                 return '<';
.FPsG!Et              else if(c=='*'||c=='/')
{"YvhfB-Q^                  return '<';
8x9db I)O              else if(c=='(')6I%m~n [@P2X C
                 return '<';
+Wz1f0q$H!D?              else if(c==')')
2fpL.a(BYKc                  return '='; ]Rbb8] P
             else Q0\d'UVNV |5]k1@9f
                 return 'E';)vl7E `L K O
        case ')':
7`4qk)Y~'f)ni              if(c=='+'||c=='-')
}5R,P)^ k,KT                  return '>';
,AqS@8d%F`.d+s-q/k              else if(c=='*'||c=='/')NA:[G@lj#_:oy
                 return '>';
R |`C"U0lDdXT              else if(c=='(')A,{!X3jbE
                 return 'E';
z7AT `WW%{3sA              else if(c==')')vdO.w0c/lK*Z:ha
                 return '>';9X5s1f B#S,w&Yi
             else
#Y;kS#^+U&m                  return '>';
{#Z;A@z         case '#':9q,R9YeB4Kqo
             if(c=='+'||c=='-')
L8l'{%Q)l%i%p                  return '<';
*A;o4Hh's$Lw`              else if(c=='*'||c=='/')hu eg GE\9v
                 return '<';{v%e,e&nF w*tK
             else if(c=='(')6R#r{Q,[]W2~P
                 return '<';"HL\ [x9h-E
             else if(c==')')l`(O2EzP+K8_
                 return 'E';
pg$K `I5Qq              else6J v o:v V&Kh
                 return '=';
'~2} BF#Y i         default:
Yy R_ mM2O_              break;
.P)heE!u2z     }&Cai!B|W%|.I)l!H
    return 0;   
[6oz8U,}z }k _1D&Ga n Q
_e \~{i3D`
int isOpr(char c)
,Zs)@&L$d/B {
%w0Cl7C9D_sp     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
8T,fc G.T)W         return 0;
H'q'sS$iV M4z.nh'd     else 6j4h*r;no
        return 1;(R{'fF?t
}tnj3e4_(Z w
]F O%D'V%J
float operate(float x, char opr, float y)
fc!v7gUXe @ {
uHN4Z`V dAc     float result;
'iC ]9J3Ie kV2U     switch (opr),S.JX8M;D(t?g
    {
MZ zr`R9UX         case '+':
$i-sAjA.[X c#|              result = x + y;}l6X3t6f9i:O
             break;.@8r)A0_/K
        case '-':
H.kno%o;t,\              result = x - y;
F s'n2xW              break;
}3P*bh1Q D[         case '*': a]ZiA2cUb n` |;Yt
             result = x * y;
w*L Dc6z3E4` c              break;4wa'IF"m"@
        case '/':
oyp%eAtD              if (y == 0)
([jo x a8at"n              {
nLH'vUH%P{                 printf("Divided by zero!\n");
O@kx_6{5`2{                 return 0;
@ \f4Zd+S              }
{ EON4}/Q]              elsev7m,C~,};b.\Od
             {
Kf$zV0P                  result = x / y;c_T+K8^ F]6YRU4r
                 break;kFOi/k tlj
             } g?'}i&c&@mv l
       default: N5Z g[EL4lk
             printf("Bad Input.\n"); &M8b9{.s|"e:@B3n(_
             return 0;
_f!o m\,Waq;C5\(cR/Y     }{O$eg E2_ j6py
    return result;,}\;I-d-Axb4Hg
}    Y/Nh5xj%I/{"g X'j

3k5G1?'OUe i&R float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/*`7k}hZ1{[8w)@
{n9s#B5JQw t$t
    Stack optr,opnd;e#?%NRC Sf
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
7lS0pO+W~ i4b     char c;5X p@ ]5N(j6f DTF
    char buf[16];
$Ax0|S G(e,z     int i=0;
5i~/T |H%fG I%A     4d8l#qy!n
    InitStack(optr); /*用于寄存运算符*/
DIZq5H2t N     InitStack(opnd); /*用于寄存操作数和计算结果*/7@Af,|T ClWG
    memset(buf,0,sizeof(buf));0i/x9B|u kn
   
PT q G}6?     printf("Enter your expression:");
3S2tLj+_^6Z Kw         
{+w1Bt^'Y/] Z0[     opr_in.ch='#';
6RC%h@3fE9{/|?[     Push(optr,opr_in); /*'#'入栈*/
y#E7N-h\1n$X     GetTop(optr,opr_top);f-O]0tn6w.x%^@ F
    c=getchar();
%{({8x2t,\     while(c!='='||opr_top.ch!='#')
qG-l;s4Ka4T2l     {
,cJ3w7i;]R0f$p         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ iP~,|*h!V
        {
pD@#e~ZnMht8s             buf[i]=c;7R1^ h b GQ"X
            i++;/l F/Y-H3m"L
            c=getchar();#O'H aLlG$l x
        })m!Y+L2a~2X5KkG'X
        else /*是运算符*//sSE@2i ^
        {&oRhq/kn8T
            buf[i]='\0'; \h%[ @.M8v&qJ
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
"Z m{ y1ds:_)`]2O             {
%}6S8k;wq                  opn_in.data=(float)atof(buf); y3u b/m-t1q[
                 Push(opnd,opn_in);/HW ob5Ib4D` `c
                 printf("opnd入栈:[%f]\n",opn_in.data);lIFR&J*U1h
                 i=0;
K|%pb;m4qA'e                  memset(buf,0,sizeof(buf));
'c qZ9\2S&eP7G             }!\ S7F5A.I7OI
            opr_in.ch=c;
A|Z@)Dps:~             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
*?AgLI}u             {!MXc8?j{
                case '<': /*优先级小于栈顶结点,则运算符入栈*/ I [P%_a:m$Y(G/R
                     Push(optr,opr_in);}p'v#fK"Hr@8v
                     printf("optr入栈:[%c]\n",opr_in.ch);*R$S8]p~+X3JM
                     c=getchar();
e-@5We\'@,g&xYcO                      break;
d5h V qBRm}                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/.}g$W:_~1y{
                     Pop(optr,e);
6j4Fb2]V#K[ q                      printf("optr出栈:去掉括号\n");Kp/pbN _M O
                     c=getchar();
*~7HK#{;K!L:D                      break;
N*~ d7` [f.t%`!tpnQ                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/,m8O@1can
                     Pop(optr,opr_t);
k.JZ;]_Y2qY                      printf("optr出栈:[%c]\n",opr_t.ch);
D%Z4hdkwOu,n                      if(Pop(opnd,b)<0)
:XG9TFyi                      {F+_.s l"Cz-s7g5K6|p
                         printf("Bad Input!\n");
AO5_&]-iG%S8T                          fflush(stdin);
[+?7{}'g_4G p                          return -1;
&^q-j.Q9v|/O`;D                      }qA!`8_^)oB,_Sb
                     printf("opnd出栈:[%f]\n",b.data);y^&fuDV*m8z
                     if(Pop(opnd,a)<0)
K)lx`4h"]A3MDb!i                      {}#iv'?$Z VD+z(w
                         printf("Bad Input!\n");9x2K9TOK
                         fflush(stdin);1gl'M Gi H6c
                         return -1;
6w~D5\ ]d'x8A                      }
I#G9hxE                      printf("opnd出栈:[%f]\n",a.data);Y W8?X_P.A
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*//OU{j2j(f5qb
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/?{(K.So+?,wCQ5{
                     printf("结果入栈:[%f]\n",opn_tmp.data);
&s+XQS n r                      break;
v,S'i-Z(~bK-C             };b)B$D4C&d{ iw
        }2dEy N1a/@ SE
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
$zdLfLF#M     }
fn(T#Bit0V]mI{     GetTop(opnd,opn_tmp);
:o){LNm/C MQ     DestroyStack(optr);
+{,`4\B {Ml$jpc     DestroyStack(opnd);*rEf(EI9Qy`
    return opn_tmp.data;
;Jobr0_j#_&} }CNo z}5YI-c8w9@

'^e` }[ QI char *killzero(char *res,float result)
xOWo,g {A U {Ob"d1g4N;n
    int i;4U8g0D}j1`8F

ng4O,BM     sprintf(res,"%f",result);
yT h~ivGs     i=(int)strlen(res)-1;
1vIT!T*J2Q3~     while(i&&res[i]=='0')
'[[vU-o     {
4`j:F6cx-YY'E         res[i]='\0';
$I%nRcG}} h+D         i--;p1K;\A!kU/d
    }
.IG2u*^*kj7R3@     if(res[i]=='.')
,V cO8NX:@6I4Jh|         res[i]='\0';
&}5X(ly.f Q/z1f     return res;|.G1te i
}
#I0HUU {\\ 7j&m:z$b8r1S!v?
int main(),|8N^"V_C+IS
{
aNW,qy}     char ch;%yY ]NcS
    char res[64];4I+Sx q3H
    float result;
Ca(md$`6C*d     while(1)
}9u%F_"[ _y a#F     {
s4DK#BmE%S         result=compute();%O/g;?\#Jv;Sq/[
        printf("\nThe result is:%s\n",killzero(res,result));3lE6n O{P+Z
        printf("Do you want to continue(y/n)?:") ;){(S[1|H0Mh,m!d(GN
        ch=getch();?2eFbgp
        putchar(ch);
;N;W?`j+d5m:M         if(ch=='n'||ch=='N')d)?Or,^6~k2eE
            break;$p(ZHj$Z
        elsee%xgv'q#}R_'|
            system("cls");
&IZ;aY4u     }6N)rp'O0px}
    return 0;a%fB[8r
}[/i][/i][/i][/i][/i][/i]F;r(L9By ewr/s

R }C7f@b%X9f `-g [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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