捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.r q0~ vLtezD
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=cB6Z0C]-_NEz
/**************表达式计算器************/
AQ4tC1pIxD)R #include <stdio.h>vu?t ?f o!pZ
#include <stdlib.h>
g4uL }%eS #include <string.h>
I5l,nC5D*y { #include <conio.h>
1H B+@/Kz{ p4MB #include <malloc.h>
.G1yo kR!{.\b Kmtpy3k)L0q0p(?
#define STACK_SIZE 100gt L+?/kld,T
#define APPEND_SIZE 10
!cG3z.f@!L@4po)Y-k
`f'J'b%J(i+_A^ struct SNode{
Xi$y yd2D%|pO6P0P     float data; /*存放操作数或者计算结果*/,\[ _;Wjzm*}I
    char ch; /*存放运算符*/@ n5B6G;V{
};
q"DF1oHNHA wRT*sa3RR:Jg
struct Stack{5R9j8f)Xz4LknL a
    SNode *top;U@cE!kf l#ua7g
    SNode *base;
/zs:eF `c     int size;
H_4u*_Sm };
vkZJ1X M4\1Ms2L
} ay z2O [+V+l1c /*栈操作函数*/
6jm7tP*j7dnz6A'u int InitStack(Stack &S); /*创建栈*/ d*i'p1a:PEC1d
int DestroyStack(Stack &S); /*销毁栈*/ ^X&g/Ct#zdv0P
int ClearStack(Stack &S); /*清空栈*/4}Z,m0@5E_,x N5b
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
#x zcj6\%~1O,`"g int Push(Stack &S,SNode e); /*将结点e压入栈*/
5d8GV^^C;wbt int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
_F`c%S,gla
1\ i.HEB2} iw(O /*表达式计算器相关函数*/&h#d5qg:VPz
char get_precede(char s,char c); /*判断运算符s和c的优先级*/1e5ol+\"go,ERUN!Z
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/^/U6L}!f3e8e5n d
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
5J$O)c2@ u H float compute(); /*表达式结算器主函数*/ qf3j4e ^ jm#Xj ^
char *killzero(float result); /*去掉结果后面的0*/ ch)y0m$qYr'u

!w%h` {|LG;U@0M int InitStack(Stack &S):z.z |8vS4g0\ v(u `
{
nwlh8d+L     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));)S'?Qk&qDNuQ{
    if(S.base==NULL)
q Rvw PAq.M     {
nt2s?kSZ/v         printf("动态分配内存失败!");
8a&YX3c X         return -1;nFs2j(sGV
    }E_KbUE
    S.top=S.base;
4{-hdB/~%h+HO*v"q     S.size=STACK_SIZE;,Pa/\*O4g F7q
    return 0;'ae!e]/O&f
}
T:[3|^4]9q&s1q _Fh*~]"@@)@
int DestroyStack(Stack &S)
e ^s2Q*zR6Yld {
%H-h7B'`%j6c     free(S.base);
G(o |\o*ZU     return 0;/]C3T?"O:I9b+J H
}
VHZpO C Z Q.^.WbC J
int ClearStack(Stack &S)
+Q jT;|.\ { mT(E#ZJ1W
    S.top=S.base;HDi"{`oE
    return 0;8f+s&Aml&Hw+r
}
SRn7^[6X1D:T r5AB 1}s%Q'~(s?p5m
int GetTop(Stack S,SNode &e) Pj%] Wx@ t?
{Vb L*W wi
    if(S.top==S.base)
pWlox     {
u f6WR,pc_&t b!O P         printf("栈以为空!");
'oii6["?;wm         return -1;x9B/L[Z.?c"v} E%|^
    }
,^V5R%N8]f/Jp!~(m     e=*(S.top-1);@%HD*vUJF!m(i
    return 0;
/Q7e1{:U3f-{ } IG}(N`
U7_:dscL
int Push(Stack &S,SNode e)
;y hV R I {
:g([-R+Y9Mr ]     if(S.top-S.base>=S.size)
)bKR'wva     {^ lR,A/yc4AB6g
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); Z_ ]Pu@;?
        if(S.base==NULL)
D bX,Z;p%H)W i         {'i.oL?z}
            printf("动态分配内存失败!");5d[-i|Sa!L ~`
            return -1;
b Z h#];O[!X'S9D0Z9H         }E,Rfi*tzv
        S.top=S.base+S.size;2e p'ss QWCN%q
        S.size+=APPEND_SIZE;0BOaWd,t T
    }
m xhQHT3x;}5XD     *S.top=e;,n`}S2y%h
    S.top++;Ne l@7gPA#\
    return 0;
4R/wa*@V,q+{3]|B0{zM }
3EF!Hn u F3h2Ji#goNm.J+V
int Pop(Stack &S,SNode &e)
O:NvC6yk] yu {V}(}\a W;tg
    if(S.top==S.base)
UO\4HV b     {)@jY.^E'~2A.L3P:X,h9`
        printf("栈为空!");;ysV#~-s kZA
        return -1;
f R+bJ y"UI     }9L,z`.G8UC@
    e=*(S.top-1);
3@3y~$@(i'i?     S.top--;qC:i` N3h+`
    return 0;Vh} jJ
}
_7@\o'Yj rv3o HO`$h
char get_precede(char s,char c)BQ?:Huo#[
{pq+_!Lp&d
    switch(s)
7Q[:v a_4m!Ov tIrV     {4{Y-P!mb d1DR R
        case '+':                 D:B?:V'Ek+h
        case '-':6kO\ r m3wj^C[
             if(c=='+'||c=='-')
&[fEO[m                  return '>';
'O`Aup v|.b&@&[8x              else if(c=='*'||c=='/')4a4I*VU%DTM)pY8y
                 return '<';
7q%M Nc{&W              else if(c=='(')
u3N!gb#~/Q E+t                  return '<';q!Q!h[h+ZZ[;h5A8_
             else if(c==')'):KuJ\w/b6y#h])O!f
                 return '>';2a6a4P,O[ u mj9x2yT
             else v5G2U5m$xdO5t7vh
                 return '>';
#D[;[-T:L         case '*':
+W2LP dnZ         case '/':
wr@(e|2Xn              if(c=='+'||c=='-'){'a^K:wBD^
                 return '>';
)i(zYq!f}X`!j              else if(c=='*'||c=='/')+CV$FA*j S8i0{
                 return '>';z2f1F2x:T PVZ8h5yA
             else if(c=='(')
O:uZXsL ?HO                  return '<';
5L:q q@a#H*H-E{+s]              else if(c==')')(I9?*BY2a1|z#h;| Y1bz
                 return '>';
7w)P c3o!c              else
Y?!Bd/A1w^PWJ%S                  return '>';
9nT v;U/t'X~,L3U         case '(':
Vl3vx%tO5ukf'M7O              if(c=='+'||c=='-')
9LtX;Gn{ Y"o                  return '<';&["Zpk%n/M;ILG
             else if(c=='*'||c=='/')
Lr2b?3WdQ+s                  return '<';
-w-\;B*h!O-L              else if(c=='(')
*Rj_6H*e?                  return '<';0p)b#R6c9K|"\?
             else if(c==')')
Ccw.B&D)`                  return '=';E @'m8]ahjz a1[$T
             else2Jng ^g4R.P
                 return 'E';hqGuCG
        case ')':ux`osG$w(N
             if(c=='+'||c=='-')
k-hF~:RK-]                  return '>';l{#{jKQf
             else if(c=='*'||c=='/')A;o j OM|s0S
                 return '>';
^OR'I*EL              else if(c=='(')
,u8k{ d j j5{qcq                  return 'E';
\|h%m,L6X              else if(c==')')
j qc&a.`'Z                  return '>';7YRtxP
             else
_ pV`%iBTVB                  return '>';&lppo~?$u?8T[#X
        case '#':
Ksd:nw.~-E:v+cT              if(c=='+'||c=='-') k[GuP$r
                 return '<';9?)ODZ;U$}
             else if(c=='*'||c=='/')]nN-T)}3Ai;s5r
                 return '<';
9dd9Q4Et.H+I.t3T              else if(c=='(')-c]}~y&Kp'@:s&f7y
                 return '<';'F"g%n\D#F?Z8n7S
             else if(c==')')4@7@*}1S+G l
                 return 'E';P:a9Ah"@4\ Yt
             else
:a,tAc-zq$deu                  return '=';"p{ Rp4?+i*]w
        default:
s;Zlxs k              break;
ou!`I6pX)j     }T3G1W6G1s i1Z&v
    return 0;   
9E X'y3gUzKG9H }
lz.d,f1yA,v H0Z4nmR+bw
int isOpr(char c)r2pL7c8xo g
{
%B3~"[ t ~6Z^     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')^/`2zo!H9G5GI
        return 0;
:uz U'BM(A#})sW     else 5W\2E*@-Q
        return 1;
2I#d a_k'a HP| }
]ZZ H$RP{S Y0N4JQTc
float operate(float x, char opr, float y)
J(hXbr i {
bdFv}} \1`     float result;
4}"M~!b!t'R^ y     switch (opr) [#V3~'L1Gp"u\0V
    {!wZ3ATU@
        case '+':
X(a1h%T#bp!J#{[              result = x + y;H]3u\` B
             break;
Xx)J A2m!N,k Vm         case '-':
\$J_uU.R3v/`xYn              result = x - y;
^)x(P8Mi5^              break; rKHd)G"l;xc]
        case '*':
4BZt9Z3tA6TAlJ[x              result = x * y;#NF qr`"h ~ w$B Az
             break;6]'q3};wkA#G8~i
        case '/': vV:T+L ^mQ
             if (y == 0)
&R7j8J2w9z dH7Z              {2^;qK.ON!e;C
                printf("Divided by zero!\n");
?!DCp9Z                 return 0;S \_L'z mQ
             }
#|&h#s5Zq$g9QM              else%Y`pK.}L
             {
3GS0C+k P5Q'~ I4Uwf                  result = x / y;.f/ozS A#Rs%pl
                 break;
;[lmgNhM9|              }(z;}8nz9s'WX
       default: 9is\&V1S
             printf("Bad Input.\n");
&|7Ir rD0Nt              return 0;
aC-nXC     }
zps/w.z.da     return result;
/l ?sHU y W*zc }   
V8Q'\h1E/gu]-Ro%v "` FlCf.G'Jh9z,p0f
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/ [G:O6Sxng
{.] T:P9? @2w/a
    Stack optr,opnd;
EtB4DHp     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
cG#vwX     char c;MJxo}e
    char buf[16];
it)xCz$SEX2@A     int i=0;n*W?nw O s|-j$Qq
   
)Q6G;Nfl/L5omr     InitStack(optr); /*用于寄存运算符*/P!}YzynC/Py8s&@(@
    InitStack(opnd); /*用于寄存操作数和计算结果*/
@f0V!m,w2bk]@!G     memset(buf,0,sizeof(buf));4P/Fb-x.m2z
   
k0^4E?C(nWz     printf("Enter your expression:");
[/Z9}XpN0w         
Yga%sj J     opr_in.ch='#';1A^ ZS @oBmwc6m
    Push(optr,opr_in); /*'#'入栈*/x$Uk XpswIF
    GetTop(optr,opr_top);
6XW{&}U9s4M2~     c=getchar();
PEa o h;^3k     while(c!='='||opr_top.ch!='#')
Q?oP3w.eqNA     { o1m Bj1Z3y#qn S
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
m @y4ci8` @]Sp         {
o!V5h&|,h!_$w:{             buf[i]=c;
)I|(| Q?8Y             i++;
*t2l$XL_I7XZ4aL-o             c=getchar();,S O;Q]}
        }^0c0L5_:w
        else /*是运算符*/(On g^`S
        {
&G[,T\'e:Y+R             buf[i]='\0';
:G wu}o.K6_O             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8Rf-Ym,kU             {
/j9D[mBkq n8jn6s                  opn_in.data=(float)atof(buf);
Ap `)h&CUX                  Push(opnd,opn_in);)Uyw-hd*h%A
                 printf("opnd入栈:[%f]\n",opn_in.data);
4U R%q$HM2R6u7u                  i=0;
I:w6H&e@7k0F2OZ/c                  memset(buf,0,sizeof(buf));
(Q!F.HWkgp             }
o [6wG"K/d#T             opr_in.ch=c;
(^4ljj5O3KB             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
9Ybyb ]'`w3`             {S$e{1fSnD,ih:P#Y b
                case '<': /*优先级小于栈顶结点,则运算符入栈*/ \5j)vC'y,ky_
                     Push(optr,opr_in);
bYl[;zLZ4~1VxP                      printf("optr入栈:[%c]\n",opr_in.ch);
%fFG*FN'z                      c=getchar();c~@SZQ:q2O'Qf
                     break;2t'jE'[y*Uld2A
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
+T"l*F(M1M Q'U6C(]3O                      Pop(optr,e);+n5lf&Mkc)](LF
                     printf("optr出栈:去掉括号\n");-G+@e!s3tsy'A
                     c=getchar();4b EivI G{ w P
                     break;j0I}#e v+E/A
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
'TN jax_-xp                      Pop(optr,opr_t);@8Jd:p$h;\7_c vN
                     printf("optr出栈:[%c]\n",opr_t.ch);
:rv2M6gTw                      if(Pop(opnd,b)<0)&B[y$jW!g
                     {
|%k"X*q4s R mO+\                          printf("Bad Input!\n");
0xx)i0F](x9G!JP                          fflush(stdin);
b+ko"Xu yj(QRcr                          return -1;
"zl6hG5sy                      }m7?C![/B*u
                     printf("opnd出栈:[%f]\n",b.data);T&FS8j"Bsz
                     if(Pop(opnd,a)<0)
'Hzkj7OZ#Zb                      {
h$d@"MX                          printf("Bad Input!\n");'N FwI;KDo
                         fflush(stdin);x0G3}c%vE;B!?}|
                         return -1;ERlH u
                     }
4u%o^1V9],s{O8s9c                      printf("opnd出栈:[%f]\n",a.data);8za"Q&t{ zH
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/;M$Q$z9g8u7wY f
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/U3V NnK4Yrua,S?.` l
                     printf("结果入栈:[%f]\n",opn_tmp.data);
I zlv#ld2BW%V7V                      break;
)W0`rR-^             }g2uv GL
        }gV$HzFm(XJ
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                KOn9N&`Q;o\
    }3Na-Ft }
    GetTop(opnd,opn_tmp);
3n/P"V8Qm3N     DestroyStack(optr);
p/\hpqlS Hfg     DestroyStack(opnd);j5x3VM.k,W
    return opn_tmp.data;
5d?Qdu.Q3| }
_"Q I7} y )VI:mel(R5Tiv
char *killzero(char *res,float result)2P!KV6Xs TW
{kZ|4G7lc+K,s
    int i;
m?8n.n,cN1FV-A@9W;r
E[pH4`&I"]     sprintf(res,"%f",result);
bx/Lq+UF dp     i=(int)strlen(res)-1;
0a ?.a2a9F     while(i&&res[i]=='0')
2TN^aj!{:p     {Z$W;M t1dPr
        res[i]='\0';sC9[ \nD6y|
        i--;uE\i7Da:\
    }-}4\4_6M/T.tm
    if(res[i]=='.')*J@([2M9DSHT FZ
        res[i]='\0';)i:Dz#B}4M.~
    return res;1B|:GcfT
}
%u4H Q)cj,Ib4Q)v
NSm7bG P.[ int main()
[w6w'[ k/N!Wk {
(yG@:z8Y9_@^*U     char ch;9W {,TPeoX(EQ
    char res[64];XDk'O.KK
    float result;
7`:pD(B5SM(C     while(1) CV%sx:g0s8s
    {'E})A fB-erM
        result=compute();
@ G%L2{sk+l         printf("\nThe result is:%s\n",killzero(res,result));] MLa3[g{e
        printf("Do you want to continue(y/n)?:") ;| C9aly
        ch=getch();
|,CjaAQ M"@         putchar(ch);
F$I6XQAg1C         if(ch=='n'||ch=='N')
s Q#Jt3i1iE             break;
xf$]+vw#W&Z         else]O9MVlzJ
            system("cls");&b%Nr*Y Yv
    }?p*r~[
    return 0;
hS/k2X1J2@;U }[/i][/i][/i][/i][/i][/i]
*?7x `&ne$~"F cNo
'v/XGhf!` [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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