返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.2 Y2 w! a$ T5 b7 g+ @2 H8 ~! n
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=) E5 @8 x6 Q) b4 U( J( m& }
/**************表达式计算器************/
# s. M9 |% ^. {) k" s#include <stdio.h>" W/ D2 R' r0 ?% `6 K8 n
#include <stdlib.h>
1 }, D0 c- s& k& I#include <string.h>3 @# L. B1 N5 H- s! C! n; r
#include <conio.h>
8 y. m% |/ e% K$ N3 \#include <malloc.h>
  c7 |$ S1 w# {# B: l/ p
6 W0 i! W; }4 W#define STACK_SIZE 100* g$ Y: s8 k) C' `
#define APPEND_SIZE 10
% X& J- T; B, j; j1 w
3 w$ O( k* W4 L% gstruct SNode{% |8 n  E8 i, Y# E  b6 [% z
    float data; /*存放操作数或者计算结果*/6 _: I5 n" V2 O% d8 u& x1 @
    char ch; /*存放运算符*/! p; `9 U% a* E6 P
};
" e: t8 N7 b: t' X4 R
9 a7 N7 ^' I! L) i" jstruct Stack{
# w, f( }' E8 y8 h    SNode *top;
! b+ |' p, `# N    SNode *base;- w: P( B* C! d5 C
    int size;4 O1 U0 m2 e  _$ ~6 H
};/ S& m; q; W2 ~  K# l# B
6 \# U  o4 B1 V* T' `
/*栈操作函数*/
& R8 g9 w6 j" ~int InitStack(Stack &S); /*创建栈*/- d; V8 _( a6 B) }1 [3 L( Q
int DestroyStack(Stack &S); /*销毁栈*/1 W' U. x6 B. ~. p4 I6 V* j" l, I
int ClearStack(Stack &S); /*清空栈*/
2 c5 G4 `; C- p: r6 \" ~int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/' T+ }5 b9 T& ~+ n$ f- d
int Push(Stack &S,SNode e); /*将结点e压入栈*/- h9 Q3 L; E; C, D9 f! K
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/8 A' V+ U6 ^8 N7 v1 h

# v" s6 G6 J+ o7 A/ S/*表达式计算器相关函数*/
& U& y: D$ \( W, k% Dchar get_precede(char s,char c); /*判断运算符s和c的优先级*/% ?; b: ?* y" P
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/- q" F* t! ]+ H- G  p. v' x
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/7 X& }! ~0 h! A" z
float compute(); /*表达式结算器主函数*/
; k/ U! g, x6 v" P* ^) Wchar *killzero(float result); /*去掉结果后面的0*/
/ \: @7 ^( X2 ?
/ }4 D' E/ i8 Pint InitStack(Stack &S)3 U. `2 k* N8 v; @
{3 @! l9 t1 @0 i. O3 A! d. h, o
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
, |$ P5 a; T) A0 ~7 E9 [    if(S.base==NULL)& Y  h" h% v' }. J, K# Q
    {
2 p4 D3 A: r5 x        printf("动态分配内存失败!");* r( Z0 G0 t' F  ~* m2 {5 u0 m
        return -1;
* x! G. H' o( i    }
5 ~/ b" ]1 K5 T: u) O( t8 J$ C; d    S.top=S.base;
3 ?# S* t0 S, r: I8 v    S.size=STACK_SIZE;+ ?) l6 |! S% X$ m# C
    return 0;: E. R2 `9 ]  t3 G, _9 q' R$ J7 c! i
}
0 c' f4 T9 R% s6 j6 z% a
2 c2 m' N+ f7 d, tint DestroyStack(Stack &S)5 D/ [) y9 h, ^5 c( p: `$ U# {
{
+ k& y/ _% _% \    free(S.base);
! N" ]& N  F/ i    return 0;
2 a. _, Y0 |( d# P+ D6 I}
8 g& u4 U5 X, U6 M1 W% ]
- x( `2 p7 ~6 S( _& I# u: Gint ClearStack(Stack &S)
% c. l' ^4 h: M{
: t( j! ^3 A" f    S.top=S.base;, c7 @! y/ e) d* Y0 l$ u8 U% W/ g
    return 0;, A" y: w/ u' e/ o0 R
}
2 @; h0 ~3 `# O; l3 k1 j4 A; \! _+ O8 |! R4 t
int GetTop(Stack S,SNode &e)
* e" F+ ~: x2 f% K{
3 U9 v! ]/ n8 s' z" Q9 K( E    if(S.top==S.base)) C. x' n3 a$ S" n- |
    {
8 R* ^: a- j- v% `        printf("栈以为空!");1 J) B- d& P8 f/ H# [
        return -1;
( s) _7 G( g9 v& }( }    }& R% y: ]- H* ^
    e=*(S.top-1);
0 L% b0 _' A5 w( G    return 0;7 t  u0 ~6 h. L$ X3 _$ {
}
' y1 ]7 G, ^. O6 j2 k3 T" V" w' d! O( `& Z) L" c
int Push(Stack &S,SNode e)
" X9 q/ b: }- n4 u; J{$ ]% Q" t7 [' h1 W# J" o! _, U
    if(S.top-S.base>=S.size)$ ]9 {" k1 V8 i7 p7 A; _$ t
    {+ A9 L2 Y4 O. O
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
7 W. f, a( z1 j& v        if(S.base==NULL)
& y5 a8 ]5 Z" g, F! ]  \& N        {
; }/ L6 t- t2 c3 o6 q) V( y0 e- B. J            printf("动态分配内存失败!");3 V% w' U4 f8 ~+ q
            return -1;# N( J0 s8 Z/ T- h
        }
4 X' u. h0 f, Z* o6 X        S.top=S.base+S.size;/ }' h  N. v" N  F4 j
        S.size+=APPEND_SIZE;
/ b3 z' b/ z- S& z1 K, @! s5 }( D& o    }
. r; ^1 `2 q0 k+ ]4 z" U2 u    *S.top=e;. o0 R. T/ J' p+ B& p; h
    S.top++;
5 A1 J( t7 o9 G" M2 \8 P( A/ ?0 W5 {    return 0;8 T/ h5 v3 D4 {
}+ A& T1 I5 ~6 E) V- |
, i5 ?6 g0 g; p3 U! O* `& t
int Pop(Stack &S,SNode &e)
/ [! J1 ^' H+ C6 N& Z8 a{; l, r; g$ e, Y# ^* g
    if(S.top==S.base)  L2 n1 @/ ?. {7 ?; V
    {+ D9 w& z* `0 K* x1 ^7 R& ^* s
        printf("栈为空!");) s6 t7 w/ ?( H& y0 j; V6 b* u4 F
        return -1;  e% q3 B0 A& U8 o- d
    }
' v4 x6 d1 @% `3 @2 I    e=*(S.top-1);
% S2 G- B/ h8 a. U; J    S.top--;
( i7 @; }3 d$ q5 }    return 0;
  p) W! Q. _  C& h}
& [$ S0 F# d# ^' w. f8 p" ^! X/ s1 k9 [4 S: ?% r, w$ @5 |, u9 A" x
char get_precede(char s,char c)
# k( _6 z; i! X. n$ l# ~3 r{1 o' `% J8 U4 M& i# M
    switch(s)6 d# ^" w! `: D# A8 H" q" }
    {6 P( V9 T+ i# F( H9 [
        case '+':                 
! q5 ^! j' ?7 i) N  E& B        case '-':9 [( i/ X7 `# A+ ]0 c% Y
             if(c=='+'||c=='-')
2 z: V, I% G8 C- F' h; W/ |                 return '>';
* F/ t5 F6 M. Y+ \: G- _. F  O/ d             else if(c=='*'||c=='/')
1 f( g% G2 J$ P) u- R                 return '<';
4 C, z! }; `% A             else if(c=='(')3 k4 a! c* w& ]
                 return '<';
& J" z+ G( A* p) `" c2 a9 }             else if(c==')')' W: V5 A$ L! a, q: }/ _0 k) F
                 return '>';. t6 p% B1 \( H
             else
7 z4 S1 r* Q& ?: O1 A+ T+ Q                 return '>';
1 m! \5 t& P8 @/ A. p& a( {/ f        case '*':
* r2 B% h& e- a# Z& e% @        case '/':$ z7 f% W: c+ }; A
             if(c=='+'||c=='-')+ w* Z" r( D# Y7 e" S
                 return '>';
2 Z" j9 E9 s% Z, ]9 ]& r, v/ o             else if(c=='*'||c=='/'); n1 ~, B! r0 M! G
                 return '>';
0 D) s) g  E% c* U1 ]- Q             else if(c=='(')
4 q  v9 f5 l, J; Y3 |+ w                 return '<';
* i6 s6 j3 b3 f* U3 k+ Y+ V4 B             else if(c==')')
9 A2 s2 w' g' u8 {                 return '>';
* W7 x  s5 M9 ~* p& A             else
# _2 B! S/ T! |4 e6 J& j( ~4 s                 return '>';
7 w. I  B# ~$ ]9 U: a0 |        case '(':
* I# a9 e, U9 c( f" M3 D+ K             if(c=='+'||c=='-')
- e+ p4 `: ?# V) i                 return '<';
# _1 N: K- |9 p1 K" z' d             else if(c=='*'||c=='/')
. q/ k* P1 l' E6 a: ^6 X                 return '<';
, X9 }3 e* I. c# ^' R6 ?             else if(c=='(')
4 Y+ |0 R3 M, s  q$ P                 return '<';
  u- y: f5 `! M  i6 G& S             else if(c==')')4 g" W4 T; P4 W# L8 ~4 w  b  r
                 return '=';
. g; B' `6 k1 d) K. S             else
* R  r0 O9 M& F3 x) C: O: t3 L8 ~                 return 'E';
, _6 z$ i/ g, C- D8 o  }: t        case ')':
) i% U: `" E0 h2 k( H             if(c=='+'||c=='-'): l0 e4 F" h! V, W; x/ P) `* f
                 return '>';+ \, @& C3 |5 R9 j5 c) Z4 h; ]0 q7 P4 b& H
             else if(c=='*'||c=='/')
7 J9 x- p2 x0 |% E2 u                 return '>';
; }8 j' ~9 m( a, Z7 K9 k& @' Q/ ?             else if(c=='('): V4 P: U+ [/ w5 O0 ?/ K) y3 l
                 return 'E';
' Y* K5 m2 C4 d$ u" Q             else if(c==')'): T6 [7 M+ Q# g) Z- u' @# D
                 return '>';' J5 l$ s. |, u" Z% Q
             else* b' e8 j) Y$ H1 V- M  z
                 return '>';1 h1 w) }5 g8 N: I0 w
        case '#':  k% H) Y1 ~9 r6 g& j
             if(c=='+'||c=='-')
3 i. _7 ~% B0 T& w8 F2 m                 return '<';9 ~  p* ~2 J: I$ C; |- A" J
             else if(c=='*'||c=='/')
" l) s3 ~2 i" f- i2 p- r                 return '<';
  O8 F& a% ^) M             else if(c=='(')* r. j5 n& s3 B* P+ h
                 return '<';
0 D) x- v+ ?3 w: Y) }# [             else if(c==')')
. c: D) p: Q0 }                 return 'E';1 ~. Z4 a( k6 r- M- E
             else6 O2 R) G/ B; ?1 F+ n0 Q
                 return '=';
6 ~5 C+ P- k* f! y- H5 T% o        default:
5 L9 t; F( j9 C5 f7 g! [             break;
. Q  ]0 b2 l3 [" Z" z0 v/ t( t    }
+ r- J* O+ `$ R0 X5 E  U' N( A    return 0;    0 x9 x3 v3 z$ V! X
}* z+ T. _" {5 W& \/ z  C

, |5 K* |( O' t& Z5 Y: S( zint isOpr(char c)1 ?; J+ M! L8 j& m
{
2 t+ V) X7 @" U  y9 p0 H0 U    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
3 H( x' j% H7 |, B$ k        return 0;) H+ @* B: T% |1 C
    else 9 A' r) \+ S4 n1 B, Y/ [- C9 e3 p+ E
        return 1;; v. K4 W. R- z2 r
}/ Q8 M; G) u- b6 l
7 E, V+ W6 c9 E" o
float operate(float x, char opr, float y)9 m/ E, z/ Y! I' l& Q2 o% J/ r8 i
{3 I% F+ x. Q: ~# h0 {
    float result;$ |0 M) z7 ?) t3 ~
    switch (opr)
. H* k& V1 t6 y/ M; Y, I2 i    {8 N" d9 ?1 f' c6 P- n* J
        case '+': ; `$ A) r) o/ z6 ?) W
             result = x + y;) D3 f& w( y) ~1 s  }
             break;
% z" M. c7 S/ I2 `- c1 f        case '-': 7 t, c( u: w" o+ K! P4 X+ p
             result = x - y;0 g' p- Q- r& C7 B! x. P) d. g
             break;
( H2 e% s3 K) J, D( _; ~/ ?        case '*':
& G+ U; a6 u3 W; O             result = x * y;
2 K( L' k* |) J             break;
4 r% ?( Q1 \1 w* q" a3 a' p* ^        case '/': # G6 C$ C3 d' }0 |8 A# ^
             if (y == 0)$ E% w- E5 v; V& Q
             {9 S" `0 k3 U% J- z. b
                printf("Divided by zero!\n");) w, a0 S  q: T  ]# D7 t7 [
                return 0;
" v% P! n! H. P2 t! p; E4 Q3 ?' _             }7 r6 i. P( O, d2 N) R5 L/ h/ ~7 a
             else+ a6 G0 y2 D  S
             {
, y0 u8 `5 G) u4 N& q1 y( x3 w                 result = x / y;
) _; }/ S, \% \0 z/ i( R6 s                 break;' E, w0 Y0 w- O5 k; k& C/ P& p
             }
. t0 z5 I' a! I6 g       default:
7 \) M( N* v% g7 |             printf("Bad Input.\n");
; l7 F* D  C( p: M8 L% x1 U             return 0;
% E4 V. U. c; q! G    }
( U; \3 ?, J( w6 W* N& Y+ G* `    return result;' \$ i. @+ @8 X
}   
9 L- a2 b0 c# P" o  f8 }% B9 |$ J4 L$ S1 @
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
& \$ }" u- C& r( [3 u, g{+ ]7 ]! K' Z4 O" \+ R! l1 M
    Stack optr,opnd;* B* f1 d# W) I
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
0 q0 G9 U  U# P    char c;& ~9 F2 c+ F8 r, F% T$ ]* t% N
    char buf[16];
5 V* a* `2 G  X6 T4 _* t" s- c    int i=0;
3 T+ T0 F0 A5 V8 Z   
3 V  t4 n- \, i2 W: {    InitStack(optr); /*用于寄存运算符*/
, @1 _. a0 x( p6 F    InitStack(opnd); /*用于寄存操作数和计算结果*/; M' _. {) W; p- `/ i
    memset(buf,0,sizeof(buf));% L% j5 i! h/ t. B
    + p- S" d; y8 Z$ T* `7 Z3 L2 o
    printf("Enter your expression:");
' Q! r) o' k7 X/ w        
- }% d" e0 c8 D6 v) M    opr_in.ch='#';
" X- N4 p* L. |- s& N# ^/ [8 \    Push(optr,opr_in); /*'#'入栈*/
$ {; ~% s( e% ]4 T    GetTop(optr,opr_top);
/ [1 K, b9 O4 U5 b    c=getchar();
- v2 r% o' S1 F8 Z* d, t& q5 [0 N    while(c!='='||opr_top.ch!='#')# A  `0 ]# m2 R# A. z
    {2 D; i6 q) q% H( {9 Y
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
# b" u% d: B- r; k! ?, w$ C/ n        {9 ^$ \& _8 L) ~& ]- ^; L8 U! j$ e
            buf=c;9 l/ O5 d4 C) H- E- d8 C4 z3 Z3 r7 o' ^/ \
            i++;
% S# u' }6 q7 N5 [" `            c=getchar();
  v, i& q- c( m9 \: a" W% h2 ^1 H        }
. ^- F8 X' X# Q* J9 B; Q        else /*是运算符*/
: C( ?0 R! @2 T) g$ P5 P        {
% K) C, [( _0 {4 ^  u6 x            buf='\0';$ Y" h8 z9 O0 @) ]2 J0 N4 F# T
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
  _9 K! p- s, l- A            {! G. ~# h4 `. S, `
                 opn_in.data=(float)atof(buf);
$ _; J+ Q: J, T! t3 l+ R8 v* o+ k                 Push(opnd,opn_in);& r! @. F7 M" C* J
                 printf("opnd入栈:[%f]\n",opn_in.data);  a3 p, I* |( R
                 i=0;1 b/ h1 C/ g2 [2 E, x" L
                 memset(buf,0,sizeof(buf));7 j% h4 g) E6 P$ O4 ?% |" v
            }3 R+ Z5 m; U6 O9 Z! I6 i/ C0 k0 c
            opr_in.ch=c;) h+ T$ \+ e) u# T2 S
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/4 w4 U9 v  _* ]- T$ @( d+ n; B
            {; ?  @! `+ l' P  z2 Z# Z) M
                case '<': /*优先级小于栈顶结点,则运算符入栈*/3 j! E, v6 v0 z, d2 F
                     Push(optr,opr_in);
( a2 M( O$ R2 o$ H2 J/ `5 }                     printf("optr入栈:[%c]\n",opr_in.ch);# j3 i% J  f: t8 i2 F
                     c=getchar();$ C$ L3 c, r3 ?. b- I0 a. a
                     break;
) r3 x/ m2 A7 o3 Q; N- W                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
0 `. m7 e0 n) b$ t+ h2 g                     Pop(optr,e);0 D# ?  B) P3 z0 j9 V" e1 W3 H
                     printf("optr出栈:去掉括号\n");
6 o  W4 [% \, H# x! _                     c=getchar();, ^8 b$ |: F' q
                     break;0 N  m. c4 ^9 `1 R" S- o
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5 H* h- l8 W4 `$ I6 |1 y
                     Pop(optr,opr_t);7 P( J0 ]% b5 a3 R4 Q, A; [) B
                     printf("optr出栈:[%c]\n",opr_t.ch);
, v6 T6 j! S' [  z5 M! H0 F( H& m& `/ K                     if(Pop(opnd,b)<0)0 |- z8 M+ }, Z! n& p. Q7 i
                     {
  C3 f' G  v# M7 v                         printf("Bad Input!\n");- t/ g+ E, x/ J$ H( ~
                         fflush(stdin);
+ _/ r+ U$ t5 Y: I1 ]9 a: ^                         return -1;$ n% ~0 r3 _) L8 E) y: o! r
                     }0 r2 a! ~7 I4 z; M% W
                     printf("opnd出栈:[%f]\n",b.data);
: P4 W6 ?  H3 x, B& U" S                     if(Pop(opnd,a)<0). t& O0 {" U' e9 p
                     {2 a* l' M0 @3 y, G
                         printf("Bad Input!\n");
" c6 K  I& `* Z* T, y0 @                         fflush(stdin);2 Y/ G/ J! w$ Q, D+ e( W
                         return -1;
1 d. }1 I1 h: }1 p2 ~4 t+ R. h) c) W                     }
+ b& v9 ?* l0 d* P7 ~6 [$ V                     printf("opnd出栈:[%f]\n",a.data);
4 b( Q5 l0 q9 `9 T% v1 h                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/, B3 Y! W% a( Y0 a1 l5 F4 N
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
  |% [6 H3 R- K+ a( s/ B" |                     printf("结果入栈:[%f]\n",opn_tmp.data);& e# g7 @8 G& F; x% n
                     break;
: Z0 B0 s! q! W8 \  ~- W" V/ Z            }  ]% S. T. T# Q: L- w8 L
        }
% \. f$ S; x4 Y/ j        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                4 M% l5 c8 W) r- C' K+ k6 o
    }! [' U+ k- ?6 ?" ^% b
    GetTop(opnd,opn_tmp);. F, e8 J/ l9 U% S6 O6 |1 z  M
    DestroyStack(optr);% @3 r8 y5 J/ O: K9 g
    DestroyStack(opnd);" t( U- W  x+ z2 I" ~
    return opn_tmp.data;
; q7 a% ^+ C6 \$ s0 r}
. k/ Z& s% v6 D8 R3 Y& _; }5 [5 r8 z
char *killzero(char *res,float result)
& \& k9 K5 s3 @7 |0 X+ p{
. E& p$ Z3 o$ I/ p* k    int i;
/ g7 D" q" I6 H& @1 F3 s  A
; ?9 ?; E$ Y* U- z    sprintf(res,"%f",result);7 K9 ]' F; h' n6 _
    i=(int)strlen(res)-1;
' v) Q/ ~' U) W& f- {* j5 L    while(i&&res=='0')
  k  }1 [$ y. G3 M1 T3 x    {9 f5 Y! e. ]) I
        res='\0';
' _5 P0 w6 [; \7 j: m# K* P        i--;9 {" p( |" ^3 J& S8 A6 X# N- U
    }
9 h! }5 c  N: o; V) @0 z    if(res=='.')
0 v+ }7 `! l$ F2 A8 K        res='\0';% A/ {- o, I' j( [$ d
    return res;
  ]" H: J+ Y% y# l1 D" z+ H5 R}
" R6 W& @- Y6 v# j* z* S" B
' t& I: {( i& Rint main()
6 N. o) h& \1 u& P& e{
+ z; H1 H& ~  f    char ch;
7 X) K0 U5 c. i  u& Q    char res[64];
; F, K0 R; P0 e* ?, t    float result;
& ~3 n3 A) `7 O) r/ J    while(1)
& [- l2 m, E# P6 M  @    {
3 \* B  P+ k1 t# D9 Q" X4 |) R) \        result=compute();
6 [- {+ c/ x3 O- f- V. L2 T% y/ ?, p        printf("\nThe result is:%s\n",killzero(res,result));
& C5 d% G# C7 M        printf("Do you want to continue(y/n)?:") ;
: F& [4 g4 ^& V, J/ u        ch=getch();+ ?* |) H) [9 _2 Y5 G% W) h0 W
        putchar(ch);
; s8 N; J1 i9 [3 ^8 @& B        if(ch=='n'||ch=='N')
$ u7 u$ R  o& z) [6 m            break;
2 {1 P7 y. I$ Q        else; D% w; o" R# r# T1 _+ `
            system("cls");
/ x  l' k2 K0 w7 O, i    }! O  i) m2 K  g9 R3 j
    return 0;& {0 b$ K% d9 Y) ?. j4 p
}

, z9 B# s9 D/ M! J. |5 k7 h% ^4 Q* K0 I7 s7 z. O2 v# h* d
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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