捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
:T7n UqNG-G%R 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=g'] }hzC|
/**************表达式计算器************/
y'^ b-K'q[_a #include <stdio.h>
E&ctov eUVg;GR #include <stdlib.h>
K3OM'As vQ #include <string.h>
e$u`O,P/s(V #include <conio.h>b\(xT{3j*Y
#include <malloc.h>o g2\2LJ1U f|

4`f-hv$o,M#` #define STACK_SIZE 100.C ? d!Z"}[#B kc
#define APPEND_SIZE 10yi8kVX0[G7kc
,ZO$E!Q+_
struct SNode{
A8z(E;k M/O`&b:R2X     float data; /*存放操作数或者计算结果*/Yl(U1}y e"t G
    char ch; /*存放运算符*/
U0AQ*zo7a i9v ]i };/D4Hh%erl b

S2J.U~(?_A:p struct Stack{c$\&qK7G:_
    SNode *top;X {q-n$G;|k7Kw(p
    SNode *base;
$@? D?-h%[!_     int size;!g{&mN bN6X1`
};
)TsIM C+{}
8ic5VS.`XZ /*栈操作函数*/ S2C)Z!J0t4g
int InitStack(Stack &S); /*创建栈*/6C0C!VH2m~$`:K:w
int DestroyStack(Stack &S); /*销毁栈*/LU:r/Sz+M
int ClearStack(Stack &S); /*清空栈*/oM u/g `H*Af d
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
b4gH dS H#F/H [_ int Push(Stack &S,SNode e); /*将结点e压入栈*/HU`i!tfK i
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ `!| X6f)p6ZW

5oMmj5JxhA.k /*表达式计算器相关函数*/
1R+C[ ?#J!I}N IT char get_precede(char s,char c); /*判断运算符s和c的优先级*/!k.Q{#@1Q
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/!dr`GzAE)c._
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
_M;Po#W1O@%E#c?u;A float compute(); /*表达式结算器主函数*/
`WQ{U cHJy2A} char *killzero(float result); /*去掉结果后面的0*/ +F(S7[@5R

"OSOan@~K int InitStack(Stack &S)
f8GRb S {
7kp4h*y'\#y     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
@_$Ll(wn     if(S.base==NULL)JM^e z
    {n/|(t'wV$n
        printf("动态分配内存失败!");s] SK#_%R%N
        return -1;8Ee;e|s P
    } Nu@#A6T/d]
    S.top=S.base;
v!])e*}1xZ#W/Q     S.size=STACK_SIZE; xLHD7J+^!TH h,gI
    return 0;(T5X$`O eK`|e4~ @
}
O&uh;^5a3Q
-EQ f U*~(zW` int DestroyStack(Stack &S))?:cc1EDUBo
{
R:^-\4N?:Ez)R     free(S.base);
|n.~|B9_     return 0;
@1~,w {0m(q2Giw }|(} b%SL!W Y;NO5E`
Y*N4mG^ T:~k uh$z
int ClearStack(Stack &S)y4R['KTQ
{4i(S sOa8l9V'PE
    S.top=S.base;
4c:\*R5r6Zx     return 0;)C;Y*gD| X9E Dx
}} |'H8KE-m7Vw
!i C/iE9fL3r.j
int GetTop(Stack S,SNode &e)
g5P SB@sw3^|e {
#@!t M6F;M7{#} x     if(S.top==S.base) \d e@T2h;]!h
    {7SonA H dPbp
        printf("栈以为空!");E+Uv L|2D9`/}&P"U#D1J
        return -1;
;knu|J"x.A     }
4E[_ Oy fJVs     e=*(S.top-1);1E*o-m"`M-K*Z+\w
    return 0;Mg;RuW;QS\I
}
.wA M[$iFRq i4M-@G1[~L,j
int Push(Stack &S,SNode e)T(s \4yl~m$H
{
}"b0J(_y+QP A     if(S.top-S.base>=S.size);or2c4|-voV
    {
Dn1~*fFg         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));do \a1MI Iy
        if(S.base==NULL)2gthn4w
        {-n'`z!F!v4G8it
            printf("动态分配内存失败!");qLA;qbTWX
            return -1;
6TS.`4P5zdjN'j         }
P%HG8ba K?         S.top=S.base+S.size;
v[jT`         S.size+=APPEND_SIZE;
5Cz3B*D4J     }
%gy4IO"^V3f9i     *S.top=e;c$}sDx#j
    S.top++;~+h!w+K }h
    return 0;
[Dasx|+I }
,V*w4Km'pe9R~
"Z$|0x&dvkW/N int Pop(Stack &S,SNode &e)#u$p#W1p;g]EmF w
{
/y*uV-kJ5r4MN Z     if(S.top==S.base)#@1FIM_%O
    {+Bs;k j,L2TRK's,u
        printf("栈为空!"); M){t-G)H*Lf
        return -1; }(KJ1jW6p
    }
-Ym'ls,|)k8h     e=*(S.top-1);`?P*[!tn3F;{M%O
    S.top--;
r:K V{"x2^,o)Ge     return 0;
x7?(tCQz| }
m;m"U%s$~GW 4^;C6_!S"l}
char get_precede(char s,char c)
6Q r8J0fh4p {
uaFF c     switch(s)6f;j?^CYm6W{
    {N J4z}Z8AK9zU
        case '+':                 
t)m`!t.|0~.`         case '-':
(M$]`} n&F}4oD!L]g              if(c=='+'||c=='-')
D lV0L'IN8Ns8o"|8w                  return '>';5w| B4V6Qf
             else if(c=='*'||c=='/')Zm%l#XV)c.@
                 return '<';n2hf_+{
             else if(c=='(')
Ur2M#iV9}*Wg                  return '<'; |4o w U6?$I1^B j
             else if(c==')')/Aj0F^a
                 return '>';$jwE9{s
             else
,m~^in8TH                  return '>';J$d^~\5f/l j1^^
        case '*':
5@ Q-Y:]_\         case '/':&F p.EW0f/W`/`$e
             if(c=='+'||c=='-')
8OE*O n^I%gQq                  return '>'; G1@ G!h L
             else if(c=='*'||c=='/')-`]G\$nl
                 return '>';:BMo)N-Z8H3p2Bhj
             else if(c=='(')
:\0k |9zD F-W*Qn!I6w                  return '<';
N*o1gg9hO)z:q0X$}              else if(c==')')
x8S5h0Q#?m.Pid                  return '>';
B(F#z8|%? |*h5Ty"c              else9z9v N Q+]8K*K?
                 return '>';
~G^_K]Ke:D         case '(':
EIW5d#vo4?"c@)`              if(c=='+'||c=='-')
XS8VzVB                  return '<';
Zu.?&A1D7`              else if(c=='*'||c=='/')
p6pvrE#?vH@C                  return '<';k)M#w7|_l K|d1c
             else if(c=='(')
,Fw%gom X/|                  return '<';8s3s*u#y2@k]
             else if(c==')')
? C2F z5V/L                  return '=';
H(P5TS5r7A#M,j              else
,V5{+UMk%g;Fd                  return 'E';1l ig8T5q6p&c8BY.{
        case ')':0q c1x,wCk5d
             if(c=='+'||c=='-')
"DO+Y [|Lr                  return '>';5{4\u.|z$M
             else if(c=='*'||c=='/') j m?E4e/d!U/yE4v
                 return '>';
o'd{6t)g S_ c9{              else if(c=='(')
q)K_"MsH                  return 'E';
8pI'`A8Sk ^x              else if(c==')')
o'ds ]S Z                  return '>';$v!R`^6t8C1d
             else
|n|V6r                  return '>';
"^$N$Q:Q^ x         case '#':
I[\%nZ4B t/q              if(c=='+'||c=='-')
1P%J up)?B7Z                  return '<';
gB;KfL] WzJ4r/y2y_              else if(c=='*'||c=='/')YI!_.R([&X$M
                 return '<';
C%@@4e n2g;_              else if(c=='(')(g KV"k'I^"R
                 return '<';ce`Th
             else if(c==')')8I4[3Nd8FxHT N|w
                 return 'E';^R8@1|)z
             else
0P Zn"r6Z.Ag                  return '='; C*z/X [.u fg-b2b&L1y B"ul
        default:
$B1ui%a\L {.Ta              break;(Nsuj H(G
    }
3p)tO2Z0j1| c     return 0;    _ W%Iu%Jg
}
AtI}T'hA-q M0v1|\Fy0\2w:m
int isOpr(char c)V)oYG*?O.C R
{ s9PX-jj%Snp
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
6EUBrq!Sr/\         return 0;
J3ZZ Qro     else z r3Xj v&JqI/^A
        return 1;
-R6UTgm }
C4` K2`pH&K1Q u8vO"US
float operate(float x, char opr, float y)
#ld0V }V%ivK] {
#G/SaIPd     float result;
:t%pro1fH     switch (opr)
L4Q,\ I_7`HE     {){m;Ph O!I/fS+xcYd
        case '+':
4L*@~8qYUrQ9K              result = x + y;
Sg8DJZh x              break;U4A/g?%z!?i$N
        case '-': M zF#sLVOD[Z
             result = x - y;
JYI!| UF0v7e              break; H:\!^0zrj_|
        case '*':
#gOG p+Hi,B`              result = x * y;c#olRGr9|
             break;i*_{4@ N/P(ZX0^
        case '/':
@,KkPJ%[&x F              if (y == 0)
S#g-oL lG              {8aM3Qedh8t
                printf("Divided by zero!\n");_o&iDqec!t&X
                return 0;.[E.ho4|0l1]!x@1e
             } gB f&VS(wJ
             else-l3L J6\6h8a
             {
2o6S*S\4Lu                  result = x / y;
^o_F.EW-I                  break;
+p0G&D2xKT~e7bVA              }klez_"d
       default: 5qO&[1JG"^:m*U
             printf("Bad Input.\n"); %V]7lf0Y4b.L
             return 0;
s\+uo B7Nz     }
&i9x*i }o7x'cZs+d     return result;
UbBq([+lsE)L;H }   
,]/W5z-F/U
4Lc:z;[`jP? float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
(XN3`lv%hM;Pa {
.HdB#k)N&X&r;A5^U     Stack optr,opnd;
[ K \^,?!K/XC     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;y.Dlgf|}
    char c;K8q"{5Vm
    char buf[16];
!T(Z/b9~*g w%C     int i=0;
+WZ;~_*s#F1M}    
k*J\P].wY ?&J     InitStack(optr); /*用于寄存运算符*/'x7H^!j8N fj%@
    InitStack(opnd); /*用于寄存操作数和计算结果*/]%M-hb ]L1X/G
    memset(buf,0,sizeof(buf));
5K}4x(t}     /vMM*R~j%id
    printf("Enter your expression:");%F@d(T7D~ uU `
        
/vW,R-l;k1UK     opr_in.ch='#';
1|;U2e!A|     Push(optr,opr_in); /*'#'入栈*/e$XHh7nH
    GetTop(optr,opr_top);
:p3AsEe ?Y-eW     c=getchar();0Z:zEdET M
    while(c!='='||opr_top.ch!='#')
6EE}-y3Ii     {*\A BSQh.q
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
P L X#~P"K,o         {
-Fs!I8O8|!j+@8@             buf[i]=c;
m9uD#tS:xN2C,A             i++;
7K` vG#t|             c=getchar();q4l%fVw9@ G
        }
$b}rDG         else /*是运算符*/ Y)C$O Wy;_ Wk8{
        {~]_3c5?M4T
            buf[i]='\0';
GJ|Z'kw|             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
"iWI bx ah             {
EV_!kv|yM                  opn_in.data=(float)atof(buf);
T] ]D w"sK|!gt                  Push(opnd,opn_in);
o"\%k d}L;J$G'u0y0z                  printf("opnd入栈:[%f]\n",opn_in.data);
LHI4[\X                  i=0;,G#E uv(?X
                 memset(buf,0,sizeof(buf));
AXC7Z/z)^d8`@-S1q d             }
%q3L-[SV9A@             opr_in.ch=c;e7mzx2`U,p
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
Yzv)t)yx-b#g1p4mt             {U.H$WJ6n
                case '<': /*优先级小于栈顶结点,则运算符入栈*/M.tW?4_+_)|9FI
                     Push(optr,opr_in);4h%}4UHnY
                     printf("optr入栈:[%c]\n",opr_in.ch);s"\ W O&C~ U
                     c=getchar();
hd*lRo T4^`                      break;P.I8d |TUnC u*O
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
/WS+g`N7h                      Pop(optr,e); qP8k(t8b-QCP9U
                     printf("optr出栈:去掉括号\n");
!l8W1D-kSrk.Kv5v6u@                      c=getchar(); Hq b y%Y'O
                     break;
|/h;{/d6a9{~,}'rN                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/` HM-FI!e-|vv[
                     Pop(optr,opr_t);
-A&bT8o.\#t9?yN                      printf("optr出栈:[%c]\n",opr_t.ch);
@6s%J'Rr[                      if(Pop(opnd,b)<0)3gB8`rx
                     { {]&u4A4NJ
                         printf("Bad Input!\n");#h Ly f1\*W6@z r|
                         fflush(stdin);P0?s\E|8h d
                         return -1;
"H4O t*M9_}                      }]_Xz @/E$\
                     printf("opnd出栈:[%f]\n",b.data);1s%Cmt ?5[s_
                     if(Pop(opnd,a)<0)
2F6oHp]@\q[                      {'ye\] Zn bm;bA
                         printf("Bad Input!\n");
Z&K'DvH] k                          fflush(stdin);
3tb+rB(s(A                          return -1;6yfC9I;uXRCo.?
                     }
_&`{,{$C6r0SP:JV] M                      printf("opnd出栈:[%f]\n",a.data);(Jz"IH.J%]*H4`
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
L#c%o1V;{r                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
}QhUb?W                      printf("结果入栈:[%f]\n",opn_tmp.data);
y*Pox0K|                      break;;a c7xM4A
            }
Q0^ O$C;z2\:{         }
u`JEh3f I uP         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                x"N\5cN k7q4q
    }2Yi2VW:D%{
    GetTop(opnd,opn_tmp);H8f7D5K,|}9| r*z![
    DestroyStack(optr);
C?"FqY K     DestroyStack(opnd);0Kx+@C%n??
    return opn_tmp.data;
zPPF-Z:V;J9q }
,r{+vN&YB&lx
W4nWg6T!n char *killzero(char *res,float result) Ml,\&\ G*y
{;YF ]X*w9g8Hv
    int i;
r\M W-h;O+tD'FA vF+f#\&q"{mX
    sprintf(res,"%f",result);oIFB&[duZw8@
    i=(int)strlen(res)-1;Jps,a Z ^6c
    while(i&&res[i]=='0')
l8n!`,D+O`G2D4B     {
h+IUwE(]1B         res[i]='\0';v*GpBg w(lX
        i--;X.CM@Zl"T.U
    }
h } g/]$h#C     if(res[i]=='.')$NTSBEa hZ9@n*X,A
        res[i]='\0';,K1B1^^x!?
    return res;qU ~!ZU;xh1w N
}O+V?E5?Q1N
?"Wll [,GE?+r"L
int main()*T o-o,Z r#WT
{
$lrW0E3kpe#K     char ch;
"p4~ZS:r[|     char res[64];
W$Wd$uoR"^     float result;;~"^'_:J0_$P3l-b0G-p
    while(1)
,to5e k9auAg     {
V@vK g{(M$S K         result=compute();_2l o2p"W{
        printf("\nThe result is:%s\n",killzero(res,result));-E7x hefl2B
        printf("Do you want to continue(y/n)?:") ;!x?5]6g`#W-?(Wv
        ch=getch();6r_4w-eyFp `
        putchar(ch);
"{ n Dabk'K         if(ch=='n'||ch=='N')
@j'm,i.Wv.a.H             break;
H-qM{fjN*x         else
(Z-}!qic!^             system("cls");
!rS2z;zs-G^7Z(CWrv     }
3R$b} z{/C1n5{     return 0;
O^3DS3mP'K5v-O [ }[/i][/i][/i][/i][/i][/i]
$a#~nT*j
bL3w*N _4B0o)u [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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