捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.IVK cZ
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)="n5Qsn`L5z)f
/**************表达式计算器************/e9o3i9kqAdk,@:?
#include <stdio.h>!W!P}[J#\
#include <stdlib.h>A N5y,xS
#include <string.h>
JI[+X2y+w #include <conio.h>
)T T#_:ibS`@Tj/[ #include <malloc.h>gvG~#tG[S @'hO

3Uo9V2T&b]u'Y #define STACK_SIZE 1002v5Dk8Z0E&S,dh9?%Z
#define APPEND_SIZE 10'E S4E v'W7m+w1S%]I
,N^xGs,P-H6o Q
struct SNode{
NX1lf{^M     float data; /*存放操作数或者计算结果*/X$H Vr!o2_i/r
    char ch; /*存放运算符*/bHN fQ4Z`-^8LH
}; C'xy;jDU6q
jI@!E*H;RP/a*P
struct Stack{
!G HZ`2[V#^.P&D     SNode *top;
"j!k Ivu4XSX E3n7\     SNode *base;
!S#b~1M/s] K4N     int size;NZ*dBVCqN;`
};c$E/r%d4K8[$U"@ z@

']&~8bB7mV4a S /*栈操作函数*/
*f1a` bc {Z int InitStack(Stack &S); /*创建栈*/)J }9`-q;O8hQ4Q
int DestroyStack(Stack &S); /*销毁栈*/
"eS }:raF\ int ClearStack(Stack &S); /*清空栈*/
[o3Mn/[!a int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
AwH7Vv int Push(Stack &S,SNode e); /*将结点e压入栈*/
9v4vp d l)v._ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
yS B%x)|!x.[o7[-c R&]-\.m7Z
/*表达式计算器相关函数*/.H8nFm$r!jW6d3N9_5f4U0z
char get_precede(char s,char c); /*判断运算符s和c的优先级*/Yl6G~8IP
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/Y1tz,los,h*l i
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/w.{Nq1]/}Bm
float compute(); /*表达式结算器主函数*/t`U F8~'D1] u2E6zU]
char *killzero(float result); /*去掉结果后面的0*/ M ie8p yy5J
V0i+s`3wbq Z'^
int InitStack(Stack &S){)Q p*d5Eq3V;OS!?-~/l
{
f2km1p W-Um$Ce     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
Gc+f;Jp5C*GZ     if(S.base==NULL)i$f ?'d2sh[1L-v
    { RM:g$So
        printf("动态分配内存失败!");
*SS%l!o9m A         return -1;
b Vc%g ~&}     }Zp4G aw|
    S.top=S.base;
.H.xfo5BD,NQ$C8O     S.size=STACK_SIZE;
%xg2e!N4g(F#lDP'E     return 0;"k0b sb"h)rCY6DN X
}
R;f lNn1w ho7T/Wyx%Vr
int DestroyStack(Stack &S)9D.nUR/n-Ox
{R+CH,cI,[J5M
    free(S.base);jR D y4`&V7W
    return 0;3o6xp"a&RK UV
}
jW5utE#Oq iK] K1n5H Ot
int ClearStack(Stack &S)0P_4y+m#@wr
{ i]-X9NRoP3_Q
    S.top=S.base;*J5cG KP+aF9En[ C
    return 0;Kbl'Z n
}f OG u#~)@QE)S}

5e$l A_Uw3t8B int GetTop(Stack S,SNode &e)
Y+EX3V7b1]Iee,^ {oZ X_]F.]
    if(S.top==S.base)
$fK5]o X4[,Q:oS     { Sb cY|wDb:{
        printf("栈以为空!");
7J.iM}4yG         return -1;;N5U Ht-s"[Bm
    }^5m/OHJ
    e=*(S.top-1);
$Z6Bx3N)OrV2q!j5b     return 0;
0Y2^rELe1a-U%H_k7k }
r,XRTN0~ e ~ (j)p&~vf'Tn
int Push(Stack &S,SNode e)
Pg q$eKKi {
` W f[jM%VS     if(S.top-S.base>=S.size)
jqV1rD,JCW5j     {
x6epC y1i         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));w(ym4MV+^e
        if(S.base==NULL) X Z |G upy/g7wj
        {
8m U ])A6U?1A"x             printf("动态分配内存失败!");!Nwc @*T7W5gM!l o
            return -1;|5H:yE(R [t
        }
b;oVe(a [+K)G|N         S.top=S.base+S.size;
U;s*p%F#M0`m&Z1H         S.size+=APPEND_SIZE;
z'w'J`"I     }*yG6GpTyM}V
    *S.top=e;$k#w Z7wHj
    S.top++;
+s)o3fP E6aj(p,]     return 0;
2[j#zI+w#u&q }6a#`*{7?S,P*L$~

tr`TQUP int Pop(Stack &S,SNode &e)
4vD \^t`%Q h(?+m {4Q.~O R IG1Y^X
    if(S.top==S.base)
a.uG6E8V[@     {
mA2r8L!n8I         printf("栈为空!");
G*p| P&H5f         return -1;
P?5GXP2V0B8NFj;U9d     }
'k)Y&@x"s*@.W     e=*(S.top-1);"GX'\(T)~(|&^lf _ n4z
    S.top--;
7rV)z5A/M+V/B,Kj-y     return 0;)~'p'|%W$qV#U?
}.|8UG @K\:u'[_D
U|$o~E[!l[:yP_
char get_precede(char s,char c)5~$so2qcn
{!h9P C#_$\(M
    switch(s)
VS(B?dY;k     {
)|/K Z7V]{y         case '+':                 t-M iSP
        case '-':
vMb&]-u(M&[ S              if(c=='+'||c=='-')hr:fY3\j
                 return '>';
nr.r/`Gq6t0[              else if(c=='*'||c=='/')
5bP'u2_.qX/zz                  return '<'; Qlt7{T`~B/x
             else if(c=='(')(Hjo gp/Ej u'C
                 return '<';
wJ4^"_"g s              else if(c==')')
R iTMQ6M"o                  return '>';
4j%F s6w~ p              else g D2r_y!g
                 return '>';?-d,a DR5Lj\
        case '*':
o%^2a;k.Hgr         case '/':*tgB2D.C`C;x
             if(c=='+'||c=='-')S1Pg9v(L1FEv
                 return '>';
xfjA'W ?.q*Uo$h              else if(c=='*'||c=='/'),H"q7p&L"M8J:qav2F
                 return '>';
"h2A/u4{:o |              else if(c=='(')
j/?!s#ky                  return '<'; M0[ ~T3|!s4HjO\d%F3z
             else if(c==')')
.t_D `"fA                  return '>';4APB!bt$Y$Z0Tz[
             elsee1]2fl[i+C
                 return '>';
$GiO:OVw         case '(':
+X~$G+b"wpF+B              if(c=='+'||c=='-') mm!nma'fY
                 return '<';
N^4V ]e}B5g4O              else if(c=='*'||c=='/'),?l;_v9fQE
                 return '<'; A zFh)vH8q-i
             else if(c=='(').Jux+RQdMS
                 return '<';
y/m9B5M4X(B3\              else if(c==')')8u4bq)^9B,a;e-X"?
                 return '=';:\_9]hg9xg0lS
             elserbRO2inv"al#AQ
                 return 'E';
W+[r%sz@g         case ')':
7k/@)pzj8F"]I"_              if(c=='+'||c=='-')
)js TJ5E|2G                  return '>';
8J ncDgr              else if(c=='*'||c=='/')
YiL@'x                  return '>';
#IMA2b rb+R              else if(c=='(')
8C/vy5fS"Z;X$z                  return 'E';&A+l1Yr2I|}
             else if(c==')')i[6n}1t*k ia5j
                 return '>';1U6qY9xZ ?~H
             elseE?Q*QaJ
                 return '>';U{ d0S8I#X}
        case '#':
y/xIy]#c              if(c=='+'||c=='-') B0Z'tF"Y*h O
                 return '<';,`3mg/U'De6@9`\
             else if(c=='*'||c=='/')k2xoAE D8]0T1t
                 return '<';
4y+{)k:Pv(dk              else if(c=='(')
k~;G:u%~1ge(W                  return '<';
R\ q1qCg1so-S8| L%K              else if(c==')')3x,B Y\q d
                 return 'E';
1~;gbT }              else s9dwB@U"^
                 return '=';
@ vbS1c'Du~t         default:~WZ6j^8B)u!~
             break;
PRhb}Tl}     }
;Y.OIx$fW*rH[.a     return 0;   
,sO:k#?0tbSI G }O{4\ _c0l2t!rQ"P`

h;j"r8? })oe int isOpr(char c)-\uIWT.Bou^
{
w]nJf'Z,pq M3mG     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
m7q W5L JH         return 0;&p\#r/Iz8p,um7G
    else
oi5B7n&ac         return 1;
/g-P(C?"~#A0v3a }
B@zZ%?xpm!i
&z$JBA(~Z)h1_*|e*T[ float operate(float x, char opr, float y)
9u vn/P-N*hk*S:S%B {
w g[4S.}?     float result;}"XYUzN g
    switch (opr)]bAZ[QM}
    {
iK0Zjo         case '+': \ o#m{O y&Y,G
             result = x + y;
,\&T6` O&O6?$kh              break;
x:f c(uIT8z         case '-':
'tV/h1Lnr+]9vD Z              result = x - y;k'DZ:w,?/]
             break;z*A z8R~(i;U#N2W
        case '*':
"iK[eecl              result = x * y;
A-CSda7R6e1s"Q6aa              break;
T#ptI"^;m;w"v X         case '/':
oMdq3|)LN              if (y == 0)j PuYU_h[#P t&^M
             {
h c*s"a0Lf$qa                 printf("Divided by zero!\n");|.wtAd.T_rMGl
                return 0;PM)Zkl H7mHtx
             }|,QV@{
             elseb.ycZ/Nw)C }AH
             {HVa.Co}
                 result = x / y;5]VC8SOk$N
                 break;%h5U-O@!SmT6l
             }u!hL]6g/W[ub
       default:
5{!G%Pl/Zo5~ zv              printf("Bad Input.\n");
B9?'w2Bt0?+y5G              return 0;
*J]l%rS m     }w^j#f EQ5@R
    return result;%e]{.J_F&[
}   
*]3[;Xj ~6O
3A GCW!D8s float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
-S1rf az0B&L{ {a:SR5u'Nf
    Stack optr,opnd;
/o(z.nB.R z u     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;Yua#@5Hjd
    char c;S6r \]C|+kW)aK
    char buf[16];7JIoY.h/LUB6p
    int i=0;
@ yo {7@z)Z ^(e    
U0t\ j6]&B8u6JG2gs     InitStack(optr); /*用于寄存运算符*/m[;W*d$n;IA _9H
    InitStack(opnd); /*用于寄存操作数和计算结果*/.W.x#B8J [6kG2ja$g
    memset(buf,0,sizeof(buf));2D&Nl/p j:FX
   
X8b0d*^;y+Tyu ]     printf("Enter your expression:"); c$Ea wu)Ls
        ;DU-AR+\s2@:A
    opr_in.ch='#';
4g$w$Z?%q8I'e(h3s     Push(optr,opr_in); /*'#'入栈*/
qz$_5V[6z     GetTop(optr,opr_top);6qa5b~%hNM4P"`
    c=getchar();-N+m/v\ ~gm-}
    while(c!='='||opr_top.ch!='#')
,Q)k_5bu]6i-r6r[(Z     {`3k}%_zY5m-[:}j ]
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/C.j\|O#g:W7\.kY-s
        {
!|A-g'}A"`)Gi)l             buf[i]=c;C{$t],U
            i++;
l`H+}9jfMr             c=getchar();U l/V3V,IC
        }
p-P]t,Lp }^k         else /*是运算符*/
}8{*fG4t/K2r%Q|o         {"U vy5Y C5vm
            buf[i]='\0';`^0TO{3w
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8W"y | MO \&R ]i2s             {
1ciy8hf#rLD                  opn_in.data=(float)atof(buf);DnVNO F9LO
                 Push(opnd,opn_in);
p#ClaQH/l0r|                  printf("opnd入栈:[%f]\n",opn_in.data);zB*f eq
                 i=0;PiN'Tn:s
                 memset(buf,0,sizeof(buf));
P2A A C,[{S h9r[             }5I(k zD,EV~g
            opr_in.ch=c;
Wg/|,Y:w5Q5E             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/6T8sI*yTY J
            {WV1u^ m^h
                case '<': /*优先级小于栈顶结点,则运算符入栈*/p}ex.rYiK9f
                     Push(optr,opr_in);
h}C-m;[ ]8ddU                      printf("optr入栈:[%c]\n",opr_in.ch);
+K1hv-s1z2}~2V%E&}                      c=getchar();
~0x*HA lu                      break;!IlhWpe
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/!m0L kc,H,k#?
                     Pop(optr,e);@v1[F5FyOP
                     printf("optr出栈:去掉括号\n");
%SbM`FdU/M;N                      c=getchar();
z2Wo nKth%[)J3~                      break;
Y y+sFQC|                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/;c4k2l ~1o~hg
                     Pop(optr,opr_t);
^cw;zhC8v                      printf("optr出栈:[%c]\n",opr_t.ch);7F:d2pN8Tw
                     if(Pop(opnd,b)<0)lCkN'}&yZ-@U
                     {M#tr_NW#P
                         printf("Bad Input!\n");
E[qD `%Y"f'z                          fflush(stdin);Zp%[&tI%}*[6a2w
                         return -1;c'F,]t;c
                     };Auz-\uy6C)NC9DY
                     printf("opnd出栈:[%f]\n",b.data);
6t^*g&K3k`&W                      if(Pop(opnd,a)<0)
I4n@fD&L [&KV;{5gs-}                      {,p8K I6QU
                         printf("Bad Input!\n");t9P.f%f1h
                         fflush(stdin);
6X3Olr-z2`\rYC                          return -1; d(Q JK1E K#vKr#YF
                     }
u-Ir'r8lV$`4Io:^                      printf("opnd出栈:[%f]\n",a.data);
3Ym6`xp4L:Ecl                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
M |$} y+nX                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/)Gm pkQ;M [B~3I1k,}
                     printf("结果入栈:[%f]\n",opn_tmp.data);
:@BT+AM!g l7T|                      break;
Zf7x-No(adeD4g             }^EF i9@S.W`g
        }
l6|)s^ _9B ~         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                G!XDX:uH`
    },H D,K#?-tAW
    GetTop(opnd,opn_tmp);
&v }tj~ w     DestroyStack(optr);#{T%e1_{"{k+G'W7P
    DestroyStack(opnd);p D8A-Y'wg
    return opn_tmp.data;S7G_~,SX
}
!R7DoRGL n~$u0gt(Z3~2N
char *killzero(char *res,float result)hTb1cgn
{(k)Ym~4Sg](^x @|
    int i;
Rg-MYS:B R
8M f/eM$J.xu9Y,Jl     sprintf(res,"%f",result);V5r:\7G4@iEn
    i=(int)strlen(res)-1;:r7KC;X6Go3l
    while(i&&res[i]=='0')\.c9\]nOI
    {
.kQ3v#R/Y}V\+_{         res[i]='\0';
C'l!NQ^ ASi^BT         i--;:J'F;Rj CU$p4_.y
    }9vS.x SDu,n
    if(res[i]=='.')
5sT!eRHM         res[i]='\0'; ON*lT `
    return res;
tQ~z$[8f }
;v E v"Q!n1G H qozn_/d#DH
int main()
j/X p vH)mgd*O {V lH,Y3K;B
    char ch;]*{"S]ujC A O%GK
    char res[64];EZHQr)?B(\
    float result;M |]*^)i^c"e,c {
    while(1)
l{rD`A'wl.H$j     {
Px4hzKfk         result=compute();
8M UZ7Ol+fFu|         printf("\nThe result is:%s\n",killzero(res,result));)Zd'x%v(y:K
        printf("Do you want to continue(y/n)?:") ;7g$a.wl!I?`!T
        ch=getch(); TE/c2w:T
        putchar(ch);TS*L0d@
        if(ch=='n'||ch=='N')na {|D
            break;;o&U VSmz R Nc2d^
        else
'xXl@ ^             system("cls");
hkNRKv8kO3}7@     }
h-i/ag"w k1S o     return 0;kd'K xj
}[/i][/i][/i][/i][/i][/i]
fL9v)gX D!SJ&b 1`kTI$vJ
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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