Board logo

标题: C语言表达式计算器 [打印本页]

作者: zw2004    时间: 2008-1-21 17:17     标题: C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
+ \2 K: G" B" ?# c* }8 ~程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=! Z: K' N# X5 L1 G* w' D
/**************表达式计算器************/
2 _# d+ H2 D( g/ _6 T& R#include <stdio.h>3 E- t' D% I: x/ x' n  z
#include <stdlib.h>
9 Y, ]( S: y7 u#include <string.h>7 c. b, ]- e  I6 ?
#include <conio.h>
9 d9 m" |9 ]# m#include <malloc.h>
3 _% u6 M9 c* Z$ V% S& C* N; G; O( ?$ n8 N) O- O
#define STACK_SIZE 100* ?% r6 r* v* I' o# Z6 ~
#define APPEND_SIZE 100 G& m9 ^0 C3 u. e  S2 k7 u/ |
5 N7 ?& T: k: r" ^) ~) T
struct SNode{
; P( p/ ~8 E7 j' d  }3 V# F    float data; /*存放操作数或者计算结果*/7 t" R. g( x- K0 x% ]/ h
    char ch; /*存放运算符*/1 s( G7 O( r3 i" \
};. y8 E4 {6 X; b9 Z
4 J0 f' W% j3 K% l5 H; Q1 w5 j9 u
struct Stack{
; g$ x8 r9 r& C. M9 k+ ^    SNode *top;
! H0 E% t) D! z7 V    SNode *base;1 F: P8 K+ p- \5 C: D. r
    int size;4 ]9 e! I3 h# Q
};
1 y& o# F6 H+ l1 |% D! ]  C% |3 s/ V
/*栈操作函数*/" B) i2 Z( d8 O- Q: T  U
int InitStack(Stack &S); /*创建栈*/5 N2 \& r  V2 @$ E
int DestroyStack(Stack &S); /*销毁栈*/
" Z" F8 j: ]6 x" |# yint ClearStack(Stack &S); /*清空栈*/5 n: O4 v: g# H0 U, l. V' I
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/  C  x# k! g- @/ U  l+ y
int Push(Stack &S,SNode e); /*将结点e压入栈*/
8 u- F1 b- @# \( A8 E0 Rint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/" {- E; ~1 p2 b4 k
3 R8 m5 ?; B* _. \
/*表达式计算器相关函数*/3 {* P! m& a: \* M
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
4 p& u0 D' J  O0 C- E+ fint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/  o/ V/ x% k$ q- E
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
  w3 p+ j; P0 I  @float compute(); /*表达式结算器主函数*/' n, P5 B& N$ G" B( Y
char *killzero(float result); /*去掉结果后面的0*/ ) G$ i+ ~. r! _+ e) F4 s

: M6 r* Z' c& P) n7 K( Zint InitStack(Stack &S)) J, u2 r" y7 O2 t4 M# {% U
{/ q& h3 @6 A/ Y: y' q
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));' m8 n1 [& {2 A2 [
    if(S.base==NULL)
6 D9 P4 s( c+ s2 h- D) T1 l3 L1 u    {
: F3 Y8 N( S/ g+ v3 |        printf("动态分配内存失败!");9 [8 R1 J/ v+ Y
        return -1;" h  }; x; ^6 ~% n
    }
0 s0 U$ X; i: |  ^& D    S.top=S.base;# G0 z3 Z0 S9 L; ?
    S.size=STACK_SIZE;
, Y1 n0 |1 i5 P1 l- u$ o% [    return 0;% W0 I- @2 ]9 `* l$ [7 H
}! \  w& s) X0 d, M

1 v9 ~& A3 a  Y: xint DestroyStack(Stack &S); w; t# A' q# c" T
{% t7 u' _$ g8 h. Y; ?2 U, E3 |5 U
    free(S.base);
. \: ^, x' n4 N' ~! e$ m    return 0;
2 w6 \5 f: r2 W) F7 }2 M& g8 j}, u  S6 ]- m& N/ U6 I% f/ ^
+ V% H: A0 u- q! @! c
int ClearStack(Stack &S)% K- E6 H4 ]' l! f4 S) [
{
# w6 Z# s" x8 l9 E7 {9 k* u9 {    S.top=S.base;. U! j$ G6 k! F2 C- u
    return 0;4 `" \/ l7 G) a
}1 b/ Q+ V2 q" \# @
2 V: X- X' L5 ^0 U+ j" x
int GetTop(Stack S,SNode &e)
" X* o) E7 I1 d" b+ l& R{- C* w; @6 G/ H/ N/ w' [! L
    if(S.top==S.base)
; z7 o1 j5 ^$ c+ _, W( B4 j+ Q0 n; Y    {
$ o$ X! I" Z3 l5 K& K2 d        printf("栈以为空!");
2 T) o' V! a7 n/ I% e4 w3 Q+ H$ @        return -1;
5 X0 X" p) m* n" z/ k% T    }- p% W- {9 e: U; Z, l1 @
    e=*(S.top-1);% d$ B; Y1 e- _* Z( G
    return 0;5 j# |5 ?- J) ]( E; h: d
}' c9 Z8 n( S# E& o6 E4 V# h' X
7 V7 n+ O/ Z6 w- h  a( `8 N) y
int Push(Stack &S,SNode e)5 V1 `& }/ H0 T* @. V9 U1 T( N
{
& \% C0 z5 Q& ^# d1 k% }- N' I+ ~7 J    if(S.top-S.base>=S.size)  P+ E: r" R" u/ m
    {
9 G. V0 P' n0 i        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
& X$ G/ v8 N7 ]/ Z        if(S.base==NULL)
: G  Y+ k' v4 m, B        {: r* H! i% a3 ^
            printf("动态分配内存失败!");
4 l8 m/ _6 q+ i' ~5 X: c( G            return -1;
1 \. ^; w3 h) |        }! @! r/ t4 o; F$ q
        S.top=S.base+S.size;: _3 ?% M. r# b' Q7 Z
        S.size+=APPEND_SIZE;$ w" `' m; a& M
    }
$ C. D# i6 i$ x* \1 S# j' c    *S.top=e;
+ s! @% @) ?5 P5 S. Y2 Y1 j' ^. H    S.top++;; F' W) \) [/ R: Y
    return 0;
3 ?* Z. j  O. P; r1 J% q, A2 v}; {' c; r6 T9 t8 d
' J- L0 R: j/ D& O0 `
int Pop(Stack &S,SNode &e)
! n2 K0 j. ^0 r) R/ k8 x1 b; K( W{
9 R; s0 r7 `" [- a9 w: R    if(S.top==S.base)
$ n1 y# A1 Q! |. l; d7 o    {
& s- b  P3 E. K7 u        printf("栈为空!");
9 o  ~! P! }" j7 @) I        return -1;
! I2 v& D4 W& @0 b$ m. o    }, C* ^& b" S9 f# F
    e=*(S.top-1);
7 `" ?  n! }, Y6 r, _! _4 `    S.top--;
4 ~3 g" c% F& n- y$ E  F    return 0;. m4 P4 Z. G7 B9 f
}* V9 ~( F/ r2 |
9 f- n$ h0 B2 D# N: E
char get_precede(char s,char c)
. d1 r4 t+ z% M( H{, w7 X) T3 G4 ]
    switch(s)2 U! Z# Y6 D8 Y% V9 o1 `
    {8 T& @* z$ N, }2 t! _  t+ [2 Z+ p
        case '+':                 
2 x* c9 W1 Y7 g" U. [; Y        case '-':
3 J6 u. p' F& a1 Z1 s             if(c=='+'||c=='-')
% G1 e: |2 O& d7 f9 X                 return '>';' |# b3 F; d2 w7 O
             else if(c=='*'||c=='/')& v+ v7 v. o' ]
                 return '<';/ s9 U$ J% Q6 i6 k& n: X
             else if(c=='(')
" r0 I4 \5 F, ^6 T4 q. r, F6 T7 c                 return '<';
) v- z4 L, M, {  y3 A9 O, |             else if(c==')')5 \& d0 v) y, V
                 return '>';
& Y: B' u  {8 B7 _7 X% {+ k% x6 U             else
& Z4 f% v3 L$ [; ~  W" h, I+ \5 n                 return '>';
' j0 i, H4 ^. S! I6 F9 R% X        case '*':8 G$ g" N7 \. M( L
        case '/':; Z" y! R* a! S
             if(c=='+'||c=='-')8 U6 A2 p) x6 W# W9 P
                 return '>';* q7 ~0 {- v/ H* s) {' E, I, ^- n
             else if(c=='*'||c=='/')2 N& N- a3 k0 q3 l0 k
                 return '>';
: ]0 ^' w: K8 `* \% ?             else if(c=='(')' }$ |- L+ h0 M5 z2 ^
                 return '<';
! }* C8 D  _5 |" O& S& l             else if(c==')')- q2 o$ I$ O8 M* i- }8 A+ G
                 return '>';! I! a' J5 I8 O- U& c- G( T8 V
             else& D# I9 \' W1 \: [! Z
                 return '>';- n0 c5 t$ p. Z1 C
        case '(':! A: m6 z* k( q, P/ F
             if(c=='+'||c=='-')
, B5 R8 q1 r5 K: t, t. f! k# \* `; C                 return '<';) i3 P5 W7 x8 ]  l: D1 T
             else if(c=='*'||c=='/'), k6 `3 ]7 Z+ `" v3 p; h$ _, B. ?
                 return '<';
1 m. [7 p: s2 ?) c: M, I+ W             else if(c=='(')
0 s% y8 J2 n6 L3 G+ z                 return '<';, ]8 D. Q. k$ J( M8 t: z
             else if(c==')')
, j  r$ R+ y9 W5 h4 ~6 G                 return '=';
/ [( w$ K4 u& Y) i% a             else
1 v0 V+ X% `) m                 return 'E';
1 Y/ t- V3 x& q4 p        case ')':
1 e8 n& v2 z& t' V+ R6 d) |             if(c=='+'||c=='-')2 @1 u) K6 P8 z8 l/ e3 s5 D- j
                 return '>';& j/ s% b4 n- h5 x( M
             else if(c=='*'||c=='/')
6 J: Z3 E, S1 \/ |" r7 H3 L                 return '>';
0 _, [* \' ~& ?  p             else if(c=='(')
! C" z3 l; q5 f+ q, [9 @                 return 'E';$ e; B( [7 ~: r; W
             else if(c==')')$ h2 V' H+ L! f
                 return '>';, J  |% |+ y) i/ b. B
             else0 s2 n% ?# H6 F$ y* N8 \" p
                 return '>';
$ `  o4 n3 p8 k/ o) y! {        case '#':
2 x& Q+ {3 v: o6 x, d             if(c=='+'||c=='-')+ p) w; M: u- O* p2 U3 z9 P7 O$ W; e
                 return '<';
1 \- V# t5 _$ Z/ w! b3 ]/ g+ C3 a             else if(c=='*'||c=='/'); q& f  \# J* E  v2 W
                 return '<';
% m$ ], c; m7 w, m& e             else if(c=='(')% Z6 |8 T  p' X) ^8 A
                 return '<';
% u6 w' L6 o- z1 b- Y             else if(c==')')8 f, C5 X9 ^  d( y" n7 K+ O
                 return 'E';
9 h2 I( X7 x$ i; ]             else7 W7 z$ j' O# n! n( X
                 return '=';
' u3 h) `3 {$ ^4 @' e1 F: S        default:1 @% `5 G% A& S/ R! l2 [7 j2 V
             break;6 L/ U% p& E1 t' n
    }
9 ?3 J5 }- b9 z; k; s    return 0;    1 W# V# H9 V5 u/ k* `1 z! J4 j
}
# [0 L2 ^' d+ F$ j2 U9 @3 A, g
. G0 S2 T" R# x* s* K* Mint isOpr(char c)
( N) R# t: M9 `  n, N{. z4 n/ e3 X: ]; s3 Z+ a: ]
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
& R! c$ x( Y& ~# E        return 0;
( \* \( }2 G1 e& j0 \! n0 @- j    else
3 ^1 j. E0 `# ^; u& t5 {' K( a' i        return 1;
' P& y3 m  R' _6 g- C- k: l1 h+ e}) f$ O6 g) S& _5 o

' \  @" y2 ?, V8 f9 L- M8 k7 Ffloat operate(float x, char opr, float y)  E/ g% C7 Q$ H+ Y1 n
{
) s  Y) X- p$ u5 x  S; U7 Z    float result;2 u% s# \# V7 Y, H' v4 g
    switch (opr)& W$ L  l9 l# s+ k) \5 P! S( w
    {; A: j' ]# j, d6 E& I( i) G
        case '+': % p$ e  ?1 o4 M. W; ^
             result = x + y;3 z* D! d2 {6 ~* J' k
             break;' ]$ T, H2 C! g. ]) i
        case '-':
: U, X& G# ^- W3 M             result = x - y;. i5 n0 `) w+ ~4 y7 d, e
             break;9 Q! g2 ^( _1 F5 u
        case '*': ( l& ^4 q. v# K0 l
             result = x * y;
8 ]' D+ U9 X6 O' S0 h) G  `; k  i             break;
0 x7 L0 ^- C- h        case '/':
1 d5 \/ S; _9 j0 ~: K             if (y == 0)
! `) ]+ E( C  v0 G! J$ K             {
# Q% v" I% w" o9 ?4 V% e, P  m                printf("Divided by zero!\n");
; K  M! @) c+ x* D, P                return 0;
$ g! ]4 Y; S2 v+ G9 n! i             }4 L$ p  \; h. r2 S) X" I
             else
! h2 K# t& t& V$ C& @5 E5 m) X             {
0 M. h  W8 [& j5 h2 c                 result = x / y;' K0 t& P5 o; D
                 break;+ X: G+ b0 {7 I3 a- P: I$ t/ y
             }$ E+ d& z. r+ X4 k# t; f/ {- r
       default: 1 q% C7 Y1 c+ e) q1 ^: T
             printf("Bad Input.\n"); 3 r# q2 {* E$ m/ j/ p7 Z
             return 0;
: f, z- z, p5 D9 _; B    }
) m6 H- d; _1 x1 r    return result;
7 z( f2 d* L/ C3 k3 J}    % q6 o- u7 \. D! {& y3 N

9 ]2 [9 @9 B, X2 a/ o, ^float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/4 ?  c. n) ?$ x" H! k
{
" \+ _2 I9 _( ~+ T; J    Stack optr,opnd;
% j9 V+ u- S! O9 K5 g    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;2 K  i2 y% `" B# f
    char c;
1 X+ {* e0 i, Q5 V9 @- y0 n    char buf[16];) M  C% j& _7 t: N+ O8 I8 Z' I
    int i=0;
( e, }; S* U  |/ y   
: w( a# v0 {+ B: {: o# W    InitStack(optr); /*用于寄存运算符*/" k/ J& o: r+ Q4 J. }* |
    InitStack(opnd); /*用于寄存操作数和计算结果*/
0 b9 L8 d. x4 K9 [8 d( C" k4 ?( _5 N/ }    memset(buf,0,sizeof(buf));2 x$ s: V8 R- w2 A  }
    : @6 O: ]; r: o$ k& h
    printf("Enter your expression:");3 e5 D) W( G/ a6 c, t
        0 Q0 M# z% R  F* p
    opr_in.ch='#';6 h: W" F0 x, Y$ U
    Push(optr,opr_in); /*'#'入栈*/) x. m; X8 m, m- m: Z  ^) x
    GetTop(optr,opr_top);
& }- `' F: D9 k# T5 s    c=getchar();: G( {- b+ e' b8 t' c$ i$ N% Y
    while(c!='='||opr_top.ch!='#')$ h% G$ p( x& J+ ~2 ^
    {
5 N* `* [! M' X" h( E        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/9 v9 F0 J4 o, |# j% ?7 c
        {
% d5 e+ x6 m' j+ j! ~) `            buf=c;
  m: i. a4 \+ @  ?            i++;
$ i4 b3 s3 q3 H9 I! R            c=getchar();% i3 H% [6 u* M& c% @  X
        }
! t( V+ `  Z+ a2 Y0 e        else /*是运算符*// {6 u8 Y. ?  C' s# S
        {; {, c2 o$ e: _, b1 u+ k
            buf='\0';
4 [5 D3 K7 O$ D6 H4 `* Y            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/& D' [/ i! G3 x# \7 z8 ^
            {
% i: \7 H; }% ~, z# j- ?$ ]: O                 opn_in.data=(float)atof(buf);
. k/ N' O" l7 r  e# r                 Push(opnd,opn_in);& y& ]& p' V6 o- _- r9 [3 |* i
                 printf("opnd入栈:[%f]\n",opn_in.data);
; G6 L/ k: O2 [* z: k                 i=0;
; J0 o1 C5 v* i7 s7 h% w                 memset(buf,0,sizeof(buf));; B. y6 b) h# c: k# n
            }0 o6 I1 a4 p0 w0 J
            opr_in.ch=c;
( d$ N/ R# Z( s! P3 d/ L            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
4 C, o  X: b/ K; D            {
/ A' b6 p+ K  S. W- H* H                case '<': /*优先级小于栈顶结点,则运算符入栈*/
2 V  A- f+ o1 }3 _                     Push(optr,opr_in);/ U7 I) q- e5 H7 p; C
                     printf("optr入栈:[%c]\n",opr_in.ch);
  Z2 T% Z) F- Z1 b( \6 ]                     c=getchar();! h! A& `6 O0 n
                     break;
) _: {+ j$ j. d, O3 [" B" m                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
9 N1 T- A, ^$ _( o                     Pop(optr,e);, ?* f5 J" h( m4 `9 g
                     printf("optr出栈:去掉括号\n");- i7 @, N) [7 c6 n0 p: @
                     c=getchar();  Z( h) A- K( ?) X+ O5 d9 m6 x
                     break;
$ B1 {# a5 D! B* i! N" W                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
. S0 G5 N0 ~) P0 L/ f                     Pop(optr,opr_t);
4 P0 T$ X7 W1 Z1 I7 t: R  \$ e) x' N% P! N                     printf("optr出栈:[%c]\n",opr_t.ch);
) d4 K  T, _" D                     if(Pop(opnd,b)<0)2 y$ W$ {5 w  L& ?
                     {2 J, K% @% G5 l6 x! t5 ]
                         printf("Bad Input!\n");5 C' N& \1 |8 a2 A6 s1 D
                         fflush(stdin);
0 Y. e7 [9 }% e+ B                         return -1;
  O- V$ ]& k  C3 Q- a                     }
- P7 Y, q5 e+ G) M* S, I% j                     printf("opnd出栈:[%f]\n",b.data);1 F% j- u. P7 T! j7 ?- _7 X5 A
                     if(Pop(opnd,a)<0)) v; ~$ f) Z" ?; x+ z" {8 {
                     {4 ~4 v8 a4 j2 P2 F! a6 u9 k+ {
                         printf("Bad Input!\n");
  b1 @# c: v( v- e: `* K                         fflush(stdin);& `8 _! y1 y- @) s' m
                         return -1;+ W+ [: V0 B- @+ ?) _; G
                     }) f3 y! g( o# l, G; V2 Y! R- ]
                     printf("opnd出栈:[%f]\n",a.data);
* z; }4 l+ x$ N- N1 g                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
. m* d0 Q0 i9 c* ^3 u' @, V                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/, f# [8 J$ h4 m+ d
                     printf("结果入栈:[%f]\n",opn_tmp.data);# t; ~8 H) `/ i7 ]* |1 i# v
                     break;
- E9 I6 w5 J0 J: P8 c5 Q            }
, ~+ T6 n" C0 N. _1 ?7 E        }* I% p: J* m- y2 E
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
, R' J9 u3 O1 R    }- S" i0 n9 k% @8 z
    GetTop(opnd,opn_tmp);
2 R) x7 i& p* _3 E    DestroyStack(optr);+ ~  S: b. w5 ^" P0 n4 w
    DestroyStack(opnd);; L& ^5 S& N* L
    return opn_tmp.data;
( M, Z: K& P( l) V# \; E5 C}
( P1 S6 }1 v5 L  X3 q. S3 P! }) [2 T7 f
char *killzero(char *res,float result)
4 j5 L6 S4 g+ v) \" G; a& T2 ~. c{5 j) I' @' o' t* \. b
    int i;
6 j# M! I% T7 K% j. R7 ]1 B. u7 P6 m
    sprintf(res,"%f",result);
! m! C7 T- e, A: }    i=(int)strlen(res)-1;: E7 }! m# L3 q
    while(i&&res=='0')7 d3 }) ^. w1 U' F; `4 _
    {
2 Y' P. n" o% L: S& x        res='\0';
# o* O- G$ z% l& r" c        i--;4 F- j& M- A* M6 T9 G
    }
6 o# Z) p2 X% T8 C' R    if(res=='.')' d# j# z. x* X; a
        res='\0';
: X2 k3 z  v$ i; Z4 A    return res;
( T/ v# |& ]! W}
; ?; p) k8 n: e- {$ x" `6 g8 x. o% g( q, I8 \0 C
int main()
4 V7 d0 _/ |3 b3 V{
2 H2 y/ b# z, P0 |$ W    char ch;
, N# G. O- a# W- R5 |/ t    char res[64];& C$ M. M5 U: J7 c
    float result;
, F2 f. ~2 y/ q* c' Z& y5 k0 n+ j8 g7 j8 D    while(1); ~/ {2 I# E5 n% W' X  n. y
    {" h  S+ T7 b5 B: k2 m
        result=compute();1 K; O+ U/ n1 X
        printf("\nThe result is:%s\n",killzero(res,result));
; B, o/ V4 f4 W3 `: K& M        printf("Do you want to continue(y/n)?:") ;  n" J) c" ^$ N, e' G, ~$ S! |
        ch=getch();$ R; d- y5 X/ T% o8 P
        putchar(ch);
; @3 k- ^8 k9 N: ?! l        if(ch=='n'||ch=='N')5 x' X7 ?+ T8 U  a# J$ z& c1 p
            break;
4 Q6 J- W% J1 G" U        else
! w! \* ^' U. k3 f8 n( T            system("cls");- J2 k4 E. c  F: i
    }
- r! z% ?' U$ s1 ^    return 0;
4 d. ~( d7 w, J) V4 E" C}
  B8 l9 {" W9 l! r

( K9 p( N+ G& D[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




欢迎光临 捌玖网络工作室 (http://www.89w.org/) Powered by Discuz! 7.2