捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.^%P7clKy/x
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=+G p Fp2K Y
/**************表达式计算器************/
2z{N%`noS9L@ #include <stdio.h>
.]}T6O7e~*|;r'Si #include <stdlib.h>U9N!b'M j@&{oxA{1c
#include <string.h>
8h,vRYD #include <conio.h>
,SKDM#K&o1Yqf #include <malloc.h>#@)\ru@
,s`Tq5p3geL j
#define STACK_SIZE 100@(nd8C tXjO [[ s\
#define APPEND_SIZE 10
j1wD*yHL:Z nbkf;q#^.bG'J
struct SNode{|%Gqy7G5N
    float data; /*存放操作数或者计算结果*/
n1xB7P#}-B I     char ch; /*存放运算符*/2| j:Qek|(T6uM%q
};
5B Bqi$k:_2b6p {*b
zUT5mUz%By)z.?p struct Stack{iZ ]hr6U(LBc&k[n
    SNode *top;W*Ts(t}nS
    SNode *base;
?B8A+Hu9f/a8M)S     int size;
/G9I}/x$\-H?-o };k Y:_kL
LO lERg
/*栈操作函数*/ZO BVrWh1?P ^.I
int InitStack(Stack &S); /*创建栈*/9]A%_1cP1F
int DestroyStack(Stack &S); /*销毁栈*/ KVne3ZKb#H
int ClearStack(Stack &S); /*清空栈*/;P-t1I8P'R$G!jg.Mv
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/6X F:aD$F3ohB
int Push(Stack &S,SNode e); /*将结点e压入栈*/MPXw)cq!v[
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/pD H\*D5QP7w/b(p
M{*{N6P
/*表达式计算器相关函数*/
9D%J'^fH7zV3l-| char get_precede(char s,char c); /*判断运算符s和c的优先级*/_U.v2Kc+b
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/-G;D1^w y
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
RDHmc/G g float compute(); /*表达式结算器主函数*/
hv'V:or6n char *killzero(float result); /*去掉结果后面的0*/
:GM!O"A9P0{WK E/e'bK%K(zg3T0rA
int InitStack(Stack &S)
,I,|i:FV { p-Z{\M:V|Pr
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
hr'd#~ H:es     if(S.base==NULL)
{h6lD s$Fb:n*D     {]X ]']RsN
        printf("动态分配内存失败!");U8{c(P~w4GS
        return -1;
w1j5vIZC     }
)pv9NzG@T     S.top=S.base;P5R |\@:Ia-g
    S.size=STACK_SIZE;5G#Zt }W/m p Fh~5T9i
    return 0;2Tx GH&g
}
S!o D h*Bb'W 7N4j JC%g1l(d5H
int DestroyStack(Stack &S)
!hS*Y"d)y!PQJ:i {1D$M$E x$KHq
    free(S.base);
5v ^O}|%T@ |f     return 0;(C_Ed F/X
}TY#qBRR,T

2vxf9CNAp{Y@ int ClearStack(Stack &S)
1T Ze qw/mt {
~5G:}5bW%u-k&d[     S.top=S.base;pD4Fp{V5EUs#A-Rq
    return 0;
x&C*sf$}(yF&` }
9KBg:dc7L _&g p
;l6C&t b*wC$r2B)_q int GetTop(Stack S,SNode &e)N,z:P ?.E!EG1f%S*o
{ c6J;Q.G"G0X
    if(S.top==S.base)
5l%jm#]xC     {
A#N @:J e8RhSg[         printf("栈以为空!");,IF5{&N,Q
        return -1;
1k#O1c%BTQ     }?&fT+tI'q r)N
    e=*(S.top-1);
Q5S5Sh/J     return 0;
}8]x O _9A+E"lB$d }
,]h@h)m*Y 8O+F:[.|5Vbte5O*b
int Push(Stack &S,SNode e)(Q zg%~1l VH,n
{c9xDyb#W V p
    if(S.top-S.base>=S.size)
^%j%g@5@__MJ-d{ w     {
&w:?wy|K         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));HDY%Lai ]Hq
        if(S.base==NULL)
-xj%\6@*Y&t Ql         {TRc@^(x
            printf("动态分配内存失败!");
MM2L i.Jq8U|Qx             return -1;
N_ZnykAy         })J/iC%Dm
        S.top=S.base+S.size; z x$g(U$W@~y
        S.size+=APPEND_SIZE;
B/CJ7no r     }
P6V8} |/X;qTGI2T     *S.top=e;
O^#B.R T/ly2A     S.top++;
)y"P ~M6^)`     return 0;
2\n P,n.s }
\8}4v`Y6p!Di
Y(sG,sm"s3Y(n7A7s;I int Pop(Stack &S,SNode &e)K&M9g.f Lw2gR)Xk^
{5`'nN7Lh
    if(S.top==S.base)
W$m-`K-GjZ     {jY[+i{w K0mC-z
        printf("栈为空!");
O!Q[3s]sW         return -1;rS'v1A;ue3{!hD
    } v9m&P'{}tl
    e=*(S.top-1);:Y\N1`zR
    S.top--;
EZ.l*jc3^ph]     return 0;
+j v @/D] }zK#ZJ {5K8pa
Ze%Mx#qx
char get_precede(char s,char c)
4?i C6oQ_,q)]Pg&x6_H {O h&K \q8z#\h
    switch(s)
+K:]H}'dO%R?;]     {
2j ^R(T Zx         case '+':                 
TjgKJ'c5y         case '-':
_d7G o4nj'k              if(c=='+'||c=='-'))W H ty2O4r(c~
                 return '>';&g5WYx@
             else if(c=='*'||c=='/')
.TG*^a,`6x&d                  return '<';
%`K{r V              else if(c=='(')}#L g#n5U7c
                 return '<';
{$s1HZ0Q R!Gg              else if(c==')')$J)[EW#j] Q1e\!c.f\-r
                 return '>';2l#ko eg0k
             else
&M+J2FM}                  return '>';1o$T5@,M nl[*G P
        case '*':v9p;jqD
        case '/':
3QzB)c?&M?&bnEIF              if(c=='+'||c=='-')j:rK(Czthoa
                 return '>';
;t.V [^;c1[&p              else if(c=='*'||c=='/')
N Tgl'Cz                  return '>';1p~h:k R`5D x @D
             else if(c=='(')
km t K*pD6[I"mJ                  return '<';
)o!T Cx0x|Y              else if(c==')');lJG Xrv
                 return '>';
(P S&@|7L(q sj%s              else
$j z'Y0obih3[4{$O"B                  return '>';*h4`)Nr }/t
        case '(': e2\4`[)S+Xc&LD
             if(c=='+'||c=='-')
(B"R IA&n(AS7J `                  return '<';
O3~ f\ daxCaIo              else if(c=='*'||c=='/')
`g6Jv2l xk                  return '<';
f6Lq"F3R muf              else if(c=='(')@)kuC@G
                 return '<'; _3YFe5eT8s \
             else if(c==')'))NJQ7kD
                 return '=';%LF9NfM4{
             else
IyH-a!z]#PH+C(_                  return 'E';_'Q*gW F`/~p
        case ')':
&z/{iR)c.h              if(c=='+'||c=='-')m'p/|;`6n+Uw
                 return '>';'}\v!`4SR,@
             else if(c=='*'||c=='/')
GBzO7g;XQ0R~dW                  return '>';
}:\,\2J*EoUj)sJ              else if(c=='(') n6?q|5U
                 return 'E';M,d~/\_PQ&e6b
             else if(c==')')
Hm"OW@I.xm                  return '>';
U*U7b'O1W ~G;K9Mm              else
J9i8Q6VH,Z$Q*~2@vf                  return '>';5y']#Z9v-F9D"m9m,V
        case '#':
$[ BKxC+Ge0CJ n              if(c=='+'||c=='-')L0_?F8_7S/e"R
                 return '<';4Vus`'l1u&S/N
             else if(c=='*'||c=='/')
vH5F~k/p'EiN9Wym                  return '<';
N&bt*y9}              else if(c=='(') l F ?D KFdr
                 return '<';
'w2g ?E"GF2I4F              else if(c==')')
B7?Q_jP                  return 'E';
(p-g WH^1b              else.q?5m~f{R.]/E
                 return '=';
w$Qxo Ej]         default:*e^&}:n Oa ~
             break;
W J&|'tav x*CT     }0j,[Igz s^h
    return 0;    'I%H@*R/p)v q4NI6Z
}%u [#dmL r|

k.^J6X2a int isOpr(char c)
${;Qh'n H {5X.w%{.w }^
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
h(c,y~{AFm         return 0;
H6~$L;UN,@4v5rEg     else
j F:p a"qFN         return 1;
.w^]$wCQ }/n7`}*wl&_vu|

m#Zfw&d1p@[lN float operate(float x, char opr, float y)%^/D}Y9p%r
{Y/t%S)`Qn]Z7r?:o
    float result;
gN{zGm?/h9oH Q4_     switch (opr)Wo:^Bs
    {*h`[)I%UgA j
        case '+':
(KHW2Z H wx              result = x + y;
UETr u1}              break; I7z8} l j/W2Z1V
        case '-':
R%e#_M9fM+[              result = x - y;
5oKKt+f!]L Y7io              break;{*M|)c;WB
        case '*':
~ji9c No*b7u'c              result = x * y;
n6a1}v+v^tW              break;
e4c:_/gZoC*Q8o         case '/':
`}`(y0yeNb*]              if (y == 0)
Nk;@8eqzA?VO4O7z/_              {+f(fvJ,qDp0K A
                printf("Divided by zero!\n");
k(gR K xa"~Z                 return 0;
T+RqbB              }?$n'F u'\
             else u IU-vU4x;_8X
             {g.T o5`:uk-DQb7NI
                 result = x / y;W8g3eS4vWC8fDX
                 break;
B"qK(iJ,ip              } @7kU&U |4J?Va%Jz
       default:
A7hV d3C5_CA              printf("Bad Input.\n");
%T7jJ X|{V3H              return 0; n]&hW?+b4?e
    }3siyh2v*e6Vhm
    return result;el c$F,Vn`
}    \T8Sx&ce#}&yVG,D%}@
I;x:{d o/?+|{i
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
$FYGD8V {B||ld;nE
    Stack optr,opnd;
t:Rr(S3y0A     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;0M A3~%@ uF}
    char c;
']D{!u4U$@e~9^Y%ZA     char buf[16];
T1t){%W!gWD     int i=0;o6g-K0nc1g
   
O*i1X%g;U ?     InitStack(optr); /*用于寄存运算符*/
Sf+\*IY`Nt     InitStack(opnd); /*用于寄存操作数和计算结果*/
l!u1gwX }VKU     memset(buf,0,sizeof(buf));3e.T#He0@ [+f_
   
+T l9o#e.}     printf("Enter your expression:");S{ oy7wK
        
"| W"Pa%mV/K     opr_in.ch='#';S`'Y,A*B5Sl
    Push(optr,opr_in); /*'#'入栈*/0WDK/B:k9Akf&G
    GetTop(optr,opr_top);
6K`6J#XQ S     c=getchar();} BLe7\H,I;Yj
    while(c!='='||opr_top.ch!='#'){,Z;pR1b zc5D2w
    {
xr'C+YC:S{         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
Iajs n/HP         {kQ}n(\&J'K
            buf[i]=c;
;x8pqZK'UN8g             i++;,g[#PVAr`(ZX
            c=getchar();
(W#P:IJ-W&fm _         }
$s9A-O-}Ir8kg.p         else /*是运算符*/
[y#UDSjC         {O%Qi&r mxT
            buf[i]='\0';
2a$oS;?8} W6Xb2k ^             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
X:iq4vt+m n             {
\7Uk!K!B b x                  opn_in.data=(float)atof(buf);
Y1i w\\h1Dzgh{cJ                  Push(opnd,opn_in);
I t&Bw;v I ?Ahry"X                  printf("opnd入栈:[%f]\n",opn_in.data);#h0h^lWgkq
                 i=0;
#~,Y6Sf6xd                  memset(buf,0,sizeof(buf));
S"ch5Coe]q&vo!y             }
.{`g,nXO [O             opr_in.ch=c;*{ _g"EO1T*r
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/n+B[3J4EsuBX ^
            {Y3Qr [3qa2Pb U/cV
                case '<': /*优先级小于栈顶结点,则运算符入栈*/V3c2oL_ \K sK
                     Push(optr,opr_in);
G,R%W;q?$w                      printf("optr入栈:[%c]\n",opr_in.ch);
~"UV;B*_&W                      c=getchar();
_ U*}9C|e_ChF`                      break;(~ Jk%q j Ay|o!Pc G
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
g{:cxp8WM                      Pop(optr,e);4I4T6n q1vBd&J:n9?$i
                     printf("optr出栈:去掉括号\n");
#zR(Q:z/h Q"PW [5Q                      c=getchar();;I2vH JXg)?X
                     break;6]UN7cnhcmF7y
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/4],^4?1BVP9f
                     Pop(optr,opr_t);zy:A7Z`M
                     printf("optr出栈:[%c]\n",opr_t.ch);PLG Kp2b_'J
                     if(Pop(opnd,b)<0)
f6V9@!|*mP2k                      {!L3Vp.cW |
                         printf("Bad Input!\n");7neX IR)`
                         fflush(stdin);
AS0r0I#MC3Ry                          return -1;
i5`.\.H2q{Z                      }
2t }/}S^q2v ~                      printf("opnd出栈:[%f]\n",b.data);P1gm'tvB_|
                     if(Pop(opnd,a)<0)AZndA-G}&p4M p D
                     { NAV#UKp+No#S \
                         printf("Bad Input!\n");
6@!yXGq J2u)R                          fflush(stdin);;|X ?z!OaY1F:Bg`
                         return -1;
5|yQ5?:fxg+_                      }Q%gZN{;\%h]0w
                     printf("opnd出栈:[%f]\n",a.data);
&tNJ f F%N4NE5|                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/*La_7p sD!?*A
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
YnRv#E(?|                      printf("结果入栈:[%f]\n",opn_tmp.data);+J}NP(Fy5C d
                     break;)c5~-?I/or2U
            }
bt _ zy3]c         }M(ds\N8oy
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
%V$t-zV0SQ+FK     }
#U'oYgz$b,Q     GetTop(opnd,opn_tmp);
YHm:l WWN     DestroyStack(optr);
&J$cvx D#K i     DestroyStack(opnd);
[/d6Jd*iiPv     return opn_tmp.data;
X8DWl"}9J~jH }r(kw)O~)u%m

8A4C|h:Z^^KM M char *killzero(char *res,float result)
)X Z Z}o-p5{)^0p { z}4i!d0_
    int i;H S qWVl&SOM zz
?i#a0Bs | jykL
    sprintf(res,"%f",result);3\na!]!L
    i=(int)strlen(res)-1;!uA-}u6out[cF
    while(i&&res[i]=='0')
|[$W5nf-R"J_     {
I,RA!Xqp3j+A         res[i]='\0';
?5Wl2N0U;jP         i--;
2Aay{3N     }$tB#kr)b
    if(res[i]=='.')
o e0u2pr p4y+u         res[i]='\0';
,SZJH&zO     return res;;]c"PB5c7B
}
ps X#|;iH6L 7nJ/Rf'B0j%s"z
int main()
dC?bH&hG {
B,a"b)qbU9w     char ch;
!@6i"e#vr9Z'SE!cl     char res[64];O+u:a+e:{'O y,?S
    float result;
_9Z?~7Pz"O4r;tA     while(1)w'O/[J$O S
    {(w)\Vds6nO rqD
        result=compute();
lRWT B6i/rWG         printf("\nThe result is:%s\n",killzero(res,result));@7~,Omy*?2V;m
        printf("Do you want to continue(y/n)?:") ;
Z!I.T7Er         ch=getch();
:@,eW.c4D H V2MH!f(^ ^9T C         putchar(ch);+x rN Wb%Y8D
        if(ch=='n'||ch=='N')MBO@"TX$y
            break;
M3`O#AoL-AtG         else[(T/ywGc
            system("cls");
If_9P|6N     }
sb8H"|3z.oF&qs     return 0;'jWA.n!j)`
}[/i][/i][/i][/i][/i][/i]y~ [l1c7v }6En
f8U,qu.zMms f
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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