返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
) G8 R- s& e0 X. C5 V程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
3 ~# a' F* Z, ?! L; \/**************表达式计算器************/* h  K- X+ r* ~9 N: h( n
#include <stdio.h>& M  E) K1 l- _# O
#include <stdlib.h>
  }8 p) i1 p) z; ]* Q' m% J% N4 S' v) s2 ^#include <string.h>6 `& O+ g! a* J/ M2 H
#include <conio.h>* d9 F! X+ ?, T: |: E1 X4 t
#include <malloc.h>
6 L, F- g( Y8 F' [+ W; k! g9 D9 C6 F. r4 x# P& Z
#define STACK_SIZE 100+ Y( J& `4 L1 w' o
#define APPEND_SIZE 10
' Q% _5 V; f1 b6 o+ `
6 V1 A3 f& _. |struct SNode{, }+ P- w  H+ U) t4 S
    float data; /*存放操作数或者计算结果*/! U8 \, S: V- w# O& F) _' c& k
    char ch; /*存放运算符*/8 D0 O1 P$ u* I) N/ {
};1 G- ^7 [% D) V+ X
. W4 \7 g3 I+ n0 c- [' n* x  O
struct Stack{
7 L7 M9 k) H( K) [  Z    SNode *top;1 l1 ?( O, b  @. @. Z2 u, T
    SNode *base;8 _  o1 t* p/ q9 P1 w! e& s2 h
    int size;! N  P" @( C# W4 J0 p
};
. j( ]. D$ J/ Y' Y4 y6 l
" z# X# L2 u! o( n. f/*栈操作函数*/
3 m- S3 o3 U) e- @* P0 n6 y$ ?- wint InitStack(Stack &S); /*创建栈*/6 G) T2 z7 {1 V1 U* V& E! ]
int DestroyStack(Stack &S); /*销毁栈*/! I6 B. N; z9 V% e& Q0 `
int ClearStack(Stack &S); /*清空栈*/
4 P- z- ^: U; i6 f) vint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
+ ~3 I- ?. E- D. m5 K& e* d/ G# {1 X6 Jint Push(Stack &S,SNode e); /*将结点e压入栈*/* b5 [9 k+ q& O1 V9 k
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/( t+ S0 }" ^, M- o2 y" R
( \+ t/ s) Z# l3 [8 f3 ?0 H& l
/*表达式计算器相关函数*/- a2 k9 e2 H) [2 M3 T$ o, o3 F7 Z
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
# B; Q$ A  K; q: ^+ Pint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/  j4 [0 R; j2 Y- K$ p
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/" ?" x$ @+ `6 C2 K% ^
float compute(); /*表达式结算器主函数*/7 n% P7 ~. P5 a( D2 c" m& |/ w
char *killzero(float result); /*去掉结果后面的0*/
7 v( _2 S$ F6 X# t9 ~8 Q/ N- t" D$ L/ Q9 C8 b! S
int InitStack(Stack &S)' s2 a# x+ t; ^5 S
{
( W/ G" A4 q1 L( p* Y1 l    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
9 Y  L' D) F! L+ v# A8 v    if(S.base==NULL)" m0 Q  ?3 V5 P$ J2 T7 ^0 Q
    {' {* X* S" _- Q1 ^! `6 S
        printf("动态分配内存失败!");
: p! _* P! I, d. a; c( a/ f8 T1 B! d        return -1;$ |# B2 u: u9 U  H6 q3 L
    }; V* C; D4 D2 n( P# k" c$ X
    S.top=S.base;( ^6 |  H, B+ q. ?) |6 \% o
    S.size=STACK_SIZE;$ a" [$ D! W6 m2 L8 s3 z
    return 0;
6 y3 ]6 w2 ]' d, U# s9 F* B* _  @}
, X' ]' @4 e1 r9 o  y3 w4 O- w: W
1 a$ m( O$ s) k& Z; N" i5 Hint DestroyStack(Stack &S)0 i$ E: ]4 @; ?0 X2 o7 ]% g3 l: r$ ^
{
7 H# p8 A* ~( ^/ i" ^8 b    free(S.base);" p+ a! d: \) ]) D) e: _& ]
    return 0;4 M3 k' p: g  j4 I5 z2 M
}
  F6 v6 q# Y9 k# o3 y
/ s) T& Z, S& r6 u7 w' J3 h. w( yint ClearStack(Stack &S)
+ V- g) h; A" ]( A% \{) [0 T) e3 ?# g  \( t
    S.top=S.base;+ J5 E5 j" S+ x; M! e7 n
    return 0;
" }' r# n* b3 k% U/ W- f( j6 H}! h9 R) D% w/ w/ c$ m1 W' j
0 N& o0 `- ^1 E) X- e, j2 D, P% O: `
int GetTop(Stack S,SNode &e)
5 C" Q$ Z! t1 B{  ?* y. D# R8 {# h- A0 Y9 P  _
    if(S.top==S.base)
! `9 X/ G3 S& L+ l' D; _' }    {. {' V8 C6 e+ F
        printf("栈以为空!");
8 g* r/ e7 \/ H( i; G2 m3 B% U        return -1;
- j0 L; f" W' {. C! K# m    }
" G  _# c! s  J/ @    e=*(S.top-1);1 G2 {2 L0 {% F
    return 0;
9 w( _$ _3 _, Y# q  j% }, s$ v' ?}
7 |. j; r/ n5 e+ [, X0 n; D& d. z: C% }. x, D2 ]9 S+ H; k' j
int Push(Stack &S,SNode e)
4 w: o, n" i2 N4 \( _{; g& @" j5 U; X" o9 _9 v  |
    if(S.top-S.base>=S.size)) b+ z( U! M/ b/ a( q! P. ~
    {, I& ^% s( a# h, {: f
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));# @% o8 v6 q6 [% D- }: F; j9 a
        if(S.base==NULL)
8 V5 z* o' m6 ]        {4 I5 C" q- G, X  N( N: a" h
            printf("动态分配内存失败!");( D& ?2 `, O: y/ W: ]1 _
            return -1;, O$ i* N9 ^% B* P4 P3 H7 m
        }8 |. j% P- ?2 M3 W' J- M" `
        S.top=S.base+S.size;
$ ?( u+ h. H; q: g! ~2 R        S.size+=APPEND_SIZE;
! t5 Q$ p8 l: K& l% F3 t& Q    }+ s1 W" L: P/ B! t& A1 s9 q
    *S.top=e;: F  l8 M6 p" n* v0 r& M+ q; F' H
    S.top++;
' G2 X5 ]9 Y2 Z; D4 T- J    return 0;. m" N; u. V0 v; e
}* p4 g9 j5 V: U6 B1 Q  [$ K
$ B' R+ Z! X/ {) v
int Pop(Stack &S,SNode &e)
& S0 r. E+ X# E( p* Q{4 _# [- I, e9 z4 L% ~
    if(S.top==S.base)$ z/ y) o" o: I) i6 B  x1 _
    {
$ ?1 V5 i& q. D6 V( `- y: u        printf("栈为空!");# g/ f$ t* l# ~; M6 F* H
        return -1;& k0 Y+ b: C3 o
    }* {! y8 I% M  a% ~$ [$ \- P4 J
    e=*(S.top-1);
5 q2 v9 t( G9 s9 Q" k. ^& [: M    S.top--;: c0 Y1 d, e; h  l2 ]$ x' P  J' n
    return 0;5 R  {  d2 S. e" A
}
0 C3 `0 n7 s) n7 {+ o2 M* X9 J
1 M( L0 q+ a6 G  d" ?( s, u: gchar get_precede(char s,char c)' G- b8 ^$ e% ^& Q4 g6 |6 t
{
$ u; n: s' I( {$ w% D7 u    switch(s)5 b6 b6 V( f# _3 M9 l
    {4 E7 ]5 g, p, X7 d
        case '+':                 ) ?/ ^2 ?/ m8 Z" ^
        case '-':- d4 [5 G. |' W; y2 y' l: |
             if(c=='+'||c=='-')
$ X" M7 b/ |( i' O                 return '>';
5 b2 `7 j" A+ h& j, ^             else if(c=='*'||c=='/')
: s; \/ ^( s6 k8 D! {1 t                 return '<';
! S0 f8 T  A9 `' e# V             else if(c=='(')0 l: n$ U% U& p& p$ L+ R' H
                 return '<';* _; \) z/ l8 W, _! J
             else if(c==')'). f9 H: w2 [7 l; D/ d. \
                 return '>';
! Q2 f7 x% s  z             else & Y" P! s2 T2 W( H: k& \
                 return '>';- B* T+ O- D$ Q
        case '*':
6 F# p7 D" \' S# V! w/ z        case '/':
8 J! q: u( P5 b- M7 D, k6 g             if(c=='+'||c=='-')
3 M) z$ T7 b: w" j                 return '>';
0 [" e4 \5 w) j$ {: V             else if(c=='*'||c=='/')
; Q$ ^7 z0 l+ K! h                 return '>';
9 D# ]0 t4 L; Z* Q             else if(c=='(')
  I: V4 D; B' I0 \; Z9 C0 S6 ]- p, `                 return '<';& s4 {9 y. s8 r5 P2 T' r
             else if(c==')')4 l, |& g4 z! o% _% g" z$ S0 Q
                 return '>';
0 E# y! ^& g! p6 M             else% M" u( p# X: K- ]
                 return '>';% U6 [* p  ~- w. M+ `; ?0 i
        case '(':6 U3 `6 ~+ q3 A5 n
             if(c=='+'||c=='-')
# u- ~0 b  W$ }8 u1 t+ Q                 return '<';
1 ]' X& J% T/ `8 j4 M1 @             else if(c=='*'||c=='/')  {( Z+ X3 F" Y6 O; ~5 g
                 return '<';
* R9 C' D7 Z5 \) j8 h7 K             else if(c=='('): c% \, s' b% }  h6 M. P0 d' a
                 return '<';, t6 _0 _7 E# [; g: x
             else if(c==')')9 y, n+ y1 _7 }' a
                 return '=';
2 @; T# a5 O! h& D' R  i) }  U) G             else- ~. W  V: R- v4 t' v
                 return 'E';
0 B2 n' I  y- a        case ')':' i0 e0 M7 D7 l
             if(c=='+'||c=='-')5 f3 a6 E& w  Q2 l) @
                 return '>';0 Z: Z$ O% `, n" d/ M& F: d- {$ P
             else if(c=='*'||c=='/')' `- K' ], [/ B; {
                 return '>';
+ \3 c. @. n2 j' M             else if(c=='(')  L# r  ?4 a' U/ R7 Q$ s& i  H) z: O
                 return 'E';$ ?- b5 x% t! F2 `
             else if(c==')')
+ L+ u* f# t: Y' s. |, d% K: N                 return '>';" j. N; z9 o  B5 L6 m' F
             else
$ p2 |, w% H( Z                 return '>';
) J1 _5 ]" m7 l0 c. _        case '#':- w4 t9 a. V" {  D6 q
             if(c=='+'||c=='-')
# D& N/ Y* w: a! S  ~                 return '<';
6 |' u2 x( H; W$ C. ~  _5 T             else if(c=='*'||c=='/')5 a: Q) ^1 l# U, L; X6 b
                 return '<';" P3 b' \9 h7 \9 j# k( L/ D2 H+ z
             else if(c=='(')9 }8 a! _( a9 d* O& z
                 return '<';
6 {9 P, }5 E( w' e+ w9 O             else if(c==')')
2 A% G' L" n. }- S7 J- w% ]# U) h                 return 'E';
/ \% t4 O! e0 b- u" H" |             else/ x: ], m& r, m5 I
                 return '=';* m; h4 Y0 m5 x/ u/ o( k
        default:
+ Y3 i# Q. U9 z" L) N3 d9 S             break;
3 H0 n( X5 P5 N! C# P    }
; O3 ]6 o3 ^; ?. l% H. |; I    return 0;   
; l5 \/ z. g8 _" x6 y8 V$ i! ]. G: J}6 W8 A" Z" W* c( P- [& _- a
: ], f) y+ B  Z/ L
int isOpr(char c)
" F3 P3 l5 v9 F1 T5 y{2 g; N! w& A1 O- E) r
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
" D2 b* {% M$ T        return 0;6 i; h2 s2 C5 R: Y7 F1 e
    else   ~* }4 s* p" k) ^
        return 1;
* Y0 _* {, i1 |& Y3 B2 ~$ Z}
( m; H! ~; ^, a1 f+ b4 d$ o7 d$ d9 M
float operate(float x, char opr, float y)+ ~4 F4 U) G! t3 }
{, g8 `5 L6 @$ I8 ~8 a* U
    float result;( c* N! P/ ^9 I, q5 ?2 B
    switch (opr)
4 R( u" l' c1 E8 }) y    {; l# F: {5 ]% O5 F7 j* o
        case '+':
# e* S; v" N- B5 |) Q- [# Q             result = x + y;
: R) I, j1 w+ W4 m             break;
9 W! w$ ^; {" r. h2 Q$ z1 _! o* S( V        case '-':
* W9 C; Q+ W! o7 R  ^  J' ^             result = x - y;( V. F  O9 q  N. E
             break;% J1 ?% s. y  `
        case '*': % p5 a) H: J% b
             result = x * y;! H$ M* W7 j- f( E
             break;; p2 d+ m$ j$ N8 l  u
        case '/': ; t* F* ~, A5 C4 ]5 u7 l
             if (y == 0)
* y- n2 v  G4 R             {
; ?5 u3 U' J1 Q/ E1 T) c                printf("Divided by zero!\n");
1 B# W8 H4 ]5 I& _% r                return 0;: L* h& E/ I# {/ {. z
             }
9 ]0 Y, R; W4 _6 ^             else
6 D% m. D) v* K5 ?$ Y9 V             {1 [) B9 ]7 h* p0 A! \; \
                 result = x / y;
; l" c: l) N* q" @- ^; {                 break;
, g. |3 n( ]* [- Y             }
* s- T% r- x8 w, a- X       default:
+ C- U3 P# ^1 d             printf("Bad Input.\n"); 1 A6 v/ i$ C' q! s0 j
             return 0;# K7 e6 M8 M9 T! L2 Y
    }2 N9 }0 k6 x0 x! x, n3 Q
    return result;5 l6 H7 M: m6 g: r6 e
}    $ U& K. d, S- @# H

* c- L. J) s! b. w* ^float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
* a4 q4 ^2 C% y7 Q+ o3 L! E{3 U+ e" z6 z9 W0 r* T
    Stack optr,opnd;* G0 j* K* d8 O+ i" l3 L
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
( c! T" M+ t* [* E* a    char c;
, G* W2 F$ M# O/ C    char buf[16];* ~7 M8 K4 B5 n* w
    int i=0;' k7 T3 \/ }6 }. @" h1 @/ p! t
   
+ I7 M3 o9 X  ]$ j1 ~9 [    InitStack(optr); /*用于寄存运算符*/' q& W4 Y7 e' z4 @: Q0 k. G/ S
    InitStack(opnd); /*用于寄存操作数和计算结果*/$ N4 R2 J) g" z( f+ J2 J' f9 N
    memset(buf,0,sizeof(buf));, X6 x  b: c/ p4 y" h+ @6 U
   
5 R( g5 ]$ ]/ ]( k8 v  u! ^" k8 c    printf("Enter your expression:");
2 V/ R+ u5 y, N2 b/ @& K& m; l        " i1 ]1 W3 F1 u/ U, ?: o8 n
    opr_in.ch='#';
' ~2 c4 ?4 {  J" A5 R. A- K    Push(optr,opr_in); /*'#'入栈*/
* P' W1 L1 ]9 A7 j1 r1 G0 d    GetTop(optr,opr_top);% a4 B6 R0 a) _
    c=getchar();
1 a, r4 L5 O6 U) d  n% _    while(c!='='||opr_top.ch!='#')* I$ M) B6 N! l8 z
    {
; Q9 o5 {6 U) |        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/3 o/ o& g' c( t' q7 \
        {0 K; K" E$ Q. @% R: h, u' t
            buf=c;
/ C4 b- v  M' W: C% R( N, a/ \            i++;* H) z9 i1 R, D
            c=getchar();
# O" [' t& G$ {! H2 p  r+ Y5 K+ E$ d        }
: l% m& Z  a) p1 j% [        else /*是运算符*/7 _$ g8 q6 w5 L: N6 }3 W. R4 v: _, G
        {$ r- l" v6 h- Y) V& W; ^
            buf='\0';1 o( V* j0 z. W/ V2 m  r1 C+ D0 a5 h
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/. u6 z. |; l$ K& e' z
            {* l+ y# m) M; v% H  B8 S) u9 h
                 opn_in.data=(float)atof(buf);+ A. ]9 r0 w5 J
                 Push(opnd,opn_in);
" e7 I! S/ O6 }+ x5 H6 v                 printf("opnd入栈:[%f]\n",opn_in.data);
2 s& \* s) G3 t; J- t                 i=0;2 s0 N1 H" u; o2 I# C5 D  T% y) z
                 memset(buf,0,sizeof(buf));
: `7 |/ Z0 l$ ~2 c1 u3 T            }
" @( A8 w! \. q$ `! E" h: t$ s5 Z            opr_in.ch=c;! k5 l, p- D$ c5 P" E; y! v4 v% ]* v
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/2 v) m2 P8 k  h: G" k
            {- s- A. x" C8 e! Y  x( D
                case '<': /*优先级小于栈顶结点,则运算符入栈*/9 J. ?$ i9 {7 P5 D5 q! f
                     Push(optr,opr_in);
  i/ e& D% s- Y- l                     printf("optr入栈:[%c]\n",opr_in.ch);4 U& ]! h; V6 x. H7 r
                     c=getchar();
: u! @: X8 x4 O! S. L4 w                     break;9 X; k6 |( z' }2 T4 j  X
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/" O6 y' |% h  c( Y  O3 X9 H
                     Pop(optr,e);
' n- v" x# B% B- i* _0 q8 ^! ?; u8 C, V                     printf("optr出栈:去掉括号\n");
2 ~2 f" g) S/ i; P2 q( v                     c=getchar();/ H7 ^$ `! O/ J' e( L8 I
                     break;  Y9 d/ t& z; t% G; S6 y
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6 o3 S2 X& v2 i4 u2 r0 o                     Pop(optr,opr_t);- ?, h7 m# C' ?% M# r
                     printf("optr出栈:[%c]\n",opr_t.ch);: |6 H) `: p. p% l' y, S
                     if(Pop(opnd,b)<0)
( I  y/ o: c+ J1 K& h                     {
* h  a5 W% P  z7 n0 s9 ~                         printf("Bad Input!\n");
0 a( @& V" O2 {6 ~+ |# m( J: e                         fflush(stdin);
' }4 ]3 @9 k2 ^                         return -1;7 G2 ]5 N: f: s; |
                     }
7 O3 F: d2 k, n, C* J. ]2 U8 Z1 u                     printf("opnd出栈:[%f]\n",b.data);
1 M* _2 M+ {4 F                     if(Pop(opnd,a)<0)
  I6 d. w$ u) i: T4 x% l- X, `                     {
. ~. H# Y& _# t  [  |                         printf("Bad Input!\n");
- K; {  |: Z$ C                         fflush(stdin);
! i' N2 w( c! n6 W                         return -1;
, B/ r: i: V" q) n; H) ?                     }& U* T, i5 f. o* i: k, Q
                     printf("opnd出栈:[%f]\n",a.data);
! D: U, |% Y4 z/ P" N5 v, _                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/$ x8 v- K& y. Q) T
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
/ v' M1 |+ M/ h! E                     printf("结果入栈:[%f]\n",opn_tmp.data);6 d' n; M! u- Q* ~4 @3 ?/ V  E$ c
                     break;# ]7 g8 ^* h/ ]! h. C' Q
            }
/ b& b; s3 R, p5 V: q5 G        }
) R! ]( Z' I* Q" X3 ]        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                + D, z2 k7 q  {* Q; @# s: e
    }
0 O- @0 Q! O* Q8 A+ H0 b; d9 X2 @    GetTop(opnd,opn_tmp);% W0 }+ B8 j  E9 {; \$ v3 {
    DestroyStack(optr);4 V# c9 B4 ?2 P- M4 F* G
    DestroyStack(opnd);
3 M- l" H( e6 a    return opn_tmp.data;8 Q, x3 }1 B1 O6 R" }  y; f0 N2 I
}
. O6 R1 l2 I2 W- h7 z7 |. j, o5 _) q) ]" _- c, B; T( D0 P
char *killzero(char *res,float result)0 b8 d% h' V, m8 R! c
{
/ s' }  q8 }% F- ~& Z' t    int i;' _9 |4 {7 J$ [* N3 m7 s
! _; N7 i/ D+ {% I9 A; n
    sprintf(res,"%f",result);* E: \- n: {1 C' Q
    i=(int)strlen(res)-1;1 N  V+ `; s# }
    while(i&&res=='0')8 ?2 z9 \  @( u1 S' U5 H  j! N
    {+ m4 g! ^5 F& @- ]5 ^% B
        res='\0';! u% D7 R& h9 l+ K$ ^
        i--;
0 |, A, y; W; m& e, `2 @' w    }
7 r, M+ L% c/ U: r: n8 f* J+ [( `1 J    if(res=='.')
% {5 _2 L9 `9 N" P2 R        res='\0';
6 B$ u4 z, r; _1 \    return res;
  E" q4 j7 k, {1 |; h}
5 A* ~) _3 b2 p! Y1 {8 s
  d. f4 Q6 U: w) x6 ^' fint main()
! H  X! _' R) s5 Q{
5 I% ?, Z: S) `. v    char ch;, r* [  L( J# [+ Q( _, B! h/ p7 E
    char res[64];
0 |9 y( a9 y( R, S$ ^    float result;
! L8 |+ @9 h" j; {' e% K/ q0 e    while(1)! w4 }2 v) e0 |0 \3 h6 a7 M; C+ P  j
    {. @: ]+ T' S9 T  w9 E& q4 t; |
        result=compute();
2 n1 r- A! H* G! J" D        printf("\nThe result is:%s\n",killzero(res,result));
0 g3 F' b6 q1 |1 B( S7 C. R9 A# q6 U        printf("Do you want to continue(y/n)?:") ;
, n5 x1 Q+ V  T* `        ch=getch();. s2 S- R: G% Z1 {' y9 n
        putchar(ch);4 r% ?9 c1 Y: W
        if(ch=='n'||ch=='N')3 s& p/ {  ~3 I  p7 t" j
            break;
! |6 R" D. b" N  T- t% J4 V        else3 u$ n8 G( Y4 \- f) k* m& V8 ^- Z
            system("cls");
% h1 H2 c5 v0 j9 }" H3 w1 @8 a; L    }
6 z6 _& N/ t* n$ W8 z9 U' n4 H7 e    return 0;
5 R" T* U& v0 A}
" ]$ q" q- n9 R) S" S
  `0 v: I1 K2 I6 T1 u$ N
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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