捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.(B,B9`*L(M+]l
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
#x8_#dd0P C /**************表达式计算器************/7kc2g*Dh5l5E
#include <stdio.h>4lzcm8L q(v
#include <stdlib.h>~,gZ?2f vh M&L
#include <string.h>
Wz"soo #include <conio.h>
a.w`@F fq #include <malloc.h>hLkL-_ gd:NUQ-c&c
]5{4r)e.Iry6l7?+r
#define STACK_SIZE 100
Ufq+o'A M&n #define APPEND_SIZE 10J-_a`1TsG
m w |5O4g`LD|:[
struct SNode{)lg{8J$w7A
    float data; /*存放操作数或者计算结果*/8i,~N_CJ7nj
    char ch; /*存放运算符*/xg&a*y t8Xo ?
};
D7t;@0O} o1|[ !`f1b9O1kY8hId
struct Stack{
W7tycs H"M'r     SNode *top;
;o R9RzI     SNode *base;
i/uBt%}4Z     int size;
A ?MZ!ZS;^/O6P };
Q#@J{0o/m#M\(]
/hg%a:W%xF | /*栈操作函数*/tPY!ao9~X
int InitStack(Stack &S); /*创建栈*/w Si~)p
int DestroyStack(Stack &S); /*销毁栈*/&B [3G,`1b,h;s
int ClearStack(Stack &S); /*清空栈*/ eER8@E9i
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/`1Y{t3gpid XX
int Push(Stack &S,SNode e); /*将结点e压入栈*/
7C.u~ Bk,Y:t)e'T int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/B7DU.~*z"PZ

)@g1vt2puf /*表达式计算器相关函数*/
3_3VQ-{.x U)}F3d char get_precede(char s,char c); /*判断运算符s和c的优先级*/@+Q@;[I/E8C;L/?9c
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
(@Ol:eI]d float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/%a D.k+r,s!KC3n
float compute(); /*表达式结算器主函数*/0pi*x8w"K7b
char *killzero(float result); /*去掉结果后面的0*/
KzPg-Ae \4e vY~{5T
int InitStack(Stack &S)
RIY:r {C}O9o*y {d-k;E`:w(w}
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));1p^F ~NBo o
    if(S.base==NULL)(z'|O @ r7C Lnp x
    {
sNrU)jD.x#Q\ iS         printf("动态分配内存失败!");;w2dycY@2_
        return -1;W8{KbO m4H
    }
8Gro `b"ixb:i r)u     S.top=S.base;
*]cw1s]D#E     S.size=STACK_SIZE;f]rD^O!p n [?_
    return 0;D)wN-a6Ue^ b'bY3`
} t8[V8T"MU:T9@S
2W@(E:y(I1p2Ou
int DestroyStack(Stack &S)%D'm2},qA,pq;f%P:y
{+_9s5HLBx#c&M(B
    free(S.base);T(W2xV'V@x3}
    return 0;
M8_o~Xf2t C%T }
WA7`xJXYN^
D@%W(C7n int ClearStack(Stack &S)CK6L)_ D%\%m}
{
KU6D"NzK     S.top=S.base;
-l1v7{:B!oR!qt     return 0;t[7i3i^)lwAe
}g+e,h@!Hu;n Zz bU
z#MiJ p{Ltx3Rv _
int GetTop(Stack S,SNode &e)#K _n.R]6? |/q
{'qRqeT l2I q
    if(S.top==S.base)-_u,g}I)F&i
    {
C,E ]Z[j         printf("栈以为空!");
7v-^2fP/vBln         return -1;
e|*n)r[:}6{C \2W*x     }h-J1`jP:G
    e=*(S.top-1);
-x7{bBr6w     return 0; `/Z$fB @#c
}
-D2j j@6sk:oVk#|J
1tDZe?;t&u[L int Push(Stack &S,SNode e)
'j%N p d8g)j5i9g5t {3~jkr4W w1o
    if(S.top-S.base>=S.size)F,|*`:im"m XV.K.W
    {4^}$x+h_ n
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
ekx2H_1U c2s         if(S.base==NULL) ZZs#f2k.V?
        {if$Kl I$k2g$P*AW\
            printf("动态分配内存失败!");z E!X*q0D+Nlh9} Z
            return -1;
9cv'f3e$Y`b^         }z&DA%AD l
        S.top=S.base+S.size;%G9[(KDr lu6a
        S.size+=APPEND_SIZE;)h%|;_hhihwz
    }6FsGT&B#g w
    *S.top=e;5BMp4r/b~?c"Bc {.O
    S.top++;%T8T_0M&ht ] yv8Ss
    return 0;
^0B%H {7|s H5ahm'j }MC gb;j P0]5@

F B;w3qJh(fpt int Pop(Stack &S,SNode &e)
B'o w&{ |*U)h3A8A"NM {
F^\d)g1}     if(S.top==S.base)
6v\ M+ul:T     {^1B&I h x F
        printf("栈为空!");h*? J#U^ Q
        return -1;_"Vdyw}
    }.j+eV N]I${R u
    e=*(S.top-1);{2w gL aS/X
    S.top--;
w2v)yJSZ9k     return 0;
!`+^+R K7L ~-v }
3]Z,C s4s4]
rvU9q)f1t er char get_precede(char s,char c)n u1O;| Y
{
Y!];[j3~-{K0t     switch(s)mS4[kKOd/d l
    {q yQj!U3K6Zr!K9n'E
        case '+':                 
Y{:l#aydy         case '-':/qjpH f0\
             if(c=='+'||c=='-')
9H+q[P%Xm h9CF                  return '>';t~ ~+D*t(akd2xb
             else if(c=='*'||c=='/')#WJr8BN:eq
                 return '<';
kUjf$F9f cZ:R3B              else if(c=='(')
hR,?0[6La1|                  return '<';
'oF s$f#Y \"mh              else if(c==')')
y5R n*^(w^.D                  return '>';g.~6k:t },M
             else ;}xl^)V
                 return '>';
x D1D:^'kp~"bW Z         case '*':
6Bf+UJ'p _M         case '/':
IZ3Y E!d3@+B5AK4j.B              if(c=='+'||c=='-')$N2k _Ub7alv
                 return '>';
V6dXQg[k              else if(c=='*'||c=='/')
+I#a/`/D{Br:vo                  return '>';
S0R8Y ]4dtt              else if(c=='(')D*r_4d-A
                 return '<';4N$Ufqh$jvT
             else if(c==')')
x.B!c!Y,H'iN;D b1W                  return '>';*EN$b3T6ez^RFu
             else3mgV#}ws9q
                 return '>'; D)^7\b8U,g8X
        case '(':
9X4wd4W c%Fsg              if(c=='+'||c=='-')y/Dp[}Vo
                 return '<';
B9s_Vm%m_o_6k| R              else if(c=='*'||c=='/')
pR-KI&N{:LZ}.gq                  return '<';
)y:xWgSsF              else if(c=='(')aY J'N BeN
                 return '<';
S%O[9K v_ Ou!D              else if(c==')')p+caI4qO ` j
                 return '=';8r4@E.jP/b%Kp D+D9s
             else
m&lH5y];`4N                  return 'E';
@!]y9T Zs         case ')':
p.DixM:IF              if(c=='+'||c=='-')
/` {(r\_/u&~                  return '>';f0M'e%j`9E4y[
             else if(c=='*'||c=='/')
|'wj+K OG                  return '>';u!]`"{Lk
             else if(c=='(')T)i8U9iE+c%u6lo
                 return 'E';
+S7M:K3Vvr              else if(c==')')$LL f?,n%`
                 return '>';
%n$d,p/Gpta              else
7MU[#t9k9C                  return '>';N5\1Nv(w"@O
        case '#':
XW.sXuQ G              if(c=='+'||c=='-')
SI'i&Vo@ `                  return '<';
+Rjz9B5r$C_K              else if(c=='*'||c=='/')K,e.f:^@S5n"e
                 return '<';o-] qD;ph%[8ur
             else if(c=='(')
T lLEii _;])g                  return '<';G.Od#gczkP
             else if(c==')')/VJR"x;C$q
                 return 'E';
m h(cSm;^              else3ZdgO!IY3v$j*T
                 return '=';
Iw n R1cqC L         default:
&k'XQ.w\ n              break;yz.lLx
    }!InXU&M'v j$H
    return 0;   
g0D~.}8?e+Nl }7E g'w3{%f
xp}$n ?{4w3~#g
int isOpr(char c)
A5Ki/xQ d K"f {
7tO x#KF'r3d     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
]/Gz"vfg5uo r         return 0;
3\D8eS"C"xA"|     else fn#C;U/w&uMP{9J/W
        return 1;
@!p/~Y(t H"W$Fk$e7^ }
:QG N)x2C,| z
1J S/_*qbtU6Ku float operate(float x, char opr, float y)1e,PTyN+L{^
{)Y&xn_ E K?
    float result;] ^"^lK9mn
    switch (opr)"\/K3G4U }#v
    {f,z-\y-w/WU1g
        case '+': B)Qg*D6X-J-I
             result = x + y;
+x/\ynt@FT              break;9WC-x ZU!v:|Pk
        case '-':
6sa+R}W6hM              result = x - y;
? Vy?]N!h9M.P              break;SLM+r9IN!G'R/^
        case '*':
v8vb PXU              result = x * y;
o8mvJtE              break;:oKvrba e
        case '/': 'm;G*TEz
             if (y == 0)
,M!Ad3fA.C x;|j              {(?;[mO1wb
                printf("Divided by zero!\n");H _2S3|"X j*}0s Q-fp
                return 0;
QD"? ?.OQ)b0C              }"L:?p Jj
             else d4Slg$_It
             {
)L Q[)_7v/xH*b                  result = x / y;"J9iT9`.` ?q*o!W3\J
                 break;Dp,T"T)]1DZf^!VM
             })o'o1r^*~I9q
       default: +t6|Nn ?K i#^
             printf("Bad Input.\n"); +b AP;}k Q?3gc
             return 0;
hqA%d?%Kp4IT     }
aun$EI A2v:s,h2X     return result;
ZTXH o-n7u"T*b:P:lA }   
.]2D1_u\7k /s*ERhd*J Q
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
:m@S)f9R HB#Q9U {m8H"Ui9B4G5F
    Stack optr,opnd;"X$?!_"TS L/v
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
3s$P(}4t&[P%d%Ip }     char c;?(g fPl\rG-r
    char buf[16];
1In:R]T     int i=0;
r AJ#I!U2J#A     $MYn8Ioh a(d
    InitStack(optr); /*用于寄存运算符*/Jw)N[V'p
    InitStack(opnd); /*用于寄存操作数和计算结果*/'ec.YN}7h
    memset(buf,0,sizeof(buf));4\-nIE \c#{
    7\;f2nWb.dxF#S
    printf("Enter your expression:");c/qK.K#T%LONd
        
~:O4xQ;|0r+j     opr_in.ch='#';
5F7pf`'Cb0]6p     Push(optr,opr_in); /*'#'入栈*/!V Qj6s:T
    GetTop(optr,opr_top);
|'C?,W ?(h[     c=getchar();
9E.Q:VtP5Q2x     while(c!='='||opr_top.ch!='#')[0~pm&Z,q"gj
    {cs6ZT)s
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
9X6f7fP4M7L"{ M Sp         {v1NV Z%s.fx
            buf[i]=c;
!Uni\K             i++;]8T0qjv1UA
            c=getchar();5~xJx"~#O+Xl
        }$v/[k iFDSm3[
        else /*是运算符*/
e#WV#~Q9g6\         {C5~Q7b*fX2l
            buf[i]='\0';)|+pf/s4~,E5wF6VJ i5z S
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*//e_/^2g%UF'w
            {;l*R D;KCM
                 opn_in.data=(float)atof(buf);
yzXXGm~3Q1`                  Push(opnd,opn_in);)J'Q7z0YAXuS
                 printf("opnd入栈:[%f]\n",opn_in.data);
Q0n?!n%e_                  i=0;
"Bs;n8[ I9i)rW                  memset(buf,0,sizeof(buf));
ip8@:CL.pOf             }
D;h4X.? s?$^             opr_in.ch=c;#u'B!]F ^j Gy
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/A$Y_e&[)B^~q&B
            {
4|@'](V_P                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
EQ*@v7E TX:~.I                      Push(optr,opr_in);
}1|M| uT(C                      printf("optr入栈:[%c]\n",opr_in.ch);
JYw3?*Z/tm0F8b                      c=getchar();#t3f'c\f
                     break;
.s2h+DFx y?dg8[m                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/:Xb;q5r&[UY
                     Pop(optr,e);
!fB^r"GX W.M                      printf("optr出栈:去掉括号\n");
_7Fz xaOa,w                      c=getchar();
}9@_ n}+T!dz                      break;5N)x G)~Y*w RBT
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
KQ5A|s q V\                      Pop(optr,opr_t);
LY$?R/I)EX!\ p                      printf("optr出栈:[%c]\n",opr_t.ch);E'Q:tD$WRdR
                     if(Pop(opnd,b)<0)
0y'o[Z/q(w"NA                      {
)O:k y"Akw)d,l                          printf("Bad Input!\n");
H/S5yl*a-YNGz {%o                          fflush(stdin);1T1Lh j'Q#a$Ul
                         return -1;
0X$z4{)r3s!]$p#p'X_%F                      }
jEI]&d                      printf("opnd出栈:[%f]\n",b.data);
K2`jsegG                      if(Pop(opnd,a)<0)!N:E5yUT YT8F$_
                     {Wl(bgdnJ7x't
                         printf("Bad Input!\n");
PHRa5bwk                          fflush(stdin);N_t N7W
                         return -1;Q$|,EQn5VXb
                     }
e6I J5Zd~                      printf("opnd出栈:[%f]\n",a.data);
%F Uk/JdA`wn                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/^3p`Ll pY7R!s5n
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/&MO4HMko$W6z%V5\J
                     printf("结果入栈:[%f]\n",opn_tmp.data);
D6RYY^Q                      break;X2Q3i7Fh
            }
\%{j6Vq%m         }
)?| U2bzuX G|         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                3WYe |W X
    } x0{h"smPhW
    GetTop(opnd,opn_tmp);+^3^&d.Gj+Ex
    DestroyStack(optr);\P#b/q-?`
    DestroyStack(opnd);U|1z E$S2_6m'} I
    return opn_tmp.data;hN7J)}+?3b
}
*{n:yB+j@0z LuG1l,p
char *killzero(char *res,float result)
&t^vD*Ks \T {$K1K/}Sv
    int i;E#}/G8[)@ w~N&j
r,\s'w.M&x
    sprintf(res,"%f",result);
+e u"} ~s*u     i=(int)strlen(res)-1;7K};c0A$V}1K:|
    while(i&&res[i]=='0'),a V7B1hc }9~j
    {
1F)u px/xmr`         res[i]='\0';(xq|s)\Q_[
        i--;
.y9q,Je2@ J     }5Nu`$Nj H
    if(res[i]=='.')aD&@MY
        res[i]='\0';
0eNs ?'Nh Z&G     return res;
-Y(E XL"R@"E?YZ/r }3z(f#z({)obYEtM
4C%K r\#ne'iz
int main()]!d5x.BYo d6wB
{/hL w#t`6@
    char ch;
@p(^#A g v1B@     char res[64];
G:G j8sYJ     float result;"M0v9w.T4Y'zd3x?onz
    while(1)
l)B{4]]T-|,cy     {-C3Xyt1p#Y|+F@
        result=compute();
l s yWQu         printf("\nThe result is:%s\n",killzero(res,result));
;]\.I gM?         printf("Do you want to continue(y/n)?:") ;JTf]^8I l c`c
        ch=getch();"R*AJ"L3w/{3B
        putchar(ch);Bq:Sm!qi
        if(ch=='n'||ch=='N') F5W? NC?}c:Q
            break;-S V@a*hz(f~t
        else
~#Z*]j{H+L+R             system("cls");
3^"`:s9Y Q-lSa     }
jAg5gSb I     return 0;
e%J3SS7uoA }[/i][/i][/i][/i][/i][/i]AY4@G\'|8a

4lp"N N9CT7gj:r [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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