获得本站免费赞助空间请点这里
返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
  r1 T/ O' T: c/ P% I程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=4 M' c2 R6 F5 Z- r
/**************表达式计算器************/$ _' f; Y  v' t1 {3 T
#include <stdio.h>
" W! z, M& u6 u#include <stdlib.h>
% w! ?, N+ `8 l( e#include <string.h>. W' M5 o# d1 D& _) e
#include <conio.h>
7 y7 \( G0 W( v#include <malloc.h>
' w/ Z4 D) Q: ~& D( ~# Z- ]% m  i/ Z5 c% v* s3 P. J
#define STACK_SIZE 100
+ W: ^/ m4 S8 R; `#define APPEND_SIZE 10: P1 n8 h7 [2 Y  o' P8 c, P4 l" P

, }/ D; R# ~" U3 P: ]struct SNode{
/ r1 c- g6 i3 _0 j3 B    float data; /*存放操作数或者计算结果*/
: ^% P) x) a& \; y) C+ \; a    char ch; /*存放运算符*/
5 G2 {* f" N" n0 ]) Z};
# _' ^0 Q& X' z* s5 r$ H% r2 f1 \2 o/ I
struct Stack{9 S% L' L  _0 P( L
    SNode *top;
3 j7 S" h1 j, M) f9 \8 [* ?    SNode *base;
2 T3 N& U4 q  L5 ~    int size;4 b* k  e% }5 K" N
};
* X: u0 M  r1 n6 K6 i- ?6 C9 o5 Q  O4 j; `4 P: R5 P
/*栈操作函数*/
- T: x% I' w8 }! q! o- y- zint InitStack(Stack &S); /*创建栈*/
. ^) i  E% F3 Y- `# J) ?( d; P* d$ aint DestroyStack(Stack &S); /*销毁栈*/. ]0 Q5 H) }1 U( ~
int ClearStack(Stack &S); /*清空栈*/5 a- X2 l# U, I1 w
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/  B/ E4 z$ R# N+ R) R
int Push(Stack &S,SNode e); /*将结点e压入栈*/3 b6 A/ g- Z- F' C5 C3 ?* x
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/- d$ U# G; E* Z/ p/ o( E/ V3 o
/ ^7 v5 N$ W& \8 p) N
/*表达式计算器相关函数*/
- T. V" T' D  Rchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
: p' ~: Y/ I' `7 v1 nint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
+ Q4 |. a' D: ?( k# |# p; S) Ufloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/3 i& q2 R% M+ c6 q& ]# ?/ k; H
float compute(); /*表达式结算器主函数*/
! Y& u9 C1 p( w* \1 qchar *killzero(float result); /*去掉结果后面的0*/ 2 k3 Y$ R- b+ x/ `6 E  ~1 m

# y7 |+ b" F8 y+ i$ Pint InitStack(Stack &S)
3 B) {. C' i" m  `4 p' }1 c{- P+ J1 f  O* v* n0 N  Z' t
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
; Z! i# g" x* E& P    if(S.base==NULL)& z2 g+ t5 A, h/ q2 k" \) r1 B
    {
# K* z+ _8 S  m$ |        printf("动态分配内存失败!");) A. ^. I9 |2 i; a4 Y
        return -1;
8 q3 `) h1 G" Z( D4 s    }
( S2 Z. S- _& @% ]% b6 ^' q    S.top=S.base;6 U6 _5 R" N+ p8 N, \5 u
    S.size=STACK_SIZE;7 }8 J7 ^7 i% l& m  K' r3 |
    return 0;
+ |  f- H2 [2 O( I7 e}
! I* n% \1 D6 j5 R5 L  Z' P# J* P$ W# r, Q% g, i3 l+ H* r
int DestroyStack(Stack &S)
& L4 _! c3 l/ D0 T% {/ B" I{: J$ n" T0 i2 t) {
    free(S.base);
" e+ `* H: u. N    return 0;7 K( g4 V. @! b- [/ h) K% q+ x
}6 f- h2 l& I2 B3 c  _
' g0 S& K7 F6 M  o
int ClearStack(Stack &S)- L( m; }5 N0 q/ r3 l
{
; `" D) h) [4 ^, g    S.top=S.base;2 H  H- R; S) {* A8 [, `. T
    return 0;: j/ M: m" X: m& m8 d  d1 L
}$ c' h7 X1 E8 X1 J3 T# X9 P
- u7 ~- U, [4 ^  `6 O- m
int GetTop(Stack S,SNode &e). ~% {: G8 _: Z! @, P
{
8 G  w3 d- D+ k; W    if(S.top==S.base)6 b* H4 A, S3 \& \2 o8 E
    {
: I' c2 Z8 n5 D& A$ }        printf("栈以为空!");
* m2 V- `% B$ ^3 R( \5 M1 v        return -1;$ b/ n7 H# d5 Y; S
    }0 R. }, C: ]* [6 e
    e=*(S.top-1);
: s  u/ P. g) z: ~( {! O    return 0;5 P9 S! S5 F+ {( P9 p. y
}+ I( g2 @  p; X8 p* D
6 p; y4 s* m% y% l: u2 h! H
int Push(Stack &S,SNode e)4 P6 C" N- i5 {" u. q8 h2 [
{
. B+ G9 ^% l# C  p. p) i# R. C    if(S.top-S.base>=S.size). K/ ^4 q9 Z! P+ X( ?: [4 D" \
    {6 z6 H9 H: q6 {! g
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));% Y7 Z" f4 H3 u' _
        if(S.base==NULL)
4 V# U* j$ i6 V/ [$ T* t1 W. }        {  f& J0 O9 P* M$ m7 m4 x9 \  v
            printf("动态分配内存失败!");
$ [! I' x' S7 z1 S2 x/ _            return -1;, D% O( ^3 G, i- r2 F
        }
2 h' z( L* o: C8 d0 _        S.top=S.base+S.size;
$ T, m. }* M3 R+ |        S.size+=APPEND_SIZE;! S, A9 Q2 o1 J6 Q0 l; @: Q
    }; k& r' R7 [+ W4 `
    *S.top=e;
3 S1 k: l/ t8 |    S.top++;! y: z/ N( ^7 E# R, T
    return 0;( t, Y3 C( e$ [* z1 o
}
# I% j( y2 G; G9 u
, A! ?4 q" Y3 ~9 W# aint Pop(Stack &S,SNode &e)$ U6 R& {+ `! i& [6 J, @; Y
{( V# C! s2 ^: q+ B1 q
    if(S.top==S.base)
" U, H) E$ ^+ Y. X/ B! J; E    {
& k+ _3 {  q9 X        printf("栈为空!");
1 z4 S9 ?0 b7 l  a+ Z2 B        return -1;, w$ e) x  G) @. _7 S
    }: B$ p: V9 f: U
    e=*(S.top-1);" `# z" `4 [, _
    S.top--;
7 n  J! q: b5 j3 q: R" }* i; \    return 0;
) G4 `& s6 q. s}
3 I' D8 F: A* R/ L  Q8 p6 ?* L1 C6 X# Z! ~' ]/ }
char get_precede(char s,char c)6 V0 p* [+ R7 S3 S0 ~3 N
{4 c' s6 }! R7 {
    switch(s)" y+ p5 {% [- [
    {4 t  i- Q6 C. s" S/ n2 ?
        case '+':                 
# o( j* [2 r! L2 j. \3 m  t9 i        case '-':9 v4 Q* c  r; ~' X* _
             if(c=='+'||c=='-')4 j/ ~2 A( G% u6 x
                 return '>';" h  w$ }, q& D& x1 k
             else if(c=='*'||c=='/')
* p$ }3 Z! W5 g0 W4 Y5 v                 return '<';
! e. ^( q. w( Y) f             else if(c=='(')4 m9 R0 g# s; l6 @0 t6 Q3 k
                 return '<';
8 f* r6 A/ q* Y0 t6 e             else if(c==')')0 s* T9 u, Z0 g, T. y- k% _
                 return '>';
4 U0 m, E0 K5 d7 x' m6 V             else - v6 f! j( f1 \' Y! `+ {6 H' f9 G
                 return '>';
1 s1 m) r' n( X. [* h7 d        case '*':
9 ?5 r6 O" q5 ~4 Q7 u$ h        case '/':
5 I6 Y/ }8 W3 i4 }1 j2 U9 @             if(c=='+'||c=='-')/ C# B; c: {* D& r
                 return '>';
2 y2 p5 b- E5 j+ R1 X             else if(c=='*'||c=='/'), E1 B- G3 B" K4 f. I7 s# |" K0 |
                 return '>';
/ I+ N* D3 ~6 R- [             else if(c=='(')
5 T4 s  z6 L& ], B* C                 return '<';
! L( A+ |& u. n4 r( w8 f             else if(c==')')
# M# q2 M; C* D; v' p& K8 u                 return '>';
# e( `6 @" ?7 {) r             else  C9 n. v3 W: N7 W$ s
                 return '>';
7 B- E& h- P6 t$ N$ I5 [        case '(':7 ~; ?! b, s3 I: e/ }/ h) Y, l; X
             if(c=='+'||c=='-')* ]" G9 K9 [, g! i; F9 A& V
                 return '<';: y9 u/ Q& F; |2 X' Z. V4 H
             else if(c=='*'||c=='/')4 B( `; b  {: ^: o- h
                 return '<';0 e2 }0 ]: _& @5 X
             else if(c=='(')7 ^  Z+ K$ p+ ]1 S6 [; M6 e
                 return '<';. e9 L3 ~: p$ Q# R: h9 [1 m# L* @- P/ }9 l
             else if(c==')')
* A8 [; n% {5 y3 f/ l. r) {3 c                 return '=';% _' |! [# A* S/ R
             else
. \- q3 T. H9 V, b8 w                 return 'E';
9 c% t; t1 K/ W! Z+ e        case ')':
0 S" Y6 j2 p. K             if(c=='+'||c=='-')
( G- n5 `4 _$ p. I3 E, [0 w& |                 return '>';$ ]  n. F  D9 D8 F% b
             else if(c=='*'||c=='/')
* e- f! p( p6 J8 j( y0 p                 return '>';/ c3 a& v8 m+ g* L; ?
             else if(c=='(')3 `3 G1 H! s$ \6 R, J. q
                 return 'E';
& G. \- E" ]+ n9 }/ Y; V             else if(c==')')
5 E9 A' n) s3 }# k                 return '>';1 d% a0 M' a' g4 T
             else
6 z- o8 h5 z; z+ X- Q3 v                 return '>';0 R+ p) B. P' S- T+ @7 J
        case '#':
" z% |: V0 f' n/ \             if(c=='+'||c=='-')
0 g2 R8 V" o" h; Y                 return '<';, h! P2 H+ G/ s. ]
             else if(c=='*'||c=='/')
7 `2 A+ N  D* k9 E                 return '<';  d+ f* {) d: T+ K% t$ ], m$ q7 G
             else if(c=='(')4 w7 e7 D& n. X
                 return '<';
" ^& Y& T& \) _& w* X             else if(c==')')
3 j" \+ u5 ?) P) R                 return 'E';  A3 F& _, G' i( ~
             else. i- I! d8 F: k0 R# a1 c
                 return '=';6 l/ }7 o% j% L7 x# [1 A
        default:5 G3 m: A! Z& n: q
             break;
7 }- r3 u* ?( R0 H; V" b. z1 k    }
6 h: h! `3 p6 V0 v    return 0;   
, Z  p1 _2 q, Y$ D( L( T) m}, c  F* n" M# T

' x; t6 R$ l$ L5 b) G  j% Eint isOpr(char c)
0 l, h1 @: U1 P2 j* b6 U  ~4 }{
) s2 |* y6 p+ o; C$ \0 U# P" U    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
; f% f3 T! F+ `  N4 z        return 0;
* N. b3 |. i1 A9 r' I- ^    else - T) d% [9 H% l! m( y; }; B
        return 1;# V. S  E8 ^6 `8 K1 X
}+ i; o6 j. ?; z* ^5 `* P

3 x' f; f' Q+ z7 j! _3 b  Ifloat operate(float x, char opr, float y)( D0 n$ D2 B' E8 S5 E
{4 q3 y' ~! m3 o4 U. {' I
    float result;
$ |$ ]1 O  l: O$ e( F    switch (opr)
: G9 D" i- l! G- t0 P    {/ e2 ?/ x8 V( M, N$ c& H. l
        case '+': ! N/ K4 \9 |1 B; B% c
             result = x + y;
) Z% ?8 Y3 n/ S: `- v7 Q4 w4 k             break;
6 Y; W9 `6 i" d7 r. K/ ?        case '-': 1 d8 V' b5 U% Z
             result = x - y;1 O8 W) ^& m# W9 U2 h# }" A! L0 [
             break;
2 l6 L% n5 e% e& w7 X5 Q2 p7 C        case '*': 7 a0 _5 X% p, l
             result = x * y;
  H3 T" N3 u& |1 P             break;6 S9 u* c# P/ g( r# f
        case '/': ( n) ~8 v3 k4 R! ]% d; J* P
             if (y == 0)" y2 p; }! n, ]% W( r/ c- Q- |
             {& G2 `& |4 E0 {
                printf("Divided by zero!\n");$ y% R! ~: z/ c2 t6 a) s, c5 g
                return 0;
% @2 Q2 G6 l; u: X$ N' h; s- F             }
7 D/ X8 d3 K6 t             else; U: R" K  E* {% M) c$ G% H( [
             {
2 z4 ^3 `3 f, a                 result = x / y;1 C8 _$ k. ^1 i2 G( Q" ?( J
                 break;+ K, q% l6 u$ V9 C( x9 Y, E/ v
             }7 x+ {7 P& p6 p( J" e4 s
       default: " M- `3 ?! r0 |7 Z. k5 Y
             printf("Bad Input.\n");
( q+ ~. d7 P" l0 p* ~( w( y             return 0;) o, ]5 o* r( q* r
    }
0 Z- A1 f4 `$ {3 C  t    return result;
* Z' y1 T/ e  d$ S- P! _, B}   
5 K6 A$ f! F/ R) H0 u" o
2 z/ J) P9 `: bfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/! O2 t) t1 y9 P* x3 p% c
{
8 S: a; r8 b. J. ^2 g9 u    Stack optr,opnd;7 S, L7 e) H; V9 b$ T
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
' L( s# ^4 ^/ i. I9 }2 D. [    char c;2 z5 W# {  e, G  `. F# k
    char buf[16];+ |0 G" P' _: R6 h, u
    int i=0;, i+ p9 c8 h' y
   
4 U& j# c* s" [4 E/ R/ F! f% \    InitStack(optr); /*用于寄存运算符*/. ?+ L: D4 l+ w
    InitStack(opnd); /*用于寄存操作数和计算结果*/: e* j6 t* _4 z5 [- |/ N2 s8 h
    memset(buf,0,sizeof(buf));6 ~9 }) K  B+ o! [% a# V0 ^, y
    + k; {6 y) \" h, K0 w1 M+ i
    printf("Enter your expression:");3 z% s. U) O; s* N; ]3 i* y
        
3 y  S" s3 ~8 z  E6 y: f; ?7 V    opr_in.ch='#';# k4 t$ E& f/ D8 B* ^  P
    Push(optr,opr_in); /*'#'入栈*/( f& a# {* T# {, k$ e
    GetTop(optr,opr_top);7 j) `7 G% ?" X' J4 s1 w( U
    c=getchar();$ p( P* C' P; g9 y" e
    while(c!='='||opr_top.ch!='#')' \" T% z! C# _( ~# _) g* _: B
    {
) S+ Q2 y0 @1 \- A' ?8 I        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
. @/ X( `: J9 p# G' ^3 n        {
( j/ r5 y# l, W1 |2 W5 o            buf=c;
" C, q( b; y5 s$ K3 E  c            i++;  B% Y8 ?+ o6 Q! }9 }' I
            c=getchar();: K) }) @% o2 w4 J  y% p! Z
        }  K! {- m* R, N0 ]. G
        else /*是运算符*/3 |7 n, {/ m1 G
        {
, o  B3 u: w( d* ~3 S7 L* R+ I            buf='\0';0 C$ s0 s9 h7 z* M  H
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/: V  H$ V" T4 `
            {2 ?: K% I5 R$ D! r1 }; u
                 opn_in.data=(float)atof(buf);9 `# q3 h- ]! C& v# X5 I; Q3 Y
                 Push(opnd,opn_in);: m0 @2 G/ L' t. S
                 printf("opnd入栈:[%f]\n",opn_in.data);8 w: S- M6 l: ~2 s
                 i=0;2 m, ]  M( f! }' b: Z
                 memset(buf,0,sizeof(buf));5 s- \& @! a# n! h
            }
  }$ W6 J0 C- m- M! y' k$ f            opr_in.ch=c;4 W/ s5 B( j- I- i( l
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/" v- }$ q: i7 u8 x) h
            {
- \& U2 e* E7 Y$ X7 X/ d                case '<': /*优先级小于栈顶结点,则运算符入栈*/5 L  n# T/ i# c( W1 F& L1 m! B  O. ?
                     Push(optr,opr_in);8 q4 H9 [& p' \4 ^
                     printf("optr入栈:[%c]\n",opr_in.ch);6 L4 h9 a! m* v* o. T
                     c=getchar();
8 G+ ]# D8 d: C( n2 Z                     break;, X! v5 b* P) p: c
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/3 ^( `: a/ I: V4 [. _) G
                     Pop(optr,e);
: l( W1 {) h9 y* d  g                     printf("optr出栈:去掉括号\n");
+ G+ S2 I# S& ?/ I- ~                     c=getchar();
; u( o) R0 M2 P                     break;6 A+ g" B, H1 ?, K
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*// S3 v" n3 _% ^( r) e- p6 J8 D
                     Pop(optr,opr_t);
4 W$ B2 @# D" X+ k$ {/ r                     printf("optr出栈:[%c]\n",opr_t.ch);' L8 ]- |- ^  S$ {5 W/ E* u
                     if(Pop(opnd,b)<0)2 O3 Q# S5 N% c3 Q+ V: l
                     {3 X: B6 V+ \2 ?+ ^: {( Z
                         printf("Bad Input!\n");
, m2 H8 }; v6 W; g! R                         fflush(stdin);
6 d4 e0 r1 h9 v$ z; ^8 X$ j                         return -1;
; |* ^7 v% K/ H# P) ^6 |+ K3 |0 M                     }! |. O  T, a" N& a! b& [5 Z
                     printf("opnd出栈:[%f]\n",b.data);1 J9 h: P$ D7 v5 B- z0 A
                     if(Pop(opnd,a)<0)
, ?! m' v; G; \  `, A# G* S& ^                     {
6 j1 M$ Z* O% N                         printf("Bad Input!\n");
, z, g  d7 _4 L1 r! L) S                         fflush(stdin);
0 ?5 a8 i# r0 U% O2 ^: k                         return -1;
' w5 w, o) G5 P8 w( B                     }5 }! i  c# |$ E$ F) Q" o- ]2 [
                     printf("opnd出栈:[%f]\n",a.data);) \1 E2 a; K$ g1 Y4 z* S' U
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
: y9 n* ?& U9 W8 x( \4 k6 p6 \                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; u. R3 j0 \: s' ]3 x3 j3 t                     printf("结果入栈:[%f]\n",opn_tmp.data);
6 {4 ^% k& k. |                     break;
* q* y9 _! r, V6 u( e: j            }
0 y" q  n+ f7 g) K2 D, M6 S8 R        }
1 |) b7 V4 |5 V0 f3 H/ h        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
& t  C4 O2 s7 u" M) S5 u4 |3 r# _    }" m6 P( k! x- t9 f. O. s9 u- y
    GetTop(opnd,opn_tmp);2 j% X( P1 [" c! s
    DestroyStack(optr);* P( _! P8 o/ j1 A" d/ r
    DestroyStack(opnd);
* \6 M" y3 N, R* g2 c* d" \* F4 }1 \    return opn_tmp.data;
# R3 K1 ]5 H1 s}
% c3 h, f3 t$ O5 {- k# v2 P2 K% U" p5 n5 w0 g& d
char *killzero(char *res,float result)* ?& I, G  u7 U2 k
{
( N! w' k  v1 l! [- B2 C' g    int i;: X; t( e% i2 n7 l( m

- c+ @  O6 z; I' Q. L" w    sprintf(res,"%f",result);
6 t+ M, K& K8 O5 y& r# y+ [    i=(int)strlen(res)-1;- ]5 E: ?' T8 b
    while(i&&res=='0')0 W7 V. b0 s7 B! F2 i0 H5 X
    {
/ k& B# X, T" z* k6 B        res='\0';
: d" ^4 H( K/ m+ x+ ~; p; Z        i--;. m! ]; O6 f/ i; Q
    }
# e' H6 {) F% b' w2 m# {    if(res=='.')( v! [: G6 K1 f$ e% t) E: [0 H# n% f) m. E
        res='\0';
9 V. Y' `* ^" v6 J0 D$ w    return res;' N* g: _# Q+ ^# K  s
}
( a/ H* B3 i$ {. H% i* I1 C
: k% I# M5 k/ h, L, S2 o( sint main()! {$ G4 w9 F$ y- X# I- F
{* n6 x, |; Q3 O% _
    char ch;6 K; c4 P9 O9 t7 q$ w
    char res[64];  ~) A9 j7 G) x
    float result;
' D3 Z* j+ M; I1 O" [: Y) `    while(1)5 k% n) z3 j0 N7 f6 R
    {
/ ^$ W3 v" S4 p$ p0 a* N8 I1 J- l        result=compute();' c9 n# o2 r5 n& l$ z
        printf("\nThe result is:%s\n",killzero(res,result));
$ R" U, J8 g9 r7 S; H3 v9 f        printf("Do you want to continue(y/n)?:") ;6 _& C. s- _* L6 K1 U& e! m
        ch=getch();
# x2 a9 i2 K+ q/ N) @2 D4 ?0 f# W        putchar(ch);" K9 P' V+ q: p7 v
        if(ch=='n'||ch=='N'). X: c+ [/ v5 S9 b* i: `
            break;- q! }" U. `$ h+ i
        else3 Z& _* X8 Z7 Q% A* R
            system("cls");3 f1 t1 l  [6 [, Y
    }
. P0 n; @- d: ?9 {    return 0;
+ A' B4 ~0 X) ~. H4 @" ]}
0 }2 F% ?8 J0 X6 c

1 R( K1 h6 P9 w) m/ K( Y# `! g0 V1 A* h$ I[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

返回列表
【捌玖网络】已经运行: