捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.(z)ne?`*OzR3x
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
3rd%{Em$s,^Y /**************表达式计算器************/
8OJ\IG!@l #include <stdio.h>
Bv%w8|A)u%k3c+` #include <stdlib.h>s6dr k4U[1w
#include <string.h>
[8j?6nTx%Dx8P f #include <conio.h>
~$tZi0k7nX #include <malloc.h>.hqc.R'C
'f{ lHFN@
#define STACK_SIZE 100
_+c[ h:|/wu #define APPEND_SIZE 10
\i!X,H^X^)U*_ a[&QIFI
struct SNode{#Ii"Q\%W^I0P'v
    float data; /*存放操作数或者计算结果*/{/^Vm/C;[H%k@
    char ch; /*存放运算符*/3n,]rx_o
};5L,F BA_#_*ow

5j}+_S+u struct Stack{
'G:{H D#XdNkEPT)?     SNode *top;
T| Mt5iVi9?0B P`;U     SNode *base;
8B f{l5tpQA t     int size;F#P.Q-Q ^(C;q(} E
};co K r,L+h3Xy`;T
8{9a'E$N$jOH*u
/*栈操作函数*/6@B5g$r{;cgY6F
int InitStack(Stack &S); /*创建栈*/T'u/}boP%J?:}6LH`
int DestroyStack(Stack &S); /*销毁栈*/`%H7T7|Z4h'U@7r [4i
int ClearStack(Stack &S); /*清空栈*/0f!si,l3F%Q9_
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
/|6{Yv:e(O int Push(Stack &S,SNode e); /*将结点e压入栈*//['F:\St0rb VuF
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/'uoJn8F n4D:Y+n+S

)I3}#L6`"Ia /*表达式计算器相关函数*/M)s#S#}k9b2ji-g
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
Xz Ah2G!Q9sw int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/*a-H\5@&d
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
I$X o_3O float compute(); /*表达式结算器主函数*/T6Me9J8]Q
char *killzero(float result); /*去掉结果后面的0*/
;n-li"f`*L8R7z u:a1fu*|"b"]
int InitStack(Stack &S),t6|mB9bcBdkya
{
4f#jBHvhdHzs     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
*B3k K-]5X|;rN     if(S.base==NULL)(D| mo/T
    { kwF+HY
        printf("动态分配内存失败!");(Qt}y6G0J
        return -1;u ol"p6XT3c
    } w0} Sd8HFYz.j
    S.top=S.base;xgETP8](^M
    S.size=STACK_SIZE;:OJ6T2gn"Y:t q4\
    return 0;(q~-m!Wh"Y5Qy)L
}2f b/RbY$e`O
x}1{"nDY~Lm] w
int DestroyStack(Stack &S)i:{ [_D3TW+_-j
{5PX e(a7y&n$o
    free(S.base);
X Vp)w1q C;p A{     return 0;Q7P|'x`n
}
']a#qkc#?o;R
4lw9^hy int ClearStack(Stack &S)
(N1w D]9\0C x {
*|Up{y^     S.top=S.base;
u7[~I&P^     return 0;
J3LccnM&AH,h!m }
j8uZ[,z8j!U"zv
}#|i4Qm9}!M)u"O1`,] int GetTop(Stack S,SNode &e)
-}L5q0K!_p5^R"o {jz9OB!o+Ci kI
    if(S.top==S.base)
+hNF;azm#[4O/I1[     {/e.z[zYA$B
        printf("栈以为空!");%u2c3xIt(w
        return -1;L\6w+lR6}
    }Ox5Q~ W?2yt
    e=*(S.top-1);
JlE|A     return 0;&R!vt @U8W9J0g A3N-z-Ci
}5e|q1f$kF;p [6\

0z5YPuIg5ES int Push(Stack &S,SNode e)
;Z3p+b!P.un { Sa-N9IF
    if(S.top-S.base>=S.size)$J"cS"pa!nOqYG@
    {
@kIs NVvM         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
IE{Yd c'^:XY         if(S.base==NULL)#~$j6D FG]&AxP
        {H.~D1D{3e/n/I#SI
            printf("动态分配内存失败!");p:WU-H\/O5b
            return -1;
v)\$[m2e$C$Z.d0hB         }
#^\oqL^$IH,m         S.top=S.base+S.size;
wdURKLI0U         S.size+=APPEND_SIZE;
i/w&ce*uI)Z     }
P*D/GP9|4a$CW     *S.top=e;:u#D%x4g Kl-F
    S.top++;3`U p i I4j
    return 0;7v%U fq3qU Y k
}
5h{-\ z.X
(z1sMUd)W*ZO"U4V int Pop(Stack &S,SNode &e)j-Q6s!Uh3d6?"fD$}*fV-y
{
M2g [x*n^z(]+h&[     if(S.top==S.base)&u o l1cYvt.N
    {
6F `5SM:c         printf("栈为空!");
t#_0uw[(ZGl2e+]7@         return -1;!P]*l.E o Xo
    }$caXuc2l
    e=*(S.top-1);FL n;R&|2j)gh
    S.top--;
0i `(Wf-J(u\#DV     return 0;
o!h3E`+vW[J/b6@(vl }
C DH3T0HX7A,H:y
9y"v'D+`$qB char get_precede(char s,char c)
.|2d1R.zf \j {
$Lu3k8O.I o?3X     switch(s)r ?9LA@6d3E
    {hyew0Y0b"Ix
        case '+':                 
([?[ N Gj#p         case '-':-e%{S/f.OR-g"?
             if(c=='+'||c=='-')
Pi0F%I V!X6XH                  return '>';
)M9li,xr              else if(c=='*'||c=='/')w'g&P5hL/L(g!a
                 return '<';1Ff[e DL
             else if(c=='(')
*N]%Ik!h5a,c*O                  return '<';
.Z$C(^ nD@:^Q              else if(c==')')%p:e6^z_2rL
                 return '>';nJ0S*WrU
             else
O O8?}q8Q-H                  return '>';
QpdP\5[5Nl         case '*':-G O"j$^4v2H!S%R O
        case '/':0Fem'?T
             if(c=='+'||c=='-')S?|y9O1M,f
                 return '>';
%M(Z!X`-N3~ z              else if(c=='*'||c=='/')
7du lH W"t*WCuY                  return '>';
9PL0]kP)Bz              else if(c=='(')
jD/ix J+T`                  return '<';EG;\ Tj&we Cri
             else if(c==')')
'u`QvJ S@B                  return '>';
l2GW'g%LfH              elseruG1A\ pxT
                 return '>';Nfbs)f*i
        case '(':
[5w9c%U b a._ T0GP              if(c=='+'||c=='-')},j]apl H#U
                 return '<';/E4if7a ]?H]$l0l
             else if(c=='*'||c=='/')
hAaBH'g7k e-~                  return '<';
$G(F1H0z y8W              else if(c=='(')
b2W!e'b`#x'ft5T                  return '<';cq Iey9rdc
             else if(c==')')Ie c#V&Yk ezv\
                 return '=';$h1ujO1XZ vz
             else
Se"~ SoNM;Q:v                  return 'E';S$Hus.F,O
        case ')':
X:F;T&pE3cq [              if(c=='+'||c=='-')
7e3C3qM:P6Y"we4o9N                  return '>';~2HXchhEw
             else if(c=='*'||c=='/')
'dJH9N'[#B#pgy                  return '>';Y6})D?s(w
             else if(c=='('){/A(z$jr v
                 return 'E';xD$B4ivyVB,H
             else if(c==')')
%}Q$Z].S$p&F2c;u                  return '>';{,Oz9l J8r%s(} N
             else
(D ?4q@?\-v                  return '>';
I|+?B0V,I"S#SC5E*n         case '#':
k/X%C U)w4Y1Y              if(c=='+'||c=='-')
Hd%f]+[Uz'CM                  return '<';&ui7E]Up]-f&}
             else if(c=='*'||c=='/')
4C}nUK.uK(y!t                  return '<';8u;{8i@(e`d
             else if(c=='(')
rb!i3^J                  return '<';`0a*wUG\{!|
             else if(c==')')
6\f F [3LZ                  return 'E';$^$HMD1|9fL
             else
Z(d1V8J U\0^K?7|C                  return '=';
e+wiDLS$b#WZ         default:7tk6fS/X3z Do
             break;J}4Z(y JN
    }:i7PBE T:Y)p?
    return 0;    3d0hM'KnF4V7d,V
}
&X3PE,X$CR(n7o
%x-Fl9S!MAg int isOpr(char c)0N2?}??rF
{
6T!eR w K0J     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
y T g.i5}3J7B         return 0;oIy4\ kV#b/?
    else
%t*qhzL1qo)qo:T         return 1;
q c-\Y%ir/y6@%bV }
2UQaVtN 1In0q [4r$|5k?Y
float operate(float x, char opr, float y)
.iK,a1G0H {$F#M8H9u'i$N+g/i
    float result;#A1{hM6w3I3TVT&l+B
    switch (opr)&o yL+`E"^
    {
:M+TaQ/Y$zA%m         case '+':
$k0bB\.AY R7{m              result = x + y;
+jg2YN/]-n8H              break;
9L6X!w:X_         case '-':
!D.l)r!{Y/H0o3@              result = x - y;#B"W%?#dn7z _+n
             break;
-P&HBg*Ws*G%H?         case '*':
#H1g-pTx_ a7K^q              result = x * y;{\,N*y p$M
             break;+NcW F(H)j*|3A
        case '/': B,G7m%a4O5EN
             if (y == 0)jh D4ir`~6Q(P
             {
)m&v{?^8J U                 printf("Divided by zero!\n");c!f+xgZ4T
                return 0; G-Mi S1F
             }
,\q}+bfB}M              else {1q:F&K8|wV6{epU
             {
!bO-D7~R$|6IM                  result = x / y;
%L9`*[~R q?-V_                  break;
i:q3Xl C{JL!St              },T*xO9?(k1\(Yg T@
       default: Uqx+h"]LSo
             printf("Bad Input.\n"); }IW#h(n~0X
             return 0;)k;q)U I eA
    }
0r`#Xvv(i Yc!LP     return result;p6Wz:F2}'Vd
}    L0Djz&r4p tp
aD^/w O/x3xp&|/PL
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/7i:BI7\V"H ?0K^p*o
{
3]N,M3^3s.A_     Stack optr,opnd;*}YWOB,a
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;]I W,Deo
    char c;y.K P'M2b v:zp
    char buf[16];0e`7{II
    int i=0;"jjmag2dhu*s
   
,y(feLw Y2J} | z     InitStack(optr); /*用于寄存运算符*/\.E/\;rU
    InitStack(opnd); /*用于寄存操作数和计算结果*/ J9oY!xx)Z
    memset(buf,0,sizeof(buf));"MN&i4I&k'zoh
   
A^D0] L$F M[.c     printf("Enter your expression:");
Kb3t HmJ"e         
8b kI!y])m     opr_in.ch='#'; Xy7?w)B oBV
    Push(optr,opr_in); /*'#'入栈*/9xg{ {o2vvR4a
    GetTop(optr,opr_top);Qoi&oa m%v6S
    c=getchar();{o(j1lJxO H"n
    while(c!='='||opr_top.ch!='#'),g@8p^2e:N&Q
    {~6qP)]&X!ao
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/D5g;^ ~OP
        {4tJ.~u#C|
            buf[i]=c;
(E'I)R6w2IH0`h?~             i++;
KJr rJ2i             c=getchar();m j @:p&O.]g I\
        }x(ceFky
        else /*是运算符*/
P p h0{^A$|/w         {
1x eZ O&] lc             buf[i]='\0';0Sh'IV7Iuh)k Yr
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0H HQJcyR
            {#l.K-J0P5I
                 opn_in.data=(float)atof(buf);
DV}&r!s                  Push(opnd,opn_in);
I.nY2VppNJKX                  printf("opnd入栈:[%f]\n",opn_in.data);6`"x?t$D
                 i=0;nmTC @)qk2lJ
                 memset(buf,0,sizeof(buf));|(U6J u`,|
            }
*BNL*V~'E}             opr_in.ch=c;
FF'Rf]] m             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/8RNcuEp6l
            {
t:J[-[5f                 case '<': /*优先级小于栈顶结点,则运算符入栈*/+@3Ml0xBI
                     Push(optr,opr_in);
@Hl9h'~0g&j'A                      printf("optr入栈:[%c]\n",opr_in.ch);e$t#\1J(AE#zYq
                     c=getchar();
g}$q,_]{(I8N2d                      break;
)F7zZmH m-S@5k D K                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ E#oj7SL1|"x*_
                     Pop(optr,e);g\%Erb
                     printf("optr出栈:去掉括号\n");
*K*X@ L r G                      c=getchar();:G"ihu.yLt|
                     break;
.c9ab'P0lKg'L                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*//].B ?0ERC
                     Pop(optr,opr_t);
q LW5SW+gf;h/b(x                      printf("optr出栈:[%c]\n",opr_t.ch);#I a%oQ c4B
                     if(Pop(opnd,b)<0).ju3u'QpbSw mQ
                     {jZ M.@D-c*rzB[yq
                         printf("Bad Input!\n");Tc{A6D]u
                         fflush(stdin);sf3^'u9d*q
                         return -1;
,\ ?3MY/~                      } S,KC(X,gb D
                     printf("opnd出栈:[%f]\n",b.data);/K_nD-p"R_'G2B.}V+F
                     if(Pop(opnd,a)<0)*Pt+]4_]9q
                     {
AIE ^}1A!SYU2R                          printf("Bad Input!\n");
U;`W n,i                          fflush(stdin); n;Hp;P,e8c;g7V F
                         return -1;
K$y2Z(U8C%Y-G                      }
X(Y#bD)ye[2\                      printf("opnd出栈:[%f]\n",a.data);N5}vA2EMC
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/4~Y.|P1ll
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/a6`$QT%h1] p c
                     printf("结果入栈:[%f]\n",opn_tmp.data);J#WyD0c8GE
                     break;
M9{a z;MRHUO             }
R TI8P'V         }
l.ZeSGh$l7E/_         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                }w `7F+u
    }
%X2N$q.@ X'vA k H _C     GetTop(opnd,opn_tmp); nDjC,w w
    DestroyStack(optr);?Zn){,A
    DestroyStack(opnd);o)Yu~*_)dWuR
    return opn_tmp.data;&]iD^:R]#u5G
}{G{,PnF2m'u
/X.p-hIP/{ zo
char *killzero(char *res,float result)
&nmLd}lB"]6`M#j {
-NMVx#eT:|     int i;
1I0zJ KH ])p
1C X g{S-e-KN     sprintf(res,"%f",result);b(Kh"s*@_(D6LI
    i=(int)strlen(res)-1;Zh?hy
    while(i&&res[i]=='0')1o `qz:s;e8A T'x
    {5iXY_&]2tX _
        res[i]='\0';
K4X-LaLUoY2C         i--;v!~pKs3b mx
    }
(n4@;J%o:lU)xk7Tr;n     if(res[i]=='.')
"m tGQ8Fq-{         res[i]='\0';
?!jM]$edd Y S$p5R     return res;
aF*K*|A%{|&r }D7b-@gY.K*GC
oh"EW%l7j
int main()i+rdwJ
{_/p S'_1^ `7RC
    char ch;
g \{A+~X(ks2A     char res[64];
7U&q6Rd"ja     float result;
3NftU)T7OUuz     while(1) U7p#?AL
    {7`hb'Z q(LrLZ
        result=compute();
wZ!eu:I1w4ST"e         printf("\nThe result is:%s\n",killzero(res,result));
$h&U Q6S Vy"[p^?3N5f         printf("Do you want to continue(y/n)?:") ;KL y;_h(Rd
        ch=getch();a LW,`1LR$M
        putchar(ch);
4_Nm^,h{n1B         if(ch=='n'||ch=='N')
-PkGBd9AXK             break;
e3c? QDAd3@e         else
;k5Z:v AdcT8U             system("cls");
&C/m}0Q&w~     }
9EA&cLEy     return 0;"h9@ f_ci'j[U
}[/i][/i][/i][/i][/i][/i],w;L6pI X

H-[4A2]Nw$q [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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