返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.0 N1 E2 D" A# S1 U/ m8 V
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=, d) d# F, t" K2 W2 Y! e& G: \4 j
/**************表达式计算器************/
6 S- ^  r; ^" x2 I1 u0 T! D- m7 S#include <stdio.h>
* Y# t3 ^( d5 `. P( \#include <stdlib.h>
4 @& h4 p$ d5 a( v, {# Z$ B- `#include <string.h>
$ q- |* k* L3 A4 P" K7 K7 d#include <conio.h>7 J* r8 s0 E  @8 J/ `
#include <malloc.h>/ ]3 s  N. D+ \# ~* K

4 T5 |, {/ s* e5 `. K8 Y#define STACK_SIZE 1004 \# e' L* u, v
#define APPEND_SIZE 10
3 |: Y9 ^3 d0 B0 G5 g$ O3 I, ]% l) p( f6 e; P& H$ F
struct SNode{: e/ ~$ n1 B' H( M" [) ^
    float data; /*存放操作数或者计算结果*/1 G: b* }. \' k5 F) i- G
    char ch; /*存放运算符*/
# {# }; ~+ {; t6 i+ m5 z9 @};
2 Z9 O+ K( \" P( c3 d. k  L
" ?/ X+ q5 t' l7 estruct Stack{
2 e: C- e7 ?# f4 ?! ~% d; @    SNode *top;
9 l! Q5 y9 ?! l& M    SNode *base;
. r: v5 E3 Z' i( v& h6 F    int size;9 {: N1 j5 }4 N1 J2 M+ Z, I7 M
};
3 F+ h& C; ~0 C! G( ?& D2 ~0 Z' I( m0 |% ?5 e# n4 M: J
/*栈操作函数*/7 B- I, N  ]( m% C/ x0 k
int InitStack(Stack &S); /*创建栈*/3 M5 y9 G& }- T8 N
int DestroyStack(Stack &S); /*销毁栈*/8 Q( N$ z3 L0 w+ E" P. J3 b
int ClearStack(Stack &S); /*清空栈*/
% p$ ~  b6 e9 ?4 Mint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
1 j1 u" Y5 F2 |$ p$ N" J! [int Push(Stack &S,SNode e); /*将结点e压入栈*/# A6 j2 j' C0 U) Z
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/7 {1 K( F$ q; R$ J9 A
  a; M- A0 A3 n. ^8 i- i
/*表达式计算器相关函数*/
$ Q& ^3 ^; T* |! zchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ u5 C& M! w& bint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/8 G) K  G7 j: F9 v$ @- g8 M# h: j- z
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/  E8 A- C9 f3 {+ ]5 x
float compute(); /*表达式结算器主函数*/; L0 Y0 c- K( [: Q1 G
char *killzero(float result); /*去掉结果后面的0*/
  F1 ?& R3 v* y# x3 H+ e( ^, }4 ~7 x" d1 L' U; K! g8 y
int InitStack(Stack &S)
% z4 Q% l$ E: H  J. n{7 ^) Z+ G, f; r5 Z0 Q& h- n
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
" T. ]% `3 }6 Y6 e6 k* n) N8 E3 Q    if(S.base==NULL)
, m5 R- I( R  Z  ?0 d# Z    {3 E3 o* h; q" w; L; ~* J2 W
        printf("动态分配内存失败!");
1 u# [, E* P3 e' j        return -1;, m9 C5 j5 @1 l) M7 Z0 @+ F) R
    }$ [8 K! ^9 P2 g: H5 T) d
    S.top=S.base;( K- L& t9 W$ F  r4 t+ Q3 ^
    S.size=STACK_SIZE;
" E6 P: C7 i* F% d& u( w& ]    return 0;
, P; J% k) t" P: _0 r}
: j* P  I( W. q7 e" H- Q! i) i' @8 j4 z) s, N$ ?
int DestroyStack(Stack &S)) n8 e% r% ]- i5 T. Z4 \' K* s: S
{
- V( R/ J' E/ o8 U4 D; q  r    free(S.base);2 F0 L" S% @) i4 [1 H9 K
    return 0;7 j8 ?: Q6 H+ ^9 }- F
}( H! |+ F. x1 ]7 r' D

  Q. P5 O  Y% L8 `int ClearStack(Stack &S)4 h" p( _% y3 m: K8 |
{0 t  S, s$ X; u% t& u
    S.top=S.base;; X; H' g% R7 G  X( `$ }- A) R
    return 0;& S6 V, i; E9 w2 M8 T  b
}
( H5 U8 _3 z1 G( R- J. }& D. _9 K2 H& k' R2 M' U' x3 v4 T; C
int GetTop(Stack S,SNode &e)
# }) _# |# Y% [0 b- z& A{* }9 E1 G3 T& W1 n: [
    if(S.top==S.base)
' n: Z) X+ e5 q. W    {" T- J) K9 u2 W' H/ p
        printf("栈以为空!");4 h/ k# v5 ]/ B* `' m. l# W' \
        return -1;+ m8 O/ r- u) [0 a0 W! m' G; \
    }
, U4 ~" Z  G7 r% Q; e    e=*(S.top-1);" ]5 b5 M6 h2 B5 b2 C
    return 0;! r3 I$ e. Q. l7 n( c( M! k; E3 I* _
}
3 D' B7 G0 B5 i; E
) F1 S/ w! s& e' ?- r. oint Push(Stack &S,SNode e)3 W( j. N$ S9 X
{$ p0 d8 u& [" n+ X$ g. _  s
    if(S.top-S.base>=S.size)2 G  \8 J, a- P
    {
5 k$ T; H/ W7 T8 y        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));  r: F9 E0 \" _/ ^" S
        if(S.base==NULL)
9 S& k5 E0 N8 F& ^1 k7 M5 v- N        {
" R- q7 |4 p2 i3 {/ }0 R. j            printf("动态分配内存失败!");
: k/ j9 _9 r2 ]5 D3 |, k            return -1;) j- U! k3 k% r
        }) O4 v0 L: h5 O* u) v$ A# C3 B
        S.top=S.base+S.size;0 z& U/ |4 _$ t8 g. Z% G! v9 A
        S.size+=APPEND_SIZE;
9 y. x6 n; {* p6 T9 k! m) e4 Y    }
: f& T8 e8 H4 S    *S.top=e;
' L7 v$ z" u5 B& y7 M  Z    S.top++;
1 ~% Y1 L9 x- c' a# \: X3 W5 |    return 0;
& g- q. X: b0 H% v}
! l$ @6 i7 d: I; Q- R, F" l
1 ]! [/ o; m. ^' r3 ~int Pop(Stack &S,SNode &e)
1 Z1 L- k* N" z/ S{7 j; G& {5 D- a: R
    if(S.top==S.base)
. ]& I! F4 y" m& R! \    {. o# r& m$ \. t
        printf("栈为空!");( ^9 }0 M- f, b; }1 U9 D( M
        return -1;9 i, E$ u0 `" d, e7 m' {
    }) K8 o/ Y: b& K- a- F
    e=*(S.top-1);
- X8 O8 R4 ?, M    S.top--;6 g/ h" c; r+ C  F
    return 0;, Q; f6 i- |# y$ w
}
2 W. Z* C6 S; z& I1 T: m0 b; f8 K
- l% g4 K- a) J$ K. rchar get_precede(char s,char c)
2 z$ W1 Z5 z7 u% _  @/ S{
% o" m" d. d: l  l    switch(s)
2 a2 [7 q. H# A9 ~8 {    {0 W3 [9 a! p/ B, @
        case '+':                 
7 r2 a" y- Q6 {- B% v        case '-':3 f" z( L' D$ L+ a4 u' q
             if(c=='+'||c=='-')  v+ d; L6 F6 b2 o4 W; G! N0 r
                 return '>';( r% p1 y! j$ _$ e9 R
             else if(c=='*'||c=='/'): d( f3 z8 p) r( S+ g, G
                 return '<';
/ \* y& q' j' F+ u             else if(c=='(')  D4 a/ x4 m6 L+ J0 B2 i2 Q
                 return '<';
: @0 `& f5 g- _4 w2 ]1 d             else if(c==')')
9 v3 v# [- z% y) K: R8 {1 W# S                 return '>';9 X9 F  [( g! E; M; g' E
             else & ~% l3 J0 |$ \3 B" q7 b3 F" k+ b
                 return '>';7 L- E4 T6 P7 d5 E& d! l
        case '*':
8 z0 \& O, @6 H8 l: j9 z6 y) ~        case '/':/ S8 D4 k3 Q5 V7 q* k7 s
             if(c=='+'||c=='-')2 D! f  b" [: N! z6 X9 {
                 return '>';
( N  R( V. M0 L( D$ Z- E* m- W             else if(c=='*'||c=='/')( G9 Q; p0 C" f5 D6 u/ m8 i* q5 t
                 return '>';9 X9 N* G& W+ i0 Y
             else if(c=='(')4 r" s, [0 B: O% }
                 return '<';0 H9 j# Q1 X% B; Q+ b
             else if(c==')')
8 y' ~( w' g. \( p3 l                 return '>';" J9 y& o# m' {0 V: r# m' p* \
             else
* @+ {* h2 L$ x2 T                 return '>';
- p. D8 Z+ q: h8 V. x$ h        case '(':1 V" [5 `% N- i: Y: p/ d2 _- b
             if(c=='+'||c=='-')1 U/ S" n. }. M3 p( h- H. }% k$ V# v
                 return '<';
! ]6 A8 y% V% x/ B+ k             else if(c=='*'||c=='/')0 n3 X; Z( f  q. N+ U$ }" I) T* `
                 return '<';8 O: b6 h/ s, J, P2 o& l; b# n
             else if(c=='(')
, h4 ^7 X4 i0 [8 b( U3 m                 return '<';
8 u1 i! U! k8 i1 [/ O& T             else if(c==')')
; A" t1 j) M, s; I0 z1 j                 return '=';
& ?# p$ k- q, L! k# ~- k0 g             else
2 D( _0 K* e( ?                 return 'E';3 {  P' \# a0 D! v4 Y
        case ')':
8 M9 [3 B$ P' {! D3 F* Y( s# ]             if(c=='+'||c=='-')
  q! \1 E" M' ~  ?" Y" `                 return '>';
: f9 U, v' O/ J3 M8 Y9 W             else if(c=='*'||c=='/'), M5 ^& t0 W' X, {0 d0 H
                 return '>';/ N7 n# U: n( I+ o% X$ y
             else if(c=='(')3 c6 S+ ^# K: b0 B" g& J6 W4 `
                 return 'E';
* ~  a3 g/ j5 n8 F# I             else if(c==')')
5 A1 i# y5 p5 q& m                 return '>';
4 r$ n4 ^7 }$ M) M) `9 r! D/ q             else
) @0 Q" A6 {9 `3 i1 M  i, W5 _                 return '>';6 j. G/ m; K! r* f8 P
        case '#':; X9 a4 \0 Z0 u0 [/ u3 C
             if(c=='+'||c=='-')
& V1 K) y0 g3 S& x: K' V! {                 return '<';
/ t# I2 z6 X3 x1 ]             else if(c=='*'||c=='/')& C! Z4 O3 w( N. a; J; V
                 return '<';
9 X9 V8 i# t- y  u- S             else if(c=='(')5 _. A1 U/ m( q
                 return '<';
7 i8 J3 g3 ~8 Z' |. C% I  b             else if(c==')')
3 U$ F' O+ o# h: V: d                 return 'E';
% I$ H6 [% f$ v1 E- [3 \             else
3 o. b& q+ p$ o' y+ ]5 B2 K                 return '=';) }) N9 o$ M9 Q, f! D  P8 d7 q
        default:
; c' E9 I- ^% Y9 B/ P3 z. k2 N8 i0 b$ |             break;
& Q: m2 E6 B0 t$ s! ]8 F    }
* p8 }. V- N) u    return 0;    # Z( q% B6 Y9 m
}( }4 y/ R0 Q- B4 Y5 t

6 [4 ^# V# n( B+ P% O; l; C& oint isOpr(char c)
3 r+ {' X9 {0 I. S{: x$ O- C( \/ s6 G: i3 L- v
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4 P7 `2 F1 P) {/ @        return 0;3 C# ]/ S" @5 o8 g2 q* v+ V
    else $ C2 ~6 `, V6 t1 l4 T7 S3 g
        return 1;
7 u" t: D; X& M) h}8 N+ Q& B: B- ~3 D# x) K
3 e3 W* j6 ~/ @8 O( L* L7 W
float operate(float x, char opr, float y)
# c* n3 A% V, E8 f5 z+ |{
4 W( J% b8 {, |1 b9 ?6 }# R    float result;# E1 K; @: ~9 K/ p
    switch (opr)
3 a; V8 w# P5 Q" J4 X    {2 K. F% N, i8 I/ P& ~
        case '+':   H, Q  V- W1 z" ^& S1 p
             result = x + y;
1 z% @- D) o$ d# ~- y             break;
* t" ~1 g" ]0 _) L8 s$ M6 x) [4 p        case '-':
6 g' K) X* X5 g% H             result = x - y;' t0 P$ n6 s7 ~
             break;
4 m4 O, `$ |+ Q! {        case '*':
; f1 R% [, b& L             result = x * y;$ `( |! n' n! o/ J% i( d
             break;
4 I& z6 a% a( [. |/ \" l        case '/': 6 C. a; }4 f4 V8 c
             if (y == 0)" i1 P# {% b7 O) ^/ @% ~4 s
             {
  G- k4 r0 }/ Q+ y) i# m                printf("Divided by zero!\n");/ y0 S3 d% ?7 N9 m
                return 0;
* q8 a% Y  y3 j0 I1 C5 x( \             }
4 g- C+ H7 F; s: P             else+ Q2 a$ n% B$ F  V
             {
5 s+ U) [# R3 N                 result = x / y;
: ]* ]* x% \# w! r) V6 o* ]                 break;! U# ]9 z5 I% f" T/ t. h
             }
* C# _6 X6 D! d" b( `5 n$ I% G       default: 0 o2 f3 {, X: s& F, p& O
             printf("Bad Input.\n"); 8 M- d0 A! Z9 a
             return 0;
" M; Z8 r* S3 c2 a    }/ G$ k$ d, u1 Q# S6 {; A/ w- R
    return result;% E' ^8 r4 n( ^( \
}   
' H: }* g5 O# A$ H9 W  j. P7 I+ ]/ X' W$ a- p& s
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 D. K0 I, [- U: D  b! X{" e% i" h& d' _1 O
    Stack optr,opnd;) [$ Y/ a1 E8 d# B+ |7 o$ L
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
/ b/ M) c) V+ y" E5 l    char c;
; p1 s% T0 n% \2 j' O/ X    char buf[16];1 v( a% ^) q! C
    int i=0;" I+ _# Y6 h: T! I) J  C2 v
   
5 W$ ?0 f  N: |: i3 P9 j    InitStack(optr); /*用于寄存运算符*/
% }1 I3 Z) W  g! j' N% o    InitStack(opnd); /*用于寄存操作数和计算结果*/
' r* k) B5 g% P    memset(buf,0,sizeof(buf));
" z$ O. _8 h+ H# t$ t    + p/ {8 W' f/ w+ O. a
    printf("Enter your expression:");/ h0 T" y, j- {* }, ~
          T/ V. g* `0 L; q! O
    opr_in.ch='#';
7 ~, p9 h# \5 V# |8 m# K  O    Push(optr,opr_in); /*'#'入栈*/( U5 E7 |5 r% }3 g
    GetTop(optr,opr_top);* w% `7 q  a7 q1 ~$ |
    c=getchar();; P& Q/ A/ s% t
    while(c!='='||opr_top.ch!='#'); w, v. A) \: e% F* _% i
    {  h0 Y) o1 j" ?9 D3 P$ R; f: ]% K
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/  |) U6 w7 ?% V& N! K! }
        {
4 I: {7 u! t' R) r: \: s9 O            buf=c;5 w. U* J+ ^2 k, i
            i++;
7 C/ N2 Q5 L, x            c=getchar();
" ]$ Y8 b: ~! O! v        }, S+ \1 d0 D8 e
        else /*是运算符*/
' y* \. i( e  ~  o+ P/ W        {
8 J2 l+ L* H9 N! R, @            buf='\0';
) X* k6 z7 L7 ]6 g! E            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
; L6 H( n5 C" b& z- E# F            {. c6 Z3 s% [6 [
                 opn_in.data=(float)atof(buf);7 `) ^7 f- B: E; m& i' |
                 Push(opnd,opn_in);
1 T. P, C2 A4 ]8 [! `; {                 printf("opnd入栈:[%f]\n",opn_in.data);" u9 f' B6 n* Q* u
                 i=0;5 ~5 N; u% S+ y7 f/ {; `+ Z: y
                 memset(buf,0,sizeof(buf));
( q' u/ N) C9 B            }
9 v4 v8 P1 y" @- x            opr_in.ch=c;
. ]' y; r& Q0 J& t) H1 J            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/3 C* t& s3 K4 D" ?& X& U# j
            {
. V) v- ~5 ]0 l                case '<': /*优先级小于栈顶结点,则运算符入栈*/
& `- X8 n# b# o, F% Q                     Push(optr,opr_in);8 H! w# Q! k5 @
                     printf("optr入栈:[%c]\n",opr_in.ch);
/ u4 P4 c6 J1 x4 G                     c=getchar();
- O( i+ x- L8 Q$ k0 p2 K                     break;
5 y1 ^/ T; T( M                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
0 H* E- v: a1 u" y$ B                     Pop(optr,e);2 I! G3 O  Q$ w( Y) d2 P6 F' y
                     printf("optr出栈:去掉括号\n");
/ l$ r9 m0 J5 s- Y                     c=getchar();& ]% ]) J) C+ S, S" l, |9 g. r
                     break;
" u* f& g9 J% P: \6 G# k                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/! ?: g) h/ M9 m$ G
                     Pop(optr,opr_t);. l/ c- h% w6 d6 _' R4 P
                     printf("optr出栈:[%c]\n",opr_t.ch);
7 r* Y  [: w: e3 G                     if(Pop(opnd,b)<0)
7 l9 M$ s9 I" s: ^4 k                     {
8 P7 w% l4 m1 l0 G' ^                         printf("Bad Input!\n");  N  ?* ]8 Z( M8 l8 |9 @5 F2 n, i" e
                         fflush(stdin);8 B5 Q# R' O/ {+ y5 v" r
                         return -1;+ p- C) n# L2 }& {0 L2 c
                     }
, m0 g/ e1 S2 `( ?* [8 _                     printf("opnd出栈:[%f]\n",b.data);( O0 L9 r' |# S5 Q" B. T1 e- g& h
                     if(Pop(opnd,a)<0)
) Z' z) E( r7 t% B# z+ F" u                     {
# h$ h. G! {, G                         printf("Bad Input!\n");; A! b$ B3 A! d
                         fflush(stdin);
. F+ O) m/ U( S+ {  p/ ^- W                         return -1;
) g  e6 s0 C" ~$ @3 f' s- H                     }
0 E& l/ F: B2 N! w$ r                     printf("opnd出栈:[%f]\n",a.data);8 ^5 x* p+ l) X6 m1 }- i3 h3 }
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/. Z3 @) H6 w" _, {; r, k
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/  ]5 R, Q0 g: o+ C" l
                     printf("结果入栈:[%f]\n",opn_tmp.data);
' f+ m4 j- o+ K: W  _$ o2 i! S* M( s                     break;
, [) F7 A6 p% r' R# V4 Y            }
* K- T; ~; t4 G6 ^6 f        }  i3 d% e; Y) l1 U
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                + l4 C# o0 [4 d0 q3 I) L" Q
    }4 t6 M6 ^6 U) D" h) v
    GetTop(opnd,opn_tmp);
, ^* c1 O) R. V8 L2 @1 X    DestroyStack(optr);
: X2 x$ ?/ T% I; q& ?    DestroyStack(opnd);
. c5 r, p0 \7 o$ I1 D. X    return opn_tmp.data;
7 o" g- ?  Q+ \$ G}
7 W, c: w; j* t5 `1 D& U4 w9 H( i% J$ }2 P- l  V
char *killzero(char *res,float result)
; B! o4 s4 o: ~4 I4 m4 j  |) s' J# O, q) z7 u{
, p7 T  Z& ~; `+ M. p1 t5 p    int i;$ i$ T! U' y1 o* f7 D* L

9 g7 I! |6 @/ C, P2 f# z4 _# p& [    sprintf(res,"%f",result);9 z. M6 |" ]4 K& e& @* m
    i=(int)strlen(res)-1;1 E$ O( G. O5 n% D) _2 q+ s
    while(i&&res=='0')
# f( Z; C, r, W8 D9 }/ z    {
: p  l' w/ B) S8 A        res='\0';
1 O  V1 K( d) G        i--;
9 e! @2 C: ^( a- u6 m* g    }
! x7 B+ d9 L+ ^* t    if(res=='.')
  i2 c# y9 d( N6 Y- q* D        res='\0';5 g4 |+ M8 Q, a: B6 E9 `- e1 {0 j
    return res;0 Z, Z, l, J0 E9 f
}  ~: O1 o. g  E! g8 M  H$ t

. }% [( d+ O1 b. {, Fint main()0 V5 V2 P+ Y4 K0 w1 B8 u$ O0 V% V
{
8 t- M4 }- F9 E& o8 @6 k    char ch;2 c0 N( E. j  f, k3 D
    char res[64];
7 o8 q9 Q% w$ D$ S- I    float result;
8 b3 _0 y: F- H# x7 R! E    while(1)
- O  a( I6 A1 V) h8 ~* h    {
7 P6 ]8 D7 b* J& h- g- e        result=compute();
9 m' T/ j! I) s  v; W# I        printf("\nThe result is:%s\n",killzero(res,result));
: q4 y& U& x8 W6 }* g- v- n0 C        printf("Do you want to continue(y/n)?:") ;
! x) u8 I, S0 a; V8 Z8 \: |        ch=getch();
4 Z; Q& j" E4 g3 p+ Q  W7 k        putchar(ch);
4 Q( |) a' w5 @9 ^4 k3 y        if(ch=='n'||ch=='N')1 B# L- p$ f% Q# k' }+ Z. o
            break;( ~1 |) X, l3 P6 O1 d" F
        else! x1 \; ~" ]* Q* e( u3 b) d: E
            system("cls");0 n2 x; \7 P) C( P  d, G
    }
9 h9 a/ t/ b" r    return 0;
4 T6 ]' T2 R; g}
( f7 B% ?' f" @0 E, ~
& G0 J8 h; S  a% H) l6 q
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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