捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.ilx0_ wHf_"CI
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
i z;N0e0oO0u}dd /**************表达式计算器************/MR/N?3A9Xj
#include <stdio.h>"x_O\3g%w7D
#include <stdlib.h>m!s[(WS
#include <string.h>
D`J/a qQy)S #include <conio.h>'Tw*y+r g#g'C)x
#include <malloc.h>iJ3Z6TQLO

Lu4\4y!~Dk-xJ #define STACK_SIZE 100 y,t1zYzSr
#define APPEND_SIZE 10:SI#I

%bD{,s'~w/B struct SNode{JYZ!FrK'[S+A7^2Q
    float data; /*存放操作数或者计算结果*/1xp w+n^UX
    char ch; /*存放运算符*/
a9b5j.@;S2M;k };S4`v5eW Y

BlA4sDww%nA struct Stack{
+zT N!s9MA     SNode *top;
J;RK kp     SNode *base;
sk3_A,l/c(Q(}1[     int size;
P.Al4zJ5u };"ei8wO ^W

S pm [D3~hr5Un /*栈操作函数*/
'] EL W,aC,vM(s int InitStack(Stack &S); /*创建栈*/
J1DNQ^Y int DestroyStack(Stack &S); /*销毁栈*/
3y ]T#ST#q Z int ClearStack(Stack &S); /*清空栈*/
8BR W2t+yAm int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/,K(m7Rr eW.YM
int Push(Stack &S,SNode e); /*将结点e压入栈*/Lf S}yfP
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
9I%s? g9~cJf I@,ob+jD3[.jOO
/*表达式计算器相关函数*/0?i }{2wvU)["e
char get_precede(char s,char c); /*判断运算符s和c的优先级*/.MOt ?/C p1A
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
n1l%t+R sL ic float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/*k? |'G-C~ o|A3j.c x
float compute(); /*表达式结算器主函数*/(qj H0Vz)S
char *killzero(float result); /*去掉结果后面的0*/
Ax,P9H7MFA6U4_ 8Z~ R'\3`8qP
int InitStack(Stack &S)O}J{$M ?@D
{ kW!H!Qn?E}
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+{ X SR-x-Dw{     if(S.base==NULL){n)S/|l[/u
    {!YF_E(Ck
        printf("动态分配内存失败!");zR/qOx ~q
        return -1;q/_ JUg5U%H
    }
:T,y6l2~F$A3O     S.top=S.base;
jQIi'ou;C     S.size=STACK_SIZE;
/CN#\}!jR&j.@$I     return 0;
iX.bG+D$moN;\ }RII5m2F9^([ I

T q~Z;VS int DestroyStack(Stack &S)
RK6r&Pm5{[6W#S {
*S;y6r0G\6i     free(S.base);
9~ f#p!V$M!I1b     return 0;
f5} I#d8E2@ }
!~)B%I"WskSz 9JfY/{4GY3SL4{
int ClearStack(Stack &S)
[G#S3npQ'A {kJCz$O_D
    S.top=S.base;
h _#Q-N0{/QG     return 0;o'~Df#k%T$U!DC
}
+bT`-T-L
R(yc"I~{.l|All int GetTop(Stack S,SNode &e)
8S4T5]~B!C5r g {8Gkh!_Y_2_9\
    if(S.top==S.base)
5a;nch:N/k     {0D/| S.} ??
        printf("栈以为空!");
8`,Nk yv Bf"h         return -1;
4^2`\,OH6\     }D vD'Ns{3g
    e=*(S.top-1);-ssS:dc+^S&B*a
    return 0;
Q `D\.T }
y-j@8qh Jgy4x*^
int Push(Stack &S,SNode e)R_5qX.bL*?
{
T?| l:B     if(S.top-S.base>=S.size) Pe3WH?
    {:lO3k} _SJ-jN F v
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));O0H(J j"G/p L)E
        if(S.base==NULL)3TI)u |#\ya
        {
HLirlA hF             printf("动态分配内存失败!"); U r)N?r mAR1L
            return -1;
)o&T~$_wx o @'o         } {{3C*lsi9i
        S.top=S.base+S.size;;U+hP3O`)kO@ @6b*q
        S.size+=APPEND_SIZE; p^O$L0eF~.y1o
    }(lku*i _NNy
    *S.top=e;
mOj suv.T\e4@     S.top++;Z/vq:l K[*wG m
    return 0;
6f.n8v {L4a[yT i^!R }
-Y5f5T-^2]Wq] 'Z5f&]4u7L5?
int Pop(Stack &S,SNode &e);}/Ywuw
{
2w2u H-k~Zj4R'd     if(S.top==S.base)
u(?Wuo#ou     {0yi ~?/e QH
        printf("栈为空!");
3G,CpE |*m         return -1;
ZI1cz5N ogZ/hg     }R3Q,P*|M t\D
    e=*(S.top-1);Y.s/v4@ EtPk$];[
    S.top--;
Ha8s iU9D4?/o     return 0;
+B5q8U0q R(p2zJ Q }"xv"`S#e H%Vc
wN8UG{
char get_precede(char s,char c)
NF `9e3EN{&I {
J#_7yq C0N$N&v.e;~     switch(s)
M` l)X1oVM\     {
U(zO[7R.Nyo         case '+':                 +{T5{*z#o
        case '-':
&nR7{-sqp{^              if(c=='+'||c=='-')aSn fBQ+C aF1h
                 return '>';;Khvb7W/[
             else if(c=='*'||c=='/')j:F/O(qu%W4xFm
                 return '<';5X,w:QQUo`-V9n0q
             else if(c=='(')gY(U+kY#A9q*i
                 return '<';1?,Ne~(@7p%f'M@
             else if(c==')')
6f D\QH(E?                  return '>';
;| c"oaJR              else
"Q`/T { rj                  return '>';!Qi5~nf v!D'J
        case '*': o)I.l)`o:@&| O-@$x
        case '/':3T0f v2PZ8N#|%Y
             if(c=='+'||c=='-')(L%P@)p3jEx'|#e1M
                 return '>';
]u U#@qV(UcZ@ {d              else if(c=='*'||c=='/')-`G$r#Q1w!UR(d
                 return '>';*h b A;Z;c Lq
             else if(c=='(')K|5z+L/qS
                 return '<';:ae k`gL&p CM
             else if(c==')')|q4o2M_5\H_
                 return '>'; D;G!B b5h+OZP,Z}Q
             elseN1a${)s`\r!{+T7t X
                 return '>';0?c8v*P~:jhk S*p&P `
        case '(':
tyc5C T              if(c=='+'||c=='-')\ NG:m3I3`
                 return '<';-H\lj.wtP
             else if(c=='*'||c=='/')vQ$tS.jACne
                 return '<';)G5L1\l*L"BTa2i}
             else if(c=='(')
X"N.@t8`:g_FQQ                  return '<';(ds4m/x"Rxi
             else if(c==')')
"k x5aw(sku2N                  return '=';"|&{dTu3A)W6n
             else
'y4TfjKuHq;?                  return 'E';
P'{}ln)y)B$g         case ')': d T.Rc0mC0_8G
             if(c=='+'||c=='-')
dm9| Z'A7c.|f} a                  return '>';%k0zGN c1N1b
             else if(c=='*'||c=='/')
/W'}tH9nv(]m                  return '>';$NB&OmW'[d&q8L*v
             else if(c=='(')
@8|+Q r e:f(yI                  return 'E';
7a0mI:A'^S&M)t              else if(c==')')&]U~;uy(x
                 return '>';,Ge4oEE.qcp$\3Sr
             else
b"NbP8LV Q                  return '>';
x&A wZX |         case '#':
4P@2a'|!R j Q              if(c=='+'||c=='-') i-tlhO J-fP9xwb
                 return '<';2x-a6ueLvQ
             else if(c=='*'||c=='/')9C c K;f/o:S
                 return '<';
-\!}$aO^3W:U:QOS              else if(c=='(')"Vonj-WN1Hu
                 return '<';1o*[*[Za2`U
             else if(c==')')
kfI"x @zLy                  return 'E';H]&f!pu&N,aLQ
             elseN"i1mZ x"d.GF ~
                 return '=';
2n"y"pB.O0[4[8K cook         default:
7NG1e i@c              break;8~Xy(Bdj
    })N.{QG#yM r.}?;U
    return 0;    %u0p0k1h| X~
}iytc(g+q

T_3d N ] |,V int isOpr(char c)
8l_w^6I A"b,G] {${'V!Vc{7_8{*A
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') ?:M$Ds)Z`Z
        return 0;5a8t!b'z1T_)l lC2[;ej
    else
qj8j'?dQ h8n a kb         return 1;
Y.N9S0K@.B }f`P~+p8[O
%Oz |l jcd&m I
float operate(float x, char opr, float y)
v2||o.~S!U {b3vYY1g OU {S4z
    float result;
K8`/BO ];g R q D     switch (opr)
_o2n v@I     {
.S5vg,Lz}4P         case '+': ;w ju7r } S9q0m Q4u
             result = x + y;3Y0}[W_0P(L
             break;s2i$Egq4N`
        case '-':
KKo1[[ oh-N              result = x - y;"S&X$E2_ C'k;e
             break;6XyiN+A xD
        case '*':
*f-`6@d*o?3zGJ]H              result = x * y;A uWx5G1]pihf
             break;
6h%V_[y-N3@(z         case '/': )c|#r/lq e
             if (y == 0)%@-Y/@4W;k?
             {
/oovv:e0i`                 printf("Divided by zero!\n");2[D$En)W h0r] ]
                return 0;
{&` |8?8gj              }
-pj&HK0\-N              else
Tl| M%AV(BF              {
}In)dz                  result = x / y; m xuHtuR)d
                 break;
wb4O+a ~QoW              }
K-f3DPL&my$bBkw        default: 5T}z \)OQ e`
             printf("Bad Input.\n"); :bl;TajcK
             return 0;
Y8PA?U:PT     }
r1og6GY/^t     return result;
+sdP]1s[6`a U }    sv:q"kj?
~g ~ pst8st
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1xS0t3c0^ o'A1x1M$vO
{
6e2pO N ~,}     Stack optr,opnd; ]r,m8_1B?3Cb2iU
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;/Og+}"oVqom'MR
    char c;
/p:|;iPY1LS\JH     char buf[16];#@m{)G I$L
    int i=0;6`x;I"i;TV8Z_;xP]
    zZfhP(b6t'mb
    InitStack(optr); /*用于寄存运算符*/
z k$kR)v.F]     InitStack(opnd); /*用于寄存操作数和计算结果*/x(fho/`|3mn)E
    memset(buf,0,sizeof(buf));"R SkF+B%|/qE9c
   
A9yD+e;^;`L/f(H ~     printf("Enter your expression:");
P@ ^|A         8P JP [ @+w
    opr_in.ch='#';h7GA0mUUbHeX
    Push(optr,opr_in); /*'#'入栈*/
J$o(Z l9Eo     GetTop(optr,opr_top);+\$wyNz
    c=getchar();
'ueAv%n-}!sJ     while(c!='='||opr_top.ch!='#')
G nQ O#D'rezI\2yN     {N7O~@-F6x|;Q
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
A!z&MT8x7n         {
],?4x1k c             buf[i]=c;$] t7urG
            i++;E G e~}R,}
            c=getchar();
5N#{Xe0o9T         }
(\%Ue P$c5@/w         else /*是运算符*/:{%V\F ~2`8J
        {
$gHR]cU*^0_'~:R Y]             buf[i]='\0';+kT'VmQ};J
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/1m.\m1]Q
            {}`[NcBy*pU;r&H
                 opn_in.data=(float)atof(buf);
+b P#~)g;D ] @}3R                  Push(opnd,opn_in);5PS;E},RE$F l-j
                 printf("opnd入栈:[%f]\n",opn_in.data);
JFwK%_9N6z                  i=0;q!G3_/Jz]bEhN
                 memset(buf,0,sizeof(buf));
wWjD d J             }-GZ }?H8ie,fJ
            opr_in.ch=c;
,@?%e&]!N0H             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/$`tc$G~e+v{ \:N(Wm
            {
*ic"z:T\l                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
Ur zEVIf"@;V                      Push(optr,opr_in);
zk5sV/v                      printf("optr入栈:[%c]\n",opr_in.ch);
.E Gu Qq'F!~_u                      c=getchar();
M)d7g1@ M                      break;
dhT'u1@$XA/{x                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
2J p'k,DJt*D                      Pop(optr,e);
:GzqR@ Gv1w                      printf("optr出栈:去掉括号\n");4u2wz&~?:w z
                     c=getchar();
4N&BH*_.o;_]E4}                      break;
'hN%J0S$HYdW                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
KM6O,Z.U8JN                      Pop(optr,opr_t);
Q n&O2V O                      printf("optr出栈:[%c]\n",opr_t.ch); {v.ju Z_'uK;S
                     if(Pop(opnd,b)<0)
rV#j!L2v&v                      {,@N7b |)d$OEw
                         printf("Bad Input!\n"); Q rxv3Z`8q)A_
                         fflush(stdin);XS)og3^'D:t
                         return -1;2zMB`;BXN
                     }
B0F*e3W r3Q                      printf("opnd出栈:[%f]\n",b.data);b+[mDk.UA]Z$p|a
                     if(Pop(opnd,a)<0)Nm3O-^D
                     {,w(k.d@,S?,jF
                         printf("Bad Input!\n");
D c?3p2HM_ c3x:YH_                          fflush(stdin); v|VJn;Q
                         return -1;/X%f r/u&]:c4S rh7\
                     }
*J|q4tZ L_~                      printf("opnd出栈:[%f]\n",a.data); LWu:Q b\:T
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/7z+bQ*]W$Q
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/eJ?0JY
                     printf("结果入栈:[%f]\n",opn_tmp.data);
%K;t-[g6_'Lq)m*P w                      break;\A1N5j b)@o
            }$Lff4L.s:E1~:uS
        }Ql4Oh ~?.s{
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
;RQK+E R     }8H z1w8| ]ZSW
    GetTop(opnd,opn_tmp);R!r Gu:}T _%_ ^r6]pK
    DestroyStack(optr);*VK*V3L5]%~ _
    DestroyStack(opnd);
3T*`&r N2Ra'H"qj     return opn_tmp.data;
+K?1w7Z_%S5a+[ }
5f'h+A$o_ I
GxDr I!{,N char *killzero(char *res,float result)9~9L@E3jp OQ4b
{
6bn#]0[7B;^*V!y     int i;5QSXR/x-v%`
M Nkp.Y&N._0a
    sprintf(res,"%f",result);
C2xR!FH6_0N-K     i=(int)strlen(res)-1;(Ak sK}EXEv
    while(i&&res[i]=='0')
'}6e(h9]:J+j*?zNF     {2e#{?xE
        res[i]='\0';)cBy?'@
        i--;j v4dg~[6G3z
    }
td }PmS S"hQ     if(res[i]=='.')
_C#d!U,K+WV'tK U@         res[i]='\0';*n/b/D/`5j-c
    return res;
:h"p+Su z$R] b} }Z [sEa9b
\t e&z,[3Vp wf
int main()
r.Oq6b+K/J {
7EVMT1yn     char ch;
4Qg|3x6|,{     char res[64];5\f6BdS
    float result;
\:{-V%Y{     while(1)?4} L QZ:{ I6b
    {H(AbA$m!Q\}
        result=compute();
0Z.S!o UB*xr0v-K         printf("\nThe result is:%s\n",killzero(res,result));
X` ~ Z'xl`F6A         printf("Do you want to continue(y/n)?:") ;
2}cr8Lk Z.O#_1O-cj         ch=getch();
] ?aC9StF         putchar(ch);c Tm5X:[4u
        if(ch=='n'||ch=='N')[WXH,QA#R5Q
            break;
!n7Vqc$['f5_^(Cw         else
z7C }7f:u'U ]?             system("cls");
+z3H]-Ce!J)l     }|&Z@_c@&?_0?N)G9d
    return 0;3x"J#a5`)U6tz,f$p
}[/i][/i][/i][/i][/i][/i]C,xp/k,\7]
yn)If] c~1p
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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