返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
  G: E+ e' d- z程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=. |' \" G# R+ @! T/ U
/**************表达式计算器************/
3 o/ w  C/ @* p( v#include <stdio.h>
% h7 h) ^# e4 x+ t6 S. D9 J#include <stdlib.h>$ v0 e2 e' X! M, r
#include <string.h>
  A4 l# s" R, y, F#include <conio.h># k8 ^! W8 l9 U! T
#include <malloc.h>2 A6 B% _# W% D; B5 M  P4 p
* b$ x9 G9 J0 B2 V- h) y+ q$ g
#define STACK_SIZE 100
% k8 M6 g4 S' a4 x( w, F#define APPEND_SIZE 10
! z2 e; m- P: Y! J+ i! C: L( r# Z& Q2 P) w; O2 e
struct SNode{
+ w6 R4 p* ^8 S  R" I; z* {    float data; /*存放操作数或者计算结果*// j, h6 n: e. G6 ?
    char ch; /*存放运算符*/6 c/ l  ]7 R% R$ ]- T
};' I, O' N. K9 O0 O
* F5 g6 a) @. R0 T' q$ j! D
struct Stack{( G! v% J1 ^& M& F9 h
    SNode *top;
$ P( u* \. L3 m" _+ e9 b$ U- i    SNode *base;! `( c% u+ z8 y5 b
    int size;
! r7 i% m: T- Z: n* u};( Y4 C5 r( ~& O- P' h0 c
, _& V$ ]2 M) [, K! w( m, a
/*栈操作函数*/! M" G0 g) \! G9 C$ E# j0 J( p
int InitStack(Stack &S); /*创建栈*/
) ^7 v- b* I7 f- E+ c6 fint DestroyStack(Stack &S); /*销毁栈*/
, M7 D8 l- I' T. i8 {& V3 dint ClearStack(Stack &S); /*清空栈*/
3 z4 r2 [: P/ I' g) W; ^int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/' P& M* b. m" b0 _1 T0 n0 m
int Push(Stack &S,SNode e); /*将结点e压入栈*/
% H4 `% \- d3 g4 ~9 m2 gint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/  W) H* Y3 X5 K, y! ?5 z9 Z

9 m! K0 o$ Y4 Y! R5 O( \2 O# u" H/*表达式计算器相关函数*/; b4 o/ {$ g. J: c$ H# G
char get_precede(char s,char c); /*判断运算符s和c的优先级*/$ X. N( K* U& L# z$ W0 q9 u0 A
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
! k  ]! b. |( e3 K; M: nfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 p. s4 g# E+ Cfloat compute(); /*表达式结算器主函数*/
! j+ P5 V) g7 [" w' G: X/ X* Ychar *killzero(float result); /*去掉结果后面的0*/ 9 H/ S7 O7 I  d7 y/ P( P/ u8 r
3 ^; [( R' J# E& ~( b" A
int InitStack(Stack &S)
- X; {& q4 ~( k9 e6 E  K{: K0 E% j& D( ~, Z
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+ i9 z1 Q9 j+ d    if(S.base==NULL)3 F' D6 T. l: B* E2 b+ \
    {
8 v; N( _3 R: ]+ O* H% L        printf("动态分配内存失败!");
6 T1 F, v7 X; e3 _0 \  X        return -1;
# i; N* `- X( L    }
# w2 H( T3 Y: [5 U: `/ G0 \    S.top=S.base;
5 A5 j  a5 n) y+ o3 [5 w$ s( W) |    S.size=STACK_SIZE;+ A- V  w% [. y4 T/ c) c) q. t# ?& k' @- |
    return 0;3 ?5 X. z% N. h5 l+ P; Q' K7 R
}
: O& t9 a) h2 D/ N9 m2 r2 a% ^0 I' f# ?5 `
int DestroyStack(Stack &S)
; c0 u9 \- ^0 Z0 H# N, L2 x( F{
7 ~/ d# P* _3 R( k# h  G    free(S.base);4 G: \8 K1 V1 H9 x4 K2 v
    return 0;
5 u0 t  I- |% i}
  G. S$ w( }7 n% u4 V3 S) j) H+ S% r( h  v  C
int ClearStack(Stack &S)3 A+ j* v6 B& C1 ~. ], p6 E- v4 V
{
3 Q3 V: |- Y& |    S.top=S.base;0 \/ Q+ O8 N6 T# S; L* \5 F# A* ~
    return 0;/ o: ~5 x$ a! D8 {& j
}( P$ u4 E$ {9 G8 @& I( u4 e

# a% R( O* G" D. Aint GetTop(Stack S,SNode &e)
0 k- C9 S* u8 B: ]% V) L8 E{
8 @2 ?$ j/ Q7 }$ x    if(S.top==S.base); J* l; x. j; _, S  K
    {
: @  L4 M' f; }) i9 X        printf("栈以为空!");
" j& S; O( W' ^. ?1 L  V& M        return -1;
8 r. S# f- v; J3 X2 F9 Z    }, \' h: \- @* c2 |5 S# j; l  B
    e=*(S.top-1);
4 G/ p' Z0 w1 [    return 0;
0 J1 W! D' Z8 n  [. y}% o% n2 l" M- C
3 \) r8 v% n2 }  a7 w% h
int Push(Stack &S,SNode e)( Q- n( z# }/ b, `
{
: O! ^3 g+ I4 g8 ^' z7 X    if(S.top-S.base>=S.size)4 K. ~* O1 k5 |% \% u+ ?
    {, G# {5 c4 j1 S8 x/ [1 y4 O' n5 ~
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
7 }! [: x' a- }% h        if(S.base==NULL)/ s$ K# \7 A$ e- m* C" B' P9 H  `
        {" f- _$ t% c; q% z3 a2 |4 \/ x
            printf("动态分配内存失败!");3 }9 q: S$ z3 `# j
            return -1;9 q% ]' Q! ~! t
        }: |8 |4 a; R$ T" D, X
        S.top=S.base+S.size;& }8 x, O) O' G! H' u# \; M
        S.size+=APPEND_SIZE;
2 `' s1 i5 _7 ?3 M; a    }& X9 t# |# G% u) z9 F
    *S.top=e;
. H" d% N! I' Q/ o9 o* {2 v    S.top++;
2 X7 J- h8 u4 \# ^3 e* b3 D    return 0;
" O6 {$ s% @% X/ J; o4 k. `$ C2 n}
& n4 t, h6 b2 q$ P7 f
5 Y! Q+ E0 \: Vint Pop(Stack &S,SNode &e)# r$ V& K8 H0 w, d% n# k- o( W
{
5 W% F. g& e2 W1 S0 A& |! A8 g/ ^+ ~    if(S.top==S.base)
5 J5 _" j6 C2 ~( L3 g% V( s! {    {# }7 O2 R- H$ f+ X+ K7 t( S6 O
        printf("栈为空!");
/ P! x( v/ v" a1 o; F) Q% q        return -1;9 \  T/ v3 K- T, \% Y$ x
    }9 B( F) _! h- ^, n/ i
    e=*(S.top-1);/ _( q1 o' c2 \: L' Q" m
    S.top--;
9 e- f! x* n, V, |/ c4 U( q8 I    return 0;
2 x# ^9 {: R% f}( x' B: M* c- f, O2 E
+ }) B/ q- A$ @4 n) ~( Q
char get_precede(char s,char c); U, e6 i( Q& w6 z, w7 ^
{
' X  w' G: \5 `    switch(s)
0 S. \2 H( {! X    {
4 x0 Z; H2 _  {* [$ l( u        case '+':                 
- z) B; y& G! M/ g        case '-':
9 ?: F( I* O9 U( @% h5 Y& Z; I9 q             if(c=='+'||c=='-')3 x: p' p+ R: _9 O
                 return '>';3 j) [5 C5 E, b! X3 J% w
             else if(c=='*'||c=='/'); F) v# O& F: E$ g6 `
                 return '<';
- E( j! w( w+ z6 s# i8 `/ ^0 |2 N             else if(c=='(')
, \2 F/ ~5 H! |( s; P3 o                 return '<';
+ C% l/ J6 ?  A( p, L# ]6 s             else if(c==')')' y; l+ X+ U: S/ g
                 return '>';
# {8 U, U( E4 j             else
" T7 a# q+ L5 W$ b1 D$ u                 return '>';
8 m, O; E8 E3 a/ m        case '*':
6 m$ C9 Q1 l4 }2 m7 b3 q' ]. S% a        case '/':- F" S5 I( Z- Z& L
             if(c=='+'||c=='-'); z8 V2 h* L6 N% _
                 return '>';
5 j8 k+ z8 U' V4 h8 @4 h" A. k             else if(c=='*'||c=='/'); E5 n7 ~  \" u- {9 |
                 return '>';
3 [8 |+ b8 B% h+ ^, f             else if(c=='(')0 J- B) n3 k7 f6 f' z7 P
                 return '<';
0 u" l: L  m# G1 X5 f# `             else if(c==')')" J$ E. P( E) f0 U: H# F/ V( V
                 return '>';2 f* Z' h2 \8 n9 y% Z* t  P( S
             else! D0 |: G- u) W# m$ Y( y
                 return '>';
; K* k8 _9 o3 ~3 v7 ]        case '(':- q- c9 C  q& A( c: U
             if(c=='+'||c=='-')
! B7 x3 K  `/ `# D! O                 return '<';/ L5 q$ x# Y2 K& h( c& v
             else if(c=='*'||c=='/')
  d, h( _3 m$ c+ j$ h* |8 A( N! P                 return '<';+ v) X7 E, H7 _) H  o' F  v
             else if(c=='(')4 y  l6 a& ~+ ^8 A* G
                 return '<';
+ Y4 m; i# k9 h8 c1 Z             else if(c==')')
) c) I8 ^$ Q! G+ k+ I: s                 return '=';
/ k" D" L9 n) I( P             else
. y1 n5 [6 a: {9 T                 return 'E';- y1 |1 C% j+ V4 B( y" }
        case ')':
3 ~5 E" K1 E3 n: G             if(c=='+'||c=='-')
1 G5 t6 N. e7 O" x                 return '>';0 k4 r, i6 N; ~" M/ _
             else if(c=='*'||c=='/')
) ]$ @% N1 j& W: ^: T                 return '>';+ x8 r0 q/ Q6 k4 J
             else if(c=='(')& Y$ z+ M# a( c) v* J9 a  e% S
                 return 'E';
" ^) C+ C) Q' U7 \9 k2 P             else if(c==')')  Z! V; P8 I" U3 P( q: Q' U
                 return '>';
0 d* m3 o- d5 x' _2 x3 Y             else  K0 r' i* h# z  Z  o' f
                 return '>';
0 M( V5 F: @" `- u+ I        case '#':
# B" ]8 R0 r1 X2 W- |& Z             if(c=='+'||c=='-')
3 h$ p: d4 ^1 p* Z1 R. l3 A                 return '<';) m- J, L* l' q
             else if(c=='*'||c=='/')
7 j+ E. L. N' R- B+ z1 P                 return '<';
9 A( R2 N0 R3 w: d             else if(c=='(')& H, o( z. D' T# E) ^7 ^
                 return '<';3 t/ F) \( N3 g! M
             else if(c==')')( c/ ~1 s5 X, p- j8 F; O
                 return 'E';) Q4 F7 B, {7 ]" A
             else
5 J6 }& E1 i8 c# ], f& ~0 Q7 }                 return '=';
2 ]" ?/ y) ]0 B        default:
$ D5 c3 A$ P2 r- H             break;: l  c( p3 ?7 P5 j2 K' l
    }
0 |* T; c, H8 J* E+ A' j    return 0;   
* K, n" l' `. ~0 J! k}
! s* a: K  E6 |" Q. I* D8 o7 h( p) Q, {
int isOpr(char c)  |7 F1 m- S: k6 G: C1 x1 }
{1 ]7 N" \% K; o1 c  x: j4 `
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
% s" k/ N) H6 `- W: e/ |        return 0;
" I3 P: l! A4 F9 |, x) Q" f    else
4 q: l$ p( P0 ~" G& t9 D        return 1;3 U. |! j/ `! [4 o% N# Z, U
}
2 I3 }3 F. Q7 ~) z) _$ D" o0 W" k7 r
float operate(float x, char opr, float y)
: o$ _9 e5 A: q" P! t3 }) Q{; Y2 e3 e2 }/ p# e
    float result;" F8 q2 n! `! `; P, K* r4 Z) D
    switch (opr)9 l( }, t7 |2 Z* z4 A/ S+ }
    {
/ S! L; s: O& Q1 S0 }$ m        case '+':
+ e% G! b+ U( i1 R1 o+ E. v             result = x + y;5 D; y% E$ \: a' _, j2 @
             break;! Z$ Z- w% }8 b: f( n
        case '-':
: Q" V" T8 i2 Q4 u) ^+ r9 ?             result = x - y;
' c, j) {% v+ I# Q- b/ Z% X/ t. P, t             break;
4 p7 d! N- N/ @1 G; e2 W$ H        case '*':
( J9 P; ?' e( |! b$ `( D* d9 @! @             result = x * y;, G2 n# |8 d* e9 Y! @8 P9 C, R
             break;
0 V1 C5 R. y" C- r' q" Y, ~        case '/':
. y5 R; D, u& V0 R             if (y == 0)
# D8 h/ p5 R% k' ^) P             {+ Y9 L4 H) g; o  \
                printf("Divided by zero!\n");
6 x) S' m6 ^/ a9 q                return 0;/ |" d) I+ I7 d& X, B
             }2 q% V: s+ i# x5 a0 J! Z" S
             else0 k/ l- X4 ~2 J! ^9 k
             {* [3 R4 B! `6 E$ w# B5 P7 s1 s
                 result = x / y;( i( u1 T5 d0 M5 `) w( q5 d
                 break;& D3 ~  l) ?- j* K( R; ~  S
             }; L2 m: p+ q& J1 a
       default: 4 J. T+ W9 Z. v6 s0 J8 \
             printf("Bad Input.\n"); : n% x$ y+ l7 _; L9 e6 i, I
             return 0;$ l  D% h) }# P0 B" P0 }+ J: V
    }
, d1 a- J6 a, C: k    return result;
% s! c1 ~6 E) Y$ r( t8 o# T. U) N' e}    & K- a) h0 |5 [5 V8 o. o' g
( M* }& p+ G. [: m% m" H
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/  M- g: y+ W, o9 V3 U- K/ O
{
& \+ [* t. N$ y6 H9 ]! Y    Stack optr,opnd;$ o# K8 Z4 M9 z6 `( A8 |
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
* w! X6 _* L# R    char c;. d, t/ |1 |) z% E8 M/ y0 P8 X
    char buf[16];( z% W' i# N! }, E/ m5 }% k7 k
    int i=0;) I* g3 |- D3 ^" l1 X
   
/ a* i* Y' V! Z    InitStack(optr); /*用于寄存运算符*/
, M2 {! c, g7 G) N, K8 |* ~    InitStack(opnd); /*用于寄存操作数和计算结果*/% o6 Q1 l. c$ q0 v4 t
    memset(buf,0,sizeof(buf));, Q/ `6 ]0 {8 e) E
    - v  F# y+ ]$ K' @7 I
    printf("Enter your expression:");
* l# i* y. Q) z7 p. ~7 i        
4 h; ]) T0 r6 }6 b! T% w    opr_in.ch='#';
5 P, s& z" t! d. F% Y4 y* _    Push(optr,opr_in); /*'#'入栈*/
  W, J4 I) a* q+ U3 i. |( R    GetTop(optr,opr_top);
* @1 a  z% _# Z" _& y    c=getchar();. U- _% r, L: [, l5 M" h2 d$ [
    while(c!='='||opr_top.ch!='#')- q3 n$ k  B* ^+ Z) b
    {
$ `0 F$ Q2 |9 `. j" v9 P        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/5 }6 C) Z& q( }9 H6 F- W+ }
        {3 w6 }0 k9 o& q) @
            buf=c;' e+ t, S( [, U8 d4 M: V2 o
            i++;# ]+ _/ w- _( `9 x" q8 N
            c=getchar();' H9 }$ H, T/ Q/ C0 o# L, s
        }
5 @* C* {7 c- ~/ l6 f* r        else /*是运算符*/
. u* R1 D$ W& p. y5 C7 `& f        {. b, [) D, \5 L2 l1 O; ?5 Y
            buf='\0';( H( C& Q0 z2 {) E3 O
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0 j7 g" D- ]! R5 z2 l
            {
8 k$ p& Q1 o+ m# z% L                 opn_in.data=(float)atof(buf);
7 J' `. |, B! H* A5 S* {3 R( L                 Push(opnd,opn_in);
& S0 l% e  J+ _! H4 {( ^5 U+ u                 printf("opnd入栈:[%f]\n",opn_in.data);- n: Q7 h" V5 i* y" e
                 i=0;
3 F4 R- t+ @) n: C8 f' S' J                 memset(buf,0,sizeof(buf));
+ o$ C8 Y5 r- s! R/ @            }
8 H# r& A. d' U) Y! Y            opr_in.ch=c;
% k# `$ W" L# y            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
% G5 N% t* ^4 b! _            {, L6 d5 @* p$ ?3 \
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ W' N1 Q8 _. C3 O+ I                     Push(optr,opr_in);
3 q$ I1 v; n$ a6 @5 X) n! }9 @, s                     printf("optr入栈:[%c]\n",opr_in.ch);, P  K: B7 S6 U& r
                     c=getchar();8 \% ]- H& O9 [, Z) ~7 ?! e* t) W
                     break;
. b0 o$ {: j; Z                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/3 D( x$ ^3 X( V5 s: s) j# U* d; u
                     Pop(optr,e);+ t3 V' r! l, T. Q
                     printf("optr出栈:去掉括号\n");- U+ k+ D1 u% X  n, n# N4 @
                     c=getchar();1 j$ b# v3 S2 L  X! |
                     break;9 q/ A8 Z6 o/ I$ W9 }$ ^; }" y6 V
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
- \8 t' z1 ^; G" A+ _! P5 G                     Pop(optr,opr_t);
( t: o) U; H1 n+ ?' g                     printf("optr出栈:[%c]\n",opr_t.ch);
, r; w8 ~3 [1 }$ h, @& W                     if(Pop(opnd,b)<0)4 |5 @5 Q7 P4 b/ j
                     {$ V( I' F1 c& r! d+ c, T
                         printf("Bad Input!\n");
! U8 S4 i# m( Y% _                         fflush(stdin);
$ Q, e/ `% O$ J: w9 q# S                         return -1;
8 p% a% q* s6 Q' f+ o( V' J: F$ g                     }
! {6 W/ g3 M. Z# z% @* u& w                     printf("opnd出栈:[%f]\n",b.data);
5 ?' X* J2 X" e                     if(Pop(opnd,a)<0)
. M; b1 c( |) G0 Q1 Q" f/ ^                     {" I! A5 @% x. v: B) A
                         printf("Bad Input!\n");$ A; Y2 T# D9 r  d' J2 P
                         fflush(stdin);
# E3 v! o5 l" ~. P8 V5 \5 e9 l                         return -1;8 I1 \) T& v! {8 X
                     }. j! G" ]; s( T+ j8 A
                     printf("opnd出栈:[%f]\n",a.data);
5 g2 \, Z( G' [8 ~2 |                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
7 A6 m3 I0 b. K9 X* I                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( T5 P5 x( c) j' Y+ [                     printf("结果入栈:[%f]\n",opn_tmp.data);
; _  ]( J1 B9 k0 `% C" ^+ q; e                     break;: [5 ^& ?( A! N2 Q9 b2 g/ f
            }/ C/ T+ S) R* Y( U. _4 ~
        }4 O/ m8 X% ^0 B7 m
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ! ~: n0 P  Y% _, {
    }
/ i3 D  a9 a: r7 V" E' f5 D9 h7 F    GetTop(opnd,opn_tmp);* p" z* m0 Q% I$ x) R  [" C1 F
    DestroyStack(optr);# s% q% x' E- e0 `! E% i8 @3 U! i
    DestroyStack(opnd);
# p& d! H& n# R- H- m/ S    return opn_tmp.data;" r# A1 D6 m) L. k' E* X8 ~
}$ X  }# _) Q- E* [# |7 U- E) i

/ c" ^5 q0 C$ h" Ochar *killzero(char *res,float result)
, u2 i- T  T& f( o{
/ Q' H3 ^6 J2 G; P" z0 F& i. t( z    int i;+ r+ H6 h0 H$ K5 \( H

  m9 Z. T# Q# e& A% N# a    sprintf(res,"%f",result);4 }  E6 M8 D# F8 n
    i=(int)strlen(res)-1;; q( L$ s* \$ I
    while(i&&res=='0')# Z" g7 i/ X- c% C3 I  Z- C6 h) p
    {
: s8 Q4 z1 \3 h; Q: d' t        res='\0';
* K5 A( A- [( M& s: d% f        i--;
, z& x5 m" Q5 }    }
# S. s7 @  @: u4 l' r    if(res=='.')
; c6 z- l" ~( r0 A        res='\0';3 u7 ?7 i8 u- P$ t1 Y! G/ N
    return res;" D  e  O( C" c6 ^3 }
}% a  ^0 t, |% Z" J- P, C3 B- N
( g0 s; ]. E! q% y4 [! }
int main()
! z& c& n! n/ X; N6 J( V% Z- o{
0 @& S6 f& T& q+ s    char ch;
: q; Q; @$ _" M% r1 F    char res[64];
0 `4 ?& Z! v. P/ W* Z    float result;4 h1 [3 Z9 U3 C
    while(1)2 t( N7 Q6 }# ?6 t0 R2 L
    {
' @9 p, }$ e3 Q; |+ w* q        result=compute();
8 M) m  k$ w. a+ m) G' {5 b$ r        printf("\nThe result is:%s\n",killzero(res,result));& ]  b9 M4 I/ b8 K
        printf("Do you want to continue(y/n)?:") ;; [. J0 @3 @: f9 d0 d8 }; y
        ch=getch();3 I( o8 ?( b1 T0 [
        putchar(ch);' Y6 F4 B5 l; U& e% x; O
        if(ch=='n'||ch=='N')8 q4 L* ^9 B3 U7 u1 i2 X. d. {0 a
            break;
9 T9 k  y1 F) t! z) t# \        else
! {6 h8 N/ R! d/ Q% x' E            system("cls");
! H1 ~% E2 B# K5 p, u1 x$ y8 v    }
3 r' Q2 i2 G4 _5 _5 J4 q& J- L    return 0;# l8 |- d  Z1 f! s$ M5 a" C
}

4 }" t# F$ i1 U$ n4 |+ y
  X5 a* t; _3 A* h1 I. d[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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