返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.. S0 m) i* C2 ]8 ]2 D
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=! \8 I: ]% v0 r" m* G
/**************表达式计算器************/
5 V( X8 Y6 B4 c4 [) `#include <stdio.h>1 J# \" R9 m5 b( F1 s, T4 c4 T; X
#include <stdlib.h>
% z" d/ z( |6 Q# a; x8 W) A7 B/ T  _#include <string.h>
7 v3 w% a! E5 m  x2 w! x- v* X/ G#include <conio.h>
9 o+ j0 ?9 M' N. S# Y#include <malloc.h>
/ t! t1 p- A' M8 \7 D; T4 i4 M; ^$ g. a' ~
#define STACK_SIZE 100, M& n6 |- W& W) s. o$ n" a
#define APPEND_SIZE 10
, m) u% T% V, e; |$ T5 K, ^0 W2 z: C/ O  o+ G2 ]  |4 j
struct SNode{. A, r  T: m7 ~) C
    float data; /*存放操作数或者计算结果*/8 s4 E7 p, K9 c6 s' w: K, S4 s! Y
    char ch; /*存放运算符*/
) O3 f9 `& c0 J};. M; L# A+ b: t4 F) C) t: r

- i1 v* V9 @1 z( [1 j7 Tstruct Stack{# B. {  Z6 f( S% K) X* v
    SNode *top;/ m2 V" t+ n' ~9 B$ m- Y1 Y
    SNode *base;
/ `1 s' z  m! P( o    int size;
2 m5 [9 Z$ Y( [( F# ?1 n};8 {5 m/ G; [) g; I: Z9 [
( X3 A$ @0 ^8 [, F! b- p
/*栈操作函数*/
2 }) n- ^& y# M" \. X3 t6 j( Gint InitStack(Stack &S); /*创建栈*/$ Z& b" Y. a1 ]* w5 n+ e
int DestroyStack(Stack &S); /*销毁栈*/5 b2 k# H7 T1 U& H
int ClearStack(Stack &S); /*清空栈*/5 ~% J9 i& D1 P# X6 Y" C
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
% l" N* Y5 R1 {- b0 Qint Push(Stack &S,SNode e); /*将结点e压入栈*/
/ f% s! c3 s0 x- M8 x2 K$ Q6 Fint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/$ K. @4 ?' F4 o3 j8 O9 F" H  m
2 l( E: c. Q/ i  v8 n0 _% N
/*表达式计算器相关函数*// z8 C2 B5 S5 @) j4 f
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
- V. g; z4 t9 n5 w" r  E; s, Qint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
; t& v% B0 N3 ?float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
. p; M1 B0 m/ p( Dfloat compute(); /*表达式结算器主函数*/
! `* a8 \" [: ochar *killzero(float result); /*去掉结果后面的0*/
2 W, M; T8 W' s- i8 J5 L  [9 H6 K* v; N; h
int InitStack(Stack &S)1 r! D; A2 b# L- h
{
. g1 Z9 q: f1 m/ f$ ~    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));$ f! u* T/ D, u/ T1 D. Z" O
    if(S.base==NULL)2 X5 B  F5 g* E' `" V% G2 ?2 \
    {
7 [. l, @! I" C' J; F/ w  Y        printf("动态分配内存失败!");" ^( Q$ q/ ~! a! o1 s4 z6 A8 D1 w
        return -1;
* T7 z" [! \) C1 x0 l& W) [    }2 Q! i( P  E) o' o" I8 o/ Z
    S.top=S.base;
$ d# j7 Q5 T: g6 H! Y    S.size=STACK_SIZE;) H  C- ~: L4 l5 @# t3 S( H0 M+ X
    return 0;
6 C/ y8 N# K# ?8 O7 m; R}3 [  w+ l% r0 _

+ r/ n9 L/ L1 S  Y' r' Mint DestroyStack(Stack &S)
. x( Y3 Z+ p& R0 g$ ?{
9 x, G4 F, O' ?6 r# u    free(S.base);
1 {1 p2 G. b5 G    return 0;
: D3 ^7 ], w* {2 u) H}
  `# {) d  ^1 `0 n9 C) [6 J, R
# N- o- P% W" G! ?; w8 D1 j! kint ClearStack(Stack &S)
' s# k% \" |. g3 n{
# p! q7 _" H6 T4 ^    S.top=S.base;6 S  |) J7 H0 q6 e
    return 0;
7 b1 R7 T& f- i' A5 T1 b' W3 l& a}" `% c4 _. J7 B; B' n

0 X! G" q  c) y3 ^/ Aint GetTop(Stack S,SNode &e)
9 f. Y7 ]6 W- M! c: R. X{
. _; d1 q1 i# P9 m5 Z    if(S.top==S.base)
2 Q4 ?5 h- C- J( f: r. q    {/ u3 |/ y- v# F5 [1 U9 r
        printf("栈以为空!");) I3 {$ d& {9 x
        return -1;; ?) {: r8 d4 w0 X; |. m
    }/ v: D; e* S  ]1 G' w- a
    e=*(S.top-1);! _  Q9 D, t1 d0 }  g
    return 0;. e" z. e, W/ m0 `. a& B6 Y
}
1 @. r+ D4 b& {, w: m4 C0 p3 S
8 P. U% p: G! G2 g) Y$ q# Q/ Xint Push(Stack &S,SNode e)" F( }: b8 `! a8 L8 v+ A& L
{
* T3 {9 x- U% s  }) E- J4 ?    if(S.top-S.base>=S.size)+ t1 ~; @, V# f  \, Q
    {
4 e  W- _1 l. K% Q9 i" t        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));, o9 w- c3 M0 K2 ?& h
        if(S.base==NULL)
. n) v  O' Z, d! z7 a5 W        {
  D# x* L8 F( M6 ~' I3 v+ y8 z2 a            printf("动态分配内存失败!");* C2 p  c2 w+ h
            return -1;+ P, |- r' j1 V% n
        }
" h1 }9 l( H) w7 M/ L        S.top=S.base+S.size;
" B! W; i3 k( e8 d  Y( I( H        S.size+=APPEND_SIZE;
( E+ p: E& U! Q3 V# g# q: I& i, N    }
* @. A, `- ]% S1 r  O" ~    *S.top=e;
: E$ i- c9 N# l    S.top++;: B( S$ W  [7 X' C) T5 m) F4 q
    return 0;- X& S' O( L2 {! i2 C: R5 M& O
}
/ H; @2 l" W2 N9 @) o% ~  S3 \4 s
int Pop(Stack &S,SNode &e)
8 x6 `3 j0 K# w+ T" m' t+ ~9 k{
" O. X6 W, v6 ^. _    if(S.top==S.base)
. i' Q9 o8 I  d8 }- f    {6 d) T( X" t5 T' _- k
        printf("栈为空!");1 q* ]; ?. j! p
        return -1;
  P8 W: G& I+ d4 P    }  y1 O. p# }7 q% o1 N
    e=*(S.top-1);" t$ A% F5 L1 M" W
    S.top--;6 v: [- N" L# G  A
    return 0;6 |; J3 O6 v  p) J( j$ e
}9 A( U3 x( m4 ]3 y. _6 v) d
9 P- }* _& d9 P! Z
char get_precede(char s,char c)  c/ A( l. e# {9 M
{* M1 c) K  c# O
    switch(s)
- m( p, Z+ o( m4 a/ x$ |" N    {& w! E: p0 Y9 a# Q* b3 X, h" W. z
        case '+':                 
0 R* t4 t+ C) R3 K        case '-':
: Q2 m7 X8 l' U7 h9 Q3 W6 p             if(c=='+'||c=='-')5 ]& y4 L6 i2 J0 a; l5 B$ Z
                 return '>';* n. S! n' F4 @, K
             else if(c=='*'||c=='/')
; n9 j. w4 c; ?+ C! p' y                 return '<';) U1 U' i% ~0 o9 Y) T/ ?6 P
             else if(c=='(')
# B) N# n% v% ]: J& G) K/ g. s                 return '<';
6 |( {6 P  C3 K) `             else if(c==')')  L7 q3 F; @; z5 ~. D" ]4 B. _
                 return '>';& D, L$ e) m$ L7 }
             else ( Z7 K1 K3 @2 p/ G( O) g
                 return '>';, B0 e2 b$ u5 U' M" l
        case '*':7 b# ]; l" ?/ G/ @% l/ j; n; ^
        case '/':* `; N* T- `1 d* W: K
             if(c=='+'||c=='-')1 h% l8 D/ b' o7 D2 D% F7 ~, p% \- l
                 return '>';
6 k% G- P, J! j) \7 m: ?             else if(c=='*'||c=='/')
! v+ C- ^( b" a" S& g# \                 return '>';
( V" e( V5 B9 e% y* Y. C             else if(c=='(')3 E* ]) |0 B) t0 P: h. g* |  e
                 return '<';: E/ o+ S, K* S' T$ y  E- u
             else if(c==')')- Y/ S: \# ~; l- E0 |+ X
                 return '>';7 R- p! w% j+ @/ \" q$ c( v: r6 _! [, [
             else
+ J2 p, b& E; r3 C/ p                 return '>';
! F" h8 T7 i1 E        case '(':
" c; @5 y/ P5 E4 m             if(c=='+'||c=='-')
1 B! T" I8 Z# R; h* b                 return '<';( K( d# ?; e# d
             else if(c=='*'||c=='/')# ~; M# k, ], q9 r" d' A( K
                 return '<';
; k' g" t1 j' `" l5 o& R3 ?, U             else if(c=='(')! @  e0 H  C8 D( B
                 return '<';2 c* @8 D4 I! I) k  u
             else if(c==')')2 f/ T1 H4 @! q" g3 Q) {
                 return '=';! F* B$ X0 f( H' Z& x0 Q- R
             else
% z% z; T1 `. ?% l; I                 return 'E';
- p% y+ b9 C, ?: }$ ~        case ')':
" Q% w: B+ _; {0 Z             if(c=='+'||c=='-')
3 U# F" G% Y- D8 ~7 h- t/ e% k                 return '>';
/ |* \) X9 m: l# P4 v, X1 i/ m0 B             else if(c=='*'||c=='/')4 Q  ]- ^# Y, z. Y. {' j
                 return '>';+ C9 u$ c, h4 l: u6 p
             else if(c=='(')3 w% K$ O' e; U# X8 @5 |3 y4 a& R
                 return 'E';
: r& y0 v4 X' p( _/ v             else if(c==')'), A" j- b! q9 U- M2 s9 N
                 return '>';
3 d( v0 D" K8 k' a& T) Z* N             else0 s) T6 Q' h+ y) k; |  x1 ^" C/ |6 I
                 return '>';
+ G0 ?. P* x- q2 z, o  b* G- e* W        case '#':- q. c$ ~2 k! m% l; v3 {# M
             if(c=='+'||c=='-')
- |/ a% W6 [4 L9 z                 return '<';8 o8 i6 m( F8 E) i; T
             else if(c=='*'||c=='/')
: o4 M: z! L6 b' r/ b! V                 return '<';4 c  ^& \" A. U3 {2 e" Y; ], X
             else if(c=='(')
; t% a' b7 H, a                 return '<';
5 z3 ~/ d0 x' D& ?4 b             else if(c==')'), G) f0 C2 U# P. n; `2 @, ?
                 return 'E';
# h* f  L7 x9 ]* t8 A' H' |             else
0 q7 K* V- \9 N% f                 return '=';
$ q' [3 x4 N, _        default:
* y4 g5 U# {8 \' Q             break;$ V7 i/ x4 T9 B7 ]: b) z
    }5 d% m6 L( _! r2 O
    return 0;    2 l" i" T. F+ {
}3 l9 M% v0 N6 k
# f& b+ Z  \3 r6 K
int isOpr(char c)% w& B$ v2 o$ j- _8 ?1 j9 B& h
{+ Z3 v3 U3 q9 ~5 `$ h( a
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 i  _4 Q( n$ ?1 v( t' Q8 y  S
        return 0;4 x0 Y- v' a, t: W$ i3 ]( ^0 [3 m
    else 9 P4 K0 H  w3 N( J& G7 e
        return 1;( ?3 w  |8 k. [7 C# q1 ]% d
}7 s7 I" r: P# z
3 V0 @. E) O3 ?( i/ w! r$ v- ]
float operate(float x, char opr, float y)
( P+ X5 K3 s* _; E9 u{& y4 R' C' S1 A) v# ^2 m# Q3 Z
    float result;
, h9 O$ V" X# g( b    switch (opr)
5 n1 ~/ Q( [' s9 @    {
# b. o$ W# u6 R! p8 M  d" j        case '+': ) v' f9 s7 B7 C) w( s+ q2 B2 w
             result = x + y;
8 ^/ d! |" g, b' O5 c+ _7 m             break;
* j7 m9 c$ p9 f8 t# z. }& A        case '-':
0 c: `6 b0 M( i8 ~% v1 b. Q             result = x - y;
) n. \$ L" `4 q$ G             break;# X' G( M+ b. H( ]
        case '*': 7 x. t) v- H2 G% ^1 T3 f. G5 o
             result = x * y;9 k- x& y9 Z  `6 f
             break;9 z7 `8 t! T! U4 C( `9 J# q; a
        case '/':
5 u+ T4 V6 `- Q3 e             if (y == 0)
, W% Y: a$ O' E" T6 g; D. L             {
3 a; y* p& c! q9 D                printf("Divided by zero!\n");0 n3 |& U8 F9 `; x
                return 0;3 A; I/ X) U- t& ?+ }2 ^
             }
: ^# o4 `4 C8 e( w9 ]$ @             else: t, h9 |7 Q" t# n0 J8 _2 K
             {
, X% r+ }8 J7 {7 }8 h+ z3 D                 result = x / y;9 Y  g+ L$ U% R/ A  v$ G: W
                 break;
$ ]( k) v, \! t4 \, }. R8 P3 v0 l             }. z4 M: U9 s! J5 s6 P7 V
       default:
% h  d& n: W! v1 X1 f. L  \( A             printf("Bad Input.\n");
9 m( `: T  H% @! n3 C             return 0;- ?# F0 N; l% C! u. D
    }
$ Z7 l) T1 Z) x    return result;
/ A0 ]  r! z. ?: o" \) m( v& J}   
6 [1 q( v0 v, b
6 _/ j' C- L2 Yfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1 `6 P: u* U+ b9 k6 R; X
{
  S: ~0 y4 `" A& b3 ]    Stack optr,opnd;
/ O! ~+ U8 j7 W: G- Z    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;; n4 O6 j" q& \$ F3 F/ @
    char c;) l1 H0 `4 A- v
    char buf[16];
0 n+ ], o8 Z+ N, M/ z% ]* c    int i=0;
' N4 n6 `# q. P/ s# p   
( P6 P; v% Y/ D3 p7 W    InitStack(optr); /*用于寄存运算符*/
, r7 ~& W! }2 j8 p    InitStack(opnd); /*用于寄存操作数和计算结果*/8 a0 c' e" |7 u- t. ~0 n& ]! _
    memset(buf,0,sizeof(buf));
  Y  T/ C4 K' t4 ^7 j% `    & p  j" V- r- L- `8 l
    printf("Enter your expression:");$ S9 F8 D. L6 E8 ]
        
% @8 a+ u( b3 ^8 L    opr_in.ch='#';  B4 d# `! Y8 M4 E# {! L' y2 X
    Push(optr,opr_in); /*'#'入栈*/
7 f' s% }# ~) I  s4 w9 R    GetTop(optr,opr_top);0 I& F% c: I! Q- J, |: e" g
    c=getchar();: w8 h& q9 A6 o2 G9 a9 }
    while(c!='='||opr_top.ch!='#')
4 J6 V" Y: p" Z+ s: v    {
0 u% ]" M6 t: S' C        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/4 s% \1 N4 `8 ^! D8 y4 U
        {  R  U/ G+ x8 X: ?6 v  i0 o
            buf=c;
0 E2 |6 T% v4 n) K) j  S            i++;0 s+ ^* {6 L& ~7 c3 ?
            c=getchar();/ m% i3 E4 X- c9 I1 W# c
        }
, V+ i1 I1 f: k6 Y8 P0 P        else /*是运算符*/
5 L) x! m6 G$ Z, z. R7 u        {
% [1 D3 S" n6 v3 _            buf='\0';& h9 a4 Q# c3 D* E3 |; z
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8 `5 x& F- i9 A  E& e9 o% ]            {
; C1 n# p7 S/ D1 P                 opn_in.data=(float)atof(buf);
6 C' [' e1 x# A+ X0 ]2 V) w                 Push(opnd,opn_in);
4 g! I; P% e) P( s9 w. g9 m+ _                 printf("opnd入栈:[%f]\n",opn_in.data);
- A2 J0 V& W( N$ m; d# {% ^7 a, k9 \- [                 i=0;+ U3 P, G  p1 S7 W0 o' P8 K! o) C
                 memset(buf,0,sizeof(buf));" l0 o7 }% |7 a
            }, F: J8 o" {6 C9 I
            opr_in.ch=c;5 T8 a2 {" b- r$ v
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5 G3 f# D! `: t5 }: t7 r' x            {4 M8 n& X: e" ]5 H5 c
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
0 Y9 ^3 ~( r) S) @6 c                     Push(optr,opr_in);# J" \: w% A+ R. O  J$ ]. H7 @
                     printf("optr入栈:[%c]\n",opr_in.ch);
( A' G. \- [; M4 Z( D- f8 Q                     c=getchar();
0 M  ^" M/ t* f) S% C                     break;  T2 Q: W# g; |2 G5 F. u6 i' U" F
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
6 P* J# L5 e% |% s3 g$ n                     Pop(optr,e);
0 F- J* ~0 ]3 o, e* j2 B                     printf("optr出栈:去掉括号\n");  ^/ D) D; g( ?7 v8 [$ ?( s- r
                     c=getchar();4 A' C( Z: @/ f% Q( I' E
                     break;$ Q3 H. H  d# v
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/: I. L7 K4 B9 m+ P' ^/ d1 {" v" p
                     Pop(optr,opr_t);
# f+ e* X9 a- A, e                     printf("optr出栈:[%c]\n",opr_t.ch);
+ ]1 ~- N0 C0 _: P4 `. e                     if(Pop(opnd,b)<0)& m! t; K" e# s+ z: K
                     {: W: C! m3 t9 V6 ^6 p0 K  V
                         printf("Bad Input!\n");9 v3 U) K; ?, C6 F, M( @# m
                         fflush(stdin);
& Y) F1 k" C! D# ]                         return -1;
1 j7 \! p7 X- O; x4 u7 t                     }; J8 V) O& Q4 W& [# D
                     printf("opnd出栈:[%f]\n",b.data);- i( |0 k& u: O+ h2 u  Y
                     if(Pop(opnd,a)<0)
: S+ S6 q9 A0 i. F                     {
. F) ^8 G- d( U4 n                         printf("Bad Input!\n");1 o; f# R7 e. K% P) a/ O( T
                         fflush(stdin);
+ m5 a7 H6 N# G                         return -1;- s- X8 ?0 I& z  g! s( {
                     }
3 j+ R: ^8 C' M- M& }                     printf("opnd出栈:[%f]\n",a.data);
/ h4 V: h! C+ S6 b& j8 d                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
- ]2 x' u" R( C* q! B                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
8 l5 J4 `* x3 a                     printf("结果入栈:[%f]\n",opn_tmp.data);
4 F6 `" F" Q2 a; T/ c  n                     break;
* p5 X* |+ E6 k& \/ I- K- G            }1 j2 p! A4 T1 s$ S
        }
. g# K% D; z/ E, o) [$ i2 \        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                + t9 x* s, A" h3 k/ t- ~5 I6 t, R
    }
0 V$ i- g$ t  K$ I    GetTop(opnd,opn_tmp);' ]4 k/ j- G# O- ?
    DestroyStack(optr);
0 m) ~2 W7 }; l7 f" ~    DestroyStack(opnd);4 n  Y$ A0 o2 }7 J, K9 k4 w" a9 e
    return opn_tmp.data;- `" a' i/ |" c% f
}
% O3 c! X! [% y' O; L
9 R% I- ~& z. O! x( Ichar *killzero(char *res,float result)" \, Y) x; n3 P3 Q2 h. y) o
{0 M$ e4 t* l. C, w) u* [
    int i;9 H- c+ R0 ?) l% |5 h$ X
" \. b0 e- e( s6 ?
    sprintf(res,"%f",result);
: d/ ?" `8 O9 `    i=(int)strlen(res)-1;
# O8 |! p, L( S: [5 H2 Y4 v    while(i&&res=='0')
6 r5 L3 \- e3 {2 i7 Q    {0 \1 g% h  ^4 {& M6 a' [: i; k- A
        res='\0';5 x7 r6 P4 _" X1 \# D3 j; H! J
        i--;" {3 m3 _) H) _
    }
% f3 V8 S0 K  r9 g( r    if(res=='.')
/ y  f# {) r- n8 Y. i4 D        res='\0';( c% v6 I& h: J$ c0 ~$ J4 _* C1 v! W) Q
    return res;
* s, y3 \/ {  ^2 j  i}
; }2 ?9 m6 Q5 B' H; @
$ W" f8 m# v; ]$ m/ Gint main()0 G9 A9 e( {- ]0 Q0 A, F, \
{
, h. t# L; w, J3 ?- w+ X  d0 _6 K    char ch;9 |, G! N3 F0 F: {& ~
    char res[64];9 X5 X. i9 c- }
    float result;; q# C0 `( d" U& S! c( h5 b
    while(1)
' s+ E- z# Q- q, v    {
- a; X' y% v9 D5 |: S' B. K- `' @        result=compute();+ F0 A4 ~: y+ T; n5 j! b* j# S1 y& V
        printf("\nThe result is:%s\n",killzero(res,result));
4 `8 R- O/ e4 {2 m5 w5 O        printf("Do you want to continue(y/n)?:") ;  n  Q+ q! `$ @8 k
        ch=getch();0 k9 y! i% |& P8 M! I
        putchar(ch);2 \3 A  {. z% W0 [
        if(ch=='n'||ch=='N')
$ R$ A+ s' p5 t( o            break;
7 |, V! o* O" u" [        else
2 g6 n" v" E3 S5 B9 F0 s6 @            system("cls");
# @, j) a. }, t8 b* R    }
' }* p3 e! D& {6 k    return 0;4 `8 ?! H* V2 }- P
}

  a7 o( |% s$ ?3 J+ {( e; u  v. ^3 h) A
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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