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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
% V& H8 q+ p, {! `- h. a程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=$ K# b- x2 Y, `4 |4 {1 b% {
/**************表达式计算器************/& m- d0 Y5 M3 {% X' \# E& v. N: V
#include <stdio.h>9 v5 d0 g1 m8 _  }6 O' L5 ^; {
#include <stdlib.h>9 p1 S3 k9 n. _6 V
#include <string.h>9 b; t# x2 @5 [9 z# [) B, a* C" k
#include <conio.h>
5 s9 U& f$ S9 E2 r! o2 L% g#include <malloc.h># f+ O  Y0 [+ w/ r
* n# P9 [$ k8 y0 Q, X+ O7 q4 c
#define STACK_SIZE 100
! }. m5 q" M* C& j#define APPEND_SIZE 10
2 ]) B3 ]: g2 d3 M6 h
+ j& o5 i  l3 y! R6 zstruct SNode{
: R6 m/ x. L" @5 N% p    float data; /*存放操作数或者计算结果*/
9 d3 B: |4 b2 u2 B7 b0 |    char ch; /*存放运算符*/( S9 Z! _( x$ v$ r. h6 s3 n5 `
};
! _; C- M( r/ u# ?
3 w' \8 K2 f9 _5 D1 B0 \* jstruct Stack{& y1 P" g$ N6 _  ^
    SNode *top;0 T1 D2 v/ V5 b% G$ ]
    SNode *base;8 Z# ~. e' l% t9 q% S1 ~3 X. ]2 [
    int size;
) g: j: v/ Y) a- ]9 q; L};
: u& |' E" b, L2 H- z) D
, ]& z+ x+ I- x7 O( L/*栈操作函数*/
/ `' }7 ~+ D+ t6 Nint InitStack(Stack &S); /*创建栈*/
0 Z5 f, R1 w6 ~3 A/ j7 R6 iint DestroyStack(Stack &S); /*销毁栈*/& ]2 j5 r% v+ l! h; M# n( o
int ClearStack(Stack &S); /*清空栈*/
3 C% T7 \( _) p3 c3 _6 G  X2 Wint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/" G% t2 O4 {2 _: l- h6 w8 ~% Y/ U# }
int Push(Stack &S,SNode e); /*将结点e压入栈*/
4 l. t! N9 p% `1 V+ eint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/7 K* b  f; o6 [/ Q# K8 o+ t
( z3 T# u" x6 Z7 m# Y, |  b" \4 d
/*表达式计算器相关函数*/( n+ o6 T  a5 I1 i+ @
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
  W4 B4 P1 Q) q! [2 H" m0 T4 zint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/9 v" [) T/ {# F5 u' e
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
; p6 @, R0 k2 x( }& Q8 _0 X4 Xfloat compute(); /*表达式结算器主函数*/1 I/ Y- z4 v- w9 M+ J
char *killzero(float result); /*去掉结果后面的0*/ 2 R: b/ G7 j! f" i8 r: g
2 r" P0 i9 N2 ^4 o! E
int InitStack(Stack &S)8 M7 Q+ \  W2 J/ b. J/ c
{4 P4 q$ {% {+ R8 k8 i" @
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));; J; B  l! w$ [! {9 L- D! w& Z' Q
    if(S.base==NULL)
( ?! \6 b7 |2 x. U: s; G/ o( b    {
& d) L# m! r+ x# D, t4 h$ ?        printf("动态分配内存失败!");/ O$ F' m; O. j* G
        return -1;
9 ?/ {: \9 z  ?4 j5 v/ k    }
9 U3 D& g, U0 Z9 _  @, k    S.top=S.base;
2 z) C/ }" \1 Q9 m0 n+ m- M    S.size=STACK_SIZE;2 o2 \( \5 o; `, e8 O$ a
    return 0;' Q$ C+ J1 s! d: g1 p0 R/ _
}
' a1 L- f1 k- _% |  S+ T4 a1 J5 X/ T3 R0 r. g# D
int DestroyStack(Stack &S)
# J# d2 Z7 o& n7 C2 R{
  Y' y" e+ u. I# N. W    free(S.base);
1 Z' ~3 M/ o" w+ h    return 0;
& e: U$ T3 P+ E/ W& I% ]9 W}; }* ^( ?2 d7 z7 U! d8 F- i

( o( J6 p5 P' U; V$ r+ tint ClearStack(Stack &S)
9 a3 F% B1 U0 L' T2 Y{' D: z6 b1 f% @
    S.top=S.base;
% g# g$ T& X7 N  B# @9 |2 {    return 0;
7 A2 N+ G3 N5 j- N/ }: X}! B2 z- @5 s0 @1 T! {, }
+ I$ Z3 S, l3 A! B( M2 W4 B4 J, l
int GetTop(Stack S,SNode &e), P  ?6 `& C8 u6 W0 i, h
{, @5 k4 Y  t3 z& J8 O4 V
    if(S.top==S.base)- J4 d( t) R1 ]  V# o
    {8 l! W, j; k0 a2 G2 G% z! Y  T
        printf("栈以为空!");9 H0 I7 i# c8 J1 W+ c0 R  y
        return -1;
9 J- L5 w8 W, Q    }0 d3 _" n$ h9 ]  j* b7 n+ X
    e=*(S.top-1);) K+ j6 ]% [! N0 d& u
    return 0;5 K% [1 Y* _+ r9 T
}
( i$ H. p6 V% b  f% ~5 u# M# h" ~: o/ D" V) o
int Push(Stack &S,SNode e): |9 _; M, S6 ~, ~; j8 K: D
{- J( {, x! P- c5 G: C# I7 E1 Q
    if(S.top-S.base>=S.size)
6 U9 y, m! \2 K3 ^    {. @# L. r7 v8 d
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
; p9 W! V* [( H& t6 [        if(S.base==NULL)$ }  a; I0 Z! d* Y
        {
! X4 {1 i$ m/ {7 g1 T* Q4 G            printf("动态分配内存失败!");9 P; `3 J' y+ ^+ [; ^; M' t/ c7 I
            return -1;  T( W% J: T# ?3 L' s
        }
4 b) A+ p+ E1 \9 V, e- q7 I! F/ ]        S.top=S.base+S.size;
1 k; |$ n: p# Z( n7 l6 |        S.size+=APPEND_SIZE;
; D$ ^/ r( X6 W7 z    }& x( f& v" D, \8 b, `6 f2 ]
    *S.top=e;
) L6 H5 b6 m! W+ m- _( K    S.top++;
/ t: p1 m5 a9 J    return 0;" C! e& [. H+ t, _5 J7 Q( q
}
3 F1 I9 L3 y  E8 U
9 j5 W: V7 i8 |) S! R( B: ~! g5 }int Pop(Stack &S,SNode &e)) w, o. w) j* r$ E3 W
{; Q8 c: x( \- Q5 c0 A
    if(S.top==S.base)
. o) A/ X1 H8 D, j; F* Q8 M% N    {
3 h/ E) ~( {! V  C        printf("栈为空!");
' g0 S1 e8 q  y" F! m- H# ~) f1 J/ d        return -1;
" g3 O% s2 X: k  h7 `    }
9 Y7 ?: _, \' R6 V0 M/ D    e=*(S.top-1);7 t$ l/ b$ w+ u: w5 I
    S.top--;; Y* ]8 T! R3 S+ g5 _/ E
    return 0;  N. P# o6 o5 a
}
: T* g. C+ F+ _; Y% ^1 G' E$ N! w- p8 D
char get_precede(char s,char c)4 u2 @, K$ ?& s" ?( z
{! P* Z3 L- h  \; u
    switch(s)
% N5 m0 O) Q8 P: {    {
# h7 |: `9 n' X) s9 y0 X        case '+':                 
. j9 ^: }) V3 q9 K# S: B        case '-':" M1 M- \. ?& x
             if(c=='+'||c=='-')
0 ]% c' H5 m/ o6 t                 return '>';0 e# \" z& S, [4 I3 }
             else if(c=='*'||c=='/'). o, b; g4 g2 P1 W7 A) L: b, S" u& @
                 return '<';: a: X: ]$ P2 n% S( `2 ^
             else if(c=='(')$ W" a2 m  @7 P- f
                 return '<';
8 x1 ~+ V5 G5 U/ F8 H; K             else if(c==')')' h( Q2 L- {# \  V0 i' ?
                 return '>';
+ |4 L8 ?* A3 B7 }+ T9 ~  ^: S             else 3 P8 J8 y2 I8 j
                 return '>';  |: M- d! T8 E4 ~
        case '*':
! t$ S( ]8 h! g        case '/':
3 F' }+ R* v7 O( e8 B+ _             if(c=='+'||c=='-')
" w( ]- \9 ]9 D- i( N/ D3 ^& L                 return '>';
& N, G, B& q5 \8 ^             else if(c=='*'||c=='/')
" @4 j+ L1 _$ M8 b" q) @                 return '>';
7 e" Z. F4 N# D- d, t             else if(c=='(')  p( R( u  e: X3 s4 b
                 return '<';
( Q- T+ o- V# R' e/ Z& ~             else if(c==')')% B# D* J4 _: p1 o/ Q4 L9 @1 C6 a
                 return '>';
3 W6 ?4 [0 |9 J# H$ ?+ x             else( k$ d" v. H$ T* a. X. V
                 return '>';
* a5 Q* G, Q$ R! g9 A) G* P        case '(':( O2 O$ ^/ t: }; U
             if(c=='+'||c=='-')
* v  n2 I4 _. F% O                 return '<';5 s% \. K; F3 F" S8 R# e
             else if(c=='*'||c=='/')
$ z4 y+ k7 t" c6 Y" p                 return '<';
+ x& Q# ]* e) i; U8 S             else if(c=='(')5 \; B# b2 J' h+ E9 y/ t
                 return '<';2 {$ j* K" \* O! u# X" L% d9 |5 n% u
             else if(c==')')" Y+ Z- i4 f. X! E$ l
                 return '=';9 f/ Z" o" |* }6 Z% b& R
             else
6 K9 D7 x" F' H) ?: ?8 p  l9 E                 return 'E';- Y3 M4 r) y9 E
        case ')':
' J( V+ N! B) h7 k             if(c=='+'||c=='-')$ m2 [) G9 I* K
                 return '>';
" h  n6 _; e+ u  y             else if(c=='*'||c=='/')2 R! N+ b  P( M) V
                 return '>';
; m; {* o& S, l! B             else if(c=='(')+ L- \5 Y8 @0 {4 ~/ J/ p) @
                 return 'E';
+ _9 N6 U* t/ ~4 \, a3 L             else if(c==')')
. k7 w; I: n1 S1 C: k                 return '>';$ R) w# I- g. @' w  }
             else
% C) `8 [5 _  T  }- y                 return '>';3 L8 g5 X7 I* G- n
        case '#':; ^8 ?* K" V' f  j- {4 x3 K
             if(c=='+'||c=='-')  ]: W1 P+ V" R& K3 o
                 return '<';
7 I8 \0 o3 V! d& {9 @/ _             else if(c=='*'||c=='/')* [' h1 e9 I( J/ {
                 return '<';# L+ o$ C4 U& s, e0 [# K: ?
             else if(c=='(')3 M' q9 e3 {; I8 {4 ?
                 return '<';) |7 t% E; d, L1 j
             else if(c==')')+ T! [2 B) f7 Z
                 return 'E';9 z+ v4 O6 A6 @9 B! f/ Q" Q0 o
             else- E' n" a; f0 w3 G
                 return '=';- g4 S8 @- e- ]4 j  L: Y# T2 ]
        default:
4 K6 m- `! f# ^, W& B7 t  _' a             break;
& S/ B8 L5 {$ `6 W* o& d    }; j, Z1 j$ L9 z) ?' ^* x
    return 0;   
6 y7 d. |$ ^2 `5 Z) b% ~2 {! M}+ w6 t; o7 y) d4 M  i, c6 |2 {$ i

) H6 \4 N2 r2 c4 c2 W( Q! v3 `% kint isOpr(char c)/ l$ R5 C2 c3 x- X( l7 U
{2 l1 o6 L' X) m8 c0 i2 r
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')6 [( \! J# H7 w: E5 T, r5 t
        return 0;2 p1 w7 A- J3 [, L4 C
    else
" b( {# z& O+ x0 h* ~& A        return 1;
& b- X9 e/ W/ Q! m3 ~% z0 U6 I}4 b! F5 A0 s" [( m

' B+ M& Q8 ]/ `2 r* {' H/ N: Zfloat operate(float x, char opr, float y)) T- D( I. Q+ e  o" t) b. x
{' i; f* C, P  X
    float result;
) O, s  y6 v8 q; @1 x    switch (opr)5 k8 F' u5 A! T2 Y$ ]
    {
0 D# l$ y: N+ _) [- D        case '+':
6 ~. i2 n5 j% ~             result = x + y;
8 ^$ n5 W" Y- C" N- D) A             break;
5 `2 p! e* A8 M9 J: a        case '-': " p( f9 f  \: N- s
             result = x - y;( q' a9 `4 L1 w- ~& z( l4 [! K7 z
             break;& W" a' v3 a! a" p
        case '*': + j8 d  `2 X9 U% M+ v. V6 z( l
             result = x * y;
1 o/ s" N( ^: |8 U: S2 u' F             break;; E- n' _$ t) q% T/ c" c0 |3 w) C
        case '/': " z+ Z6 [( P( a& Y) V" a
             if (y == 0)9 s* v& k( k: w' F
             {
! Z, K" Z, v: o2 }* `  t$ L                printf("Divided by zero!\n");
& `" I1 Q+ r2 i* v) W                return 0;$ s* O1 J, ~6 J" @4 \/ a3 R! f$ z
             }
! e& r4 R4 I& E5 H4 |! X             else
* Z% w' L: n1 x7 F2 l% D             {! u  P: u! r+ d0 v; _
                 result = x / y;
0 a* _; P7 [) ~! n2 o                 break;
2 `" c( ^( |/ y8 }1 {$ R4 |7 l7 r             }
+ B6 M8 I0 q6 B/ Q/ q, U+ o& U       default:
$ U% R% D, t) B2 C/ y             printf("Bad Input.\n");
: u. B1 D' w5 G- l9 {& R: i; P+ u  u             return 0;* v- N' }* [) J7 H; Z: K8 F- W' R
    }
% v& q: m4 R3 t3 G$ P6 C" f    return result;
& L& A5 P2 F* w2 a}      \& w& S& }" M
# X, C8 d! u2 n# g* s: O
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
, W5 S0 h2 B# R3 x{
; p: V1 W- \3 F% c    Stack optr,opnd;9 }  f+ S$ r; G9 M" y/ k
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
, U$ _1 u% l' }  N( h2 t    char c;
3 |* V, W. @: F( C- W6 n    char buf[16];/ X2 {1 `' z. {* X; v" V, G
    int i=0;* _6 V( i8 o2 P; s7 c5 H
    ! b! E3 N7 L: \; d
    InitStack(optr); /*用于寄存运算符*/
2 p( z. ^: C( h+ B4 O    InitStack(opnd); /*用于寄存操作数和计算结果*/
; K4 W4 `$ u5 c' Y    memset(buf,0,sizeof(buf));
8 ~3 U8 I/ H+ F  y6 ~1 `   
; S$ I' {7 i% m( S, W    printf("Enter your expression:");
0 d# a% H4 [' W- f; `" e        5 M  @% C. r4 [, I- a# s
    opr_in.ch='#';+ E+ k3 W8 g# s2 q. c$ L
    Push(optr,opr_in); /*'#'入栈*/) r# ~: t' X% G$ u8 X
    GetTop(optr,opr_top);3 |3 E$ y% j2 n  g
    c=getchar();
+ H1 d) i0 M7 D1 u* L    while(c!='='||opr_top.ch!='#')/ b& P6 ]" f$ d; x8 k
    {
# L5 g9 J. ?' h4 D8 h+ @        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' E/ T8 u' j4 i- ?+ H6 v% N        {% `# Y: h: n* M* ]! v
            buf=c;
& c; h6 ^$ T: J* P# @2 T            i++;% u/ P( y1 D& x' z# j# E
            c=getchar();
- P3 y1 x* y7 Z' x: o        }
' |$ o2 v, M1 ]        else /*是运算符*/
& ]0 F+ y5 ]3 P/ O, n% X2 Y. ^2 P  j        {  i1 P3 h& V) @2 ^8 \
            buf='\0';) p6 q, T: t) h
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3 U- R+ x- |0 x2 i. X
            {
$ s) E8 d* {/ n- l1 J* _                 opn_in.data=(float)atof(buf);- `+ R2 [8 ]" z0 Z
                 Push(opnd,opn_in);4 g& D9 ~5 P, F7 y* f
                 printf("opnd入栈:[%f]\n",opn_in.data);
. E$ h* |/ n6 D+ V: e$ W( \' H                 i=0;
  Y* w5 R' C. w5 ~                 memset(buf,0,sizeof(buf));& @5 |4 {% |8 l  l) p7 M; q& i
            }
; W. z) O6 [1 p- p  p. e) O+ v: T            opr_in.ch=c;$ F# _9 ~- q  k  ?  Z1 f" c
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
. ^, Q- q( U4 o! o( g            {
! M  A% L$ {  j1 M% A                case '<': /*优先级小于栈顶结点,则运算符入栈*/
" u; ^4 G3 c+ v                     Push(optr,opr_in);
5 M% n3 a# \& a$ W7 V                     printf("optr入栈:[%c]\n",opr_in.ch);  K- I1 m) e5 A! ]
                     c=getchar();3 I: u, p# }6 `1 F& ^& B
                     break;
6 [3 d- f. O& a# |                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
( W  g) M4 b3 M' h3 T( f2 \                     Pop(optr,e);! f' h$ M: d0 q& H4 n" R
                     printf("optr出栈:去掉括号\n");' U% x3 t% B. c4 Y( W, u
                     c=getchar();
# ]( H1 ?$ }$ U3 X* _6 t/ z                     break;
9 Q5 j! ?0 f, F% \, V" _% u: B' I                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/, A: B, D  d1 z2 r9 b4 c& O
                     Pop(optr,opr_t);3 c) ~1 q+ [5 ?
                     printf("optr出栈:[%c]\n",opr_t.ch);
: I% R& O% ?( [& f                     if(Pop(opnd,b)<0)" z$ n( L5 z1 [8 M
                     {0 W2 D3 o* i; ~  s: k
                         printf("Bad Input!\n");
: K8 Z, ^/ g- D                         fflush(stdin);5 F4 A/ E. @& F4 t6 g
                         return -1;
2 u3 I' _6 B: ~- G! a; Z5 @1 I  l                     }
' }4 L+ z: J1 p/ \                     printf("opnd出栈:[%f]\n",b.data);
  G4 K& F; T9 j% R, a8 E7 J                     if(Pop(opnd,a)<0)3 N: Y; g' z; T% q2 S; a. o
                     {
+ C% b  ]) z  |' c                         printf("Bad Input!\n");
0 Q2 y/ R& F+ A* N                         fflush(stdin);& W+ B( q& I/ r  e2 B1 m8 `, I  B+ i
                         return -1;
0 Y. h+ ^7 R( e" M% u6 z                     }3 h. V7 n5 ~! J  b% [. w
                     printf("opnd出栈:[%f]\n",a.data);
. M8 ]1 w. J1 f! D* T                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
' I2 {9 N& e4 k) D# ?* f                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; |3 i  K% ^( p. s3 |# ^* q2 E% P                     printf("结果入栈:[%f]\n",opn_tmp.data);* y' i  V7 X3 @) P9 f2 H$ \! m
                     break;6 M7 z; w1 u( H% n2 T6 v6 D: S
            }/ T. d% o$ I1 u+ D9 N% B
        }
. O: l! S8 u3 W6 m* M& ^        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
8 {3 \( x  A4 O' e: P    }
, N" C  a9 A0 V) G$ ?6 ~7 e3 ~. B    GetTop(opnd,opn_tmp);" [( w. y: |$ Y9 f% b$ ]- k; _
    DestroyStack(optr);
5 V$ X$ n/ }* ~7 l; M    DestroyStack(opnd);$ j0 P$ K$ k; B
    return opn_tmp.data;9 A: n( G- m; y( a2 {# e
}
+ W) e! }1 P3 {8 L* H
1 K* ^0 B/ i3 i% A+ hchar *killzero(char *res,float result)
& }% l) |" x( q  Q7 }{5 h9 j. A  K. a% g* c
    int i;+ o% J1 b' ~$ R, ~) g$ `7 ~4 H; S' i4 s
  Y0 l- J3 z; }1 K
    sprintf(res,"%f",result);( V# G  z4 b' Y9 h. }3 ]
    i=(int)strlen(res)-1;
8 M; [: U. p% L0 Q- L    while(i&&res=='0')
' W7 l  @# A& ?8 B( J* G6 `    {
6 f% r  [# b& ~8 \: V        res='\0';3 \$ V# `# ?% `9 B3 c
        i--;- P; [2 s5 a' M0 c7 b! d) g0 _
    }! a$ l7 [# {; ]2 r8 y5 y: s% B
    if(res=='.')
7 D% A0 @4 V1 R        res='\0';) |# ^1 o  M1 D6 s
    return res;
, r: I: S- d. O$ O2 g}
" e! \- P& g% t
" o( }" {. O3 F0 }- L/ W4 o2 g: g# vint main()
7 O5 @4 z8 S( e; E0 \{# l# _, K9 p5 {: x
    char ch;
% P8 {% W7 V' h3 p$ S# ~0 C, m7 F    char res[64];* v! C; ]0 z+ g, ?
    float result;
% S6 p; G7 g. k    while(1)
% C" G' ^0 g3 I! f3 T0 k# V    {1 [: L* O+ r# A: u
        result=compute();
3 ]  }7 ~# j% W& F* X        printf("\nThe result is:%s\n",killzero(res,result));  H% ~/ c1 o$ s5 z+ f& Q
        printf("Do you want to continue(y/n)?:") ;
+ |6 h0 X" i3 f' Q0 b        ch=getch();
# H( K  Y+ p! z1 ]% t        putchar(ch);
& C  f2 t4 ]3 |& B% Z        if(ch=='n'||ch=='N')1 _2 D9 n+ B! M+ j4 _
            break;$ s+ h" m- m  V- _0 C4 W9 [1 f0 ?
        else
- P' q/ u0 X+ b' J( M            system("cls");  S' v! h! U5 T
    }. Y  `) H2 _  y/ ~1 X  ]1 \, ?
    return 0;
6 J3 Y9 R  ^+ T" [' p- c}

2 r, W: D# r: c- r# g) e$ n, W( M2 [& r1 J) z
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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