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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.4 e* _  G4 u# H# O) j
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
% y% n% W3 b/ I% C( `9 `* D/**************表达式计算器************/' N; \% z1 b# T2 y. F* R# t
#include <stdio.h>7 O3 w+ q0 m; B. T- p
#include <stdlib.h># X4 L9 G$ z+ b) t. v* D) e$ z$ c
#include <string.h>) X, j9 d, `0 ?
#include <conio.h>
& y1 S) [# W0 \9 z) D4 B- U#include <malloc.h>
7 n0 ~- M8 T$ w2 H1 J3 x$ w# P) \3 t' t5 u* Z" D  ^$ U% J& A
#define STACK_SIZE 100
9 j# W* w0 z# e0 y2 ~# J: r/ u3 X#define APPEND_SIZE 10
- {9 Y$ R$ E; N2 q- Y1 \, R5 P. }% f2 q$ h
struct SNode{
6 A+ K7 y) \: n* I6 u8 Z    float data; /*存放操作数或者计算结果*/. V" e4 P( d( @+ n1 r  q" b6 l
    char ch; /*存放运算符*/
; h- x0 u0 N" D0 Y" @3 |$ U0 T# M; c};; b+ y" u' c* N: P/ {8 Z

2 c7 f( M! R# n/ B% N. z% Rstruct Stack{$ j, B1 v& g/ o& q8 R% m$ J
    SNode *top;
/ p8 r# v& W. r    SNode *base;
* Q3 x2 Y1 H: A* c    int size;
6 F- {* [+ w/ F* c};
; V1 H. t& [! m. M+ H, [! \8 q2 A, E+ q" c+ q& C& F( r
/*栈操作函数*/
; U. w1 A) Y7 t  s0 _: a/ [* \int InitStack(Stack &S); /*创建栈*/5 D7 B4 Q& ^# A3 r1 a
int DestroyStack(Stack &S); /*销毁栈*/9 Y$ P' Y2 I2 A$ M0 O/ D' h
int ClearStack(Stack &S); /*清空栈*/' b6 U- i  T2 v$ I
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/. Q' X/ k6 c1 r. E! F  R
int Push(Stack &S,SNode e); /*将结点e压入栈*// r4 B; V" Q* f& `
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/' Z! ~1 [- C) Z9 Y$ @/ I

8 J, i5 m4 `$ G, p8 B8 [/*表达式计算器相关函数*/
3 w( u' b, W+ Cchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
* H& n" Y4 `. T4 Oint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) ?- z9 M* R# T- y# E4 y7 V
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/# N" ^' g' L' y9 {$ I+ j0 u
float compute(); /*表达式结算器主函数*/
' K( w. Q1 c% F9 \5 j' ]char *killzero(float result); /*去掉结果后面的0*/
' E" P- u- W6 K, V+ `- e9 f& x
int InitStack(Stack &S)
! c: p! a) g+ J3 r7 F{
: m5 P7 \1 F: Q# T$ X    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));0 Y; M- m7 H, T. S' w0 B: X
    if(S.base==NULL): y! _% X) \2 o7 l6 a6 B
    {+ V( u! p$ K" T7 O
        printf("动态分配内存失败!");  e! K( {/ j* D7 I/ Z& V" x: c! T* F7 @
        return -1;
, J) B' q# O* ]# u# g    }4 j' I/ B9 r9 l' z. N) N1 @
    S.top=S.base;
+ H" W, J; q# U, A9 k    S.size=STACK_SIZE;' e5 T$ @. `: ~- u/ U2 O% P* \
    return 0;
3 d0 S% D# J! \$ l: z4 _}
; U2 C- l$ L& h; O# W$ C0 p. M7 e; ~4 u# L! M5 z$ D
int DestroyStack(Stack &S); ^" G( Q# r, e% T% v: Z7 g  Q: Q! l
{9 S( d) T' V) y/ q8 f# g2 F# Y( o
    free(S.base);' {" R! c; f/ }: ^
    return 0;& i' ^1 u' u% n6 p$ {7 Q
}: [2 H; \8 @! V
* x2 s% M5 @& ~( D( w
int ClearStack(Stack &S)
  s6 f2 [$ X( X- |3 N{
+ n6 K! R' a$ T* D! V    S.top=S.base;
1 A7 |& o  w0 J7 Y8 e( W    return 0;4 ?* I$ k0 u4 G
}
! z$ _6 ~+ T9 O8 s+ {
, v1 B: E8 v1 u: n5 Rint GetTop(Stack S,SNode &e). P  o1 G6 o* ~7 M
{
& D4 n& D  v* z    if(S.top==S.base)
8 ^! ]/ T' E1 c- h% \    {
4 \6 I9 D% y- z5 z$ E        printf("栈以为空!");
. a& B3 |5 R# T5 V. Z        return -1;
% R. a6 \8 q2 i    }; o+ f' `4 Z% M
    e=*(S.top-1);7 _% f- ^/ U2 R; O
    return 0;
' k+ j2 l1 F4 D  c" a$ A}
5 B$ t( z6 `$ o, ~' D; L: b# G  G, ^2 k5 U
int Push(Stack &S,SNode e)7 n) O7 y' f' W+ ]
{
% I9 g3 h0 H5 \  B1 h( ?! u    if(S.top-S.base>=S.size)
- J( P5 `0 s/ |1 C0 ]    {
  B2 I4 k  ?4 i7 w" t( C4 k( A; ?        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
4 Z+ y/ c, S' K4 `6 _/ T        if(S.base==NULL)( ?; K* N) j- M- s9 J
        {
9 ^# B5 J% k) Q            printf("动态分配内存失败!");
) z% h$ G: X: }            return -1;1 b: C8 {' `1 j; P+ j
        }
) s9 j% n! {  v! y3 h        S.top=S.base+S.size;
( t9 s7 F- O$ O" D6 e3 F8 G        S.size+=APPEND_SIZE;$ \$ W; z0 a  m: C
    }$ k" i/ v0 e1 y3 k$ r! @8 H; F9 \& h$ w
    *S.top=e;  B9 H5 F5 {! i& o& Z+ M
    S.top++;* W" N2 U% I- \- X2 r0 V
    return 0;0 t7 j8 G5 w0 g. b* @0 G
}
4 @5 P7 X6 J; v9 c
3 C( }/ b% }: N# fint Pop(Stack &S,SNode &e)
4 Q6 {0 D( X/ T{9 ?" U, w. x- A! K) U2 b# O
    if(S.top==S.base)
7 l3 I7 u* K/ U/ \0 n    {
0 O2 O# b; u* ?8 P' g% C: c( J' J        printf("栈为空!");
8 j2 O6 ]2 R. U: z/ {$ D8 ?        return -1;. u& D  e) y. h1 u& S. D$ B2 ^: l
    }7 {2 O4 J* P: d' v  p
    e=*(S.top-1);( S8 u5 d! X- D; I
    S.top--;
' G' j7 ^0 k8 _8 _) x2 m    return 0;
, {  y9 W7 W( w: g9 ]' m0 z% Y" r}0 V6 m' c# o9 @9 U% l/ N! G

' [! e% d7 L% n: m- jchar get_precede(char s,char c)
; }# t1 k2 `1 {- t8 S6 v/ d{! u7 U+ X6 A. M  v6 [/ M2 h+ s
    switch(s)+ f6 f# ]! p6 @7 ^6 l: y2 m4 K
    {
- n5 M( K3 ^" ~' t        case '+':                 
. O4 @, a3 H8 h+ X2 R$ i  T        case '-':8 F/ s- k) k) {9 a# a
             if(c=='+'||c=='-')9 s( k; O2 N+ T0 D1 v
                 return '>';
5 W. c, J+ p( a2 R, E9 w             else if(c=='*'||c=='/')) B  C1 ^% L% Z' I6 @, W+ z
                 return '<';
( r# \$ Y: X) D9 W4 f5 E             else if(c=='(')
: _" H$ E- G# X+ Y* V) L                 return '<';5 F/ V' H  P. U) h6 @; F5 A$ l3 i: i
             else if(c==')')2 l! W) a" R. O/ X% A
                 return '>';
7 o) [) r, [. x* [9 z             else 8 m$ z5 Z2 k8 V, X1 \( Y
                 return '>';
$ ~: t1 c7 s" A8 f0 l+ r. o* ~        case '*':/ e5 Z3 X) I1 f' w2 b8 S- @
        case '/':
4 k+ Q3 E. J6 x1 n$ ]+ S; T/ r             if(c=='+'||c=='-')
" G  a4 z2 s$ E1 ~; ]4 P                 return '>';
! T) E8 w8 c- ^% t. Z" f             else if(c=='*'||c=='/')
8 |- O& z# a2 I3 ~2 d0 g$ g                 return '>';
! @  U# B3 Q/ b: a" K             else if(c=='(')
5 z* V" b) C1 Z: m/ [! G                 return '<';6 R0 v! ]( Z! M6 ^& Z
             else if(c==')')
; K0 k/ x. F2 w. ~' E7 }) u, i                 return '>';/ P: Y" B' P+ \4 K8 S& i
             else7 z0 g& ~! _+ U2 d. r4 w
                 return '>';; B$ s# E7 K9 l& G5 T4 t
        case '(':
1 @# ?- |3 [* @0 @+ `! G             if(c=='+'||c=='-')2 \+ K, D1 `1 B
                 return '<';
6 _& d& x7 b& l: a8 O             else if(c=='*'||c=='/')' V, A, m) o3 \1 J1 z% A& n2 {
                 return '<';- i+ a4 \. P. ~' k% N# W2 U
             else if(c=='(')
4 Y' ^2 L2 O6 ]                 return '<';
, }( _9 Q: c4 @4 d             else if(c==')')
" T7 o$ V  q/ S  }& ^. d                 return '=';. p! f6 F- D9 Q- J$ ^
             else; n/ X9 w1 G# H& q  \
                 return 'E';3 u* H5 l& f6 G6 j/ o& r( |1 F3 y
        case ')':8 ?0 s# N# V$ _' X4 u3 X
             if(c=='+'||c=='-')4 O6 h! O# I* w. u, Y
                 return '>';
2 j6 J7 l- M4 _3 |9 F             else if(c=='*'||c=='/')
: }% u! S, U' `8 g8 {$ {                 return '>';+ C8 T9 X: T0 [& W$ G( _
             else if(c=='(')$ t4 ?/ r7 t1 w. u3 |2 I8 T  o
                 return 'E';
' P3 x3 D& J/ L: T) i$ n* Y1 U* [             else if(c==')')
$ \# ^8 l- l% Y$ r( Y1 Z" j; A0 d7 N                 return '>';
2 M9 r7 B8 q+ L4 y' i             else
- w6 S8 r) `3 c9 L. t                 return '>';
3 K8 ?6 A& p  q6 e& ^        case '#':- W& Y' @# {7 V9 }! N, A
             if(c=='+'||c=='-')/ |$ ]! z5 x5 @/ x6 J  L2 o
                 return '<';
( y5 b; f8 w. M9 ~0 h: |# g# s             else if(c=='*'||c=='/')6 f; [- w+ D' X
                 return '<';
: D) c' l. o0 J* i             else if(c=='(')
1 t/ C: v* Q" m4 i" U5 A                 return '<';
7 _# v$ X2 V+ }; v+ {  ~9 w: J             else if(c==')')9 b! @' _3 h( R2 c* l3 d/ i. @$ z
                 return 'E';
/ r& w' p3 D) \% M2 W1 ^             else! {- E9 S( R2 D# ~; d3 L; X. \; `
                 return '=';
/ H+ L% J  v8 c# \        default:9 G& h/ {3 ?- ?8 G. T4 |
             break;
+ R; O7 o" ^* _, t    }! d( g: @1 T4 S  m6 {
    return 0;   
. y  f' u0 `/ R$ v$ P7 G/ K0 J9 S}
/ ]9 L+ E1 l: s* W( K" B8 F  o5 m6 L6 s" f4 v3 R
int isOpr(char c)
1 Q7 n* [+ _( x" u1 ^{
& {7 C% R3 Z& s4 u6 x3 S3 T) J    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
: h! j. ~$ P  a, J/ ]4 A        return 0;
4 T* s5 r# ?/ q* v  _' O    else
' x) J& B( k% f$ X& Z, {        return 1;
" i8 g+ [' Y. l* A4 `2 }9 `}
8 m5 |# \8 i/ l( G) H
# c$ @# X) `8 e+ Bfloat operate(float x, char opr, float y)
2 j1 }* s9 v3 }( D& {+ p1 Q" ]" s{
: v# L7 \+ S. `/ J- Q8 Y/ m    float result;+ p# `9 l( H5 |
    switch (opr)
/ `8 g5 S4 h- X- W- b  M, v/ }    {- m1 t1 }# q) E
        case '+': : l4 E0 r2 h- r2 N6 W- y9 v
             result = x + y;1 n4 O6 G! _/ ^
             break;  s7 j; U& T# [* [
        case '-':
7 }; e$ T2 B+ X* {3 ~             result = x - y;* e- N- Q( D: \. D: s
             break;) X+ ?' I9 L/ v( @$ E% X
        case '*':
$ h& r5 R% \5 L# J/ a             result = x * y;& r2 P3 ]7 G/ C# P
             break;$ Z  W& j% w; S
        case '/':
# u& w# A( h% |  [' f. i( |8 P- \7 |             if (y == 0)
" D2 l: H* [8 j$ B             {
" C: s/ L+ d& t$ T, m5 G, q2 t                printf("Divided by zero!\n");/ J# _) |5 f8 \6 x
                return 0;
8 U% O( C. d" L+ Q             }
" ^2 L! X& y- a% v             else2 K1 s: G( q2 H  ^- u
             {
/ X7 j6 c+ b4 _! W                 result = x / y;% f4 L" W6 V' L% U, R7 W; A- H
                 break;$ {/ N" F7 P5 D" w
             }, k8 Q) J' L/ I4 N
       default:
) b+ w, z2 q6 u1 J" Q/ l             printf("Bad Input.\n");
, E/ P5 g6 q% L( j. \             return 0;% A/ F- q, r/ N1 D( Z; a
    }# n3 y/ W) G& Q- |
    return result;6 I: ^- B! J% x/ g4 ~
}    " k- `) ~) e6 a! R: `" {2 C

) g  e- ]7 T: E2 q# u8 i% k% ufloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/! P  [/ M3 |' M+ X6 M/ [( G
{* l3 ~% c; N3 p" d0 Q0 J% ^5 S
    Stack optr,opnd;! J9 Y" K3 b1 t9 J2 t& A( N
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
$ D; s% H! |- e( [8 z0 u: E    char c;' z8 W9 g" ]/ F: D* z
    char buf[16];
7 P6 L4 u3 G2 X2 x% p  q    int i=0;6 ?" a' _& m5 W, u
   
, b# p; C* s- ^, p; `# `    InitStack(optr); /*用于寄存运算符*/) r! Z/ t& c" c* |
    InitStack(opnd); /*用于寄存操作数和计算结果*/" i  C2 Q4 i, H2 Y9 E1 {7 i
    memset(buf,0,sizeof(buf));6 @2 L# D% Z8 X
   
0 E+ V1 s% T) G    printf("Enter your expression:");0 S% m" z( v2 }$ S! L
        . a6 ]# P# }6 J; S  d% l6 f
    opr_in.ch='#';
! Z/ l9 n, X+ j1 I7 n    Push(optr,opr_in); /*'#'入栈*/
& {  E; L: l; n) ]+ ?! i8 {# P    GetTop(optr,opr_top);
0 b$ k0 w$ |1 Y5 G    c=getchar();$ H0 k  Y) f2 y- y6 M. Q( C
    while(c!='='||opr_top.ch!='#')
  g+ a6 L- x3 N    {4 w, S  }4 X/ D( s8 y  V- W
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
  q' B$ \/ R) V% h7 }- y& V        {: V0 O) ]8 S: p: t! L
            buf=c;' x$ g7 e8 l8 X/ A1 k" Y
            i++;
5 R% w' T: @% ?& p            c=getchar();
. H( X  n& N( {7 m& E! B* C5 N        }8 U% y4 P. h/ j' i1 h# O; \
        else /*是运算符*/- X: }5 Q: M1 k' D( [0 K& A2 l) V
        {
( H; V$ n) a7 k; q1 S$ W0 R            buf='\0';
8 o5 }$ Q) Z9 \# b            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/' H# C) X1 Y, m- v7 b; p
            {
) G% b. c" b# s" {$ e9 G                 opn_in.data=(float)atof(buf);2 W" J2 G; I( {% m. y9 Q5 u
                 Push(opnd,opn_in);. ?$ X8 ?, d) c" y: T
                 printf("opnd入栈:[%f]\n",opn_in.data);% y$ S8 K5 d3 s+ j! c2 ^$ s
                 i=0;& e5 `  g8 X* L  R
                 memset(buf,0,sizeof(buf));" A9 m3 X7 p. F9 w, W1 Y
            }
0 S& |1 U7 I1 ^( Z* k            opr_in.ch=c;
5 ]0 J# V  q% D6 F  j$ c9 h            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/+ q7 i( N6 H4 s5 |# D
            {% A0 `' G/ x1 ^
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
4 {! G9 q" U# f0 ~1 n2 |9 e                     Push(optr,opr_in);
" S7 ^* q0 X) k$ |7 }                     printf("optr入栈:[%c]\n",opr_in.ch);
# g6 U6 c( z5 ]+ b& E- c* J                     c=getchar();/ E2 r& T4 k8 W4 @
                     break;
8 V0 }+ |2 V% Z* C7 Z                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
# i& I* G9 a9 d: h' h- t% V                     Pop(optr,e);
# t9 b3 r7 v8 _/ u+ `' r* r0 e                     printf("optr出栈:去掉括号\n");; b5 L% ]  m4 f1 A+ a, q
                     c=getchar();
9 }& A( E. \+ e                     break;
; B8 ^" z5 G) z7 V8 n( y& m                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
) V( m# q' O% I9 L! X                     Pop(optr,opr_t);6 g! p3 b% F" n* S" ]* o
                     printf("optr出栈:[%c]\n",opr_t.ch);/ R% W# {2 U1 E1 |5 k
                     if(Pop(opnd,b)<0)9 ], _" N1 J' o2 U( ?
                     {3 f9 T+ O, |+ i+ o+ _" B8 o
                         printf("Bad Input!\n");' U0 P3 V, Z, o3 K; ^* ?
                         fflush(stdin);% t0 E9 o" }" U: ~
                         return -1;
6 C2 b5 }- @/ ]6 p; {                     }
/ a( l+ B2 `9 {' d                     printf("opnd出栈:[%f]\n",b.data);
/ ?: O/ m7 j0 V6 T6 T                     if(Pop(opnd,a)<0)
3 ]) _4 a9 f5 `                     {
0 N- K8 X3 ~9 l- A- d; S                         printf("Bad Input!\n");
! c& ]) d0 k6 p4 M) _5 [                         fflush(stdin);/ O  x3 u1 e- P' z( p5 k
                         return -1;
. A* C  O. e& }" R                     }8 ]  l! x: U: e5 k9 d. Y0 V
                     printf("opnd出栈:[%f]\n",a.data);8 P6 G# F: @1 O; i2 F* s+ G
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/9 Y9 V5 k1 t1 I& t% j$ D/ w% y
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
6 `" M; [7 t$ ^/ u6 A% b                     printf("结果入栈:[%f]\n",opn_tmp.data);2 [9 r4 d! U( ~# `* a9 [: f
                     break;+ o* r0 ~( v. R7 {
            }9 E  r  ?" \7 I, z0 Q
        }
/ R3 [% M$ F4 O        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                7 E7 s. a' G9 n! h0 v
    }
' j8 `2 k1 @( Z- k% `    GetTop(opnd,opn_tmp);
$ X, n# `" A, P8 h8 R' _4 S4 D$ U    DestroyStack(optr);: i3 U# c+ }: O  z; A+ W
    DestroyStack(opnd);7 c! u& I- S2 |5 [5 U
    return opn_tmp.data;5 k) W* x4 A9 `# `* m
}" p! ~3 g* M/ X

2 D0 n: P, t* N( Tchar *killzero(char *res,float result)$ l3 h* d6 P9 [% I& Z$ Y
{
; x: N* V+ e9 T    int i;5 w) Z. H, `$ b0 H$ p9 z  P

* s3 x0 D9 L; i4 @$ l    sprintf(res,"%f",result);1 D+ D7 ?0 U8 a  p( Y
    i=(int)strlen(res)-1;  G7 a! g& _' `  l- v& _
    while(i&&res=='0')
& r% P( p7 J4 k; _- M. J, {    {
! q- g: Z) v$ X% ~& M. c  j        res='\0';
& K* y) a- d/ O        i--;, y1 J, o& N- N5 `
    }
2 {6 L' P0 y& F$ e9 B5 C' R    if(res=='.')
- w  H- Q0 C+ [4 P1 b. D3 G        res='\0';6 c0 m7 c" l- ^+ v# ]+ o' M/ a
    return res;
0 \) }$ v! N- w7 X( i: f}# J+ s5 R$ m/ M4 N$ H  O

& }. n* U% w' K0 N% E$ |: Uint main()
. C5 b$ w# h& q: M{
% R  R2 E/ a  s    char ch;$ j6 u, N: E* }
    char res[64];
! }* [# |/ Z3 Y5 _! X/ u    float result;3 @7 r) E: R" o4 l* F
    while(1)
  d- |. `9 K, ]* a; a+ ^    {
# `; s' C* D) b) d8 C6 m+ q% u$ o        result=compute();
3 S2 D- u3 V  M4 c' g2 d& Q7 l        printf("\nThe result is:%s\n",killzero(res,result));
& s. X6 v4 L; f' M5 a        printf("Do you want to continue(y/n)?:") ;
6 W2 [. z1 H* i" X/ I3 A/ C        ch=getch();
. h% t! k6 J' l: z6 D, z7 L        putchar(ch);
4 a3 M! t) C1 n. |  Q, }        if(ch=='n'||ch=='N')
6 \2 E- ]7 r' i  Z' a0 K            break;
* h+ E" O) F. S( h        else
$ S8 P( s) ~: V' e! G            system("cls");- F! `0 |3 {. z+ e& P
    }9 k/ R. P5 w7 E# r
    return 0;
3 D  r8 x) d8 V4 A( d; y9 V! O! z- R}

7 C! P* e3 m9 Z
5 ~& V' m7 U; h& O0 A  L' U+ H[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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