捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.;Bs%V8S#l0Jr!]:Gc
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
5c!CN/wn{$]&eL"k /**************表达式计算器************/
.?-[z!EaS$_\&o #include <stdio.h>*f|&l1Jm
#include <stdlib.h>
XdG mY0[^c #include <string.h>
fW6o {9uUfzb:@ #include <conio.h>
(jvOpm YK;}1] #include <malloc.h>Q1E%fLB~pekW
e)C$Ar_B
#define STACK_SIZE 1008k3P7{!MHu-`R
#define APPEND_SIZE 10
o9Y(j8Z'l {'j
7~@@1x!V t c struct SNode{+Bgfq n k-s XT
    float data; /*存放操作数或者计算结果*/
l,{au/V~,g     char ch; /*存放运算符*/V3fANyC/H
};$v+U^:Lg,s_1k(h-u [
0?,D/Z(^Z/cI
struct Stack{
nU^uj6\Z     SNode *top;
i4Oftozv2r     SNode *base;}C-`&w`
    int size;Kq&@}:ap*pN
};/TzDs(iJj3Avx

3~+{ w"I*{+B /*栈操作函数*/IV+]`&G*r6X$[t)V
int InitStack(Stack &S); /*创建栈*/.s4Ij-~~b?
int DestroyStack(Stack &S); /*销毁栈*/#P Rb_`
int ClearStack(Stack &S); /*清空栈*/
;]QZK6m9n:C+R$l int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/s$s}%GmcDD
int Push(Stack &S,SNode e); /*将结点e压入栈*/
,Q9d1U4w*g6VK int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
[$A*Z,A9u-L
!f d'y7B:`b.XV6r /*表达式计算器相关函数*/D X*PD eqA*{A
char get_precede(char s,char c); /*判断运算符s和c的优先级*/1`1q`*H'V0q
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
a.v5k%{i3Hx7c float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
y2b&D1\[r!} float compute(); /*表达式结算器主函数*/T ~7P F(qP8wE6_
char *killzero(float result); /*去掉结果后面的0*/
9Z*iy Nf_
U X M"zUW;k"D,z int InitStack(Stack &S)
,h|!t!\N.T$AnPm {
0mp8Dr7Y{1V B [     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
z"\0Al`N     if(S.base==NULL)2rVs&kHkJi1M2I
    {^-aFh&Kb1z(@
        printf("动态分配内存失败!");
TF qdQ%q         return -1;VJ z.T3W:b
    }9@:RIHlY7KA
    S.top=S.base;)} HO+gtG @
    S.size=STACK_SIZE;0k#Z2V ^6\;r+P1Y@
    return 0; fnd8`7?!|]/@ Im!t
}
"JbvO i`Va;? eI$gR(V#lo3K5C
int DestroyStack(Stack &S)^!Qg M+N.P
{
U"aTy+Ki,?;j9D     free(S.base);
D/w!Cg1{lb3Q     return 0;
4u4hz'_bc_q)L7} }
\5WeL G!R_"m.x/LB
aQ)I V x g5W yr int ClearStack(Stack &S)
2K)W7v4Xfxr {
eaJ n)~*KM     S.top=S.base;
Cg LR T` Y&B     return 0;T R(m[9P)^
}
u;~(SS6} jX9t:W +xMC.}(v'X%}
int GetTop(Stack S,SNode &e)
q4m ]/yb"IKm {2oL["_%m-vfQY
    if(S.top==S.base)
N*?.qcVx5d~     {
!_~kD5YJ         printf("栈以为空!");
hr%T`#L c eW         return -1;
\pX%u!OP     }/?:]2Y6{7u8JLJ K
    e=*(S.top-1);#fxyQ'[p"~p/w5h{ w
    return 0;
ls+R&hz|u|eo }%k&{&R)Cco,l+n]

P;[8h&iMS/\:C int Push(Stack &S,SNode e)
7mJ~ @$` Z? {
]Eu&O/kA     if(S.top-S.base>=S.size)5[*Ix;G1hj |C
    {
;A$P#dJbn         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));{U)iXq
        if(S.base==NULL)
_c8w b/X         {
%U8D-a L`}r             printf("动态分配内存失败!");V;[O-H|@"gr L
            return -1; x?/A!RnHP
        }tAz$} T4V%M0b
        S.top=S.base+S.size;{5hL Q5kY5@
        S.size+=APPEND_SIZE;
%o+cD h%c L'LmV     }
k,}%r+ij:^ N     *S.top=e;
5Z K iM%ai.l6K     S.top++;
y6{)M:z-nR({     return 0; UHzRdI'y
}b k)C'?I-Wd
[0]j7~,{&~(O
int Pop(Stack &S,SNode &e)i(q.w,j7w
{
/B vo'f5m     if(S.top==S.base)xl#Tb X t V6~
    {
-] ~r"Qb;}i"C[         printf("栈为空!");
`Tp@,w_nX)j _5i         return -1;9e-P+gkWf
    }
({0CjZ.UH!A     e=*(S.top-1);/S`/_} B2~g I%K O
    S.top--;%Qd"JD!I/D%]o
    return 0;
6kan ``,F*] }0u7` I*h(C/qnL

Y&bYGnP*p/O(| char get_precede(char s,char c)iw ?{K8X%A
{
5R-?U(dP     switch(s)
/D gYB4}     {$O/T6C)R!Gpg+iR
        case '+':                 
x3dW^ I:ZN n/W         case '-': B OFy%[Q z
             if(c=='+'||c=='-')"pA#R8[vOA
                 return '>';
Xe_*sM;K/z              else if(c=='*'||c=='/')
F5x&F6|/ZV5e*o9B                  return '<';
2D+Ac g;aC(L:m ^-ih              else if(c=='(')
/['n+f!V0J M3u                  return '<';
7P9H@y+P Lp              else if(c==')');J%H7Gz!O3c5h.MY7m
                 return '>'; Tb!i9M h$C,U
             else WU-uNofH s.W
                 return '>';
%XlYG(W@ wb c/e         case '*':$^~5D^ ~4h"W#v
        case '/':1nh:u4G-kf"JK!vFK
             if(c=='+'||c=='-')
LJIO ep}                  return '>';
7A)qg'S/I3d7w              else if(c=='*'||c=='/')
|!X){ s3qagB                  return '>';@&jV2Wzw5j:K?|K R~
             else if(c=='(')
@V?8I(CG:pR                  return '<';
m/J.n6\U;BQF              else if(c==')')SC8Y#[Q4V |
                 return '>';
-S!OUR^2~              else
W6Q$z4b"L6H                  return '>';
xzK pb(J         case '(':
w_'g-Or-VX*F]k `              if(c=='+'||c=='-')
5T1{O+yE8mg                  return '<';jh4{2P KK.d*u~
             else if(c=='*'||c=='/')
T \8xaW0p1V                  return '<';
i@ ^!Y)y              else if(c=='(')
E,@&]w@eHCkb                  return '<';
J8Fx+~/?F              else if(c==')')n5Ma jq!P4l
                 return '=';.m9}HKE4W;}
             else
{v.N ix/RsG                  return 'E';PG'? dN+{y
        case ')':
:E*z8S U%ICDk              if(c=='+'||c=='-')
MH!n F!R                  return '>';
K*A4c m2uy| fT7{              else if(c=='*'||c=='/');w0S ]'hJ
                 return '>';4d F8k(a'M`
             else if(c=='(')
6xzE:nK Oy                  return 'E';/cZ J#w3SD ^ lrv
             else if(c==')')1x5P*t_ w
                 return '>';Z3}(K*fWVA {b{4UZ O
             else
[z0R jPgnK$J1M                  return '>';2a0^!E3x;k/G
        case '#':
1nvi'yI j,~W              if(c=='+'||c=='-')n!D h0C,Mo,GB
                 return '<';k3b:j l&n?t{ w
             else if(c=='*'||c=='/')
,n*h\9uS:SBv$B0L                  return '<';
&Abe w4T V              else if(c=='(')
7X _"_Uj6^F0o+t                  return '<';
f{6kAW;L              else if(c==')')%u%dt ])D?
                 return 'E';
2d XIR%x&Z]              else
^xAD \C S e9T0W                  return '=';
KWo5aCJf         default:
Q4e?'S8WbX              break;@qeTV[`mE
    }
/s4a+Zz |dd7V_rZ8[     return 0;   
Q5?4|(I'{S)@ }9f9pq T^_c

-[l+hofJk int isOpr(char c)
Q3f1B5{ E.~"qh {.qpF6T)\G7^2c
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
`K9s.N;R         return 0;'Yu*_8P%c-kp
    else OI.c N{
        return 1;
#eR&K/fBb-Q)z }7l2t@Nt8R"jN
vsO:j[7E#@
float operate(float x, char opr, float y)
:p0N2\8P Nd$Y B {7I'?+J7X(igJ'f
    float result;
;Q\6?_g8M!Rc     switch (opr)$k,c,ck'@nT Q
    { J4{M0`l^"J)_l0\*W0d
        case '+':
:G9ccjpa~              result = x + y;
/\$e Sw:qVO k$h*D              break;t zs)nC,X
        case '-': yr$hl3X:kH"i6F6Eb
             result = x - y;
%@0xg_#C@/}+p^zi              break;
%IRab2{u6Z`I"?         case '*': R lDEy \K
             result = x * y;
aRA `&S              break;
(i/hq2fo&d,F4L-M         case '/': Mc|aX,s X
             if (y == 0)
![SKp/@              {
y\6Fqgu Y                 printf("Divided by zero!\n");
1M3HR,@+X? i+Y                 return 0;,L7E/WV6o$? }i]
             }A6] j k6n,tc
             else,R(QxEeO7qqk
             {&y1OePOjn
                 result = x / y;4R2_+})\6ah1A
                 break;
m4J8vDB[F#w*L              }
C3s1Hn`rH [z I        default:
1ChA2y(K{              printf("Bad Input.\n");
{6v S9VZ \r8I"Cu              return 0;
;CMS2J.Se"Or"x}     }
tQq9M9b4E     return result;
G^9DsX }    ;U2?co,N

u!^WI5a#ac8d float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
K?r ^u5I.F;Fo x {
w@3P |B6po3hW     Stack optr,opnd;n\9H)BKy
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
am*Ut0b6C{M     char c;T u:]?P4U
    char buf[16];
j9eS}w9d)G     int i=0;ov)y"p.?s
    ;[!olkf5ZUY5d
    InitStack(optr); /*用于寄存运算符*/qm!WH2Y;N9m
    InitStack(opnd); /*用于寄存操作数和计算结果*/
gZM[2b     memset(buf,0,sizeof(buf));k#L%^a*BG ~Mrf
    4vkt0gKyq
    printf("Enter your expression:");
|+I+S-U:G         T W1o!YM(`
    opr_in.ch='#';@;i'Ae9?(cc
    Push(optr,opr_in); /*'#'入栈*/$N]xw9\[L
    GetTop(optr,opr_top);
0f]p8@o\r     c=getchar();jQq R!p(KSO|
    while(c!='='||opr_top.ch!='#')2o x v-N@2nL0H
    {1_r*\ K6q2];`mB
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ yEh8HDG
        {nU;^u |+I
            buf[i]=c;
.Ep|0on$nu5|?4lF Z             i++;
\^l[M[ uM o             c=getchar(); o1bX-g7y O\
        }W o]|'t-RuJ
        else /*是运算符*/.N|{ b5}lA
        {3J]:~f(r+F g`.Dd"?P
            buf[i]='\0';"n#c4I'W2~VD
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/ QR)J*K,a8F!eC
            {
x_[["zX\!tR                  opn_in.data=(float)atof(buf);
xu lPz/M1XFwA,w*].B                  Push(opnd,opn_in);\mI5]Fh0D
                 printf("opnd入栈:[%f]\n",opn_in.data);
F ZS5?5X                  i=0;
/q S'cL6` R                  memset(buf,0,sizeof(buf));*j3qmtjn
            }
-^qGb~:y             opr_in.ch=c; Q-? ft"z
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/;M1bj{ x[ou#r
            {YIy4Kj#B Q
                case '<': /*优先级小于栈顶结点,则运算符入栈*/D'W/n)}@)k
                     Push(optr,opr_in);
tV S"h}(o                      printf("optr入栈:[%c]\n",opr_in.ch);&zlU j5W&s7S
                     c=getchar();Ns$b7P D'A
                     break;8A"SZcUh*n6PVH
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/^1RzC h__!}g
                     Pop(optr,e);t9DPz&G#T,T6aH(r-V
                     printf("optr出栈:去掉括号\n");
,hYp{]wk)^                      c=getchar();b1[rF ~S{g
                     break;@&f M2[+a*eK&u
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/Q)j#H'WMdT
                     Pop(optr,opr_t);
%Wi7z ~SD;lQ a*XX                      printf("optr出栈:[%c]\n",opr_t.ch);k*l4_iB g
                     if(Pop(opnd,b)<0) ?z6J `XcO#Ycz\
                     {b@TMG,X2}0?0P"\
                         printf("Bad Input!\n");U/GE,v1l
                         fflush(stdin);
F }9~y*l(P7h(iN8r9[                          return -1;
6RIAw*gI                      }
@4_o+Aj$xu{                      printf("opnd出栈:[%f]\n",b.data);:IV.?K A2l"|_R
                     if(Pop(opnd,a)<0)
,LP eW1}z                      {
0\%Iz1D`!}+N:n                          printf("Bad Input!\n");
z}2gi%Ui}.d#iF                          fflush(stdin);
x ~Z*a0b;m mC                          return -1;
{(p.T/\ B%`                      }{ ?G,`P bF
                     printf("opnd出栈:[%f]\n",a.data);
i6V3l-acea$YI$S                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/+Z Szt9x @/}_
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
`Pwd%H {6Mb2@Lu                      printf("结果入栈:[%f]\n",opn_tmp.data);3eQYO ~8x5l
                     break;
Q9MqX+H"x)x%S             }
+C+C _[.Uo$ui_3vm         }
F*aLC[#UX         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
!?pG!Vj6z ~1Z     }
[)]w&T8c#I {k     GetTop(opnd,opn_tmp);f{0@$Ygv%e"hr
    DestroyStack(optr);8m9As(t p/\3gmy
    DestroyStack(opnd);6ovU#vxKL
    return opn_tmp.data;,y*yy X-jC` j,b:a
}
y4NI7eq
c/]l#wv/Z)f char *killzero(char *res,float result)
'}NR8Ai,t { @3N o"jZO"?l%u
    int i;$[D+karD y(Dz

/H%\FrH;cT6L     sprintf(res,"%f",result);
@T"] g9LL_ jWd?3N     i=(int)strlen(res)-1;
z-Rv5s7t;i.l9iID)@     while(i&&res[i]=='0')
`J2X-xh     {:ldiq%Kw?x!B
        res[i]='\0';
4CH,bn~O8H         i--;G4ooQY\wg
    })D[#n;G.t~\j
    if(res[i]=='.') Q0DR:HFhcj#d%WjG
        res[i]='\0';
T/v;[7yj"b     return res;z^rE\S*J
}ep#IS3pPG'r

uQ4\#{/Y}]9GQ7I int main() r;k3q.J@*D|
{
:]Wff@&Y-T$x*aK6Y m     char ch;
5sI5y`hQmMO     char res[64];5{6N~p;bff3j8v
    float result;
"d%~)Qs9p0U }3}     while(1)
Dj Mk4D p     {U+d1K@\|9B5\]
        result=compute();6L.qK-QV
        printf("\nThe result is:%s\n",killzero(res,result));[@2U(he#]
        printf("Do you want to continue(y/n)?:") ;|4C'Z k3L @
        ch=getch();8yS ~(s Q2MHD;O&bm
        putchar(ch);;@9F%oo@
        if(ch=='n'||ch=='N')2@$W-`({4w$n!r,g$F
            break;
!O JDq7I{         else
'Al XH*xX`$U             system("cls");;fb5P`[|+SE ^*b
    } ? pn$z/R~
    return 0;
7P5bO%n}5j%Z(] }[/i][/i][/i][/i][/i][/i]
CWx0qK)P+k
Pp.z'eboe4vI [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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