Board logo

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

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

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
: G' f: Y! ?) Q& v' w* j7 P程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
1 c- `7 f% g0 H/ l: z9 ^9 M/**************表达式计算器************/
( P- Z  u  n6 `& q#include <stdio.h>
" Z0 {  M. J0 n; B#include <stdlib.h>
) J/ r) o. E, J5 w! h) ]#include <string.h>
6 c/ U# e1 O1 `. G#include <conio.h>
6 j# U- `, I. H7 b$ ^8 W#include <malloc.h>
& e/ _/ X3 I# r( M- v" ?
! B5 z9 N& ^+ N  y3 O#define STACK_SIZE 1007 Q+ q4 l# q2 M- L6 g
#define APPEND_SIZE 10  d. d( |5 d. t% m9 ]! L( v3 {
+ o6 a! A3 `0 b8 ?" V2 e0 M
struct SNode{1 A% @+ n: y+ J# V
    float data; /*存放操作数或者计算结果*/
+ U3 t* |; f1 q  F    char ch; /*存放运算符*/" I6 e) n1 C0 v! X0 j# t$ [- A1 C7 a, c
};
3 i4 ?8 D& h0 G% j* a% [5 f
+ Y  p0 Y, u4 `struct Stack{- r' ^' {# S3 B# g: s& U+ W
    SNode *top;
% p' j' f% R" j+ h. f1 V    SNode *base;$ O% i9 j& a+ V% t* A
    int size;
9 q- {- i9 z$ t! g};( p( s8 a1 v) l. T. ^- h$ l  J

% w+ `3 w% s, I# w: K3 ?7 X5 h/*栈操作函数*/' L. n4 E8 R6 k) `% e- l
int InitStack(Stack &S); /*创建栈*/* x+ w8 }2 L+ {3 @! Q9 r& X5 J; ~
int DestroyStack(Stack &S); /*销毁栈*/
& G* a# {; L( @1 D; p$ X' G6 }3 gint ClearStack(Stack &S); /*清空栈*/
' B! j" t  T- ]5 P& Q. L. Dint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
1 H0 K8 X2 }: e/ f/ g) V# Eint Push(Stack &S,SNode e); /*将结点e压入栈*/" c# {8 A# r/ y  a) R
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/! T( ], Q, P4 G; q9 Q! W

) m5 K. c' D; I+ \- D( i7 d8 w/*表达式计算器相关函数*/& `  e" M6 ^) q0 l9 c) t
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
* y' a$ v+ }* a# i! a, }0 Qint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/  P( ^1 z, P& U3 G4 g% ~+ t
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/# h* X; D1 C: _; Y, v
float compute(); /*表达式结算器主函数*/1 N1 n7 d  C' v" n: |5 B9 n( {
char *killzero(float result); /*去掉结果后面的0*/
0 {: B) V0 S- P* Q8 ?
$ [* N/ m/ X. ]0 n$ i& F* l; }! Jint InitStack(Stack &S)" m3 c& L; N& w) b+ F( v
{
: M. h* p, ]" n6 \6 a( r" Z  T    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
  |7 M( g& W) y, @, `( ^, \; c    if(S.base==NULL)  k' n; O# Z' F: P9 A* l0 o
    {5 |9 m# e: P" c& h% v
        printf("动态分配内存失败!");" l6 B. X& Q/ }( o
        return -1;
7 h2 O$ l! w/ E) f" d( v0 [    }$ Z1 D6 ]: j8 J! ^3 `
    S.top=S.base;* O/ I* `9 K, U6 K* y
    S.size=STACK_SIZE;% `. f" e6 z5 n7 V: A! W7 X6 q
    return 0;
1 [0 v% r* ]: }8 Z}* L) M( `( d8 r3 ~( S
$ G3 P# m' t; ~
int DestroyStack(Stack &S)7 }4 n) R6 _. S1 r$ g! M
{
! l7 J+ t: y4 R+ i2 J; ~9 Z    free(S.base);8 ^6 L0 R6 j) S- \4 D2 f
    return 0;% D3 Y- j4 I! k4 D
}
: R. E5 Y3 I1 \9 H
; A, k0 z1 Z/ D- {& F  D# zint ClearStack(Stack &S)/ [6 o% _4 f, s( e4 q
{2 V# X9 h7 O* f
    S.top=S.base;: v& o2 G: k( C8 @# `
    return 0;
9 J6 |4 W; r# C# a6 e; O}
1 w9 `- [8 l& P7 B' \2 g" E. z0 m/ w+ V: L' k- a6 E& W: R
int GetTop(Stack S,SNode &e)
, r, w: X& G- A; G' O" l{
, Q+ X0 F% o* i4 c* O    if(S.top==S.base)
( C& t6 `% C" [1 `& n- u    {
# e4 a: H* s5 X        printf("栈以为空!");
! i; s3 E/ T/ Z' j        return -1;9 w9 I  E$ j4 v' u" L' b' ]# }
    }7 P+ J& `8 w, s' d+ o4 f1 M- u
    e=*(S.top-1);
5 P% d4 B5 n+ [% |, U    return 0;
4 ~8 S! ]1 d+ I) V0 @}' F3 h, m" S# X( B% P$ h: {

3 S/ \: w6 ^& p  U  oint Push(Stack &S,SNode e)
3 Q) Y$ y: r8 l, q5 ]& I{) I3 e) ]) _7 T5 h* ]
    if(S.top-S.base>=S.size): Y0 {( D+ [5 J+ Q3 A
    {
6 z2 _7 @, @  M  L4 h$ h% W        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));7 M* T- L/ k* u; Q/ U2 V, P
        if(S.base==NULL)5 T  k, o2 ~$ [% C* X
        {, L2 T; H/ v' Y" a* e% c
            printf("动态分配内存失败!");8 n+ G- G! b% N# q! c! n* F
            return -1;  i; G9 v! N& V
        }/ ^3 [! d) c8 j, p/ N# p# U: C7 s3 m
        S.top=S.base+S.size;
: ~  ?+ O* K1 _% {        S.size+=APPEND_SIZE;
4 X  i  N% _/ }! R% X$ y    }
/ g5 l% U5 e% v2 f. ]3 F    *S.top=e;
5 R  U* Q9 ]  Q; g4 a# `    S.top++;) E  ^' S, N0 X- a( q, u4 @
    return 0;
; |6 F* r4 G& g+ H( |' S* u3 W  V}
  r8 K  y( K* o9 U1 q. U- ~1 U
8 @- W0 c0 l; _$ E: ^int Pop(Stack &S,SNode &e)
% F' V; s6 k- L{/ q! F6 k: p' Y2 Z9 v: i( ?! ^
    if(S.top==S.base)$ V5 Z9 U% h& @- r' b4 V$ f, x$ v: q
    {
1 V4 ^5 b( x: V) z$ b" E2 o        printf("栈为空!");) L$ q1 M1 j( D+ x$ y/ B  e$ r! m
        return -1;/ y+ p  t" g' |* y7 |5 a4 R
    }7 W: @# s9 b" |# }" y
    e=*(S.top-1);
5 n2 Y* C9 o- E    S.top--;7 K, ^8 P7 H& g9 }; k4 D& A
    return 0;
$ J* H0 U* B# i+ s# a4 t$ }; H. [}
: O. B* @% K$ T2 w3 d
2 Y# ~& k) g7 m- Q" }6 u/ Hchar get_precede(char s,char c). B1 y9 o7 b6 B- J' o  T, _
{( F) A$ g9 V" W( J5 }, r( W+ u& q
    switch(s)
& [9 O* u+ w) E  d, ~) ]; j0 _7 [    {
) l- \7 U- T  D# Z3 r% w        case '+':                 . y% Z) w1 W9 J) R2 o) @. B
        case '-':" m/ }; d" T6 s' [& z
             if(c=='+'||c=='-')6 f' B5 O  P; s: V0 v: Q
                 return '>';
( ?$ D; p3 J0 d! F# ]! ?0 D             else if(c=='*'||c=='/')4 `/ _0 B, S1 a: N
                 return '<';
5 e7 g3 C' [! r5 o* d0 }5 x# I             else if(c=='(')
1 C1 P; S$ m1 {! t9 A+ q                 return '<';' c5 J) w" r) i: a! n4 X
             else if(c==')')
+ ~: G' A& t" l5 X* y; U7 E                 return '>';
& T7 t/ Q3 ~! |/ |* ~4 ]  u             else ) n0 g4 g6 e  X2 J" w, o9 j
                 return '>';5 q- I2 Q5 @5 h) K/ r2 o7 u
        case '*':
0 d& \" l! W; y2 W4 W  T% e        case '/':. {# C* p& e: u0 y1 Q6 ]3 }$ O5 R1 r
             if(c=='+'||c=='-')
# i0 a/ u( X4 L$ [                 return '>';
% I& C' S+ r  D& T  _             else if(c=='*'||c=='/'), m+ v* l  W; B2 W8 ]" G  g$ i
                 return '>';8 R& w. k+ F% I8 j
             else if(c=='(')
6 n6 h1 b' Q% \$ w- P                 return '<';
' J  U* @. ]/ H             else if(c==')')
5 ]( P7 h4 A+ u0 M( c5 d. V                 return '>';) c0 b) f' _! e8 C" v. a& r
             else
4 g  Y* Y- T! g, I, P* K* g                 return '>';$ `+ b7 o" h  h- ?. G
        case '(':
: P. |  g7 q6 M             if(c=='+'||c=='-')
. l# `) G, N* H% m4 _                 return '<';, g, {& E% x8 j3 L4 O
             else if(c=='*'||c=='/')% S6 t  ?1 r* z
                 return '<';
" ^8 B! F) a& C$ L! M             else if(c=='(')! }, l5 W' `& W4 \& F* y
                 return '<';
5 ?/ G# }4 V% P  c             else if(c==')')+ u& x, Z. y+ v! m6 T) Y. A
                 return '=';
3 K' ?; G5 T% H' x+ h8 R             else
% L5 x8 `& @/ C$ i- s3 `* W, q                 return 'E';$ I& V$ n7 Q$ [2 `: |' F
        case ')':# O2 N8 B  b- H8 @- l
             if(c=='+'||c=='-')6 q+ h. {8 J% k( t) \+ P% |
                 return '>';
8 z  q+ j$ d- \# j9 X0 e4 }             else if(c=='*'||c=='/')' ]6 U: }0 o8 e  G! V8 w  M$ L6 i- X
                 return '>';
! ?$ H; m' g- V. P             else if(c=='(')
, E" o7 w$ P3 A& E# t& \+ I                 return 'E';  L' l. }% L# |
             else if(c==')')# n' j( z8 S; `0 R$ `7 t
                 return '>';
# B6 i6 }* z/ T! t2 Y             else) @# V  k* ?0 {# T2 q% M
                 return '>';  S( C4 J' x5 J7 q0 H
        case '#':3 z" h* y0 p, {; ~% O4 T
             if(c=='+'||c=='-')
+ N! P2 @' o, ?. z: u7 N1 R0 c                 return '<';
( J8 R. w9 }# p8 M: Z             else if(c=='*'||c=='/'), x2 P! R1 {" g2 [5 k4 D; \
                 return '<';4 E) A) E8 W, {- A3 g' F* K; _
             else if(c=='('), w" L" f2 F8 S" u4 N- K1 ~
                 return '<';
2 c0 x% z% P4 r) x4 g3 i4 t6 Q             else if(c==')')' Z9 a# ^4 r2 q& @' f
                 return 'E';( c. ?' U, o5 h+ c3 w; S, T
             else
5 q7 D7 C; N2 Z* M                 return '=';
( i7 W; V% l  T; r' v        default:" P  q6 a; ?( d8 T
             break;
" W- L6 f& {# ~+ q/ U    }# m6 v+ c: [$ H: i
    return 0;    ; z$ ^* M3 f# t
}: V! b; k' H, i- x5 H

: w* D( v2 Z% A7 q7 C# e) gint isOpr(char c)
( Q7 X4 h1 S& _: t! q) O) }5 r, `; [{* S" e# e" T* `. [7 y
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 L- i1 V8 D; U  \* L        return 0;
: r# d. \' }0 R7 j# @/ g$ ^1 u    else
# Z+ D7 G" I/ W. b4 o# O* c( v        return 1;
# N( f& X- s6 V2 u; n# Q}
! B/ [1 i7 b! L7 Q' A
$ s  M. k+ w) A+ Z$ K/ Vfloat operate(float x, char opr, float y)
& @3 U. B. ~$ s{
- l2 [/ I  y+ {1 M: m/ g) K    float result;
. R9 k( d2 C& \$ X, e    switch (opr)
) r) F8 K% ~/ d7 x$ Q" g8 A    {
! m" n, c3 O- d0 M- @1 c6 @        case '+': $ e6 e8 V& B! R5 h
             result = x + y;1 i0 r5 @: S; p8 o7 @% f3 F% B
             break;! n8 X5 c1 q. w- M! W/ `
        case '-': 4 w& ]0 B$ \5 j* L
             result = x - y;7 D0 \" C" {2 l6 |
             break;
" ^# a0 P; U2 i% v        case '*':
8 o1 u/ f6 ], N9 O5 p             result = x * y;
! c, r" v1 |" o4 h3 b1 V             break;
6 O: w$ E/ l- P0 _/ c6 ]        case '/':
+ {  l- V! I& U! w             if (y == 0)
$ Z4 y& j9 n% D; X% q             {
: S3 N1 y0 L( y& w% {. w1 M                printf("Divided by zero!\n");
5 b/ |& N* x4 x0 U                return 0;0 l; O+ s$ b& c; {4 _" [
             }( N$ |: U) o! {0 b
             else% u" q; q/ P# B
             {% m; j, ?: H. U
                 result = x / y;
1 R# g) U$ |8 w; C! w/ H                 break;
6 [0 [4 Q3 |1 i; C             }: l; [5 F* Q+ I% e
       default:
1 }- _9 d& v9 t9 h' y" I* h             printf("Bad Input.\n");
2 W. I* ^: e- O8 B  r: Z4 {! c             return 0;
+ M8 R: J: [1 h    }
! M/ W5 O! ^+ Q) _* L    return result;
+ o2 W. {; b0 s' r( D: Z9 t! J}   
  q1 _: J' j- ]5 o5 d2 o$ F. d1 W7 E7 d& o0 i8 T
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
( V& x0 q; h; J{
" @0 D) ?8 v# [: \    Stack optr,opnd;# y9 ^: j" C. r! j: o% t9 T8 p
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;/ A  {2 ^) D, ]' p' S! p
    char c;
1 n7 O$ _1 b0 K. r; X" B    char buf[16];
1 K* D( M3 _7 \, C# G    int i=0;8 I; b0 g, z6 C0 ^7 |  K2 D6 W
    + B1 h$ Y8 e& p5 |
    InitStack(optr); /*用于寄存运算符*/
* ]: n: X: t: m) g- G    InitStack(opnd); /*用于寄存操作数和计算结果*/
1 o  ~" O- l- ?5 Z1 z( e( e$ |    memset(buf,0,sizeof(buf));
; V) |+ b, }! x3 t& R5 F    - N& g7 o, N, k
    printf("Enter your expression:");
8 j4 }/ P) h+ f* j  o- U        ) U! q# S8 @/ f
    opr_in.ch='#';  O0 @6 ?4 h% j7 U! v
    Push(optr,opr_in); /*'#'入栈*/
4 z7 d* v9 h2 S    GetTop(optr,opr_top);: x$ ~7 ?( t* y
    c=getchar();: f9 ^% u) a2 C" g- k
    while(c!='='||opr_top.ch!='#')
4 f" Z! {8 B/ j. g5 D    {
# p+ z# Y/ |  h( k8 H/ T) m        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/1 R' `9 _& h% w) I) V& ?) B
        {
3 U9 m1 D* q1 `( j            buf=c;" i* m( V, q4 I9 O9 Z
            i++;
* ~0 X/ {& K9 `            c=getchar();) z) [0 R& E/ C
        }' r: D7 \4 |& x; U5 G0 ?% I) i
        else /*是运算符*/) h- s9 }& N8 \8 Y7 Z
        {
+ n& r+ k# p" p: q% ?            buf='\0';% ?  p! E, \! \/ J2 i
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/" _/ L' }% \/ t8 h6 U
            {  n! c; ~6 u  q& w
                 opn_in.data=(float)atof(buf);
! H$ t- w' A4 c% J/ T% Q; I4 g) I3 e                 Push(opnd,opn_in);) o. _* B- Q$ s
                 printf("opnd入栈:[%f]\n",opn_in.data);: u2 [/ F0 ]2 t2 T% |8 f! U
                 i=0;% m  I" T0 ^5 r& \" L; m
                 memset(buf,0,sizeof(buf));  n: A3 `0 h! x* r! z
            }, X$ M; V0 K0 f5 I' ^! s) G
            opr_in.ch=c;' J2 \* l9 l9 l( D7 }4 G$ _; u
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/, L$ \: t  D0 P9 A. P8 s: l
            {, T# e% @( l: p3 d: M
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
9 m" i0 w+ R! W% b1 H                     Push(optr,opr_in);* j  Z* f8 r/ i0 y3 m% M+ f  v
                     printf("optr入栈:[%c]\n",opr_in.ch);! l& f8 J5 \1 Y' D2 B% l" i( W
                     c=getchar();0 R/ K  E2 v0 f  D! [6 v9 T
                     break;; w6 e7 K/ p* P. a; X' m) F, {
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/' \. l" N& F/ i2 h: _
                     Pop(optr,e);3 D" E: |% [$ N1 f2 k
                     printf("optr出栈:去掉括号\n");
9 V: A# `' C  f: z                     c=getchar();
; \9 ~& X$ j+ z3 t  g                     break;4 [9 b8 X. m  U- Q
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
1 D0 H- y4 J9 s; q5 O( @7 ]                     Pop(optr,opr_t);
8 V! [9 V- q, s& D% [/ _                     printf("optr出栈:[%c]\n",opr_t.ch);" |" H- W$ k3 E! x- ~5 a
                     if(Pop(opnd,b)<0)
7 M& s: P6 F! T; o. r( `                     {
' }; D2 a4 v$ j# Q5 l. F                         printf("Bad Input!\n");' U: M* ]/ K3 _# ]7 }% g
                         fflush(stdin);
0 n/ E0 G2 Z5 r+ ]6 B- U                         return -1;$ L4 j  g/ s% X3 Q' T$ M& b0 k
                     }, \5 P& t- m( i6 n2 _- D
                     printf("opnd出栈:[%f]\n",b.data);
, k: q) F; d% G9 J& A                     if(Pop(opnd,a)<0)0 F. {7 B% Z8 p3 q
                     {& y& f) y# |4 R; c: A4 s; y4 A
                         printf("Bad Input!\n");' Y' q5 d8 K* ]& r6 h. N
                         fflush(stdin);
# O- a4 u& K2 ^6 K                         return -1;6 z8 k4 u* T; d( L
                     }
1 k- M' M. s. u8 M                     printf("opnd出栈:[%f]\n",a.data);
  R1 u; Q# G) r# b                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/; b0 F1 B5 S2 I" K) A
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/7 l7 {+ ^; L7 n3 o
                     printf("结果入栈:[%f]\n",opn_tmp.data);% z" @6 I: P5 j$ z+ g9 e0 q
                     break;# `# E4 E( T% V( G+ G% s0 U
            }
, h1 W; i( K: G5 Y; C( C$ Z1 z        }
- ?& j; c! R3 P+ P" n        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
; ]5 u# z. E; w6 ~" w) B    }% }) M) `- ^: I  U1 y, `
    GetTop(opnd,opn_tmp);
5 k" K' m. i5 \" G; p; q0 m    DestroyStack(optr);
1 _! h5 a; D1 X/ v% g    DestroyStack(opnd);
. t% X5 ~* g; C* J  k: |# R    return opn_tmp.data;8 N& U4 A) g0 G9 o$ e. ]. U
}
/ T% \3 V/ A+ s4 `1 _5 B$ N  o. E
char *killzero(char *res,float result)3 }, G* D0 m9 w- F; a& {
{
8 b" G" m( m$ |    int i;
9 {4 Q4 G6 r# C3 R. C+ R2 v# n
8 a0 T( Z; C' K# O9 c1 `    sprintf(res,"%f",result);. y! h/ j; T" ^$ o# j+ n
    i=(int)strlen(res)-1;
8 X0 R, v0 N8 O$ N* u' D3 g    while(i&&res=='0')
: X9 G: N' p9 Y; S$ z" ?# L    {' E" r" M7 F/ Q- S
        res='\0';3 \4 U! A3 g2 e& ]7 G1 p
        i--;8 I' P% N2 J: Z
    }) n6 P, {* V8 y6 t( L8 h
    if(res=='.')/ z2 p8 F4 f# S3 r
        res='\0';: d1 D) B* I, @# R' d$ }
    return res;
4 ^% I1 b1 v+ V# Q2 w% ?}0 M1 q; f# w6 n
% M$ A$ l* h$ T( M8 c
int main()% L% `5 g0 [. D( d
{
+ E; [6 f0 |# D8 u- H    char ch;9 m. I) L7 p% x5 F! ?
    char res[64];
9 O0 o* r+ |/ a; i5 X5 e    float result;
9 X7 Q& }6 \9 u  Z2 d0 P+ |    while(1)3 N0 Q' V( t& D
    {
4 t6 S6 o+ \' ^% H! S        result=compute();
) \3 U, A4 s# c& N        printf("\nThe result is:%s\n",killzero(res,result));. I3 c5 {; V8 N! S* t4 @
        printf("Do you want to continue(y/n)?:") ;$ X& Q6 u( g* l* e. S) r; l7 s) `
        ch=getch();3 C, _* z0 L- S/ R8 X) _7 E+ t  B
        putchar(ch);
- D* n' v4 ^; [# N3 B        if(ch=='n'||ch=='N')
( A& k" y$ F7 D: \. S            break;
. K8 s# [5 J( g4 h3 J        else" J, v5 t6 I+ Q$ p. X3 ?
            system("cls");
+ E, C% k* q) k7 F, v7 D    }
% i, _+ I- @" `* @# @  C7 e    return 0;
$ l, E  _! Z0 j  H}
/ j' \$ |- x; _
* R* z- S( A# ~  u
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




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