返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
' J+ G3 N4 L% v8 ?! _程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
+ \- s, `0 s- D# ^/**************表达式计算器************/
" c8 \  l# f( V' h9 j4 Q" o#include <stdio.h>
7 e# d! X( e) T#include <stdlib.h>) B: \3 n5 U3 j& P
#include <string.h>) W% }4 d+ N8 D. @) i8 Z0 a$ Q
#include <conio.h>
6 l' O3 H: _: ?8 ]7 L#include <malloc.h>
% s4 V. ~# z& E% f6 B- ?
# e2 N/ i. L  z. p+ b; B; ~#define STACK_SIZE 1009 n7 n' [9 [. r: R
#define APPEND_SIZE 10
" _( \( N1 u& w5 w( _8 {: f$ ]3 i. k) ~( Z. e6 R$ i8 Q
struct SNode{
+ ]$ `+ A, M2 S- R: g% E) N# m2 t    float data; /*存放操作数或者计算结果*/
9 y' I$ s( j: ~3 t, T8 A/ t! {    char ch; /*存放运算符*/
( O. n) y4 v+ {: R" s0 R( Y8 I- i+ z) \: ]};! \/ L4 k% [+ [% V

2 I  F+ \* A+ ]5 Xstruct Stack{
: v3 P( \, _! }9 H% e8 m: r# ~    SNode *top;4 Y6 u+ Y" d8 L: F( [& ?. a
    SNode *base;1 O) C' N1 I( k
    int size;' v* H" S$ ^& R
};+ ~: c7 n9 X. U/ p3 d- o5 d" d9 }0 w
7 O: F; n3 P/ @- t% A# I) j
/*栈操作函数*/& Z7 P$ b1 R, U
int InitStack(Stack &S); /*创建栈*/0 ~, {3 \9 j: [1 n* h" h1 L
int DestroyStack(Stack &S); /*销毁栈*/
( A% F/ S- ~# ~) g8 ~; I* wint ClearStack(Stack &S); /*清空栈*/
5 Y9 |) l3 _& Y+ r" c; Hint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
9 {3 E) j% R7 U9 P$ C2 ]) a* r1 `int Push(Stack &S,SNode e); /*将结点e压入栈*/
5 }* Z" ^- Q. T/ aint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ E. J/ E% z/ }& u  J, E7 I1 z. D, @# ^! Q8 q8 t
/*表达式计算器相关函数*/# ~; l( O4 U, M) a
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
! N) F; N$ J: h& B3 \/ Cint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/0 @6 u8 m8 d; j+ }2 o0 d) k
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
% F: W5 `% d% _- d1 i' F, sfloat compute(); /*表达式结算器主函数*/8 b4 [( V. E$ T* F3 {- e
char *killzero(float result); /*去掉结果后面的0*/ $ k7 G+ r2 H1 L% M. Q

6 ~* S- a. d* t" [6 F2 Vint InitStack(Stack &S)2 ~: n2 E! B# D# y, f
{# c: A' a' u. y7 X3 n4 z: g
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));" u0 c! K: i, _) X# I' t
    if(S.base==NULL)# Z( s4 `6 R; `; q
    {
5 |( k0 r. v" @! G) P4 d; g        printf("动态分配内存失败!");* \  K8 ~" S! q7 ~$ `, }
        return -1;
' e  \% h2 K% f4 |. ?) m0 T    }3 G4 X3 B8 o& I( y$ C* x, t3 s& c
    S.top=S.base;
1 p5 L2 N4 _1 Z# M. X    S.size=STACK_SIZE;
, ]; R8 K( ~# `0 ?0 L. k3 e    return 0;
+ p4 P3 J* m: I- {: D. T0 m" C}# a( m5 t- M: [5 R# j

% I9 d9 T) R3 e5 |& l8 i  _int DestroyStack(Stack &S)$ u" p' Q$ Y# u! C- O4 e$ Z
{
) y  f/ v% P0 R( |; x    free(S.base);
$ }4 M1 c" c7 m' M0 I2 b3 v    return 0;. K( \3 r0 \6 s0 ?  S
}+ W" b" l3 s% O+ n- a9 `
4 M9 p: C; P* S# X" R
int ClearStack(Stack &S)( c9 f8 _. }# e2 _. O
{/ Q) e/ G% [  e. g
    S.top=S.base;# {2 R/ [. c, g' S" s4 Q3 N
    return 0;
# {2 O" e. a4 i1 M- p. p}
" m' }% {, \+ B5 j0 f  n& b/ c7 r( D, j+ V8 D. W& S, U
int GetTop(Stack S,SNode &e)
# u; M  z% {; v! p6 o/ v( J8 c# J{7 C$ }2 [. _- N7 _: Q+ T
    if(S.top==S.base)
, [+ x* h9 b( }) y* W    {
& `. U1 m  X$ F1 l. C6 |7 h, ]        printf("栈以为空!");; ]' i  b# O0 k$ R; k+ l: o
        return -1;
4 h* o! }  P7 t4 ^$ ?( g7 x+ @    }
  n* {+ h. T% |  k. O) L    e=*(S.top-1);* P" c- c1 D! o
    return 0;% C8 u+ W9 Q6 a9 l% b
}
4 \% m  r; x/ C5 ^9 d/ r  P/ y% `3 k) r: {1 X
int Push(Stack &S,SNode e)8 I' I% `$ L0 c' f
{- _7 D: X2 C; q3 k3 q' q) D' i1 y1 J
    if(S.top-S.base>=S.size)% T, i$ b3 i( G% M2 d" N
    {5 I5 t( O3 {3 H" {* G# Q7 f
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));) j* V) Q* _& T7 V
        if(S.base==NULL)9 Q( u9 \2 `( P- [. S
        {
1 p7 W/ y% C" ~! x2 |            printf("动态分配内存失败!");7 ]( e$ K6 y" D$ `8 D
            return -1;
, x! D! A7 C4 `! Z/ U' {        }
) [' R3 A( h7 j        S.top=S.base+S.size;7 ^% F. m) W* O) f0 R5 @
        S.size+=APPEND_SIZE;* ?* z- u5 D3 w( i+ h, r: B# V
    }
6 q2 S2 q3 P$ [5 S( v    *S.top=e;- |* {4 c. B1 F
    S.top++;8 }% L' S  W, Q1 ~
    return 0;6 A  P* Q. s" y" `0 J, V
}6 H6 l, {, Z9 e6 B5 O

' g9 L4 |. P5 N+ y: K5 d$ |int Pop(Stack &S,SNode &e)
. o1 A9 ?: Q8 w  |4 c  m{
/ q, C* _) `4 g( g8 r' Q$ ^    if(S.top==S.base)1 U, b! o5 J- N9 @. u
    {! F% i/ C! c5 x# Q  r# D8 v, {5 K
        printf("栈为空!");
# B: a2 _6 Y, z2 U        return -1;% {6 b2 C! @, L" _7 I, c( j8 J! Y) j
    }" B; S0 A7 ~) }9 `0 |" D
    e=*(S.top-1);7 y$ e. x5 b* H) z7 [- e
    S.top--;
& b3 _' h# l2 [( V6 o. e7 u    return 0;
! B% o4 p# R5 D3 w}
8 {1 _3 t) S, S9 i5 N3 c# z
! \8 a3 M1 e; mchar get_precede(char s,char c)6 o! x1 V8 M7 S  K0 ~; P- k4 V
{
7 }! R2 A1 H* j% N) J    switch(s)7 ]. ]( K" b, s0 J4 [# y
    {
. ~+ @7 d1 l: [2 ?        case '+':                 
2 E4 L8 l5 f1 i3 E' E5 F+ v        case '-':
2 k. _. l8 q% B/ W/ j             if(c=='+'||c=='-')
/ A* x8 H4 N, g: S                 return '>';( o( T+ L% k- S/ {! v* t" W
             else if(c=='*'||c=='/')7 y$ v4 N& Q& I! u
                 return '<';( D- u6 L, k+ U. f4 |+ I8 U
             else if(c=='(')4 p/ F/ P3 J; Y5 w& U$ M) V: P' q6 e
                 return '<';
: B7 M/ E, S: q! Z, g             else if(c==')')
0 x2 s  d6 A: U4 O" s$ j7 D7 @                 return '>';
9 U. R, P2 H' m% \             else ; g1 T# p$ g& [3 n. |6 [7 E+ j. z
                 return '>';$ L* W. O4 u2 S
        case '*':) ]5 j! u$ ^& Y3 W: N% q
        case '/':
3 ]8 f8 {5 v8 Y$ c4 e" F0 b0 [             if(c=='+'||c=='-'). `& v4 U' O% ?8 Z# F; V
                 return '>';
" G. r& A$ K# K9 l' E! B. c& Z3 ^' w             else if(c=='*'||c=='/')
% I2 [2 d1 G( C8 p6 r                 return '>';9 e1 @5 r: D! m) W1 Z
             else if(c=='(')2 `( y% B* ?- Q, M
                 return '<';/ t# w( x1 y: Z  V+ Y7 |
             else if(c==')')
+ O/ N$ ]* K1 o4 k: E& h$ Y                 return '>';
$ F! y9 i5 J6 E( x' H9 _             else! @& \- e3 o) \  a& p7 J$ A
                 return '>';1 f, w* ^! q7 `8 c% b/ i8 B4 `
        case '(':6 `: m( u7 {- J5 T- Z5 S" j
             if(c=='+'||c=='-')
  V' Z" n0 \5 Y: F                 return '<';
0 }% x5 y- G! ]1 \. K; V9 [( _! I             else if(c=='*'||c=='/')
% I! M! M4 q* y2 }                 return '<';
( F- H; R& d. K# R1 v6 p* U7 e9 v             else if(c=='(')
! B3 p) c6 m" q5 u" c* n! l4 j                 return '<';+ v8 e" d+ b7 S& e1 m: A9 G* H5 H
             else if(c==')')
3 e. S4 z" H6 l; [2 R1 h                 return '=';& {) P0 a/ ]6 L* U. S+ v+ h
             else
( I$ M+ M9 I8 C3 r* B4 j$ }                 return 'E';
. g4 i) y- y3 t. P1 Q        case ')':
( V& c% d" V) I+ V             if(c=='+'||c=='-')& O2 T  T; F% y! \
                 return '>';& `( t" D* M4 n; U8 c+ w
             else if(c=='*'||c=='/')
( E3 r) z+ g% @                 return '>';9 f& {) j! }8 w) ]8 M) _( e* Z( m: z
             else if(c=='(')
3 @3 r7 I% ]# G! P, V/ R                 return 'E';' e# P5 |) K- s3 o5 X% K
             else if(c==')')
& A( l9 Q6 G3 n5 p4 C, b; {9 G                 return '>';
# m$ N' u8 `$ p+ Y( `0 C             else
) \- g7 Z  k: Q, P/ o5 Z                 return '>';
- N( b2 o/ B" B7 E        case '#':1 @& T3 v( w0 u0 m  l+ _) S
             if(c=='+'||c=='-')9 ]. Q/ A$ Y4 m+ Y
                 return '<';
" ?( R: B" ~4 V/ C" i             else if(c=='*'||c=='/')3 |" a# l- ~- h1 c
                 return '<';4 k+ u  A2 ^# O/ j1 j
             else if(c=='(')
6 d2 r8 a/ O) A- V$ n. U! m; K                 return '<';
7 y  ?/ z4 F1 k  a  G             else if(c==')')
1 w7 c) T( Q1 k6 d; X6 Z                 return 'E';
. d* ]: h) A. Z             else8 M8 y8 }$ v& |$ M* ^4 U: {
                 return '=';
; O! X" e: z# w        default:- ]- c: R$ D2 L6 K0 S6 {( ^9 Z
             break;! r! @- s6 @/ B) p) {
    }5 e8 v' x9 c" v9 J3 L$ e" K, J
    return 0;    * `' s" n. g1 g% Z
}
' y1 ~; H, I( ]4 p" V0 Z/ u2 Y5 N+ H; H, F0 c1 p4 j
int isOpr(char c)
( H  c; m8 M6 Y# F{+ e( s2 ?# N5 h# a3 r- J3 r
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2 W  K# y+ D+ @5 C) E! q( E
        return 0;
& z0 A) I" Q1 k# N7 Y. S    else - q; s: ^7 T; T( E. e7 P
        return 1;
0 I" F, W/ Y+ \, ~& l}
  _) F2 }, o: d6 r+ ^) D* M# g$ ~3 T
float operate(float x, char opr, float y)+ c. L- v, G" Y6 x( @
{
1 P* v, @" L. K/ \! U    float result;
. v6 G0 \$ S2 A9 }& a    switch (opr)
+ G8 x! A" \- g4 @    {& ?4 Y+ r2 [0 m4 J! P' i$ s
        case '+': 6 ]9 A1 i1 O$ h2 \  a
             result = x + y;' O# I6 n/ x7 v- x2 a
             break;
+ J# Q, [: X9 P; D( L        case '-': / u; z3 v" }7 K4 L
             result = x - y;
' _7 `) z; B% K# F9 y             break;' v3 f$ H6 J* i. D
        case '*': / W/ U3 ]1 J' t" Y% B' G9 o
             result = x * y;
. w( N- U6 R7 g             break;( J- R' R# b2 r  M$ p% v: e/ x
        case '/':
% S" h1 F* q5 x9 [) D3 K             if (y == 0)" _& B+ t9 c! H3 T* ~
             {0 c1 j6 ?! u! h; l: a7 e
                printf("Divided by zero!\n");6 v& Y5 m8 w) G; ]  C# q. C
                return 0;
* E  q2 x1 K7 h; U; g             }/ l* t  _1 z4 K# ?) x- ^: z5 ^
             else
& B  b2 x9 T- T9 }; w: l; F             {9 g! ^4 L5 w7 v" G- y
                 result = x / y;
3 h1 p1 \4 _/ o                 break;# D2 ]1 S+ U6 ^6 C3 z. a
             }5 Q- h; @+ Q! K+ ?
       default: " a5 j2 o' b* [* x- |: d
             printf("Bad Input.\n");
1 Q2 ]# S& }3 h0 G: x1 i             return 0;6 Y8 R* ^0 c8 a, `8 ]3 L" W6 C  G$ ^
    }7 |0 g) B% G- N! r$ y
    return result;
7 Z  o  k% o8 H5 b}   
7 y5 h$ ]; }# _" w  y$ `. |
5 j, @* [7 A8 v- M  a2 cfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
. E# B9 |& Q6 {* F{
2 s. _: o5 R) ~    Stack optr,opnd;9 `+ `& x  P/ l6 z% `8 J
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;2 F7 d" V0 `, r- C
    char c;. I0 O- O( X; O! _5 }
    char buf[16];) J; P# `' }9 L) b
    int i=0;. F$ x# q0 A# X# g: b& l( g; b
   
' i7 U& u* ?5 d  h    InitStack(optr); /*用于寄存运算符*/
) g1 |3 M6 `, u9 B1 V    InitStack(opnd); /*用于寄存操作数和计算结果*/, }6 T2 D8 y+ T$ w
    memset(buf,0,sizeof(buf));
. z6 x: d9 B) }9 r* M   
/ T0 N& [$ i1 k3 h  t! G    printf("Enter your expression:");/ `) m; i' g, l
        
$ x$ U5 _5 a) [  Z    opr_in.ch='#';
9 G  M4 ?( b1 `0 D6 x    Push(optr,opr_in); /*'#'入栈*/5 N+ t) Q  p( P( Z5 v  @
    GetTop(optr,opr_top);
5 O# s" h' _2 B6 K6 ^    c=getchar();
0 W. E7 b! |1 R$ M! L    while(c!='='||opr_top.ch!='#'): L2 H" h3 z. q  D  }* H9 f  [! x
    {
$ x, e: w: v7 C. M$ [  v$ \( d/ \, P        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
5 Q! o6 J- D5 Y  c  Y: Y        {
5 O0 ?& \' i$ Z6 m, u            buf=c;8 m3 @9 W5 t3 p- R- g
            i++;
) ]* N: @7 [+ b  q6 O3 [$ ?            c=getchar();6 z; |8 M! s9 @) X. @' l
        }" b' A1 H0 H5 ]
        else /*是运算符*/
* Z2 c. y8 ]) ^4 ^9 H: M9 o  u! E        {
; o% F: R1 f9 y' y! A# ?* l6 F3 P            buf='\0';+ n* B& _& F5 H) q: ]
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
& x9 u+ g0 y+ J, x6 f1 N- ~& L            {
# J2 M/ w- |1 k7 w8 ?2 D                 opn_in.data=(float)atof(buf);! E: w7 w/ s6 ~9 K5 l* o. ~
                 Push(opnd,opn_in);8 r# g3 V- y) A) d3 U1 w
                 printf("opnd入栈:[%f]\n",opn_in.data);
# v- A4 j+ e+ g7 i% C3 C                 i=0;( U7 h7 `$ x9 Q3 t
                 memset(buf,0,sizeof(buf));
; L7 @) q1 U; K6 A            }
  U" f& i: O+ t8 f            opr_in.ch=c;2 z* Z$ j: M0 X6 a: J: X) U
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*// p4 M. s) {; J/ @
            {. I+ ^9 c8 K* K4 g8 B
                case '<': /*优先级小于栈顶结点,则运算符入栈*/3 s5 E4 B& Y' ?6 C5 W
                     Push(optr,opr_in);
8 s9 ?/ M7 h) x7 s                     printf("optr入栈:[%c]\n",opr_in.ch);
) }" ]( V" G( S3 c/ w                     c=getchar();2 O+ t8 @  ]& h- P' \) D: e* k
                     break;3 n) y. \0 k. n9 P9 s7 h  j! r
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 @3 R8 q& l0 N) f, ^4 W
                     Pop(optr,e);
( E7 W9 \% E4 M6 W/ z; u  o                     printf("optr出栈:去掉括号\n");
9 H! y+ g5 n3 e. ]                     c=getchar();2 f5 }; B/ a/ U! g
                     break;4 }/ G0 ?) ~: B8 a% \
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
( C' D4 L0 c4 x- R& l                     Pop(optr,opr_t);0 U* V$ ]8 {' y, k
                     printf("optr出栈:[%c]\n",opr_t.ch);( b! w2 v9 e5 Z1 a% m9 H
                     if(Pop(opnd,b)<0)
% p& Z6 c# r$ D. g! O2 ?" n' E) {                     {, ]) T5 i/ b% I- c, `" V
                         printf("Bad Input!\n");7 o2 V) _( c+ G6 r! b  q; ?
                         fflush(stdin);
% b' ?0 R( Q* g4 p; c% t" ?9 m                         return -1;$ f, [8 }$ g$ O0 e$ |/ p
                     }  _; V! V+ ~! g0 U
                     printf("opnd出栈:[%f]\n",b.data);
' U% X3 L! S: T- W' @5 j: n, g1 h                     if(Pop(opnd,a)<0)
4 G# m& l# H- `8 Y0 T                     {
' q1 L- i# F1 Z' w; x! F                         printf("Bad Input!\n");' o4 R& q1 S$ H& w0 l4 a" \' `
                         fflush(stdin);
+ [. V6 w1 Y2 m# D                         return -1;, l8 F* {8 C- a
                     }5 p5 g: N3 x8 Z4 H
                     printf("opnd出栈:[%f]\n",a.data);
7 ]2 \3 t* `# _4 ~; z4 y9 H                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/" s" D) ^; {  A( l; @6 T# L
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/0 ~  ^/ h2 h8 h0 P2 B, F
                     printf("结果入栈:[%f]\n",opn_tmp.data);
# _, d, m' i' E. Y. B+ F                     break;
6 ^5 J* ^* b/ u9 o! Q! s* D5 @            }
4 P  @/ ]" N% O/ ]! z* j, q        }3 x3 z* |  O5 j
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                : S) r+ W  H" E; l' z% ?% C
    }# d' u* y) A, x' o
    GetTop(opnd,opn_tmp);
6 t% N7 N  k7 J2 N* \3 r- P9 r    DestroyStack(optr);- ^% m8 m0 K. K" T
    DestroyStack(opnd);: H7 D2 q4 X( T  [, u3 F( v
    return opn_tmp.data;* Z2 n  e9 l5 V+ [, d! F, @
}  B+ P+ I! Y% }
( }3 Q7 [! m% t4 K
char *killzero(char *res,float result)6 K  h2 o+ u* R0 F; C. P9 K
{
- l* Q  u5 L7 R    int i;4 N8 J, k  _" X) B2 H8 I
! q2 L' g2 }" i) W
    sprintf(res,"%f",result);) }3 R! b% y) v" x
    i=(int)strlen(res)-1;3 X- m% ]' {2 o
    while(i&&res=='0')
; E% {  }* B- S    {! e) Q/ i9 {3 ]: t! V
        res='\0';3 }  [& _/ x2 B4 W) f
        i--;
! W: m% _2 T8 g! ?    }
9 Q: w# p. T* ]# j! I0 b3 q    if(res=='.')& d! ]! X/ Y  k( o. _" D  W
        res='\0';
: l" @# ~" w+ a4 x- D/ ]  [    return res;% }, v, `, z4 x3 ?. K1 Z4 O: C0 q
}
3 n' p$ \( g7 b# R$ }; X9 B
& X* b8 p" t1 ~8 i& E1 r0 [+ S' l) Kint main()
" r! V2 z" F  H{
4 S! k; F: j3 h& I* v4 A4 g1 _7 a7 f    char ch;
4 z9 _% f, K& [0 _# G, b    char res[64];. X" ^$ Y# W7 @0 Y, M6 u! S
    float result;" q8 G% K+ I( A- q
    while(1)
& j$ o0 {  r" E" j  a    {: t/ q! `7 c4 W4 m1 q7 Y* I8 O
        result=compute();
1 Z% J8 W8 s2 j: l        printf("\nThe result is:%s\n",killzero(res,result));( L! E4 g7 S2 e# ~5 w1 d. V
        printf("Do you want to continue(y/n)?:") ;* e/ N- _& i; e! a
        ch=getch();
! y: M$ T2 c% T' `8 v, I& W1 W$ l        putchar(ch);
& [7 d: ]7 @' T' g        if(ch=='n'||ch=='N')
0 {8 k$ O+ K" _& A* m; x# e            break;& h8 \* e) E) @
        else, h3 ?; j2 C) h+ \
            system("cls");8 e8 V! m, |6 C  Z
    }
2 u. ^. p* Z$ z. c, _! {8 K    return 0;) v$ p4 W9 @3 U- L, p
}
, T# _+ q; P. Y0 g1 U

: \* I% G# n, `. }4 l[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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