捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.S2k7J?2_(r!R @
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
Ka,i$o gd(f /**************表达式计算器************/
8H ~6V$_ h1O #include <stdio.h>
J'Q7w@7E5l%T #include <stdlib.h>
1g!@"QW;V?!zIvk #include <string.h>B` y+E~-{~
#include <conio.h>
3Gdb/FMU+K,y K #include <malloc.h>
0K1]iZ'{ Kks+[ U ;u],lj:?V$_!J]l
#define STACK_SIZE 100~"c`O2t6\ SK
#define APPEND_SIZE 10g8t oJhGM

?2j-gB(M*G9Q struct SNode{YD3b!GC:g$F#Au
    float data; /*存放操作数或者计算结果*/r1{1^nB6pmFH jI
    char ch; /*存放运算符*/ YD6uAk#_
};_ \F/mS,oN
h(Pj*A$lj E_
struct Stack{2\l2?5G7MP1zS
    SNode *top;5A?t-NS
    SNode *base;.tr,~i*P3[t
    int size;B/]^7^+MUi o%k/T
};!J\ W'@Ey6z&R
N {-Jc,p
/*栈操作函数*/tx:nT l9X
int InitStack(Stack &S); /*创建栈*/$j dWf7i
int DestroyStack(Stack &S); /*销毁栈*/ y)z(zN1i\6A6y
int ClearStack(Stack &S); /*清空栈*/2I9T0Y6U#g3Lj
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
;m)t*d"swt int Push(Stack &S,SNode e); /*将结点e压入栈*/
3Pc$dstY8Dg int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/0] QiCF[x

EXp"D"X&@&M /*表达式计算器相关函数*/
Q/\C _l P hry%W%?.L!U char get_precede(char s,char c); /*判断运算符s和c的优先级*/
Nm%T5m'C\u int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
@2@iwe~1v~6_ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/0\zd,V"P {6X0oO7?
float compute(); /*表达式结算器主函数*/
3T-N'E(\ZjAs char *killzero(float result); /*去掉结果后面的0*/
"a1w:NFg%{[$S$v
e)O:o+t:@3f int InitStack(Stack &S)
|uV7NKkbi:O {!iie6x TtC|}K
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
0KU ac&VA-r/Z[u     if(S.base==NULL)Dx A Cx D
    {
-s,q F.Pj^sBcy         printf("动态分配内存失败!");U3[oL9`&ef:Y*bD
        return -1;
8J*B*s4V}t     }
&mimTx     S.top=S.base;
fJ&U!?~/Sp     S.size=STACK_SIZE;G ?-t~\(p;P S
    return 0;
c7~p%uP"]d)Fh }T6@9o.u1y

:q7f0{CCo int DestroyStack(Stack &S)
5ys \/^"m-o {8Q{v#dOR.yA^m
    free(S.base);
6R1k z Y` YB     return 0;
2d$hL5d&H$y4va xt ~ } J-wZ'p)e&o.g:@Z
']"L$F:d%c4`
int ClearStack(Stack &S)HPD_n7kE
{o lJt} v;P*}m
    S.top=S.base;c@j,@`S_!p
    return 0;S0q1C3s,h~
}@0q1|-Tq cS

N I2PM z int GetTop(Stack S,SNode &e)0d Us+C*IPgp
{
4hi.p+jb}"Y     if(S.top==S.base)*|#X0f-z:As
    {
4y*K}L q{$frY         printf("栈以为空!");
:\!YTl W1]H"x,nV         return -1;_VVSi3iw
    }
\!{gcu:I vm]HR     e=*(S.top-1);
#DE$~'?/P5c0hXA     return 0;-w0av/yYAo
}
,BlJ9M4] f.Q:k
-W?!u6|],TD int Push(Stack &S,SNode e)
.A[6Tp*k(B {
0s.K6}"f.s~:C tBbd     if(S.top-S.base>=S.size)
V^ V(v*i     {,[(P G)L.udT ek
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));}q*v%O7\#D _F;A'F1b
        if(S.base==NULL)
c }J.d:vc         {CD'r@!r5\
            printf("动态分配内存失败!");
Q+Cv v ugj2I             return -1;
2H)d5C)Y8rd:zX8{         }
a6Z^] I7yh n!R         S.top=S.base+S.size;
8?S&rq jm0R         S.size+=APPEND_SIZE;\B1l8McH$L(Mr&y
    }
3D f"VmZ&tAIR'j     *S.top=e;
ud#vh0w&YP5H     S.top++;R[&C8lN*O}!e1qm1X
    return 0;
;n'~w @q,Ng:e }
Uq zs{2b6DH/~ r rkzA
int Pop(Stack &S,SNode &e)
$|JPaB"VSl {.l2^;s/t8H(P@
    if(S.top==S.base)U1E4l2yY4k.q Fuz
    { d\s&o~r6c]}
        printf("栈为空!");,J4f7`?G i @
        return -1;&Bs"F J\:m
    }
n*A&[K7U C _D     e=*(S.top-1);;q+gL P!q;v#F]7}
    S.top--;
|IuX ^gZ.H'S     return 0;
O*KO^b] k+N }
)o@@3Z\)]Fo
t$^-pluX)R3D b3j char get_precede(char s,char c)ug*@a|#d r
{ ZB!Zm8Mm[D
    switch(s)
3q(U-[w"MY     {
B4ZmW#]$k%k7pE"_         case '+':                 
g2O.`P'NR         case '-':
-?K2y6b:fu@ A              if(c=='+'||c=='-')
)Uf*Va1v6BD4n                  return '>';
:tDd_ Y;g i"g              else if(c=='*'||c=='/')9]blT?'hL+zn Rh
                 return '<'; K-dW/B_n(}"RP0O0O
             else if(c=='(')
O3Lg6pr@[7b                  return '<';
!r}h$T@O xu2h              else if(c==')')
vm|za                  return '>'; R\k*v1N!yK:R%U
             else BB|q7n9Le
                 return '>'; g/Bmj qe#g
        case '*':O6J-[0Y d W1HRp
        case '/':
;G%L1M+d~y              if(c=='+'||c=='-')
:Hu0D9^Gh3{2NC                  return '>';W)F!wf mra2[QN
             else if(c=='*'||c=='/')
0E+{A;]5x+RP                  return '>';o$f Ex3]Zj3cQ
             else if(c=='(')6t Bk0s:]2]m T
                 return '<';:~6C[)GF&Q"Q\^o6c}6}
             else if(c==')')
Ed5V-MN                  return '>';T rYt?H
             else
7H(u6C$c.Q E ?                  return '>';
6lxV(C;h"N9VT/lqy         case '(':.N-LMJ'p"Mk6A
             if(c=='+'||c=='-')C(Z~0|2utS
                 return '<';W2X+w.xs6R3VJ^%N
             else if(c=='*'||c=='/')2{M$C3Zka*Wk~(^
                 return '<';
,R:Sl3j:I(N.k'h              else if(c=='(')8VZ1D-\2z|`
                 return '<';-X&q }KT j`_+x
             else if(c==')')zB$N8\-sV f
                 return '=';*k7i)X/^5A
             else
_0mnK"a T$][}H#I                  return 'E';
k2s0O'Sj         case ')':
k2y}]n|              if(c=='+'||c=='-'),TUW o\3d
                 return '>';
K$} s NMje              else if(c=='*'||c=='/')N|A-ev5Sp
                 return '>';
(Ah_D6k+Y)nL              else if(c=='(')
|,?7lf|{or                  return 'E';,XjC%M;mq#C^
             else if(c==')')U V:g C$z^8{+}
                 return '>';
X;{6s)Ett              elseF&A"RD m,g3O[
                 return '>';
hZ6zL?6RRRbaG9x#e         case '#':1S3_j^ A8o4Qt
             if(c=='+'||c=='-')Y psva
                 return '<';
7Nqk7M/QI6D              else if(c=='*'||c=='/')!T&eS;k*_&e0A[
                 return '<'; b o'Uxw`%B
             else if(c=='(')
-iOQ-lt&l+c5O                  return '<';
4ep,m\-`6BYs3?&k              else if(c==')')V3ApU gDW
                 return 'E';]V@9YA3w7ZCI
             else
M T _)a`7idi%n                  return '=';1]#?Cd,J'@!D"c
        default: ^ed(T I0^#U6O`{
             break;Z&w3ygU ZvG4ut
    } y8sl de9LMR n
    return 0;   
yZ9RF*nJ&h2D }
#R3z k!kde9s1V
q lCj#F~ {fc/X-e int isOpr(char c)
#sC+[q2n]HI9J {;f'Z!r0w8W&f
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
g7hKFP_\7g`]         return 0;
p&J\8be     else m.z?'ct5?
        return 1;
.~k q2K+@x'~5P }(c^q5QB1s1eT8e
b5e*IE;{ y\/fVG
float operate(float x, char opr, float y)
4a;{ Yk:L:\ {
N8YCvk s.l B6_ ICG     float result;~!UQ;u|8t yA%L
    switch (opr)#@Y4q3_&n3m
    {
BGsnz~         case '+': 7P.z]BP
             result = x + y;
0C[(S"z#\Xd;g Qy              break;
p#AG,ruc `         case '-': 0G/H:n PZ j
             result = x - y;$Y%GDpB2lWo$O;I
             break;s$G wWDh L7U
        case '*':
2v B2N+r1A'?$jK              result = x * y;
)|*KI$R5A0FQ y              break;
k pO'u"h%bx g}/q         case '/': U*sPsx/I]
             if (y == 0)#g |7pc2bz1eP9u%]g
             {,{dg~r!X
                printf("Divided by zero!\n");v"Xl @(O`-Y6}
                return 0;.yJ QCQ![%|E9q.h
             }
$Y3\1apv1])jrx              else6h2F@ svPp
             {4`1Dtw&x6Kl
                 result = x / y;$i9}Dg.~!Y
                 break;
@)UWtc              }dX ~sI e I
       default:
3K%y1O%hR/DbB9h              printf("Bad Input.\n");
?B+m g3y|              return 0;`Csm!RV6p{
    }/{%_` e#C ]
    return result;
M,Q.s%T!`)u@[L }   
fW$u"g GTr$RS E#q Mn$O~n0GS
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
TM] a.q {%OI9MPDN'c
    Stack optr,opnd;.f)x+]n5|WR
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
-{]fr!]"WQBL     char c;
;PAMg"J     char buf[16];7@rxD1w m da$^
    int i=0;9@rs(ae!j
   
~3F,o [H.A     InitStack(optr); /*用于寄存运算符*/8@UcoB5s)Q"t@"~%o
    InitStack(opnd); /*用于寄存操作数和计算结果*/0}H zy7wPl7^h
    memset(buf,0,sizeof(buf));
9?:rX-f}8v qLl    
Qn/| w3FSAgex{     printf("Enter your expression:");
'`rZ0Ab1CLQ?J A         
S%q-I8a4v;g'n     opr_in.ch='#';
$I!K7dr*S/m-p/o     Push(optr,opr_in); /*'#'入栈*/ LWhyNL oU
    GetTop(optr,opr_top);
FH4t:r)~q BL"`([     c=getchar();
V^Op!I     while(c!='='||opr_top.ch!='#')
]}S_#tv     {
B `;QaT.I%n'Fr         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/!HRSR\K_8O)j Mf
        {
%Xk]w_fzGHX             buf[i]=c;
U;~:|\0M,Z             i++;
f+f(Lr+r             c=getchar(); h;[ P&@b&{u Sp
        }
an2q,Lo!u\w         else /*是运算符*/
ie5ilvbLu)Z8O         {w-S DgT3T8a
            buf[i]='\0';fgt"m Z2h!nm
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
`ZhHFGp*j%Rs"H$]             {}y W1f/sOlp#X+A
                 opn_in.data=(float)atof(buf);
%g!HP U@1Vq Em                  Push(opnd,opn_in);
4mP bqh,w:@"E(| ~S R                  printf("opnd入栈:[%f]\n",opn_in.data);
)c4M9c7tdH,X'D?|                  i=0;
7SF3M-d)JN@X                  memset(buf,0,sizeof(buf));ga3H1fS!fH4^2P9i0Cu
            }
b1| TC mkC"SpT9] p             opr_in.ch=c;
y0C#KL9f O*g/X/G rw k             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/!im4N}6Y!hG F0i
            { zeQ{au9l'N
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
X9[$k!Jm~?`                      Push(optr,opr_in);
6L2|OsX#K                      printf("optr入栈:[%c]\n",opr_in.ch);vaD&D9rix
                     c=getchar();f4v'`3NuF [
                     break;f3xDP|hJ
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
jm+{Y/rcuF)_                      Pop(optr,e);
~yVk,B@#\                      printf("optr出栈:去掉括号\n");:@g._V/Sf-DeIR
                     c=getchar();^,U3DFw^v
                     break;
0RiXnD7vr-G`                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
%G^@8Atm                      Pop(optr,opr_t);
U_I_.]o(WMl'w'P                      printf("optr出栈:[%c]\n",opr_t.ch);
#q:MhWTx                      if(Pop(opnd,b)<0)
C)n|:m3YwoKW                      { e|(n$q b-x8F
                         printf("Bad Input!\n");p'JVU8wt(bS
                         fflush(stdin);
9@.|v6w)T"G                          return -1; Z0Z)o&x2R
                     }
O,|)|Rj                      printf("opnd出栈:[%f]\n",b.data);
%a4^(t-L"uM6C }go                      if(Pop(opnd,a)<0)
(EN&f S7T S;g                      {gVv^/`8}
                         printf("Bad Input!\n");uzA m,L~9Qq,C
                         fflush(stdin);~*Z+nO7j%o5juz
                         return -1;V%?[s'uh!T
                     }8f%qSI N1Nj+h
                     printf("opnd出栈:[%f]\n",a.data);+U/]5?&SH n
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/ W5z!J:{Meb
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
K3~T"^4Uh4W!Cb                      printf("结果入栈:[%f]\n",opn_tmp.data);
+[*N8w,K P] i                      break;
X NSd#m             }
~|,X%v,n1Qh x         }
:QP8exu:o$?ZX         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                3[&pZ+g,m
    }
(ZH1Y$Y&?k#~     GetTop(opnd,opn_tmp);
K&ge&y(|'S$U%w     DestroyStack(optr);
9g3\4sh0\be     DestroyStack(opnd);r,j2zaLs6R
    return opn_tmp.data;
}G E"t9}}^ cI }
9i b U,X7T;x^ /I2Jy$iv)T1D3X
char *killzero(char *res,float result)1C O(_ RM-hZL5R,Z
{~0u}biEC-u wLy
    int i; vg-AU(G]
2Q2c'V%j Jr?
    sprintf(res,"%f",result);
h,l\:]n     i=(int)strlen(res)-1;h&Cf0?W*m:~7f
    while(i&&res[i]=='0')}*X:`!cQ.O$}:S
    {
.]6E"UbYK         res[i]='\0';1P.{QV v0^4Gw mGr#m
        i--;
a5^8e4d:l     }'J,C3{ C-o0gx hujn
    if(res[i]=='.')h1q9|~#J"| x
        res[i]='\0';UKY!UJ!s
    return res;
n2?7i,T6O7e#}8h }
'[H{SBg nx/vg9bT;vV0Sn
int main()^7w*_O`J
{
'g&WqY`A     char ch;
&U[)[9eU d     char res[64];'Z a0i8l,D1S d(L5~
    float result;AT b)mx4u
    while(1)
6hOR1cM-UjdRReU     {8y5J&kg CvS(Ne$v/{
        result=compute();E6AW:L.F5q8~&v
        printf("\nThe result is:%s\n",killzero(res,result));
(bM D f%uJ         printf("Do you want to continue(y/n)?:") ;]y&h/wtVKj|qNx
        ch=getch();0k't\I ta3N.C
        putchar(ch);#AS ALOtJ
        if(ch=='n'||ch=='N')
'Ighx? \DY             break;
#\`+e&x8ju ]9LD         else
*|B)zT:NQ             system("cls");
"~Mi[zL     }
H+~7MP$G6L.y     return 0;)Th"X^.rzK
}[/i][/i][/i][/i][/i][/i]9r%n J@ {'uZ%u
Nd6R"N&R jqa.NF lz%F
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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