返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.( K8 u1 i, q. s( @
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
  F% G  s# x7 ~! e; K/**************表达式计算器************/
/ r. F5 ^) _8 Q# W$ b( V3 s6 S) e#include <stdio.h>
) W: A' |- O0 x, L#include <stdlib.h>
+ p4 c- d7 u# L. y0 x' s7 g; i#include <string.h>. A1 T: V2 c4 {5 G
#include <conio.h>
! J" `: {' T0 K; n, L: A#include <malloc.h>
' T) R# p2 I; u9 q2 M+ Z, X. ?9 E+ U8 G! ]+ K
#define STACK_SIZE 100
+ ]- ]5 Y/ Z$ T+ d#define APPEND_SIZE 103 g8 W( C! h$ k( q4 H
" H" U" ?* @. z" d- L+ K
struct SNode{
8 A" ]# H  T, p% _1 J, ?0 r, d" [+ @    float data; /*存放操作数或者计算结果*/
' Q+ J0 V1 u# x) t( Q- O    char ch; /*存放运算符*/* N$ }. _  E+ p* N- z
};
8 I0 `( h; S0 ]$ @# i$ C/ B% ~$ G* U& W% Q9 ]$ l
struct Stack{
9 z! j: d4 ^5 d: u$ ], X    SNode *top;
6 k' @. e# x& u9 o" o! I! u    SNode *base;
: |$ n0 O% h. Z! r" x    int size;
2 c6 |* S+ X' i/ h& e};- Q- ^- x  g1 x
0 x4 l: {# d% ~- g5 ^" u- S8 ?
/*栈操作函数*/
4 M9 A; b$ j( i; D3 Bint InitStack(Stack &S); /*创建栈*/
5 [& {9 D* _" n0 h; }+ fint DestroyStack(Stack &S); /*销毁栈*/
; E9 d9 O  ~/ Z$ w) Mint ClearStack(Stack &S); /*清空栈*/
4 d, B7 m+ C; _+ ]* T% Fint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
' f1 U3 X2 F. N: P/ F# nint Push(Stack &S,SNode e); /*将结点e压入栈*/
; y" X9 n7 W; L/ A5 M, tint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/! F4 _/ h+ J" a

4 b0 B& G! B2 e) x4 y8 `/*表达式计算器相关函数*/( C) F. j/ I" X4 x$ S
char get_precede(char s,char c); /*判断运算符s和c的优先级*/9 B- M! k) r# h
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/# z' s7 m# i: a0 y
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/2 L& L2 J9 r8 E* _- R) o
float compute(); /*表达式结算器主函数*/$ r9 x6 r% I! g7 j  m
char *killzero(float result); /*去掉结果后面的0*/ & w5 w5 E( g6 `1 h
4 L; M2 j5 X) o6 e
int InitStack(Stack &S)2 O- f, |- n' d$ i
{1 ~! @* r6 m# r# x6 U4 c6 S0 a
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+ O8 S, A0 \, o7 t
    if(S.base==NULL)
2 i! ]$ e) N' F/ }8 [  I& ^$ V    {
5 r- e1 T, X9 g/ V+ H        printf("动态分配内存失败!");
/ ?7 c3 B4 Q! P4 C* Z        return -1;
7 T5 z) [) G+ J$ g0 \- U    }
3 R( C$ k, q) c& p    S.top=S.base;
- M  \0 u0 S- v7 m    S.size=STACK_SIZE;
4 Y/ @" r/ v+ c# t8 p! ?  m    return 0;
! |, x( ^+ @8 t; T7 \) g}) }* H& m- G4 }/ u5 w- ^4 k

7 b0 Q3 S* U) U) T$ [( g" Nint DestroyStack(Stack &S)2 K' Y! m/ d7 `8 z& `, ?+ }
{$ G  v* G+ X+ {& ~2 z
    free(S.base);. b2 }* Z4 c2 h" U8 L8 _
    return 0;
" i, O5 {; b$ G9 ^* i}* l; c* F  k9 e! m1 o1 o# m
5 B$ F) o2 K3 I% e  t7 `, [
int ClearStack(Stack &S)
6 n, U1 Y7 R( \' \- y  ]7 T{/ b7 m5 {5 z+ k5 d7 Z" [
    S.top=S.base;6 ~0 p% E( a+ Y3 o- e8 v
    return 0;
( w! T+ Z' h+ X( }  ^/ ^* A}
% ]8 Z1 O" f. V8 A0 I& k* m$ r% e, m" N6 f+ L( q6 k9 C% ?- P2 w, w0 E
int GetTop(Stack S,SNode &e)/ n1 [! [8 M, b( G+ ?, d0 i
{
4 P8 H2 `. m7 `' {" C" f    if(S.top==S.base)
- Z2 r% J/ w1 Z% E    {2 k/ x2 N5 E% C0 Y. q
        printf("栈以为空!");
/ N8 z2 o8 J/ v6 T% b- W        return -1;. J+ M, P: \3 H5 ~; T
    }" r. y4 K3 B4 q2 Y5 G
    e=*(S.top-1);; @1 i- {/ B( |1 l$ h9 Z
    return 0;
+ u0 K& r1 u- O6 H( o}
5 Z, S+ b4 B/ w1 J3 x! j* i" y* G- V' r. U/ ~
int Push(Stack &S,SNode e)
" y5 Z4 x" T- ^1 F5 y2 u( h: J0 ~{
+ g% T! q6 n) u+ b    if(S.top-S.base>=S.size)+ ~! y$ V6 u9 K0 Y6 a
    {
  V$ g9 H8 a% l5 b8 d8 A3 B        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));7 n  r- T; S0 O' t
        if(S.base==NULL)8 j" v$ t3 n1 w5 x$ R" n
        {
  a- A+ N. n2 O0 x3 ?: ~1 C4 b            printf("动态分配内存失败!");
, M+ p0 y+ h8 ^0 k- u            return -1;0 n5 n5 _3 N6 ?7 q5 o
        }
  Q7 P: f2 A4 e+ a3 _' h% F        S.top=S.base+S.size;3 k3 Y6 @. A& a3 j  T
        S.size+=APPEND_SIZE;7 M- ]0 L$ T4 p' T# z3 n& @( i
    }8 A( u/ M+ Y% A( M! N
    *S.top=e;  {; q2 n# M( Q: v. c
    S.top++;4 x/ c6 O% K* t$ |" @, \0 c
    return 0;* _1 n# E6 }$ x# {# _# Z
}% U% H; D* Q8 U& G! h6 I6 e5 o
- ]- R3 Q$ U' e" C1 Q+ Z
int Pop(Stack &S,SNode &e)6 w) i+ `# R7 `, z1 B+ q
{
6 y, C' N- @4 N2 I    if(S.top==S.base)
  ^: `2 `/ m! b1 z. c3 I    {
' v. r' H7 T& }1 W  V        printf("栈为空!");
1 b: O: F0 C( p/ R! @+ D        return -1;" m* a+ F' ?' b$ B
    }
! _3 E: c* g, X! f    e=*(S.top-1);6 L+ F9 Y/ Q7 m
    S.top--;
: u, Q# Q9 g7 ~" b( x    return 0;
- a0 H. P5 q$ l( ]}
# v6 T$ P: i1 b2 M( I' t2 T. q
char get_precede(char s,char c); G* x% h" S" |7 h. M
{, C( m3 |2 k( Z0 N1 k  A5 }
    switch(s)
/ Z8 P* U1 C- w/ q$ z6 p! b    {6 Y; G: G1 T2 M( H/ j0 U
        case '+':                 4 x/ r  J/ j5 y7 [: ^
        case '-':3 z* q, ]5 P1 M
             if(c=='+'||c=='-')
- w4 |% F  @2 D                 return '>';
; s' ~6 j( R7 [             else if(c=='*'||c=='/'). W) {6 \$ ^4 w' @% X; M
                 return '<';
! l4 @% [7 b% @) S1 B             else if(c=='(')4 w% A( V0 h! D5 Z& T2 l* L! g2 k
                 return '<';. n* D7 {# w, ], |0 x3 r
             else if(c==')'). \) Q2 o4 w9 t, G- F- F
                 return '>';  N, f) u( d4 Z9 S) F
             else * c+ `6 j8 ~2 E* c9 ]7 G
                 return '>';+ ]  }+ \: ^! O" V1 N0 _! H# j
        case '*':
$ I; \) T1 X$ D: P  V; ^9 A! C        case '/':
* V: L. x0 W+ ^/ @7 x             if(c=='+'||c=='-')
8 C0 |+ q) T8 I                 return '>';
) t) Z1 m* n5 _( l7 W. i             else if(c=='*'||c=='/')! g$ d) \- V4 `+ I4 v  a, p
                 return '>';! W0 e. }+ X, o& S  {
             else if(c=='(')
3 z& L" k  ?! z( H                 return '<';8 N( Z: t5 A: r: o3 G7 E; i8 h
             else if(c==')')
) x1 W! |9 W7 \$ o, ^0 j$ D0 y. t- |                 return '>';
3 x. A% o* u$ ~) U7 G4 ?7 m4 c             else/ B/ O% O; n' c! x( I
                 return '>';1 Y8 W" B! u% T* Y( r; h
        case '(':4 V% E+ B4 P. e
             if(c=='+'||c=='-')
' Z' n" h1 t: @  c" A) T                 return '<';
5 o  N+ e$ @4 e) u2 x% `             else if(c=='*'||c=='/')
# G: T- I( A  `1 c& O! O                 return '<';/ `+ R1 n/ k2 L) k
             else if(c=='(')
" }) F3 T  k1 U  b                 return '<';
: Y- t0 K: |- y+ h             else if(c==')')
) A* D0 a$ j$ e4 f                 return '=';
+ m; y( y/ s# ~2 T/ ~4 P, F! U             else* T% D% M$ a7 c; z; c
                 return 'E';5 Y' g( g! j; P% @) ~" E# B
        case ')':2 ?; i3 R2 T7 H  b1 j- U- ?* @2 a
             if(c=='+'||c=='-')" k: P6 h; |% k6 y8 V# ]4 G+ m- J
                 return '>';
0 X& b' x* ]) d( B! z$ p$ b7 F             else if(c=='*'||c=='/')
9 r6 K  V. g1 I) ]                 return '>';6 P8 w' }+ P) K  Q4 Y& I  a1 g
             else if(c=='(')
0 b! i, E. r/ X: y- N5 l* f/ I                 return 'E';
, \- I9 Z, q3 S             else if(c==')'). `- n( N) m; V6 b
                 return '>';
5 a$ ^* a" E. D: N4 i% k             else
7 k4 ~6 n1 Y% L3 ^9 M8 U                 return '>';
! f0 y, c  b4 c9 d. o* x( b* l& H        case '#':
+ ?- H( U% |: c" l             if(c=='+'||c=='-')0 Y! A$ c& p6 b! t: i
                 return '<';7 M# {! s" p* \
             else if(c=='*'||c=='/')
- C  [. T8 I8 A. \$ R1 V4 v2 q1 \                 return '<';
, i" D5 k$ U# b8 N0 K) d0 p! R+ _             else if(c=='(')8 e3 @9 d" [/ F( g% _: K3 X
                 return '<';
) ^( D3 ]0 y% r$ I: I4 M8 ~  I3 B! n             else if(c==')')! F8 B8 \( G* K& I- i2 s7 }
                 return 'E';) [) _& c$ G) r; ]5 d3 J% K
             else  \% A1 y, U  q
                 return '=';
- S/ }* i3 Y& q$ h        default:
6 F. }5 d  u  T, n+ z3 @             break;) [6 G! h" ?( v/ m3 a( b
    }. Z( C: I* v4 @# @0 R1 q+ o
    return 0;   
  q' Q; o- G# w, _( D5 f' i) y}
' f( j0 S) e9 t4 a
- J- I+ Z8 x  U' I. kint isOpr(char c)" @1 ~  y0 {0 B& ~- ~' }
{% {0 w. c2 u, p* Y0 d
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 k! h5 e* s3 R        return 0;
$ S, x5 g& O! h) }6 F; B5 }    else 9 V( c  |* c$ ?0 s+ D
        return 1;
. n6 U. f; K4 b3 z- A}
$ e+ V# N4 c' G2 m1 H1 [$ @+ a; _% w. I
float operate(float x, char opr, float y)
% d9 R: S& u+ U3 ]# }8 _{( ?+ W" B3 ~* \  u3 [
    float result;( {" s7 s: ?) U
    switch (opr)
6 c4 E' q6 w4 u: p( L' }4 L    {
. d8 H+ |1 M8 ~+ O        case '+':
, N0 g: a/ N0 J. H             result = x + y;' [) t8 a4 @* G. f2 b+ z
             break;
* {0 j; H2 F4 b, c        case '-':
0 `+ W$ z% ?( E- u- N             result = x - y;+ p$ V) M- y9 Z: K; X. e+ \& a
             break;
* p; L, ]9 n+ R) P: u        case '*': 7 Q  e, g0 j0 L0 P% V; m5 {# k
             result = x * y;
% p* ^+ ~' x! i, |" y             break;3 e, x, u3 J) r+ I$ c  ~
        case '/':
4 j: q- P- i4 {0 s4 Y' E             if (y == 0)9 k, r, G- |% z) T$ ?7 N' w& K4 @
             {
! T5 [! L  J1 o! H; v- r! h                printf("Divided by zero!\n");2 P& u" q( I# @: N! N: p
                return 0;
! }$ g1 J! Y4 X5 [9 K) ?- q; z             }# J& d+ X* q( W; {' S/ A: `" T
             else
9 }* n( R: U, C3 @+ @' ?             {
1 L! Q( U. O* H4 J( \                 result = x / y;
' N7 [; K8 p; M6 S5 @) [6 Q) d                 break;
* B( `) k7 H; i' z% m9 s- E7 }             }
6 F0 \" r% r$ |- _3 N       default:
# K- c* n: V# b' n             printf("Bad Input.\n");
9 b, `: o% ~& }' ~7 Y3 V8 @             return 0;$ S4 b" \6 }0 X! o. V2 q
    }
* v" s$ v7 ?( z6 @    return result;4 Z5 y, b# X; G5 h. d1 |
}    8 [# R" S. @* `' A  G2 o$ m

% \0 t5 w8 h8 l  E9 Nfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/! W+ W; |9 _; L' l
{3 A- B: h3 Z% u  N
    Stack optr,opnd;
* _5 p& B- W$ X    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
- M: o1 x* B& @0 R0 M" j4 b    char c;  r8 i) B+ x  l; m  K+ G
    char buf[16];
; o& X( O, s0 q" L: z. X    int i=0;
! m) L2 E8 V: j0 `- G4 J/ R! X   
" x9 g6 c% X  Z: C1 |    InitStack(optr); /*用于寄存运算符*/
# ~0 k, U; ^  w3 l$ v    InitStack(opnd); /*用于寄存操作数和计算结果*/
3 x  ^$ d$ f9 e  B/ M1 `    memset(buf,0,sizeof(buf));
) ]! }! @' P# {! g8 s; K    ! _5 V% l5 r2 X; ~
    printf("Enter your expression:");$ e7 c/ G# |: c6 \$ v. w% f
        
- H/ a( d9 c! B" M2 U    opr_in.ch='#';9 f8 @, \+ B+ F# C& N; f% j
    Push(optr,opr_in); /*'#'入栈*/
) }( f  W0 b8 O! u! \5 w    GetTop(optr,opr_top);2 C& y) u6 h: s" ]; H- W' {1 ^2 @- x
    c=getchar();& |1 k. \  K: M, m
    while(c!='='||opr_top.ch!='#')
# G! b# w3 }, {( u3 [- E$ M    {
; X  L. ^6 |% o4 ~% O* W' p        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' M, I" T. D! m2 p5 p        {
. w4 c& ~9 A2 d' ^9 o& U. t            buf=c;
' K- Y8 ]  _5 V3 F) y! M# U            i++;" {. [" [. R. J
            c=getchar();
3 j7 f2 h4 i- F0 Y% b        }
9 t3 g/ _0 i$ Z$ B/ r/ j5 }# G        else /*是运算符*/* g9 ^* s  B, W, E- B6 l2 \
        {
- U$ P) C  S4 m! ^/ ^. _" H" l* j            buf='\0';
: A9 `, d' j- U' v$ K; I( o            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/8 b" l" L5 ?8 Y  d& B5 A1 P% J
            {
( Q1 {. M" N* e# v; k                 opn_in.data=(float)atof(buf);
0 m- |# {/ M' V8 x4 i                 Push(opnd,opn_in);
3 i5 l; R8 \4 B8 n1 v- T                 printf("opnd入栈:[%f]\n",opn_in.data);% ]$ {6 V: e2 i9 K6 q( i" T+ z7 K9 t1 s* b
                 i=0;2 `: B1 X% r3 C5 U+ t  `5 J
                 memset(buf,0,sizeof(buf));
& b# t" N7 A* Z$ k7 j5 ~            }1 `# q) o& P- @; }7 b0 L4 F
            opr_in.ch=c;# J7 }" [; J2 l$ o
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/) s% \! N1 b% Y4 X( t
            {
: B* ~+ A! b0 `# m8 p" R3 _                case '<': /*优先级小于栈顶结点,则运算符入栈*/  Q: W( U& A# k- Y$ E
                     Push(optr,opr_in);( X3 y7 ~3 c$ P0 C$ V8 F7 q
                     printf("optr入栈:[%c]\n",opr_in.ch);
+ _( e$ m7 c% F8 d: V! z1 n                     c=getchar();# c! X; ?1 ]9 ~4 N& h4 K
                     break;, J- H$ T- e! r- O+ F
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/" b) x# Z% }# q1 P1 B* f5 O7 |
                     Pop(optr,e);8 j* e& a( D; R$ c
                     printf("optr出栈:去掉括号\n");
* G4 d; u8 Z% b: W                     c=getchar();
0 m$ P  w" ~* s/ _6 ^- d                     break;4 R: G, r9 l5 B2 r) I7 q. o7 S
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/9 G1 @; T' w, @8 T- b
                     Pop(optr,opr_t);
0 p& ~/ m' A7 C2 j" e8 i                     printf("optr出栈:[%c]\n",opr_t.ch);4 e4 U& B& m. t7 B5 c+ v9 q0 K
                     if(Pop(opnd,b)<0)
4 i! R" V/ V0 A% u/ L/ j2 w: b, E                     {
' |* u$ C/ F# p% S$ |0 G; A                         printf("Bad Input!\n");1 P& Z) D4 ?' e+ x/ P" }, R* h
                         fflush(stdin);
% m& D- p$ S: h' s                         return -1;
( T1 S; Z1 G# A8 {0 j                     }
5 j( h2 |7 `5 a2 W; H0 p& ~# e4 o                     printf("opnd出栈:[%f]\n",b.data);9 e3 @% w  s9 N+ |
                     if(Pop(opnd,a)<0)5 [/ g( q$ d) g3 E( y
                     {
9 y3 j& z# J0 @. m5 f, k  ^0 |; E                         printf("Bad Input!\n");
  t) c: {/ K4 @, K+ I: y& a                         fflush(stdin);1 a$ I! U- C2 a5 ^8 r  e# i6 }" N
                         return -1;+ ^' S# j9 o* h  ~% i
                     }9 A* e1 r" Z$ c7 z
                     printf("opnd出栈:[%f]\n",a.data);" @; G% l+ c; e( n3 {# [% \
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
, t- }0 ~" \& @6 E                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
- p  u- ~$ E/ p; b5 Z; U                     printf("结果入栈:[%f]\n",opn_tmp.data);
* Y$ Z) G, p% P3 _3 Z. @                     break;0 k2 J2 B% Q' x& N3 l/ }+ N; [
            }; R; v1 @; j8 @2 d2 M
        }
) _( ?" O. v4 J! \. R  K        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
' u4 z1 T0 b' ?6 k6 j& L5 A$ `; U    }# C7 f" _5 |$ G9 v; x9 y
    GetTop(opnd,opn_tmp);' \& v0 N; \3 ?! A8 I' [
    DestroyStack(optr);7 i+ r* |/ Z/ D! C% W  q, _+ [
    DestroyStack(opnd);: v; e% O( y7 `( O* m& t; b
    return opn_tmp.data;
4 }8 r% V7 H6 ], f" K7 I5 `6 h}
1 b+ L9 a& \1 C2 U
/ n% P4 |9 G) x: v( Q( R- p1 w$ cchar *killzero(char *res,float result)
9 z. K  X4 s5 l/ B$ M{% `1 }- r' N5 ?
    int i;
2 Y4 `( B& T+ }, e8 C' l. a+ I
9 i: O9 \. E- e& D    sprintf(res,"%f",result);9 I# A! \; i+ @: J- s) C, Y
    i=(int)strlen(res)-1;
+ P9 e7 i! F8 j( E% k" C% J    while(i&&res=='0')
  b. \3 `5 v* T. C    {
9 {& ~/ A6 [% p/ P  \        res='\0';6 U/ r* n# I5 r6 k
        i--;
6 I, W6 v( v5 Z8 n+ M4 P    }
/ s; T# c! C2 t1 e  r! l6 F; h% S    if(res=='.')
5 H7 h9 N  S/ N: i/ o0 R        res='\0';
4 V/ k2 |% U( z" j: R0 q) O: n) F    return res;
' d! s0 }- O. Q1 e}* Q% C# H. V  V+ h$ g3 ]

' T; [5 m+ b8 S  V; h  W$ xint main()
7 ?& a4 Q8 Y+ j- J{: B# s, n: F) R- z6 Q, \
    char ch;4 f8 o  |8 H5 _. r, l2 _5 k
    char res[64];
8 l2 {& g0 D. j* u1 B8 M; L+ a% }    float result;
7 X6 m- Y) y  i    while(1)- f% @6 E( x& o1 R, u
    {
' b# j# z, o% l3 \' Y( g        result=compute();
/ @) y5 {0 l9 |6 D% n, z" m4 R; x        printf("\nThe result is:%s\n",killzero(res,result));
  g* O7 e5 e/ E; P        printf("Do you want to continue(y/n)?:") ;
4 e- ^$ p+ I) v% l        ch=getch();
' @8 @/ e; Y. L% }# |; {        putchar(ch);
1 n* s/ g" Y; w; ^% j. r: f        if(ch=='n'||ch=='N'), O: I0 J* R+ H0 Y/ }( u2 o
            break;
7 l! W. M0 w0 ?9 l" E8 W4 y2 B        else1 `: F" A" R- y# v" q; Q  Q9 }. t
            system("cls");) b' E7 O; V/ z4 u, d  T
    }( `( r+ a$ i* s; u7 D
    return 0;3 X6 R( C! q/ _7 a: B5 V; i
}
6 m  M! r: C- E4 B

) ~1 R( Y, a2 [. W! n2 i[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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