捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
a hV7{s;G*g 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=)a,F8Y8B] P+a+q
/**************表达式计算器************/ ?bg-u#D*K0ct+C
#include <stdio.h>
$}$j m"s#fp&Nj&~ a #include <stdlib.h>f4wQnb
#include <string.h>&`%g m be^ J
#include <conio.h>
vLD+[&QMZ/}]Y #include <malloc.h>
u q:~0]T:G.v#A#c
,y2{ g;mi&yd3f-Q #define STACK_SIZE 100c_H9{0f6Km:L a
#define APPEND_SIZE 10
kXcm9[Um,CU (k5M y IdeC~
struct SNode{
P+o$FtVLR K     float data; /*存放操作数或者计算结果*//o2Lp.j0Y6DvV(k"E
    char ch; /*存放运算符*/6B6K\#e{H^
};
2Wt](ZI0B
9M,gA`\l"M struct Stack{;~ gS'yj T;Y;H
    SNode *top;_mOyO;``qo
    SNode *base; w8^2D*n%L
    int size;
v)kAn_?4X };:L$kn2GDa G
m"W8?/xv vwb`
/*栈操作函数*/w&?7D'P+TOA0|R;Sw
int InitStack(Stack &S); /*创建栈*/'`#`IIOo yGsm([
int DestroyStack(Stack &S); /*销毁栈*/
R dq~3mhpxB-Z int ClearStack(Stack &S); /*清空栈*/
c.lV~c2Z/m int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
5w?hr5}7[!E&ui int Push(Stack &S,SNode e); /*将结点e压入栈*/
Ao&F-VX Pg int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
+}q#zgW0~6D
%`r&F9L7@i5W /*表达式计算器相关函数*/
{E-DU/Fa @ char get_precede(char s,char c); /*判断运算符s和c的优先级*/
ClZy;k?#U3Y1m int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
wS D*Eb float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/!{[x ItZH*}B0h
float compute(); /*表达式结算器主函数*/
w.lm0M/I Y char *killzero(float result); /*去掉结果后面的0*/ PSaF;~

8nm6mlO int InitStack(Stack &S)
F#hm4]5U"[ii {"p;m1]y/o4?E,Q
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));'j:@8x8Ht)C*q?
    if(S.base==NULL)qC*jv [+f
    {
.j9i;IO o$EC"HA.D         printf("动态分配内存失败!");+OpM:\H/]$TNG
        return -1;
N] ^B/f;u't     }
#HX]BTL ]y j     S.top=S.base;7X2i6PD;?5x5N
    S.size=STACK_SIZE;
d$ghf#|ej(l     return 0;
}:Q4SWo$A }a5d)ijKF`$}
%{BsRX Si
int DestroyStack(Stack &S)!Un sd/\7KM4[8Yk
{
3A0fbtd%\5l/bQ     free(S.base);&@BVKdKb Sp
    return 0;5]7v0S I XN4z
}
nDB Y x&[x0a
$v$I!R{/?1eQh int ClearStack(Stack &S)
T3Z%i)O.o-x U {J"p/{&A&L.@m%p/N
    S.top=S.base;T?)v~7`,L
    return 0;
A)M"`_;f0] }
}{ V#m8[O 0g` [y6Ck
int GetTop(Stack S,SNode &e)8Ph!C}{h^4Io#HX2W+B}
{}b,@ Qv#Gv
    if(S.top==S.base)
5p0S8y$iF     {{*Oo}/kg
        printf("栈以为空!");
1f J~Z!x/A         return -1;
l'X2wt;Ae%~!u7c+P7d8E     }
,HCPn}:}q*pQ$Z V     e=*(S.top-1);9g-Yt:o'C,uS
    return 0; D%[7@2I:m7|.j
}
'@)oz!n}\K
i!rGi_ int Push(Stack &S,SNode e)
iI[m v p6LR {*u0geW?Ac!]-K
    if(S.top-S.base>=S.size)Im(p6Th#~%X
    {
!e/pR|4[5Lt {-a         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));{w#r } Y+oT/{A
        if(S.base==NULL)/Qf"^7PBd Y;K
        {
%z[+H%IH {^&]             printf("动态分配内存失败!");Qqi"E iM&V;sS
            return -1;5x"Q:L3zd]pG+^uT
        }
zBVRB%KZ         S.top=S.base+S.size;
l-G#m F"](r#flG'N9d         S.size+=APPEND_SIZE;*@1o({ i)F7X:Wl6?
    }
4me#QT.Ck$a[/{ eN&b     *S.top=e;B#q7f)VO6k-z^P!g,U
    S.top++;
1Gg@/|QHG2OTy%{     return 0;
7`8{ u%g+iS-}[9n },m*K#t|RFB
FG2u&|+{
int Pop(Stack &S,SNode &e)@8Vr1Vt U Ip?A
{
UX8zO8L ZQ"KQ7x     if(S.top==S.base)T*l8q3~;}3D
    {mB+?n\
        printf("栈为空!");.O.X UG!rr]Z
        return -1;
@6xJJq_Cm     }d(PdVc|vg
    e=*(S.top-1);
uhc*z`'b&}3^_     S.top--;
R*W \J(R:F|     return 0;
4S/Ej D#y1x*[+?r| }Y{ l8pjq+g K

S:AOk'Th p$x X char get_precede(char s,char c):d/q5p;E V@
{#^4n@ec+c ]I3b
    switch(s)
"LK8K*m'P     {Yq,Hby
        case '+':                 %zw E?Z9zi
        case '-':
*yy6yn)Cb4c L t              if(c=='+'||c=='-')5fn&^]LnRn1X/p
                 return '>';
`4cG1B8ZH+r](zd              else if(c=='*'||c=='/')/a,u!T4r@a$| f
                 return '<';xO~7U+n,o,t"\2Dn
             else if(c=='(')
!G|s(Q3}UD                  return '<';
T-k Z(Jk              else if(c==')')6O^8|4L4Dl8N n3N#b
                 return '>';$kvsv9uWg%V-|x
             else
q&aagA#{[.M                  return '>';1f4S,A!~+GCJ-@[
        case '*':
9M*^Dv:pT         case '/':U2?r+wB(J,v!VV~-K
             if(c=='+'||c=='-')8[(|C h"FR+|
                 return '>';
(G i,u `&@4H fh_n              else if(c=='*'||c=='/')0J9v&jD%l t[
                 return '>'; o/uj@ e)ku
             else if(c=='(')
(tTxxNK7FE                  return '<';
(rfU"aZ"U              else if(c==')')
5Z e4a,X:gh5ue f                  return '>';[uy~yQ
             elseN%\#n.e ]/Vb
                 return '>';
U%a/D&R%E@         case '(':9i&K8UWmGv-qw1K
             if(c=='+'||c=='-')
3t A&Bq'o                  return '<';
`}L&F wv k3D!c1k              else if(c=='*'||c=='/')2ZZ,w*S f^
                 return '<';2\x]W/@
             else if(c=='(')
u G P-M g+] wSF0e'c ^                  return '<';`?)]{B9lz
             else if(c==')')
,I#J&~9xk:G w(t                  return '=';:|%kY Y5C
             else
\O1K2g8{ ww/A#] Z                  return 'E';
o7lR*vw%WZn         case ')':&A.r;\U&H
             if(c=='+'||c=='-')"\'Y[ M.C QHI
                 return '>';
k W#O|*b;gN              else if(c=='*'||c=='/')4F v2LJ4v|7f
                 return '>';
B jN5hEf"G+L              else if(c=='(')Dv7uo]_{6QV
                 return 'E';+?;A c ]J6kKha
             else if(c==')')e+T)yr}
                 return '>';+yw!H:P7p-F a
             elseo'D_#YYg&X+T
                 return '>';,J,Unl$I8K(s
        case '#':F!G8x#}Ak
             if(c=='+'||c=='-')x9J]5FJ!q3Q(C
                 return '<';
)@3W l9_+V+s.@              else if(c=='*'||c=='/')-bq a] p3gu oV
                 return '<';%|+|_;r s"`
             else if(c=='(')
ZJjF&r5X {,K^                  return '<';It9ko5\b_ W
             else if(c==')')
gH7~0ll;I                  return 'E';
i9h(^LhA0J}              else#b&r2}+]1[5@,}xV
                 return '=';~ CI!P7p?B
        default:7|2Ry0AS
             break;`&Z9L:x)UQ h
    }1r1n7a#VL Oa
    return 0;    c+d+Hy"CG9{ Z
}#xV~7c"f{prH

U+E P*^)rg)P int isOpr(char c)&D4l9C}Z)T@+w,\
{
B sX/I"S"A     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
2{ Tuq'\.f/v         return 0;(F8Z;w!X V
    else )W k et2t
        return 1;
`J ^GA }
:uTm#ZT/m 'lU lD+c&b!Q]6b
float operate(float x, char opr, float y)
S.{3GSso2?P {
w i4^+g-NZD'y2E     float result;
$i(?}v~     switch (opr)PT.e"G{2P
    {
Xz^ xtFv         case '+': w%e"AN$h)zYB
             result = x + y;
PHi#D)q_V              break;
^Qa5p?r%eu+e         case '-':
,M4?!\ g V              result = x - y;$ol#E3WV
             break;:I/lr2?1zjX
        case '*': n&x AMaZ g T
             result = x * y;+CP(s b-e
             break;
9A0c6KM$o]?9{!r         case '/':
E6m9A;l0_J              if (y == 0)
@4`:j6R,Y!S L              {
?g1RH?/~4a                 printf("Divided by zero!\n");
]6s MupPq5_#n#v                 return 0;
V2NWCC              }o'M;Hsl%yyq
             else
Wh(jH })cd&f g!{              {lRwUpW;E T
                 result = x / y;
J4\ck_O                  break;5N7PC6|E'x3H2e
             }
CTJ0lWx%ZK;`On        default: +]1`o0FB!{&q0`S
             printf("Bad Input.\n"); :I sm0\Cc
             return 0;
IF)I:E#M     }X$zD"x.V#^(r4s
    return result;
l.l1S#n6P"h9h7n/V$I8[ }   
:Pi6^4UQ0rg Y9h+k/VI'Q
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/6\6xx P9F _}%mC
{
COdN} |-P     Stack optr,opnd;J+E-w4lR$B3r&E*V)z
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
S#WrnVJ     char c;
B,zo.j-\X Y/p     char buf[16];#dZ&z?-U E5xT0M
    int i=0;fl_ zJ|dk!f#h+i5`
    (b3f&K.gf,[ \2j,Bh
    InitStack(optr); /*用于寄存运算符*/
&[ O!F m$zi@:f     InitStack(opnd); /*用于寄存操作数和计算结果*/
RT|L/n?7C!{9^O     memset(buf,0,sizeof(buf));
i'R Fg'F zj    
f9}_p,X:V k1l5OJ     printf("Enter your expression:");#O+B3`)x"I
        m K3N{9u@;H
    opr_in.ch='#';9mp"PE R#L)]
    Push(optr,opr_in); /*'#'入栈*/
n_4`t|R8m6Z'p     GetTop(optr,opr_top);]veU,K
    c=getchar(); ?a'nSzt3O[
    while(c!='='||opr_top.ch!='#')Hf-Ls9AEr
    {
J!X,W4~4F*}         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/Ex7J `iV:t.B/u
        {gY(wl t^P,DN
            buf[i]=c;$B#`]1K }
            i++;x Dj{R*_^
            c=getchar();0Xa8tnH]7aP;W
        }"r4M@:Tw
        else /*是运算符*/
/qtp"ppA-P#U         {
"x%rCpq3vAv             buf[i]='\0';
zN-w(X4YI$w"}V             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/S,Y D){ SiU
            {
(m"QIQ'tH L7t Q                  opn_in.data=(float)atof(buf);
JN.]f)l8j)W                  Push(opnd,opn_in);/^(EZ!I+jt
                 printf("opnd入栈:[%f]\n",opn_in.data);/L U9`"M.AL
                 i=0;
V(V-BI"t5H/?                  memset(buf,0,sizeof(buf));%P uW4e4b!S0j5` o
            }$a$c*u mGj{D3a k
            opr_in.ch=c;\u&qS9O6`
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/`x)O"t~&ADuo
            {
I.w2yUgjB1?                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
tY JI-r O                      Push(optr,opr_in);\8H jg's*v9Zz
                     printf("optr入栈:[%c]\n",opr_in.ch);~:B:b$P-mWLH
                     c=getchar(); L}1|$e6b i H)s
                     break;Qi'^0H?;@m+r(y
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
(k!M$j1Hxt[                      Pop(optr,e);
]+H9~(JO.Po                      printf("optr出栈:去掉括号\n");
b5v,Br1Y-N Q                      c=getchar();
OXC:u I7M/?L-\                      break; l!W*T)mbfV
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*//ci0HA m7LHGT[
                     Pop(optr,opr_t);8M-Otu/x
                     printf("optr出栈:[%c]\n",opr_t.ch);&s+`8K"\(V+m}
                     if(Pop(opnd,b)<0) ?9Q a"X"[Z/y
                     {
`h)t1g#jO*W                          printf("Bad Input!\n");6e1{ hQ2\5kP'AX
                         fflush(stdin);BfI#X1pcs^s7eCM
                         return -1;jL] T.sS ZM,\ P
                     }
'Z_@mf                      printf("opnd出栈:[%f]\n",b.data); ~6pw.h5w4z7L
                     if(Pop(opnd,a)<0)
C}$`!IV$e2`0k'Byka                      {
(wv&^n)^H                          printf("Bad Input!\n");
5x2hf{s+J                          fflush(stdin);Oh LR:R
                         return -1;
e4bmb SZ%gkim                      }
XmJ'j+R0A}&}                      printf("opnd出栈:[%f]\n",a.data);
.uKe~AdiD%kb m                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1SH B%U-gB^8P                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6}"h*eNkN5bY
                     printf("结果入栈:[%f]\n",opn_tmp.data);L2m"M V F(h+}
                     break;
&j RUi+E?N             }0L\E1~ m{p/K
        }*pd#f7{x,eX
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
q2M(?)`!dC%iS     },Lga(q` x
    GetTop(opnd,opn_tmp);)P`A:`4u pPZ&Z7e}#|
    DestroyStack(optr);gw0?-w`(Y-M
    DestroyStack(opnd);R [K!J+Qr:D j
    return opn_tmp.data;
MV%|lXu:E }
L+[ W@BER| H];TX/@E!Q
char *killzero(char *res,float result)
M;e(T`,G {
"v!E/@f'Jv I     int i;
MUK5}Zy
jON&p c8~3|     sprintf(res,"%f",result);-C$G@&S(Tj:P
    i=(int)strlen(res)-1;)]S!T$gTw;fe|;S
    while(i&&res[i]=='0')
*[K*rF+j.?+]+j!t     {
v6c!V;Y(|[#u?         res[i]='\0';K!TV$O{~;a ^
        i--;V.kI5n9[iX4a
    }
2u\}k&d)[D     if(res[i]=='.')[!iwv0]gky A
        res[i]='\0';
?+VNL3l@     return res;
?-[9bEoz O5Z"L }
K$Jkh\m)_mOvxD!k2j
.jt-O]_ls f2m2lL%\ int main()7VK(z l:@@_
{ S']-N*h(Z KB `+tcz
    char ch;
`0r3wx%Jw }     char res[64];
$k:T(g6SL1`B     float result;%yj&VLWT0T1B
    while(1)
2?&_ ]iq$nr:Wo     {D3i[8{{:S{VW
        result=compute();-rJ M3r0K%fsC8]
        printf("\nThe result is:%s\n",killzero(res,result));| eW!}{1u G~x,D
        printf("Do you want to continue(y/n)?:") ;
Wb&F i3}k s(T m#k1G         ch=getch();;u:`c7|M b
        putchar(ch);TASRmNZ`&q|!U
        if(ch=='n'||ch=='N')$LSUn `HBnw2x
            break;
sEj3tK         else
dZ%fO2U+eXf             system("cls");T O0w s"p
    }
.Zv8Z({U'mfs     return 0;
b&`)p4A*VUS }[/i][/i][/i][/i][/i][/i]
i9o S4St2t(j#O-E)J
i9d^;l8GN [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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