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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
. g! U7 A% |! s, x# B# o/ s- w6 `+ m程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
. Z/ z7 `" q) I/**************表达式计算器************/
' h- U4 _2 p$ O0 J, f4 `2 J#include <stdio.h>
; W; F1 s+ l+ j#include <stdlib.h>& ]& e9 G  a! ?9 \4 B( s2 O) }2 R, j
#include <string.h>2 H: Z7 y& \' K. u
#include <conio.h>
( P7 I  k( m* q% ^9 K, J#include <malloc.h>
, ]) m4 O  k; {: V  `& c' F% i2 [$ B7 `4 t/ f# Q1 _/ x" l) f
#define STACK_SIZE 100! ]+ ^( U+ B( [6 J2 u
#define APPEND_SIZE 10
8 X9 v8 q" q( U9 I  S$ Y
1 q) a7 v( B% p* @* `, a& p5 Estruct SNode{( c. C# ^" }3 J& N3 S; ?
    float data; /*存放操作数或者计算结果*/
2 r8 k& b9 I. H# U5 c) |    char ch; /*存放运算符*/  a( W' p+ a# |5 d0 j3 A' e
};1 D3 S4 q0 P9 |2 W: S3 V
; p5 H( a; d( A& ~6 ]; l
struct Stack{+ Q4 ]3 E& K# Z0 o: W: S, R
    SNode *top;
8 N4 I+ M; S& V4 T7 I5 D( p% Z" d    SNode *base;
6 q1 G/ U' A+ a9 I: f& O    int size;- U7 u4 }# v8 @2 `# O- \
};
2 N, S# {% O$ H) m+ n2 ]
3 r: h8 M1 }: b, ~/ \: o+ f0 ?/*栈操作函数*/* C8 T1 T5 b. a; ^
int InitStack(Stack &S); /*创建栈*/
& p- T! f! m1 [* H# h6 Mint DestroyStack(Stack &S); /*销毁栈*/
9 m- K! a# x. X) P6 Cint ClearStack(Stack &S); /*清空栈*/
. N! t( I# r7 S+ M& A* aint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/: U7 o& X1 d  f+ v4 g6 B3 L
int Push(Stack &S,SNode e); /*将结点e压入栈*/; H6 ^' w6 w- y% P
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2 k: L# H" s' c% y' h3 ^- W* A5 [( g) g1 K; K" m9 u. P0 l
/*表达式计算器相关函数*/+ v& J$ C. ?' M3 h% P
char get_precede(char s,char c); /*判断运算符s和c的优先级*/) a7 ]* U- ~+ M! G3 m" r
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/1 V( X8 o  N% n: H7 ^
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$ }( o  {. s6 {( L- b  O! s7 r. d
float compute(); /*表达式结算器主函数*/
; k5 s9 c, J4 C& s- O' [char *killzero(float result); /*去掉结果后面的0*/ ' ~4 M7 p* H% B: p' t* [7 m6 i* V/ W

3 Z3 @1 T& z4 {8 e$ G5 Y$ Uint InitStack(Stack &S): w6 }8 H! p3 ]# M5 J0 K: m
{
" P8 A- P8 p7 B  |& F8 g0 j0 a# s    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+ a) w6 T/ d2 b8 h# [  i" e
    if(S.base==NULL)) p: i2 }! ]. O' y0 K
    {
4 E) O9 @" `0 S, X6 C        printf("动态分配内存失败!");) q* e6 u$ `+ }1 p. |, H; a
        return -1;
( b# y+ O9 n, r& p/ @% C, ~    }6 o% L7 i' o0 M8 g) Q% H% O- r6 @
    S.top=S.base;/ a0 Z9 B* C  y9 F) l& C
    S.size=STACK_SIZE;; y, J% a+ }9 y/ Z7 n
    return 0;$ P( ?/ O9 p# m: r$ g, ?4 s5 d8 B
}
3 r7 J! O9 A' |; f$ h5 s
! ]+ q% m" h8 E' P: \" }2 H8 Uint DestroyStack(Stack &S)' _' n* n5 g3 ?0 Q
{3 x( U+ t* a) S4 c+ k  h" `
    free(S.base);
) W, B9 i8 ~/ q    return 0;
2 r5 v( f4 B! m0 J" c; }, h# Q# f6 X}
- `( d1 ]* f) x2 K& O) t/ t; w3 Z7 x* g/ u' p, ]
int ClearStack(Stack &S)
9 z. p) G# `. o. \2 w# H{
7 ?+ ?% Y, U$ h' Q9 u2 ^6 f    S.top=S.base;
: d8 j, x( ?1 C" C. d    return 0;4 R; I6 [9 o$ V
}
9 s, z6 c& Y3 x8 `( X9 E) }
8 \: c6 f3 G  B6 B  d) A. bint GetTop(Stack S,SNode &e)& z5 q: _; C% _
{
+ s, W- j. k6 s: R    if(S.top==S.base)
. O9 l& j% f' A4 S  A    {, m8 P0 C0 a& L5 D' w1 @
        printf("栈以为空!");
/ R' Q) o* t5 C4 h        return -1;
) @1 W6 G# W( p+ I. v3 M, F3 t$ I    }; ?6 J$ v. w3 E/ s6 |2 M
    e=*(S.top-1);1 w5 Y! E) l2 g
    return 0;' F( D5 T- U/ @1 X, K3 K3 R
}, x  J: B4 b! Y5 o7 {- A% E

. h$ V$ z' x) Y4 @2 b5 qint Push(Stack &S,SNode e)- V/ @8 V3 M7 N! Z, ?' _' X
{7 f! Y% P9 _9 J' Y
    if(S.top-S.base>=S.size)+ n7 i7 V& q* K; w  o. i; k4 a+ e" p9 M
    {7 p7 s8 M; v/ l* c
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));6 Q; R* ^; C7 Q+ A
        if(S.base==NULL). l  {& s8 _. A1 m. \
        {
+ N) t* x8 }; i            printf("动态分配内存失败!");
+ @% B; [7 J) H" B            return -1;
+ \! }5 u; P8 H% X, G+ B1 r# d8 L        }$ w9 x7 C3 Z$ S" D- ?6 a8 U
        S.top=S.base+S.size;! K: v. B5 R# `5 m( Y; S. t7 x) U
        S.size+=APPEND_SIZE;3 u* F2 h5 \. p, K& l# R7 N( [
    }
! G, |) y$ j$ @& F& h    *S.top=e;
# H0 E) v3 v- A" i- L+ _# Y    S.top++;
0 z) ?% N  p5 _7 C8 [& e+ o! b    return 0;
6 H/ `/ `  j& B" A7 T}" P: a1 Y, J2 u; E

4 Q- W! V! n6 n6 \int Pop(Stack &S,SNode &e)
' H1 s1 X( _2 K0 B, q% Q7 I3 [{5 c' h7 V+ C3 F0 J9 S
    if(S.top==S.base)3 C+ e$ M3 d+ N, x0 [: H: p- h. O: d
    {
0 r; h* R7 ~3 E& ?" l6 f        printf("栈为空!");
) P6 i8 ^& g- _/ S% f1 D, g        return -1;4 [# c4 j! f( J% O' Z/ X  F4 L
    }2 u, j' }+ M/ Q+ a' ^# ]
    e=*(S.top-1);5 t  I0 Y4 d+ c, F: J! Y/ P6 c# H
    S.top--;2 C9 ~1 M7 S3 `. M+ V4 S) }
    return 0;
1 c  k* w+ O) G4 F/ ?6 n* y}: I0 z* r. }+ j) t. J. X
: F% m# Q! k  x) g1 [6 n8 F
char get_precede(char s,char c)3 ?/ J& v& t$ ?, W6 P# \
{  I1 X. ^1 F8 ?* K+ j
    switch(s)1 d3 d7 d* O; d- n9 k
    {( B  i) l2 H" Y: G) i0 E
        case '+':                 ' f, S- o. K  X1 K* n- ^+ q* x/ H
        case '-':
, W3 U: \9 J/ `1 _( [$ r             if(c=='+'||c=='-')
$ {! n0 a9 E0 t                 return '>';
7 t3 E. L- C- \8 P, K6 y! J* a             else if(c=='*'||c=='/')3 W+ Y1 @' B9 h% N* X
                 return '<';
! z1 Q( V! f( m             else if(c=='(')
$ \; i, i: r- b( O$ F5 B9 C                 return '<';
% e$ C0 [  f$ f) ~. y& ^             else if(c==')')" L" a( _7 ?" {, a% J4 z6 ]* g
                 return '>';6 T$ q& ^, z2 a2 A1 {" H* P
             else * [2 l  |3 u& I" C
                 return '>';6 |8 y3 u6 p. s0 z" P: K. S' o
        case '*':$ a4 d( @8 i" b5 S* b7 a: x
        case '/':3 t0 ^" [" C# ~3 H2 n
             if(c=='+'||c=='-')
% T7 v2 z/ r8 {& s1 F& ^                 return '>';6 p9 l& c. x2 a/ P
             else if(c=='*'||c=='/')6 Z" ?. R' @2 j
                 return '>';, @8 m9 L1 g" w- ?! I" G* e
             else if(c=='(')
# j8 k! a3 D! f) V/ ]1 w1 p3 _                 return '<';3 P4 x7 i, K: x* }7 V7 S# y
             else if(c==')')& F$ w+ D5 Y, U9 @4 Y3 n0 ?& W
                 return '>';$ E4 `5 D+ J( W" |
             else
: ?) D8 e* r5 T2 j                 return '>';
  L  `4 h- y, \& V; w, N        case '(':) h( Q9 v( g6 g1 [
             if(c=='+'||c=='-'), w1 b4 g/ G8 @( G" B8 b1 b, }
                 return '<';
& k  p: h! M* L             else if(c=='*'||c=='/')
6 I' o- y# k2 X                 return '<';+ r. ]9 x& _, t- R4 {5 b0 H) i
             else if(c=='(')! @" t1 ~2 m+ \5 m
                 return '<';
) `, g. h- M8 M0 J- b) l/ `+ @             else if(c==')')
) B4 j5 D! H( a  \                 return '=';
  j4 K4 v" a/ s( s             else4 T$ |: [1 K0 v2 w0 L
                 return 'E';
0 k/ b$ `; k1 f; h3 ?9 ]$ d- q        case ')':
5 i  I8 x4 \. |7 t+ I1 \2 d1 |. g             if(c=='+'||c=='-')
/ D' ?4 i4 z1 A3 R0 q9 ?; z                 return '>';
1 \2 I4 p7 U0 J5 r0 \5 s3 E             else if(c=='*'||c=='/')/ ?0 d4 v) ?3 A/ K" @6 v
                 return '>';. k. Q' T" K9 K
             else if(c=='(')
4 Y' M% a* |/ A0 F- B* [( l                 return 'E';5 [3 E6 ?7 r5 o! L( C
             else if(c==')')4 J8 `8 d% {: O, {0 F; J8 N
                 return '>';6 e/ v2 v; Z* W- J3 z
             else# `1 j: P4 ]+ h9 d, S
                 return '>';
+ j- K) Q# [5 }, A; R        case '#':  U) ]0 T* V6 X3 x1 q5 j: e
             if(c=='+'||c=='-')# s( {+ A- P6 U: y) ~8 X/ N+ q. c! S
                 return '<';" d8 C% R' v* W. D1 I
             else if(c=='*'||c=='/')0 o9 P% Z/ T4 d9 X& T9 a
                 return '<';5 a' L$ m2 _9 {$ V
             else if(c=='(')6 b: D4 z; \6 D+ R. p5 j
                 return '<';
7 v% V" w0 ~6 ?/ Z  L5 o$ a1 u. a             else if(c==')')* t1 n, ]/ D( Y9 t# t
                 return 'E';
2 y- C$ m. f( L* e             else
/ P7 q( f% g! @                 return '=';) i6 e: H: l: w# V, W: C
        default:7 y1 V" D2 e$ _
             break;
! x0 i& a6 `6 s  v$ [9 w4 N    }
/ T; M; \( \) O' F    return 0;      `8 M: D- ?; c7 A/ F' L7 o
}
! M0 ^6 R1 {2 L. g! `8 ^4 l" s
$ L& O) @) ]: e# w* q& _1 v; V3 jint isOpr(char c)
. N3 t: _# [' |/ k6 R1 J. g3 a{" U7 q7 y( w; v( m
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')3 n" Q5 A- v/ h+ k
        return 0;
  F2 ^0 \* r& c4 ]8 |* T' d0 q4 q    else 7 M, x; s" Y  G$ w  d; r6 F
        return 1;5 F6 C2 U% I% t
}5 L+ |; P6 J8 G

# w4 N! h7 N1 E1 M9 V7 i" wfloat operate(float x, char opr, float y); @$ n5 p& I, F7 Q$ Z
{
- L' K5 T, i) n/ D8 ]6 y/ ?    float result;& J8 i' n5 t" u* ~. E. L- A
    switch (opr)& L' B" l3 q# {7 _
    {# b" D$ D. r/ v) i* Y; |. _
        case '+':
- R7 a! h) g* q& A# Y( a  N             result = x + y;4 K0 I/ j+ b7 E" ^' |3 L' ~4 |
             break;
; s9 l- G/ N- R5 F5 }        case '-':
! A/ j/ [% s# {' S" ]             result = x - y;. r1 C  x$ Y6 b/ U
             break;  S; @5 E) U- T) S: H2 r$ Q
        case '*':
3 C: d  G9 ^. B- u             result = x * y;
3 K' z" M' X! Z. G6 p             break;  T* [& @5 O; D0 ~6 A
        case '/': & c/ B' W2 N! T0 }2 F' r
             if (y == 0)
  L! H9 A3 M$ p- F             {
0 c" z" @9 r3 K$ V                printf("Divided by zero!\n");9 A) ^9 h; a; F4 B, K3 }. I3 }8 }
                return 0;# c8 I! X; ?9 ?4 C+ v0 f
             }# g) d' [5 S3 X
             else- R( t' [2 L' _  E! P
             {5 e+ d5 y5 m, O& g( v' T- v
                 result = x / y;8 p- y! R5 F8 k0 M% `8 x
                 break;
, @* g* m+ L' C; `             }
5 r' k( _9 s' ]5 |6 x& s       default: & ?# [) k( M% ?( k  \+ ^; T
             printf("Bad Input.\n"); 4 j/ X( C9 Y6 @4 M2 c0 H" P
             return 0;9 t3 P) Y. G' K6 L; I; N! i- N% ^4 c
    }1 E$ d; y# q- T: Q
    return result;1 T, v+ f' H. C+ ~' _. I
}   
( x! C' U! h" I$ v4 V, x. l8 Q4 J( d/ w6 G/ J; S
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/9 k( r' v: X/ {4 U, p
{* P9 c* N! l! Z9 Z* _% p. J) [
    Stack optr,opnd;
' X2 ^- r7 Q. s- j6 ^- W7 c    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
! z/ j/ g4 @0 X# H    char c;
6 m4 D+ m& ^$ _    char buf[16];1 w5 j  E8 D* A9 q. f* }
    int i=0;
; m- @9 z) V" G0 A% Z: ]* [   
  u* t" E$ b" k7 f& `    InitStack(optr); /*用于寄存运算符*/; k. U  D! j1 o% p( T: z$ l9 n9 w
    InitStack(opnd); /*用于寄存操作数和计算结果*/9 R  i. e  z3 M! L9 N
    memset(buf,0,sizeof(buf));4 m7 F( m& Y6 j) P
    2 v$ u% U9 f  `; j2 l+ `
    printf("Enter your expression:");
* b& p: ]  @5 A+ b2 x& V        7 {: C4 s2 J* z1 F* Y) p% S% S
    opr_in.ch='#';
; x" g+ S3 y" @6 a    Push(optr,opr_in); /*'#'入栈*/! f% y' e% Z! X) p0 i7 f- ]
    GetTop(optr,opr_top);
7 o8 ]! |0 M: j* t9 i3 D' W6 \" Y    c=getchar();
" T9 N* K3 ]3 N: @    while(c!='='||opr_top.ch!='#')
) F9 `. k2 ~) I4 \" g    {- i7 |% H! d7 m% l+ t
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
& h1 U. x+ \; J' H: ]% t- K+ Z! t        {
4 h" Z7 J; E, @" g# t0 t            buf=c;7 d( ?# `( P) G
            i++;
7 ~. N2 ]& Z0 |4 J            c=getchar();. t) U* B7 x0 y4 p
        }
& a" D' h  a( T* A        else /*是运算符*/# u. H/ k6 c; m+ P7 G6 H
        {2 ^% u* X; ]' Z( E7 j6 f2 K
            buf='\0';
# |+ D$ m- o, y% _& @/ X7 O            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/% @- k& Y. f) w( }( Q
            {- F- o/ o8 \2 J* y1 u2 c  P  K
                 opn_in.data=(float)atof(buf);
7 k  N1 G, t& N# M" c! {% ~                 Push(opnd,opn_in);/ k: n- T* I+ f' h) c" |4 ^
                 printf("opnd入栈:[%f]\n",opn_in.data);
1 u+ J: y7 q: [: t+ i0 g! {/ k; d                 i=0;
" Y) N. o, ^  n) g4 ?; q% G8 g                 memset(buf,0,sizeof(buf));  }/ X" [  {# ]0 ]1 V+ j, ^
            }; U& W2 O* u# e" E
            opr_in.ch=c;' ?$ s' p9 f, }% X# i! s7 I
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/# t# \- @2 y) P& u
            {5 O. a; [# I% f3 D
                case '<': /*优先级小于栈顶结点,则运算符入栈*/5 U5 d  I/ e( Z3 K) T+ u
                     Push(optr,opr_in);
! ^& o* r- M% d. S  ?                     printf("optr入栈:[%c]\n",opr_in.ch);( z) k8 D, D1 G7 y3 B5 Y
                     c=getchar();
) H, z, w+ t* n# Y) V! m; U                     break;
0 Y# {8 \- U" j. \                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/9 d1 A% H5 P; m3 j+ @* s# m
                     Pop(optr,e);
0 d: E# k+ y$ e+ U7 [7 v                     printf("optr出栈:去掉括号\n");
3 X5 ]9 Q6 m# S, `+ _                     c=getchar();4 t! u, y7 k' {0 R
                     break;
) v9 C6 ^* f% R                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8 f% @) P6 e& N
                     Pop(optr,opr_t);
, a8 w" {0 R2 }                     printf("optr出栈:[%c]\n",opr_t.ch);! F( E. f# K, z8 @. s, s
                     if(Pop(opnd,b)<0)
2 d, B$ A6 X) x( g' V                     {
3 T* C' O/ a/ _1 G# `" M- ]0 Z                         printf("Bad Input!\n");1 U% y1 ?: l3 [- x* R6 n
                         fflush(stdin);
# x' H+ x% k' ~                         return -1;  u2 H, W" j) z7 _' b' X" t
                     }
+ T" C1 X+ q3 `                     printf("opnd出栈:[%f]\n",b.data);
9 e; l8 d& B" [2 L( n% h" s                     if(Pop(opnd,a)<0)3 u- M+ c6 n) c: ?* X
                     {6 l6 P# C- e/ a  O4 B9 B( z
                         printf("Bad Input!\n");! h3 I: q' M9 V- e6 u7 w: {+ z
                         fflush(stdin);
2 D* t6 M# A% Q" x                         return -1;
% d* a: R( ]2 F4 O* Y                     }4 \3 g- y& X2 O" B6 h8 F
                     printf("opnd出栈:[%f]\n",a.data);
/ w* q4 x, N2 v' F! Z& V; b                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 j# }/ K" a. X5 F# ~# a+ e9 I                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
$ {5 d: T; y+ V' D3 B                     printf("结果入栈:[%f]\n",opn_tmp.data);9 W; B* ?% s# F3 ]9 y" \8 p4 K
                     break;2 `) p: \' t% G4 E5 j
            }
' w' @( q6 T& x9 o* V& x2 i        }
7 ~2 Z' U4 F4 u* S' f- J; w        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                : k1 V& L5 Y5 [+ S& B
    }
; W+ H2 a7 o+ E: j( g    GetTop(opnd,opn_tmp);
/ P) b. i, q+ u: Z) E$ l4 E, V    DestroyStack(optr);
. x, Y- r3 E' x+ t: X! q" m    DestroyStack(opnd);& V  c' F& ~( I
    return opn_tmp.data;* s& A3 b& Z5 y' E0 X6 J
}/ g( Y+ y; L: |+ x+ M2 u3 u6 u; e; t0 }
! o) F# |! g8 ~: y2 r7 D/ N
char *killzero(char *res,float result)# H: f2 z: @* E
{- [7 f* C: m% ]
    int i;
* \, Y6 }& s8 r: ]3 N
+ \- i8 r3 A9 [. e    sprintf(res,"%f",result);
( R5 _" d3 U9 P2 W9 N! W; Z! c/ b    i=(int)strlen(res)-1;
% q, X5 `2 C' x; J" m    while(i&&res=='0'). u/ {# d4 B5 e4 \; k
    {9 Z# Q, }5 J' l4 h7 l
        res='\0';3 M. f  J9 X& h& q: T3 `. n
        i--;2 X* G0 R; Q  l' x- Y, I, w
    }
* Y# |* c. A" m    if(res=='.')
) Z$ j. l* t) R1 a9 f7 ~$ n        res='\0';
) G/ O9 X3 {( r    return res;
2 S7 P# [. A! ]' x}
  k. s; U0 s6 \" Y! t4 X7 }) L% m6 ~# n6 x( L
int main()
0 j. P! p; A( P& U{, Y+ g2 S. ]) L, o  [
    char ch;
6 o+ W" J$ ?5 h9 Q& s: W    char res[64];  ^+ f6 [% m% q* }9 X. Z
    float result;
5 D) H# h2 e7 f# e/ _; v. Z: _    while(1)
% K; I% T+ p) H3 P- p    {
4 i4 f& V% U2 y; B3 C% j% _        result=compute();% U4 @( N8 `( C
        printf("\nThe result is:%s\n",killzero(res,result));0 [+ y7 O' o. Z0 ?
        printf("Do you want to continue(y/n)?:") ;; R, ^; [4 i0 T. X8 n' p2 b6 d; Q
        ch=getch();
/ X  }1 ^8 Y: i) N# ~( |: o2 v- a        putchar(ch);: z3 a" \1 h' ^$ b
        if(ch=='n'||ch=='N')$ o, ?8 M& S/ C5 L7 U
            break;
: _. U& V" U$ j/ _1 a        else$ k3 S: m( [' o
            system("cls");
, i  f  ]( |' O8 _1 y8 l    }5 B/ B" z" |8 y5 |, D
    return 0;$ p) Q& @6 }/ ~5 q: R
}

. K& I8 ?4 t% {0 r" ^/ T8 J6 t" I0 Y( p; v8 L  }* @+ U( c
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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