返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
& f- @2 {2 T, q' @0 x程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
4 z. Z# C: w8 O# i: H/**************表达式计算器************/7 S$ d' v% H6 o5 Z
#include <stdio.h>
$ H7 K5 K  G, t" G#include <stdlib.h>: a* `% v, @& Z1 b, K2 K( o
#include <string.h>
1 ?# o; S) H+ N#include <conio.h>/ Y6 x# c$ F4 `! v; }; h
#include <malloc.h>' y8 O: U6 e, b! G- j' n

6 c6 u2 p( A9 ~* X, c2 h3 r3 b#define STACK_SIZE 1007 M: O+ h3 R4 Q; e, w
#define APPEND_SIZE 105 d' g9 W" P  ?
* F0 B* I& x' I# D- c, Z, B. ?
struct SNode{
+ _4 G4 p6 R+ e    float data; /*存放操作数或者计算结果*/
5 v  q1 N( @* F6 C  j, |    char ch; /*存放运算符*/
. M  j& S5 |9 U1 ^: S. g# `. }. M};
' A4 K# b( O3 D+ d, I
4 [7 p; V$ W% m- k. _2 {struct Stack{
- D1 w( {7 l8 O; D( R    SNode *top;
% g* ~! O$ J: b& O: S    SNode *base;( D1 L5 R) F4 G( j. |5 j
    int size;
3 ~0 O( _, K/ i  J( r1 C4 i};
& }* b2 S" h8 ?
+ w! M# r8 H( F( L+ P/*栈操作函数*/+ C4 m4 ~# C3 V* k& x
int InitStack(Stack &S); /*创建栈*/1 c! X! E+ R7 P+ z' Y4 ]4 A
int DestroyStack(Stack &S); /*销毁栈*/
0 |; u- l) \+ H# d! F4 t, g0 `, c$ \int ClearStack(Stack &S); /*清空栈*/" b9 m  f7 K" H# L- E. f
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/( _0 p) f9 V/ }2 q! q3 Y) h
int Push(Stack &S,SNode e); /*将结点e压入栈*/+ ?$ N. b0 W! c( x. J& i+ T
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/2 u, a5 J& Y) S7 n7 X

- n3 z, p9 l' Z3 a& k% y/*表达式计算器相关函数*/2 h( V! n  G* n" L3 I  R3 ~4 Y
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
# S4 S1 s8 S* Z6 M* cint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
7 t5 a" g; `, y' T6 m' E# @float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/' s0 w3 y! P  R. {# |+ s
float compute(); /*表达式结算器主函数*/
' b+ O1 h' c: j2 Xchar *killzero(float result); /*去掉结果后面的0*/
4 \0 Y- ~" [6 ~. x
- s. G- w& v, d2 lint InitStack(Stack &S)+ k& Q3 J1 Q( s5 S8 @2 a
{1 |; [' s( g3 C( `
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
  _! ~' j0 \+ p9 h2 _    if(S.base==NULL)
& I- k1 J  \$ b- S$ ?    {
' f  ?  D! I' H7 X        printf("动态分配内存失败!");
2 P" ]. g( `& w) f        return -1;5 Q5 k! Q7 b3 j! x: S  a* N
    }( g/ I2 [. L, |# \" h
    S.top=S.base;
/ t4 s$ U" \5 T, v# {" O& I7 i    S.size=STACK_SIZE;" K) c7 B& X. y4 Y
    return 0;( T' j6 r2 k: [& |
}: j8 E5 _4 I& K6 o' v0 t
$ G+ p- Y& O$ ]3 A. L# T
int DestroyStack(Stack &S)
% g) o: f# z8 K1 @! o: c) _{$ a9 X, f( R( ?6 M% \: `) `
    free(S.base);
0 C$ q- s3 a* A- a    return 0;
9 @# q+ R. v" d/ u8 s}
  j5 n4 V+ U5 h, T% [0 Q% [  {! |& x! F) w0 v% o1 `3 v
int ClearStack(Stack &S)
2 j$ V  S2 u1 {$ v) y  h2 A- N{
; y' o( Q* g! n0 K6 P4 `    S.top=S.base;, U* A8 Q3 G! M& O( U. H
    return 0;  b% b* q) V1 q9 d; [# z) _' D
}% v5 ]) a0 y( N! n" T

) x! _; Z4 u" t/ F) I& s6 dint GetTop(Stack S,SNode &e)9 g3 F. c) j+ ]; C& S# h: l- }+ f
{
/ ?! P/ w1 [  Z1 H+ u    if(S.top==S.base)6 U1 k$ D" u' k, e- k
    {9 }9 }3 f8 h5 v0 h) n: `- e: _, b
        printf("栈以为空!");: A/ n: o7 {  t1 `' v/ p
        return -1;
- M# l3 s. _. o) u" s$ X: d4 Y' D' g    }  W$ {% j' ^6 h0 r) Q
    e=*(S.top-1);
2 J# R/ J& U7 J    return 0;
; R9 V, g+ ~2 I) g}! K' Z- Y0 O' T5 G, s: D. _

* c- u4 D5 u' O( a0 C+ e6 oint Push(Stack &S,SNode e); d$ c$ v, {1 P9 r4 q+ W2 I
{
% y4 |6 w( }0 e' I$ m    if(S.top-S.base>=S.size)6 Q2 k: k( N3 o1 w1 M+ J. i
    {* ]5 D3 E! p! Z0 r- [- c8 I3 N. H
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));$ f; w; B) X( d4 P/ q$ g- m3 R
        if(S.base==NULL), d6 J( ~+ M9 b' |
        {: v- [  V! t. W
            printf("动态分配内存失败!");
4 v: C" _: h, Q            return -1;
% Q7 W5 o+ R% H' Q        }( p3 p" b) j! t& l+ V/ J
        S.top=S.base+S.size;
" ~2 f2 A" H- X/ I5 U        S.size+=APPEND_SIZE;
5 [* \, @" i  I# v3 |' {/ {% v4 h5 E    }  q+ z  w8 s* \. p! j! J, J
    *S.top=e;; V8 o2 X( M. D" E5 ~# z
    S.top++;
  `8 S! n" v  x( u) m( l    return 0;
6 G8 k2 U: }" ^! B9 g2 Z}
# }3 b1 Y7 R% u0 T9 a& d( j- {9 ]( }
% B1 b' u: J/ o6 ]" }7 ~$ Qint Pop(Stack &S,SNode &e)
+ ]" H* K6 k3 ~6 m{
  u3 g2 ^7 E/ o6 h, R4 k, [    if(S.top==S.base)" [! e5 ^6 Y1 Q5 w4 a4 b
    {5 q" I2 ~  Y, g3 _1 X. F
        printf("栈为空!");9 c3 v, u' f( q* N1 T% o2 N
        return -1;4 i+ I; c* Q( E3 H# p4 v
    }; v1 ]1 K+ Z* F  s& v' s0 }" }
    e=*(S.top-1);8 ^$ W, |0 {- v: i
    S.top--;, O" D& _/ t1 p; P
    return 0;
1 R+ j7 K% Q1 q0 r- |  S0 x}# p0 |# s/ c, E3 T1 V3 n
. `5 F5 Q& \4 m6 V" }5 U
char get_precede(char s,char c)
5 W4 U% o' v" A  |) ?{
7 I+ m& [% n( ^4 W( g6 G& k. m$ m2 J    switch(s)0 Z2 V4 ?# Q7 z. U
    {
! ~! ~3 J' O" ~; Y+ e7 t0 \3 A0 k$ ?" E        case '+':                 
5 h5 E* @) T6 h4 x0 b" y& D        case '-':
  n6 ]) X( {+ \+ g. L8 h             if(c=='+'||c=='-')! n" n* ~7 L9 T0 I. a/ M4 ~
                 return '>';
0 |4 g0 j0 k: v: v             else if(c=='*'||c=='/')8 u2 W& Q: n. m
                 return '<';
) _% J) R0 T+ `! u1 l, a( d             else if(c=='(')
8 e& f" p/ ]; }2 Q                 return '<';
% k" F+ T' U: {; z; J8 d$ W             else if(c==')')
: E$ s; Q( _# o- D                 return '>';
- Y0 W, `% s$ K' y8 [- w             else
$ z' Q) c5 l7 G% n  T5 w                 return '>';
. p9 U& t9 S) q) R( `        case '*':- I* v- u" _9 o( c: D  c
        case '/':
; X0 O+ n, x3 q( m" _+ n             if(c=='+'||c=='-'). d9 U/ |; W3 o& v7 t  w
                 return '>';
* c& p/ J: ?$ ?) O1 u             else if(c=='*'||c=='/')
' Q1 l6 g0 m( U' r, }                 return '>';
* h% ^- d2 ?  }. u' |; c             else if(c=='(')4 y+ W( v- \6 ^
                 return '<';$ M1 s4 G& B% X3 p
             else if(c==')')
; H  l5 Z1 D: S! }/ I: d                 return '>';
! [& B- ~9 {1 y6 {  K             else
! J# B( P$ z, Z& Q; I% _                 return '>';
% v. u+ c' w, C7 L        case '(':" Z7 d' [* W4 R) {& [/ c1 w/ k1 c
             if(c=='+'||c=='-')+ C- n& k  K, g7 R1 e9 \
                 return '<';
: q3 h& C1 K2 F/ J9 T  |             else if(c=='*'||c=='/')
( e6 |1 E) {& f2 [: G                 return '<';
& K2 g7 R0 S) W1 K* m) M             else if(c=='(')
; i! b2 `0 e, S( k2 I* Y2 }                 return '<';" R5 ?+ z. `6 {5 @7 G, o8 F: b
             else if(c==')')  ?8 d/ |/ h& o- }+ o
                 return '=';8 C* Z6 m- Y5 ]! @( n# J
             else5 b7 [5 [0 X. V% W+ [
                 return 'E';8 V# g' Y- f! A& V: D! W0 o
        case ')':. k+ ]$ j8 j0 \5 C1 F& {5 v0 i$ Z
             if(c=='+'||c=='-')8 g  O8 f$ z3 @
                 return '>';2 b3 q- c4 |  H+ k
             else if(c=='*'||c=='/')
: _5 o5 y, J! ^                 return '>';
1 p% K7 b6 @& _3 D5 R) g             else if(c=='(')! {  z+ Q4 d% K3 n7 _9 R
                 return 'E';
4 U/ C+ ?: w; _+ V: f/ A             else if(c==')')+ v7 D2 L9 O" z( P) t
                 return '>';( [) C  I+ R: t" J( p" E/ P
             else
* s3 h' B1 D3 ~                 return '>';  j9 I1 e7 Q* G4 R" J" s2 j! E3 g% F
        case '#':3 I* @: k. E! z/ @: k+ h9 i" X1 O  b
             if(c=='+'||c=='-')3 V" r" y! A0 w" |$ ^2 H% O; H( |
                 return '<';, g/ _" T: _- J0 W9 Z# j$ I
             else if(c=='*'||c=='/')' v  N' S8 [1 w' H
                 return '<';
; a/ m2 h5 r& Q             else if(c=='(')3 A- n2 ]2 G; Z$ U* T% {4 }: x
                 return '<';
- T, z/ Y/ A) x& O* ^             else if(c==')')
1 f* ?5 ~, T9 u  j* ]% y                 return 'E';
  @, q) n( n) R/ o: p             else
  g. d. \- V; y7 X5 ?" H6 T                 return '=';
) _2 D" @5 l6 B9 U& W        default:8 u) e( h: V: I# S/ C3 y& w% H
             break;- y+ M: O- O& O- W
    }  E3 \. U! ?' ]: B3 w
    return 0;    6 M# j1 s2 S! ]7 q; K) I
}
) n  ^  K4 o# G$ w9 o+ p
1 C2 b/ l, N5 p' b4 a5 I) t- xint isOpr(char c)
% H# J2 O: g( p% ?{
& u9 U) b: ?. n$ z    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')% S9 _/ N  f* U/ L# i
        return 0;
7 _4 x4 X  C8 T$ l( ~    else ) }, Y/ I0 P6 f- P* i1 b
        return 1;& p* F+ ]$ a- x9 f6 O
}
0 j% y2 I/ s8 C4 ?  e2 q: x, e/ L  j* a  u, P
float operate(float x, char opr, float y)0 k1 v! I' t* q
{
$ }. C  G7 B- n    float result;
# `7 S4 a. j/ o    switch (opr)8 |2 Q, M. L: M5 l4 Q. L
    {. R6 K* J# [. t& n
        case '+':
* D  b1 ]8 Z3 ]             result = x + y;
1 f; I* ]6 L; \1 C. e, `             break;9 C; v5 a& B3 B4 z7 _5 a# ~8 b2 E
        case '-': 7 j5 f, E, f  F9 X
             result = x - y;# g$ I" K; B6 n9 H2 \2 @
             break;
/ C' g- a' Y0 H0 s5 a        case '*': ! R+ M+ l& V' c7 b) ^. j+ L6 L
             result = x * y;
- R. V5 w' c3 \; G             break;& `! G1 B& e! D0 p
        case '/': * W- a) r; @. K( r
             if (y == 0)
! ]- Z: B# \  `/ z             {
7 O2 k4 u0 v$ j                printf("Divided by zero!\n");
' y- F9 d7 o, Y/ U                return 0;
6 I4 H8 ^/ n- A, y4 M3 |) O             }
; J7 S  U" w: l& w+ b             else4 O. f( E1 W( l  |+ y
             {+ Y" i* t8 ~* }4 i) z% T
                 result = x / y;  i. X  R, m% Q# u" W3 b. d% o
                 break;
" p0 X: [/ a; M3 r% N% B             }
/ n: J" U/ [) @' J       default:
% m8 ]/ a+ ^1 T* K- D% g5 j) j& F             printf("Bad Input.\n");
, a8 Z7 j) n' Z             return 0;7 s2 t( T1 @" `7 M" x2 k+ R5 Z- I$ s
    }: d. H0 t6 j9 z/ y; V8 Z/ B  u
    return result;
; R0 x$ {8 E* g( L* L% S* o}   
, @* S2 O; L$ w7 G
: t, n' J4 n# ?2 q6 Z$ G/ e/ {float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/$ x+ L  K2 E2 P$ l, v! w
{4 s* B4 [4 }7 q' ~  [2 L
    Stack optr,opnd;4 y$ F, F) \4 M; |
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
- E' Q$ p. B3 t7 H    char c;
# [" o) X4 ^  P1 a, N6 b    char buf[16];: Y# `8 n/ y1 T: H9 X& V
    int i=0;
  }3 B2 o8 k& t0 j" X! `2 L) g   
: ?# M6 z/ y. x+ }0 _( U+ ]  C9 j    InitStack(optr); /*用于寄存运算符*/" \4 z# m9 P1 P' {
    InitStack(opnd); /*用于寄存操作数和计算结果*/4 N* x$ m( y4 Z
    memset(buf,0,sizeof(buf));& c) g4 N4 R/ v# k* E
   
9 e1 A- C7 V* I1 e& S+ l    printf("Enter your expression:");/ j0 O  z6 N/ [' W# Q5 {
        8 c' X! a7 ?" @  p  Y8 ]& a* z
    opr_in.ch='#';8 q6 F" T9 O( s
    Push(optr,opr_in); /*'#'入栈*/- J3 }9 q  J7 U* z- B
    GetTop(optr,opr_top);
+ `" u& W7 M7 `5 @. O& Z    c=getchar();
' W; P% q- N+ n; O  b1 x( K- P5 g( O    while(c!='='||opr_top.ch!='#')3 l$ Z1 A: ?9 {( Q7 V
    {
* b5 U  \) q. [/ W( I        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
: _/ D4 b1 t0 M! X) B0 E. N% M* F7 j        {
8 r6 r4 m  ~2 E  D' p- E8 n1 U, R            buf=c;
, U9 t2 N4 W' k) d8 {6 c            i++;+ R' U4 Q3 h7 A- {
            c=getchar();" [. i3 [: d. N! t( C# M7 F1 ^) n
        }
3 i& {, Z* S$ t, H( w2 ?        else /*是运算符*/0 X& ?: @3 C7 J/ A. c4 |
        {
+ U# @! `! `+ ?9 X- P            buf='\0';
4 k! ~- [, w6 \, H9 ]            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
# Z* [+ W+ R( V, p9 M9 @            {
+ s2 m# Q4 c  I+ e$ N: L$ t                 opn_in.data=(float)atof(buf);
9 P: n. |! P# M$ ~  l                 Push(opnd,opn_in);6 U% Q" i+ k. l1 {; N6 w6 k; B
                 printf("opnd入栈:[%f]\n",opn_in.data);
, I* t% R" Q7 F# J                 i=0;' `' [, o7 U' H
                 memset(buf,0,sizeof(buf));$ q5 ]4 w0 W# s* n
            }% @6 {, ]. D$ t
            opr_in.ch=c;& k; [- w4 h4 }) o
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/8 l# U3 }# z4 T) ~
            {3 l  p( ~% k. K0 D6 n, n4 R  ^
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ ]4 K7 K1 G1 d                     Push(optr,opr_in);8 X" O& u' J/ C$ q8 V$ z* b
                     printf("optr入栈:[%c]\n",opr_in.ch);
& P' q: t: k. K7 y1 u$ o                     c=getchar();! G1 a1 @6 ]6 i% \
                     break;
% ^- }7 a4 L9 p0 G! _                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/' d) q/ Y" {7 r) A5 R4 |
                     Pop(optr,e);. Z2 O0 j' g  n1 c5 S5 g
                     printf("optr出栈:去掉括号\n");3 D! f0 f+ M4 `( T' X
                     c=getchar();9 R1 Z9 ^9 `' A! S8 E
                     break;
. j! F: z2 `4 l9 U# {  T0 H$ I; b4 Y                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
' W8 o9 Q9 s) W( M; ~                     Pop(optr,opr_t);
8 n$ u( I, `: k% Q; A                     printf("optr出栈:[%c]\n",opr_t.ch);
- n' o4 }& p" \) I                     if(Pop(opnd,b)<0)
; H  m1 S: W; x/ f" m3 e  c                     {3 q- f- |* A' f! O
                         printf("Bad Input!\n");
$ \8 H8 J4 h8 `7 Q) t7 z                         fflush(stdin);- _- U- e; c4 R# a1 O9 h! z; W
                         return -1;' K5 D" p* c% X
                     }' e8 l) O( {% }/ b% |
                     printf("opnd出栈:[%f]\n",b.data);* V: f8 P; W0 E
                     if(Pop(opnd,a)<0)1 C: C; N- J+ }# M+ d- a0 c
                     {
5 i5 t' F: n3 ]  N1 N* I- A                         printf("Bad Input!\n");
7 }% \+ |% ~1 Q1 D; d1 @* [' [/ y' a5 @                         fflush(stdin);) _! R2 I& L5 E8 `5 W; X
                         return -1;2 U6 ^' y# Y$ _
                     }" [9 F4 f/ g8 v
                     printf("opnd出栈:[%f]\n",a.data);( n' `- I+ g! W& A5 L6 E$ q
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/% x8 d: P  T8 J/ b
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
1 z  ?" u4 ?5 e' k                     printf("结果入栈:[%f]\n",opn_tmp.data);5 W1 O+ v4 t1 x. ~
                     break;* T8 N" t. l- n  e& ]
            }0 v/ F; D$ [" B5 P! W9 c
        }0 ]- |/ O  c$ n3 {# f6 {/ T" a, K3 @
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                * V# A3 z9 @1 ]; @+ \' M! C3 {4 ~
    }
, B& q* j/ ^0 r    GetTop(opnd,opn_tmp);; A+ z% ?1 a$ r  P# T/ |" d
    DestroyStack(optr);, Q/ t; a# g7 A# [; n( Q; C
    DestroyStack(opnd);
" M& ~, z# A7 c. [5 L    return opn_tmp.data;# R; G) \  g: q3 Y3 K. g1 t
}
1 K+ p5 t$ y- ~2 w! z/ s
# B0 J( ]4 X8 \& K  ]5 e/ ]char *killzero(char *res,float result)0 g' u( z: U' ]
{- ]) B$ R7 I! D' E
    int i;
0 d% v6 A) m) y
- z  \6 |# N2 v    sprintf(res,"%f",result);
1 Q. ~" F. h3 L$ G' m* N+ t    i=(int)strlen(res)-1;
: t. N6 o' a! i+ e% d( {# ^) G    while(i&&res=='0')5 H4 @( C: V8 ?9 x5 F- ?7 g
    {+ Z. Y; M0 f+ Z: ?/ l
        res='\0';
4 f) g' a1 c% R4 i: e' _& F! b# p        i--;
1 P* z; J+ ]& x# Q    }1 S6 `5 k" O' w4 V) U. o! u& Y- t5 b
    if(res=='.')
# C* e- D% F- J' ~% A2 j+ H7 S        res='\0';
; v4 `/ }: {: Q! @2 P    return res;
  e0 R) {6 _0 s/ o4 A6 L6 K}! a0 ?; U3 z, M

6 }4 S2 B) A9 x3 j% aint main()
; I' [2 I. O1 _4 C6 [, P' I+ W{# F5 m8 i2 f: E6 [( v
    char ch;
( l+ c: f8 c& c0 A2 F    char res[64];
2 s" ?: h3 Z, U! Y+ o$ F    float result;4 G8 v2 \: X5 g
    while(1)5 [% N9 M" U. y* B! p& ?4 E1 v! C
    {
: U# m) V- W* G/ z9 H# m) p6 o        result=compute();
+ h0 T& c, g$ d' M. V& M, \        printf("\nThe result is:%s\n",killzero(res,result));* C0 ]  R! r" H9 I2 Q" ?* D
        printf("Do you want to continue(y/n)?:") ;9 C0 U  A- l7 g, B% `
        ch=getch();  {" D5 Y3 M. ~2 ~
        putchar(ch);$ y' e, g  R8 A- J3 u# L
        if(ch=='n'||ch=='N')9 V+ v" ^. ^' ~1 v$ V9 h/ {% Q
            break;
+ ~2 u& ?0 Q9 }* I        else. F* K0 d4 Z, B4 L% c0 l
            system("cls");
7 Q3 {4 S" e4 C$ W# H    }
5 f% R8 Y- }- u  t' @2 z$ Q    return 0;! V% r7 }6 p# v
}

* e9 q6 g% `; y9 f( h5 X5 t7 L% g: i# F, q+ r
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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