捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
L/K Y jD!qy 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)='?T0V\ vIm1U_
/**************表达式计算器************/
tjidV8hF #include <stdio.h>
G-b:BE-kO9B_}}Q$p #include <stdlib.h>
l ~]3tY;IW nr(P!} #include <string.h>!pUR CK%K r)] {n
#include <conio.h>
/`3i]'Q}5T"c #include <malloc.h>TQ T:Kr*`|
e2Wtx"G#ZW
#define STACK_SIZE 100&L0S z h(x)C
#define APPEND_SIZE 10
S?UY+T5X S%`cXuC)_E W-L
struct SNode{ e]$cE[1{'u KC
    float data; /*存放操作数或者计算结果*/o)^t o_-Zm&\f~
    char ch; /*存放运算符*/
HY([DUo };
+v@-v4e~4tu \Jr"t\g
struct Stack{
:{v5fp/KTv     SNode *top;kk;y `)X,xk^
    SNode *base;Y.Oc|,B7I`9R
    int size;
*iV1j$~@I2V };
4Y3Y&?+[JbJ r R!b uh:S_
/*栈操作函数*/fJ O5{^c`1e
int InitStack(Stack &S); /*创建栈*/;a2NB-lSV3c$l,a#e
int DestroyStack(Stack &S); /*销毁栈*/(\8F'Gs#k"R$m2o
int ClearStack(Stack &S); /*清空栈*/B.A"D7K1t/H6o9hn
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
f ?9tn m2lR int Push(Stack &S,SNode e); /*将结点e压入栈*/s#vq4OU0T v
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
?m i ceyN HM :js:]0\a\ S7e2?
/*表达式计算器相关函数*/
t~0K7ropegT char get_precede(char s,char c); /*判断运算符s和c的优先级*/
Tm |Y!q int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
2jf \ S!^.~ N#g float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
)j'Da8n.d float compute(); /*表达式结算器主函数*/ H0{Y%D9n bQ
char *killzero(float result); /*去掉结果后面的0*/
v%J@+h+o'F\Lh
n#Z J!|c nO+H&M int InitStack(Stack &S)p_UV&? i _g z^XN:LQ
{
K%{|6OV     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));p8WPdf%M&FZ
    if(S.base==NULL)
*cvEjF3iU     {:HnO1AXd9Zd
        printf("动态分配内存失败!");2fs Z@pF
        return -1;
.V'g{j P     }2}5`J*E)h$iG.{
    S.top=S.base;bIDK"b
    S.size=STACK_SIZE;
#lJY4F2{     return 0;
HS[eY'Zk }
1\#RmC `Ow6x] 9@!E4w'w#nFz
int DestroyStack(Stack &S)!Y;N @0KSYW.v
{f.{}*A](a6? l
    free(S.base);l.~rf0v)c%wl
    return 0;
{d'B#c%H3noR@ }
o%zp Y FNs F,w
{-U|%La3_+B)A int ClearStack(Stack &S)
u0MauF|Rf {2Q {eoL'}8iJ6l^
    S.top=S.base;on T]+G(K5S@
    return 0;
?7h;ikE6^L6x&H4{ }9pZQt i#IV0w

s)n,t9[4o)V.q7^BA$`t int GetTop(Stack S,SNode &e)
&nzZ3~~#] {m4Y*@)qM_q2bZ$@
    if(S.top==S.base)7T9d/m A Kou3j5E
    {"d2zo'Yj#cGD2]
        printf("栈以为空!");
1sRh:E z]-v         return -1;2?xjeA7O$b-L
    }
:uL5I*m/AW!k     e=*(S.top-1); RY!x;f?2z(jl}D*p
    return 0;
p.|El5M!? }
,b]&eL5K$^SP-j L"|%d
4EiRr e(j int Push(Stack &S,SNode e)
h8q/D X P l3P+O} {
-N+ys~:r R8Hq     if(S.top-S.base>=S.size)B/d?}.W;t U@,e;s
    {-gS\7[_ T ?
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); y y/iK&oQ
        if(S.base==NULL)
W(R/?0vu ~0Qh!Uj"{         {!m$M/@v pj
            printf("动态分配内存失败!");
#{o*S}iOm             return -1;K4QUA(W
        } WJvO b|
        S.top=S.base+S.size;/^i gB#Wg l
        S.size+=APPEND_SIZE; R!sZ"oU-}!_
    })nE+{7C vo\
    *S.top=e;
#p z5s&^zgL9y     S.top++;
q1V ^mo-^Z|M     return 0;N@P] eJ LJC
}
T8P'UJ&F$n}(W%i O.dG7|Dm6AB X(n
int Pop(Stack &S,SNode &e)
8TT`xE!Mk {T _/n v#v%{
    if(S.top==S.base)
+C_,Yj'@ R)?HN     {
2`6lZN2s         printf("栈为空!");Eze:yL ~Q(c!n
        return -1;
g|vki2E:I VC     }
R,W$t];x,nGC     e=*(S.top-1);(oBoY-`b+]8I
    S.top--;
l^0SG4Sq7vF,U.[     return 0;
[G o5i{$b]4a` }:r-ClHjS5_(f
Fj I9P(U
char get_precede(char s,char c)
*eu"| T#a Xc {.Y G z)J"gd
    switch(s)y7a c8@ Ds)B s!zI
    {
2w yAvDw         case '+':                 nM~lvJp
        case '-':C8J"O5Q@$z
             if(c=='+'||c=='-')
@_jjKt                  return '>';
]-A%P\)O+P              else if(c=='*'||c=='/')H9IT_D-w?
                 return '<';%`L#U,W*v{
             else if(c=='(')P.UL})t6_/aX4YW%i
                 return '<';
u(~sS ^mZ J              else if(c==')')
{j5MrQ                  return '>';
I5g^Do'h:h              else
%x2oj9b6vk K^                  return '>';
Q;PnY EM         case '*':-Ed2S2R7[}:F
        case '/':&^#g-@P-lb6rI
             if(c=='+'||c=='-')
/|:e%wfI`v                  return '>'; lA cO;l4F\3` U
             else if(c=='*'||c=='/')
4?_ t Z5C CVH-b                  return '>';
5{+V&ejoP1{A"v~              else if(c=='(')
1} UL|s5A*x                  return '<';
K gW0?LB%D              else if(c==')')
3ZD{8E'l_H-@L                  return '>'; q]d7yb-s,j#tz
             else
P$\Q'e3C RKc                  return '>';
I/hU@(V-Iog         case '(':
t*n e9_\7gX              if(c=='+'||c=='-')
&~ite%{Fxr                  return '<';3H}Jyyb{!Q7o rd~
             else if(c=='*'||c=='/')
/yA'p*\.E.V4z$F                  return '<';)WLw'}#_kI*B
             else if(c=='(')(qg/^_#g(W%G
                 return '<';7d b5[+EA8ey5s(Lt
             else if(c==')')q"j @|.S8M(h|K
                 return '=';Vm2p%R p;J| ^
             else9KY\A`
                 return 'E'; C*F]Fg8o
        case ')':
#j2Jn~^.c              if(c=='+'||c=='-')
(G2[6Ib!Fl#R+aV                  return '>';i4|C-C-~+E&i
             else if(c=='*'||c=='/')Ne/T.uA/\#b G{'U
                 return '>';~W1[j*g4[#XZ
             else if(c=='(')
kS N-~,g k{OT [                  return 'E';
*k,y"Cz7t%M$o              else if(c==')')
y0l1R5a"m)Gq0Z                  return '>';
S@"]{G'K{/M              else!@.@ T2SM0U
                 return '>';
'`}*o5Q7G%^7r k         case '#':o"W D.uf a*p`V
             if(c=='+'||c=='-')
$p.y*XjQ                  return '<';
~"K%w Lu,Wd              else if(c=='*'||c=='/')'p7q3B'nGdS6V
                 return '<';1A I P?8HR+c
             else if(c=='(')_.d4z)K R3X"Z-C)T
                 return '<';
(]Y,{f4[9_X,kp              else if(c==')')
.vD:f7Z lq                  return 'E';{yt lS6s#M
             else4T5?w z8C X'X^
                 return '=';
'k"U:M,H;u+E5o!s&ma         default:,Z:c"A B@]]r d1yN
             break;
S;vB `s*]K     }} ]U[ T7C7['q,?1U
    return 0;    S E{*`;E+MJ
}5mq'L{0|aY
p/XOQ r)z
int isOpr(char c)#p:R|7POqIn#o H
{}@M U E\X
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')~i:C9? q(n5dZ0T4`~|J
        return 0;s ~Fn|
    else TS(qN Z"EBU:x
        return 1;
RK)Z@(SB%NLf }2L:V Ar\ I-X.[4TkP

ZrFj,W^(Z"M float operate(float x, char opr, float y)
0s:Fs/aNT {
8U1e k;nG     float result;?TR le]4z
    switch (opr)Uly0OP1b(N?+gO8M
    {
"OK!x(CWob`2D2H ^P         case '+': "i e&~l8g],A8_
             result = x + y;x8k!km(i
             break;9hn7CPH i
        case '-':
J1~`"c o]4f*Z              result = x - y;
Q#@^(?9Z:~5SK              break;K+` OtIW
        case '*':
9ysv`7lg-l\]              result = x * y;0Ba6eu+j
             break;7]Kg&ce*C@}5t2l
        case '/':
JAom#xV&a yB              if (y == 0)
WU I|?5F              { z6Ou B,J
                printf("Divided by zero!\n");
]4Oqq*Q                 return 0;j"`Nz"Ln \_!P5E
             }(`)I`!FC0y4N
             else;L F'Y0RH'aX|9b&j
             {{{4?V UWGG-F;X
                 result = x / y;
.yr'hJw*X                  break;
b;^4PPX*w U3j9x              }
E6h'M)` e6jC/L2x        default:
"`;vi.ipC              printf("Bad Input.\n");
]5UV7A5yGV3_)t              return 0;
k3bq8xSo]qq HO     }
$gw;K @+pEg*~G Ez     return result;
!yQ.nK+fF }    0o+X3OT)o{PI"qG

Mm0m.i7k` float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8?4w@+b)[H)~)w5d {"Q&[zuy
    Stack optr,opnd;
-efV6khHVqc     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;J \ W*pN]WI
    char c;
O.B,tRA6b LC     char buf[16];/^&ox%YO;F.\Q;?;Nu
    int i=0;3`n)U*hmw
    Q0b(K,iJ&Y
    InitStack(optr); /*用于寄存运算符*/
dSO N3^Ti     InitStack(opnd); /*用于寄存操作数和计算结果*/
bju,{)Qu#iU     memset(buf,0,sizeof(buf));~,R(^#x+zQ
   
x;n0D#C;c"iO     printf("Enter your expression:");i5E,P+X2` c;~
        
D?$Uf,l     opr_in.ch='#';
~iu3R}z$a     Push(optr,opr_in); /*'#'入栈*/
8}1xBhv gD3{5K-[,n     GetTop(optr,opr_top);#~8Z^)Z(|8J"}p W;t
    c=getchar();
S+r$QGG4V&~V'k     while(c!='='||opr_top.ch!='#')'Al9[$Y^0k ha e
    {w.Wk$v F7e$dN+W
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
L$y+}#OZ3j+xB         {
d k3].R?"t9PH(O,b             buf[i]=c;%S| CPof
            i++;
8ja+_O[0r)pf*u             c=getchar();
-j(N dV;H-W         }
{;W V `#e         else /*是运算符*/
r7h4U^s |I0~2X         {fsv8C'J
            buf[i]='\0';
(QV)k_o$}|             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/;W V[ N,I^&G|
            {
bip1f,?T @2Qx2D                  opn_in.data=(float)atof(buf); qT6s%w gx!?K
                 Push(opnd,opn_in);
1su Q x bq                  printf("opnd入栈:[%f]\n",opn_in.data);"BVJ'of4v0P'Z8^ Z
                 i=0;
\La(Au                  memset(buf,0,sizeof(buf));4t W^9{f2h3]U%O|
            }
!q*KL/} f2FX(v@ScM!Z             opr_in.ch=c;.P},m*AU
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
DD2S:c#P\H             {
M0Bvu.f&d3{D:]N!A                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
z Ey8kd6Nb                      Push(optr,opr_in);e.yt{Bc2[
                     printf("optr入栈:[%c]\n",opr_in.ch);K P,Hb'\!b6U0B
                     c=getchar();
$xN^)h,Bj']/|8F,U1\                      break;9Mm$oe2m.Rm1j,a3O
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
\ \ ]A?qkk                      Pop(optr,e);
*`@.\7\%zlDR[V*X                      printf("optr出栈:去掉括号\n");/fRZ~2UXx
                     c=getchar();
wA~8tq                      break;
4AI1}lr1vAat                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
pfM^2m~%M#O4q/A                      Pop(optr,opr_t);+M{|7fx)W `
                     printf("optr出栈:[%c]\n",opr_t.ch);"@V _/]9vi$xhm,V
                     if(Pop(opnd,b)<0)o&Gncz
                     {
a1n a8DFU                          printf("Bad Input!\n"); {m'opa ?
                         fflush(stdin);
1K1_QT LA                          return -1;
:w-c&f g x8\ M D                      }
'm:@6|Rv Fx6G                      printf("opnd出栈:[%f]\n",b.data);
7rr;G#eduH                      if(Pop(opnd,a)<0)
\:W(S2Xo6V X8?9Vm                      {"u h;d}"?
                         printf("Bad Input!\n");3NT6I.E&u6\
                         fflush(stdin);
Z},\w'Co6[                          return -1;
"}!u"_ Sw[                      }
xS0n$] Jo!M*[                      printf("opnd出栈:[%f]\n",a.data);#Tp+B Y8V r)?Cm
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
y_ Ao'yIh? ]                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/7v(e7eL2O-I$u*^2l.J
                     printf("结果入栈:[%f]\n",opn_tmp.data);O o {?:L
                     break;pAUoC/}
            }
z X su;?G)i4Q         } R&M)nM _3n
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
9FM,dv~     }A0uV(O[4q
    GetTop(opnd,opn_tmp);1G/} jv#b'p1BO
    DestroyStack(optr);
~?k|.x(n3~Q1D     DestroyStack(opnd);#p$Y$?.P"p9Ho]
    return opn_tmp.data;
;j:txaT2j+\u:i:[ }1K&eP:t&lq3T?&uj

N4bQ3W([G char *killzero(char *res,float result)F'b`\U6Ezk\
{ ] fr/`pb
    int i;*~:k7Y${9f
A!Ot7b5Ru/H
    sprintf(res,"%f",result);
c9RZ }bMo2F{     i=(int)strlen(res)-1;
V1y%S;a4I G,u     while(i&&res[i]=='0')9_ eW-Tp }o&E
    {
\&J;h'g7@uY         res[i]='\0';-N-Ld xVg/n-e]
        i--;
.Pq%~V&wI-F(tM!z{     }
BajM/x2gs\~     if(res[i]=='.')v-j|O-r-i9V;S C
        res[i]='\0';
8x"X7Z_te3v}EI     return res;t8ud.cmd O
}0bIQ.e,v
7w0T,d"z@h2il6D
int main()9YY:J&L)x#x NF
{Kh(]4h8Sfu
    char ch;ur SBEdu*z
    char res[64];#PS7\;x$a i3`
    float result;
2|yT^F3S     while(1);~WZ%E | O
    {sc,J8ThNG
        result=compute();
J5d)l%ag:h G9X         printf("\nThe result is:%s\n",killzero(res,result));
s;Z:Js-AT5i         printf("Do you want to continue(y/n)?:") ;RK4R+S p(u#w*|
        ch=getch();:^ln&k;C
        putchar(ch);
&S#E,h xTlYK Y5W         if(ch=='n'||ch=='N')]-o5[)pz,R dE
            break;
xZv `j$B)U,f         else
y/n2MCD Pbd             system("cls");
w0E'L:pB     }
xj5U/{,xK     return 0;
N,j f9Z8w8{$a*Y'I} }[/i][/i][/i][/i][/i][/i]
v(@s'N8G)^ Kc 5kW%T B0Br6B[Zb
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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