返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
. @* L7 [7 i  B, h! e5 ?程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=+ b2 ^! c# T! n( s/ e) w
/**************表达式计算器************/% y- U2 c/ U, ?7 ]8 H+ E
#include <stdio.h>
' c' B7 }/ L: i, b4 ^$ ]/ l# E#include <stdlib.h>
4 U! o3 P( O$ {) r5 j+ B* i$ ~#include <string.h>
5 U) H4 A/ c" m) B#include <conio.h>
1 e6 X. z  C# ?: B6 }#include <malloc.h>6 K+ |! W7 L" h# X4 }

9 O" ]8 {1 o$ A* P" z; J#define STACK_SIZE 100
; x, K2 P$ D- g5 u3 X% ~#define APPEND_SIZE 10
( ?: M1 z9 p# A+ }: u  {$ u2 R; j) @
struct SNode{* d, V. s, q( N  l: f, {
    float data; /*存放操作数或者计算结果*/* P( a7 ?' q  k* k" V! |
    char ch; /*存放运算符*/
* ~+ y% z+ ^7 p0 i};; Q* P' W1 P* k0 M

2 w: `# c1 e* B3 R( @" Astruct Stack{, @, ^6 r, a  U- w# ^" t
    SNode *top;
* X4 u8 }/ q6 T. X    SNode *base;
: ]* X. H6 d3 w. H4 v; q- x0 g% j$ O    int size;
% R# |" `  W8 G! C};
. i4 w( b/ D" E9 K
9 h! g- I+ e% K5 c' I/*栈操作函数*/- Q6 O  U" F+ T+ }* K: C# }! a
int InitStack(Stack &S); /*创建栈*/% a6 t3 g! I7 j7 ~# P
int DestroyStack(Stack &S); /*销毁栈*/
% l1 {- \- P# C( S7 Q) u  tint ClearStack(Stack &S); /*清空栈*/2 @2 U& B: S7 Q. L3 t% g  u6 |
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/0 w, H) p+ d+ @, Z$ j& r" j4 L
int Push(Stack &S,SNode e); /*将结点e压入栈*/
& u" g* D$ v; R: O' r1 fint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/1 l2 R" E7 d6 l2 N4 S7 q
  y1 p4 b5 q( d% w" t
/*表达式计算器相关函数*/* S' N8 Q8 [) g1 p9 A, w
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ h; ^6 G9 o6 r+ X& gint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/  C! V' w1 T% ?' S1 \4 g
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$ l) y9 h9 {5 e2 R7 ^
float compute(); /*表达式结算器主函数*/6 U. u+ X$ k% r) j$ s4 N
char *killzero(float result); /*去掉结果后面的0*/ & G# r- g* U3 L" n: \
2 u8 {/ w; X, S6 H. m0 ]1 _. a
int InitStack(Stack &S)+ N5 C/ f+ r; X, @- G  g/ l
{6 s, f3 v/ Y  k; }( c; N& _' }9 ^
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));& ]- I* d4 p& N: y7 z
    if(S.base==NULL)
2 j" K9 o7 |$ @% m) G3 B    {
( ?* c4 Y" D4 W) ~        printf("动态分配内存失败!");- _7 X8 M# M  e( L9 f
        return -1;( v. \5 ?7 f- A# U1 J3 q9 v
    }" N4 S/ B% f7 H! S
    S.top=S.base;0 X5 ~: O+ u7 R
    S.size=STACK_SIZE;/ @, }3 \8 i2 r* \% w! d7 {
    return 0;
1 `) d) ~3 ~  @! N: i  x- Q}
" n* p/ Z2 ?( V( ^+ D/ d! A0 j# z) @
8 q" Z" |: B" O( J- B* `int DestroyStack(Stack &S)
) V# a2 N  \: l9 `9 y{/ W. `; f6 J( Y* B! X' ~# D% `4 }
    free(S.base);
5 [4 o% @& A: S7 v    return 0;% O) W+ c' v+ T
}
' ~  j' k+ u2 T$ L2 e; ^3 V, K5 F/ w; B
int ClearStack(Stack &S)
$ ~3 J. A6 G- y! \4 i- \; U( ^{# |2 h  s6 p$ q; I, X- _" k
    S.top=S.base;4 G3 }, C+ Z6 N0 z' a0 a
    return 0;5 _. U7 A# ^4 ^5 q6 C( k
}
" p* ?* C9 @  ]! @+ H7 p+ [/ U8 ~* p# t0 h" I
int GetTop(Stack S,SNode &e)
4 b' e, a) W$ r7 U/ Y( H+ B2 Z{( b( I) o  e$ O5 R0 l& j
    if(S.top==S.base)( ~9 \6 [0 a' a+ X
    {
9 |. r+ H8 D( q" A( F' ?        printf("栈以为空!");: @) M8 ?3 E5 f/ j
        return -1;$ O4 A/ f: v' K/ S3 v: n5 f
    }2 s8 N# M- O$ `/ Y5 x
    e=*(S.top-1);% R" b- K) `4 {9 N) a5 z5 J
    return 0;
( e3 l2 }7 y+ }% q3 ~8 k! |# Y}
( S1 y! _- ]! `2 P: ~2 F# ?$ l( w! A7 _, J7 G
int Push(Stack &S,SNode e)
+ @& u9 |3 _0 l( q8 R! u0 q{+ `( v5 e' U' C1 ^, m9 e; X
    if(S.top-S.base>=S.size)
* P4 v5 }) d; D) o9 B    {8 o0 d; p2 t8 I8 y" h* U5 C
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
6 ?5 Y3 n5 ^/ \( @        if(S.base==NULL)
5 L! N3 X# ^9 s% p. N" L6 ]        {9 ^$ k: S- X: J9 \5 W9 u
            printf("动态分配内存失败!");
$ \8 Y$ o. J; O4 h# R5 I8 x- ^0 b8 ~            return -1;
4 c4 q8 D" }5 i% j  w  ^        }  r: K% P, r  u( g$ O
        S.top=S.base+S.size;" c" j% U, s, Q) g
        S.size+=APPEND_SIZE;
# {7 l7 }# |' ~/ l$ w    }6 q' G4 J* d$ f& v; I# K6 Q1 v
    *S.top=e;- s# j6 j( S% P/ ]; Q: R( ]8 t
    S.top++;
" o; p' ?$ P! e- M- \4 C    return 0;
9 x2 M8 m  g& S  c" g}& h' l; Z# _. ~# r  Z) _/ V

) h8 T, i$ P# A1 u; gint Pop(Stack &S,SNode &e)
  L7 o4 C* A! v5 v7 ^! ]! q: R{0 k1 F( N! [8 n. B0 ~9 F& q
    if(S.top==S.base)
/ }$ `% X( x0 e) n    {- _4 W5 v8 J% r
        printf("栈为空!");* u. s4 R* B6 h! ^
        return -1;$ Q5 S. O. W" h/ ~0 e, n
    }
$ G# t1 X. w9 b2 |2 ~    e=*(S.top-1);. X# b: Q% }' r: L3 Q
    S.top--;8 ?! \8 f8 s9 d; w) J
    return 0;9 l  [5 ]8 H( b4 N
}& U* G' G( l3 m( }
1 U. e) Q% ^' Y, ?6 f
char get_precede(char s,char c), D5 A  O2 f: M8 s. x& c( B$ N
{) ~$ e" D+ ^. m, t: [5 C
    switch(s)& q. ^- ^  _3 Q* _
    {  R) Z3 r, ^0 x1 w& i- X/ x' J
        case '+':                 
# @8 W+ f5 P! o/ F, }$ q& A        case '-':
3 q+ ]& r8 ~* w1 x$ \0 F! ^! e             if(c=='+'||c=='-')
/ [  @9 A: M& c9 u! H  u                 return '>';6 a) ?; ]' B3 [( p. U' k
             else if(c=='*'||c=='/')
% P  o8 ]5 C0 J* @* t                 return '<';
8 ?1 x) o% i9 G) c! z             else if(c=='(')
# W3 C: Y0 O- x. h                 return '<';
6 B9 h- D$ z, D: D             else if(c==')')
+ ^1 Q8 C' w; b9 Z- G  U                 return '>';' m! ]. g6 l6 p/ N8 S) Q
             else 3 F9 B9 Q( q6 l7 m
                 return '>';) E0 v# U+ q  a; Y
        case '*':2 \% n; }; R, V  j  u' G/ M
        case '/':
7 C& K5 i! i9 ?+ K, v$ i             if(c=='+'||c=='-')) ~, }7 D, [6 M. |2 \, z6 c
                 return '>';
  x1 c" d( a$ w/ G4 S             else if(c=='*'||c=='/')
: |/ V2 ^6 f* C% W2 l7 I/ w                 return '>';
% ^0 W/ c7 s0 o: U6 L2 e             else if(c=='(')
9 D+ Q# u+ F( Z                 return '<';
: z: Z0 H* b& k- e6 n             else if(c==')')
5 R" }/ ~4 ]8 r1 E/ m& J                 return '>';
# Y+ y5 {4 p8 g4 j0 V' |             else( m, Y, L' M! x$ ?5 x
                 return '>';
4 z- z; T. J+ g+ w* w        case '(':2 r( |8 D% s" ~  [7 O
             if(c=='+'||c=='-')4 r/ Z/ F5 Z2 ~, c  A* s& `2 \
                 return '<';
3 c/ N% d+ a% o4 t) w, g             else if(c=='*'||c=='/')
; l3 v! B0 ^% K- _                 return '<';+ S6 m2 o! N8 a7 ^* O
             else if(c=='(')1 B$ k0 o: P7 Q
                 return '<';$ d/ A/ T7 X: s0 U0 G7 m
             else if(c==')')6 `  q1 j6 [2 O/ K8 t
                 return '=';/ A9 I/ _* h) N5 O* I) C' ], C* M
             else/ P! j, _9 W4 E8 Y
                 return 'E';# I) e( p0 @- A8 o
        case ')':: F# O5 m/ D9 g# r7 S
             if(c=='+'||c=='-')) U0 o3 Y! h% Z$ F( }
                 return '>';
4 G) {! z( _1 c9 j4 R' R8 c- M  _             else if(c=='*'||c=='/')
7 d; }1 p0 d) \, u+ F4 Y                 return '>';5 @* f! }. ~* q/ `" B" X7 ?! w
             else if(c=='(')
' |5 z0 t; u9 w& I9 O& T4 ^                 return 'E';
9 x3 m( m! h) m+ ?8 M, u             else if(c==')')
( H8 Q3 N( e! p% g: F8 W                 return '>';
8 |, `( I" p* q5 I6 F/ x             else# s3 t) o/ N+ G& X
                 return '>';8 c2 M& ]/ v& ?6 w
        case '#':
, g" d5 t- d4 Y) L: ~  u; V! c             if(c=='+'||c=='-')
+ T, @% ?6 p0 ]                 return '<';
; |7 ~4 ^4 g" J             else if(c=='*'||c=='/')8 m) ^1 F, O% y
                 return '<';
3 {% x; O) `  G8 A, \- a2 _) P' o             else if(c=='(')! C* X5 N4 n2 W, a& L4 r
                 return '<';
! Y: a/ D& b4 O5 p; \% y% c             else if(c==')')( G( g" M; Q7 ^5 [
                 return 'E';
. L; }  E, P) O9 `. f  C             else
; `& e, O  Z9 B) k0 U                 return '=';
, ?/ ^! i" T# s        default:
- B+ f* l3 a/ u. I. L" \             break;1 J2 H% `9 q  b2 ^
    }
. R& g7 _: K0 Y3 X; V. c    return 0;    , z# g# D0 Y0 B6 f1 f6 Z+ O
}
, q6 N; \9 u. S3 {- k  a6 {% f2 I5 J& j% K- d& D8 a- ~
int isOpr(char c)& o1 E5 f% i) T: Q# q$ E
{
& z/ K/ b2 Y+ A8 M    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
( f7 A- V- E6 f, w( G! g/ m! e        return 0;
) R) \' r( {  J. p    else
4 T2 Y! i, D! N) |        return 1;) w( ^( ~% S6 i( o* }
}% v% e" G3 m; ]- R3 P5 }: z& l

: R# q% f# ]7 ~, e8 u* @float operate(float x, char opr, float y)! n) b( t; s" L$ @
{
" e, ~+ ]: ~7 u5 y8 _( |# o    float result;
# b$ H% X3 t/ O2 P    switch (opr)5 r7 U9 D8 e  j+ O, B. ^6 ~: I% L
    {( R% X: S& Z1 I
        case '+':
: q, g  z, `* D/ Z' W, s* R. R; l! k             result = x + y;
. U+ W" @2 J4 R  h. D: C2 X             break;  ^% [  X. s/ h) i
        case '-': 6 k1 t$ k& O. y3 O2 x, K+ E  o" k$ t
             result = x - y;, N7 M1 J; R7 @/ P+ J
             break;
% E- T: l5 p3 M4 L3 ?+ @        case '*':
  s" Q+ H: K& ~+ L+ h             result = x * y;- I9 r5 o1 z5 D. }% W: p2 [
             break;: \9 \% z5 c4 {/ j8 J- I$ k
        case '/':
9 G2 O! G8 I* L( X8 w8 w             if (y == 0)
( S; D8 c9 t+ }, {- d( y' I* B             {
; }4 Z. z4 X  P- E+ D$ i                printf("Divided by zero!\n");
/ Z0 T9 L1 z3 W0 D: a0 l                return 0;. G; t& |6 i5 ~4 X( t  `3 ^' Z
             }
& n/ [2 T8 [" o6 t  ]             else
, l3 a5 s3 |3 I+ D/ \4 x             {
& ^! W; l! H( |) `' R                 result = x / y;5 L/ F4 _; f8 T! x6 Z
                 break;' ?8 R3 {& y2 z5 d* ?
             }+ X7 X3 x! H' ~9 r; _/ T
       default: 1 }+ [  _3 d5 |( _: L, A
             printf("Bad Input.\n"); , G) E. _: c% u2 y& S$ B* y
             return 0;7 c1 c6 H$ L  b# d8 d3 ^# b
    }
/ N- Z/ L' E2 D+ J3 r! q( S    return result;
; d# K1 V  Y' _1 n+ h* `9 w' z}   
, x8 P( L  }3 h2 Y# a
2 H# `* b4 ?4 {( Dfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/6 J2 L6 B; ~# C. o$ c
{$ p, C, H, O6 R2 e3 o) b
    Stack optr,opnd;
8 O* j0 W7 k  t8 `# _5 D! f    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;' W8 N6 R" Y" @
    char c;0 a) F$ Q8 q" ?) I% U
    char buf[16];0 T, c0 O; k& R6 F- g' Q9 h" o! D
    int i=0;
3 Q) f. b1 {; h# W   
& }" \( W) T$ y    InitStack(optr); /*用于寄存运算符*/4 J, `$ N: u1 n; a
    InitStack(opnd); /*用于寄存操作数和计算结果*/
1 y' m. ?9 K4 U+ X7 P9 c    memset(buf,0,sizeof(buf));
+ A& t( {7 O: l; x1 q0 J    1 y, V. x" W4 c; p3 a/ s
    printf("Enter your expression:");
) _5 D" Z: M. k6 [+ }7 j        7 Y+ q+ H7 P/ c" Y1 z
    opr_in.ch='#';' q0 j5 d7 ^3 f$ Y9 L/ u. U
    Push(optr,opr_in); /*'#'入栈*/9 w+ U- {/ t; A+ V4 p0 F
    GetTop(optr,opr_top);
, S6 Y- n9 N# h" f$ _% }4 E    c=getchar();* `) ~" X8 p; z2 O8 t7 ^
    while(c!='='||opr_top.ch!='#')
% p' T  r: l5 n5 H    {4 B1 s2 H9 n; w5 A
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
1 ?1 ]  g. I2 P* D* _$ }        {
  i0 m# O- r8 Q) g! e6 A$ S            buf=c;' E' l& P/ r; A) V
            i++;" H* e+ W9 B( Z+ ]
            c=getchar();$ y! g. B% f" l, C0 `$ w
        }6 u! \. h+ |- K* F5 ]
        else /*是运算符*/7 y5 c; P* U7 c$ q
        {$ S0 O" D! i9 Q) |# _" q
            buf='\0';: I) B! Z9 ]& }" v5 J
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
, n: N  @  A& P* s- W            {  u2 X1 \  F& I/ G
                 opn_in.data=(float)atof(buf);
& I' ?$ F/ k* f) F7 M                 Push(opnd,opn_in);
7 z- ^+ z2 V1 r: j+ a5 ^) C                 printf("opnd入栈:[%f]\n",opn_in.data);
# v6 ?& d1 q% s' ^% e                 i=0;7 d. j* \3 L, \7 n1 t
                 memset(buf,0,sizeof(buf));0 F$ ?# y( l3 C( S9 l3 a1 c2 P: S0 X
            }
& B- P+ v# J1 e9 Q" y- W' E            opr_in.ch=c;
: \4 e( l; ]" e+ t            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
0 ~* S# B& X6 p2 y4 p1 N9 Z            {6 J$ w$ N4 s  h
                case '<': /*优先级小于栈顶结点,则运算符入栈*/3 ^: l5 I. ?; D) g, @4 D' h
                     Push(optr,opr_in);, J) v2 V- T) X4 t! y  p
                     printf("optr入栈:[%c]\n",opr_in.ch);
0 d- c/ U# ~$ z3 f8 R                     c=getchar();
0 `* a3 ^1 S3 N# P                     break;: N9 h; c  G  _; [2 a
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/$ N4 F  x$ H' H/ b) q$ ~; Z5 {( w( ]
                     Pop(optr,e);
8 C3 X3 B: d7 A" C4 u5 w                     printf("optr出栈:去掉括号\n");
. S1 k) o) Q) b& O2 u* p                     c=getchar();7 f9 p( X% a/ C. X# M
                     break;
$ {3 |8 s9 r& a" U                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
5 T" l8 h9 g0 ^( f                     Pop(optr,opr_t);5 t! H5 C/ K. \) \, F. `
                     printf("optr出栈:[%c]\n",opr_t.ch);
; e- b. O( U0 d3 Z# ~% w6 P7 j                     if(Pop(opnd,b)<0)/ o# F1 w) @8 K$ }" v& f
                     {
3 C1 u$ p2 j% ^: [  Z% e                         printf("Bad Input!\n");
. x( s  }2 k  B3 Q9 N8 X' [                         fflush(stdin);
* E- R2 i; P" n$ K% ]! p/ R                         return -1;
- w* z# ?8 a4 Q7 [# m) J* }                     }, p. X' }6 D$ `8 j
                     printf("opnd出栈:[%f]\n",b.data);! h0 }/ h- K! c- g7 Q
                     if(Pop(opnd,a)<0)
3 T9 _  A& b- ^7 D                     {
6 P: p/ l0 R# ]1 l                         printf("Bad Input!\n");8 E: m) c1 b, P" a; p3 f( G6 u
                         fflush(stdin);5 N' S" w6 X' C
                         return -1;
0 `4 |4 G7 s1 D+ S, y7 u                     }% p& V3 @+ d3 F) Y6 C& A3 t3 ]
                     printf("opnd出栈:[%f]\n",a.data);
  h+ y; a% Y) w3 x# E  ?                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/) v% m" W/ T2 i/ \0 R' G
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
4 b* [: l6 Z! ^7 B$ R  X                     printf("结果入栈:[%f]\n",opn_tmp.data);
* H# K8 _! ^: F5 K! E8 z                     break;3 K( `, j0 j; _2 p$ r
            }
# g/ L* h! c- R% B        }
9 V6 W0 z  O3 b) w) p5 A0 z& j        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                8 R# J' H2 K1 `( B# _( w
    }
# q$ R( F# {1 }5 |! U. }    GetTop(opnd,opn_tmp);
: e$ n+ A; F9 u    DestroyStack(optr);' Z5 W/ w% y7 d' w/ E7 }8 O
    DestroyStack(opnd);1 ^9 G& x# N+ ?2 w6 L4 D+ p
    return opn_tmp.data;
6 b- C/ `1 W, U}# A/ y* O+ t& f
8 v8 B& ~9 I' W) I) E! m
char *killzero(char *res,float result)
! ]0 q9 J  e1 Q4 r! ]% }{7 [. N3 G& `. i. t
    int i;; ~. R* l3 W% G

; X; N8 Y6 ]* G: `; z9 }    sprintf(res,"%f",result);
. B( B9 H: b( p+ N/ V9 ^    i=(int)strlen(res)-1;
/ v% q6 x. g: p' W8 M( h$ z% P  l    while(i&&res=='0')
% G: W# @9 A2 q. L# ]    {3 P6 X9 a9 j% H8 Y: k
        res='\0';
$ H$ O! u  U, u" u* i        i--;
3 a# C; s5 d3 @0 o$ M' n    }
( b% x; E. G3 C9 h3 n# m9 r/ y. D    if(res=='.')% j/ m$ _! i% A
        res='\0';3 M9 q1 o; u: X6 [. }+ M) M
    return res;
2 J* X# Q- }, d7 p! h7 P}
1 F" M* a) D, @  U
$ }3 l4 l* E- S4 W' ^6 k! R7 }" Eint main()7 q' H! i0 M, H0 r2 w
{# g- C& P- f6 N5 G; _) }7 x- S
    char ch;
( q" }5 w/ H  F& w0 N! N+ [    char res[64];
# i- ]) h* d8 q4 g0 z2 I& L' Y, ?$ v8 d    float result;
! [7 N6 W) A  b/ k. b    while(1)
) ]" O5 S; x% r. c8 \8 ~5 h    {' K3 G. p; U$ M9 F# a/ `: P
        result=compute();9 l8 o) k, A) m, F* |
        printf("\nThe result is:%s\n",killzero(res,result));
! u9 s/ ?# A! v3 ~9 ]% G- O        printf("Do you want to continue(y/n)?:") ;
$ w' l: u0 o" A        ch=getch();/ ]7 ~/ ^* C% [' Q) V$ d; l
        putchar(ch);
- C% i0 }) l6 [7 s4 v  ^        if(ch=='n'||ch=='N')
; g6 R$ |; `- {7 ?* N* Q            break;
9 e- `& M* R/ N% k) G4 V9 t        else; b# I: R( P0 {$ ?
            system("cls");
4 q, }; V# [6 y, A7 Y8 ^6 L" Y    }
) z& M; ~) I2 w* z9 q$ A( q2 L    return 0;
, s! |2 {& P/ j) @- z2 a}

& Y7 j8 w) ]0 i3 @" C7 i2 k% m. t& f) F# T: h% |4 w0 m
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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