返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5 ^5 T  e; f, s- o9 b# o- y程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
' X5 J7 T! y* R; f9 p/**************表达式计算器************/( t- H2 F2 G- d- ?; O0 W  S2 ?# }; G0 I+ u
#include <stdio.h>
& Z1 d2 @8 {# q8 e# g#include <stdlib.h>
9 m1 W2 k% I7 F& T- h3 F#include <string.h>
9 ^7 H) Q& h; `  g. y' E#include <conio.h>
; l$ q5 B  _  s8 q& \5 V  }. q( y#include <malloc.h>
; t5 X# K3 X; W7 F) R
* M7 W* f2 D" d#define STACK_SIZE 100- T$ E) n7 \' e, A4 C
#define APPEND_SIZE 10
( r) \! f# R0 f2 Z' G
  {: J. }) u5 pstruct SNode{
5 e3 N6 s0 z) p8 L    float data; /*存放操作数或者计算结果*/
' q8 j) ^# L3 Q) l2 `5 Y    char ch; /*存放运算符*/+ }- J9 c0 w7 G3 k
};
# j9 E( k/ y8 X: ]% P% J8 y2 C. J! C1 K
" `' |( I5 R5 e* G. k: Fstruct Stack{& U" x+ j3 `( q6 g) e2 A- K
    SNode *top;
& q# u6 e) q8 @9 f2 B4 v    SNode *base;8 ]; L/ B6 B  S0 b
    int size;
  {# d( ~* X" w8 t};% @: L2 W# @' u$ ]

9 f4 P6 i5 B0 I/ y" x) k$ N/*栈操作函数*/
# [$ D; v$ U4 k2 y  P( uint InitStack(Stack &S); /*创建栈*/3 u, ^1 s: Z# m& e; x
int DestroyStack(Stack &S); /*销毁栈*/
8 {% j* X& c$ ~int ClearStack(Stack &S); /*清空栈*/8 O6 K# Q; a5 o, m1 y2 l6 I
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/. U/ [1 S  q" H
int Push(Stack &S,SNode e); /*将结点e压入栈*// ~/ d+ i. I6 n* r6 i4 D" E
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
' }$ ~) r" S2 M0 [7 w" e1 |
* Q0 C3 V: g5 E) D! q( v, F0 T) k/*表达式计算器相关函数*/
. l" z7 g& \& R8 r" J: Xchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ N# q8 e: R; R( a: s$ Sint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*// X* f& J. e: ]! q. U( k! c/ I0 [# J: @
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/! ~; t/ j  F1 j  c' K
float compute(); /*表达式结算器主函数*/
& f, X2 \7 ^% X7 Zchar *killzero(float result); /*去掉结果后面的0*/ ; t+ V7 [+ p  p8 v- K/ {0 ~
3 t' v: W0 H& D( B. Z+ x7 D4 r
int InitStack(Stack &S)9 l) I7 I/ J. t3 B
{
5 X6 C) j% ]9 ^: I4 `    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));4 v' Q6 R2 w" y% I- m+ z
    if(S.base==NULL)
# h9 x# ]; `7 Q. H+ F    {* i/ D- }2 F( q8 s
        printf("动态分配内存失败!");+ N9 Q  r; s7 k0 x2 q! c
        return -1;' M4 q; V; J0 f0 t2 X3 o, B; e
    }
5 b. z* I# _" B5 U    S.top=S.base;
' C8 \. \2 w% p    S.size=STACK_SIZE;
  D! @6 i: u: h! z) |    return 0;
" E( `6 b# N! T! D7 x( s}
# a; Q4 X  y. Z7 v/ P. s
* q" h: C1 ?. Q- h" Xint DestroyStack(Stack &S)
% n% E& F+ z1 ~; z( i{  y& q2 p: j" X$ y5 B; e
    free(S.base);
) L$ ]7 y# @- C6 o% z! i    return 0;. h3 {6 s$ k% f5 Q$ _6 \
}1 k; L$ j  \* f+ y1 f: ^2 M7 F

) v' t- d* H' a/ E4 [int ClearStack(Stack &S)+ S0 {7 U8 ]1 X. `! L
{# J7 q7 n  K" G2 U
    S.top=S.base;/ e4 v) `! k* z% y9 F; N, H6 f
    return 0;6 O1 I4 Q" Q$ O( R& v. \
}
9 A* _( B; `+ X5 l. L
) ^! H# M. l- e1 y0 G/ ?int GetTop(Stack S,SNode &e)
4 U+ p% m5 b0 O: @, q{
& b" @" Q2 L% P4 F8 f  S    if(S.top==S.base)% ]5 C( ]( W% V! j
    {; D9 I$ E! k( I( N, |7 {
        printf("栈以为空!");
+ n$ k5 g* _6 W0 q  w        return -1;  e4 g+ A/ i6 X3 B( O
    }, S- z+ Q. {0 |# z8 C
    e=*(S.top-1);
- |2 L% }' o8 H0 s2 \) E: W! I    return 0;2 {$ ~8 N& t4 E. H
}
5 m; H* b& d! ?
' J$ [3 ?4 l; F6 xint Push(Stack &S,SNode e)! v+ [9 i3 s" R- f
{
; ^* F& r+ [8 q    if(S.top-S.base>=S.size)9 \2 D! r& Y6 ?& \$ j
    {- B5 Q6 |' F+ Y6 {8 X' i! [
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ O8 I4 {1 h5 o! c: h) D
        if(S.base==NULL)
! M% G' f$ D3 n% R2 j8 T+ Q+ B        {1 v; X* c  A+ X  H, @, h3 f
            printf("动态分配内存失败!");
3 y& y. v/ }; I4 a            return -1;% J0 |3 P, _7 f) b  U0 q! V- z
        }
$ R. W& n, Z% Q% z1 v' U        S.top=S.base+S.size;! L8 y# K" `% j* d5 p
        S.size+=APPEND_SIZE;; b  m' R6 m( X" b
    }9 s( Q8 Q: }& [% c4 }2 w
    *S.top=e;
8 M2 ^# R" ?* I    S.top++;, E5 O3 p, ]- v; w& Q. T
    return 0;
. C1 _# q. k/ a4 Y3 i; n}0 X. u* U7 W- K# i! V+ I9 l2 ]

& E, g5 g/ h  O% c4 k) Hint Pop(Stack &S,SNode &e)% q* f7 \% w6 _( [9 ]& ?
{4 \% b' m% n8 P2 q3 ?
    if(S.top==S.base)/ Z" ]0 z* A5 S5 J
    {
1 o8 Z$ T: h& W        printf("栈为空!");
- V0 W1 E: {- c+ y        return -1;. `* V% x8 `/ h. Q; H# Y  p1 B) [
    }+ y+ z6 m/ B* G5 p: x0 _* O
    e=*(S.top-1);, j7 }6 W2 B8 Z" c
    S.top--;
: M: S7 P3 Q: F! O8 \% v9 z    return 0;
. b' j  n, Y6 }5 S( F* }& T2 ]}
5 H: [) }* v% }: ~+ t# V& b. V
9 I) Q' y9 Z) f, Pchar get_precede(char s,char c)# i6 K- ?7 ^) [
{) m7 t( a+ u; R' @8 S; l
    switch(s)" O, Y6 O" L! a& p/ N; Y
    {
) Y% V: w/ h7 m0 \' K        case '+':                 
/ |+ }- g6 M1 U3 H  b+ Q" w        case '-':8 F5 M, H) {8 k3 V6 U6 P. R& |
             if(c=='+'||c=='-')
; R/ a7 i) M( R/ ?) x                 return '>';
( u/ Y0 S9 l: V  j9 X( Q% e             else if(c=='*'||c=='/'). W: y7 c2 G! Q0 v
                 return '<';! G3 U' Z2 h' s. k
             else if(c=='(')& h1 C2 m: v5 P: u" Q
                 return '<';' U; y' B$ Z* ^0 U7 ]7 o8 L
             else if(c==')')
. _, \$ ?" q& C/ O8 _                 return '>';
! ~( W. D# k7 K& o2 }0 s             else
; x, L! t. R; U9 g, v                 return '>';2 o5 ]* F5 ^9 D" k  U5 m* l4 }* Q- A' ]
        case '*':* y6 h- u* B' A3 j: [# I2 Y' _
        case '/':
" Z0 p7 j/ x6 h$ N$ a) p             if(c=='+'||c=='-')
- ~% [% h; V% H; N  t                 return '>';
% y8 p9 X7 M- ~/ J0 e6 M) d, z; }( S             else if(c=='*'||c=='/')3 f4 _, i+ L$ C& x
                 return '>';$ Y  Y/ ?% }& `$ R% n
             else if(c=='(')
( s$ U: H; D! Z% G/ ^6 B7 L                 return '<';0 V  ]% ]& n$ n! H3 a6 O
             else if(c==')')' g  F" o0 j, n! t  H, d( G5 f8 I
                 return '>';7 @8 D/ W) v# H' b
             else
, y" l9 x' V; m+ O& @8 n                 return '>';
, d7 c  E: Q4 g3 V! p        case '(':! h+ I$ G4 ~) G: }; ?
             if(c=='+'||c=='-')" t. g0 r9 Y! [6 L% P/ \' W
                 return '<';
( W5 ]5 |' A8 s- @* o4 H7 _             else if(c=='*'||c=='/')' G9 a. I. L) @
                 return '<';
0 Y1 }2 Z) X9 K+ @             else if(c=='(')  W8 b4 g) R7 M9 [
                 return '<';
- g4 ~+ i* }6 ~( ?( w5 L             else if(c==')')  z0 t5 a7 R) a( f
                 return '=';0 V+ W1 U, M4 J7 M# ^& I/ p
             else" H3 ^6 b; F0 E, Z
                 return 'E';) B% `/ W( Q, X
        case ')':: ^' s3 Z# x) A5 @# O% a
             if(c=='+'||c=='-')4 ]9 `2 e$ o, F* |' Z' ?8 N9 P& @
                 return '>';. Z2 u, Q# S3 o: M" Q1 E; p; q
             else if(c=='*'||c=='/')
  e. A6 x! {& M) E0 w2 k                 return '>';) r, W# A, O/ U; T1 _( [, T; K
             else if(c=='(')
+ v" _, ~/ M; ~& G                 return 'E';2 j; ]! U2 A& j3 @, G. c
             else if(c==')')
- |: j. s; A* l/ e                 return '>';: P$ Y! n3 Y3 ~9 J$ Q& H# C
             else
4 g6 @# R% t) V4 o                 return '>';* K# g# A; s. ]. v  {# ]) J* A4 ^* r
        case '#':' `7 x' L+ m# t% q+ x
             if(c=='+'||c=='-')
+ c0 m& H5 {$ U( i% H- T) E                 return '<';
' V% J, w; A% o% l) {% x; }( l" Q             else if(c=='*'||c=='/')
) d$ l  C# _' }/ Y* v! G' W. X                 return '<';
9 x" B( k$ _/ H6 H7 U             else if(c=='(')
- S/ |4 R# j+ W6 a0 y                 return '<';
$ @) ^/ w- E0 G  S! v7 W             else if(c==')')
' Z0 l6 l/ E+ D" P1 j                 return 'E';$ Z7 C& c6 d! r1 r! J
             else+ Z- a/ e! }# ]+ s
                 return '=';
; [. Y- l6 H) M2 `! p        default:  b* v6 q  u" A* F6 Z, J& C2 H) C- h
             break;+ D6 O( ?7 S8 `% ~7 Q+ Q! F
    }2 E9 g* z/ h/ M2 N9 A% j0 x
    return 0;    % W7 U: Q% s8 I5 A  C# ~/ \
}
. ?# X# W7 k$ a; C+ }7 U
+ Z# m" Z( F4 f& j9 O/ d+ d( Zint isOpr(char c)/ {5 _; b! Y& y7 d9 o, y
{
6 a( |: I$ {! [' L    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
9 n" ~+ s6 ~. J6 f        return 0;
: }: u8 V/ \1 ?    else ' }8 m4 F% v" ~
        return 1;4 G. D' {* [  m% P# y
}8 s# ~3 @( N) m5 c8 q' e5 w4 J

6 H2 U# k  r6 J2 Dfloat operate(float x, char opr, float y)
8 s. ]0 W, p3 f! `0 E{
; h; S9 A  C1 ?! r    float result;3 w! N# w( u6 Y$ F
    switch (opr)  ]' Y* i) e" K
    {
/ g/ a4 N. S9 ]7 B0 J8 K+ y- Q        case '+':
) J3 U* b9 H0 D& u( K8 B8 \- \             result = x + y;
+ |' o1 A2 F! p8 M* f             break;* j1 z8 S: N8 @! N/ s) G. M
        case '-': ) w0 }! p: c  `2 T# c* Q0 ?+ R9 _' [
             result = x - y;7 s9 Z. H9 Z8 {8 }  R3 y  `
             break;
7 F  R! q5 u" T: {' \( l        case '*': + K' y. Z6 ~3 p& r
             result = x * y;
3 ^7 \6 F: v# N4 |             break;: d0 y* T. Y  g1 L) F+ t" u. D& Q' m
        case '/': 0 Y' S+ N0 @) f/ `
             if (y == 0)
8 X- B0 b9 }' D# M6 }$ x% k& _             {
0 v+ c* Q( M1 E8 z; B                printf("Divided by zero!\n");
# o) u4 I& r- N/ s                return 0;
4 g' H. K. K) |& _1 |7 `* \! P1 P" V             }# @6 w/ o5 D% L2 R8 @" X
             else; N; g$ C* O/ W$ _
             {
1 N$ K) ]- |4 J, y5 Z# n: Y                 result = x / y;* N  ]" d, G, _, h& Z7 ?7 Q, \7 L: d
                 break;
: C! K7 U3 j# z9 @6 C% j             }
- E: C/ t& Q$ O/ H       default:
, f- E7 w5 @3 j& [, k0 ^0 Q. {             printf("Bad Input.\n");
8 u# N( i2 S$ w6 D# U' r             return 0;
- g# y: Y/ ~- m. H    }
, ^( Z% J+ H) m, d  T& ?5 {6 w    return result;3 v. ]* y% X+ @: ~( |# n
}   
" r3 ?6 A+ U, ]! K) E
5 W/ K/ [2 F  h2 O$ Afloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/& f% {7 e* r; x* s+ V; J
{' o8 C" l8 G1 ~# Y  p
    Stack optr,opnd;8 [4 w/ \/ x: v% F" e( K
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
  w2 X2 g, y6 s: _8 v# Q% d    char c;* s2 }! f9 o, h  J
    char buf[16];
- b4 S* U2 _" ], x: l( W    int i=0;
8 @" N0 M& m3 v    6 `; `; c, _- r9 p
    InitStack(optr); /*用于寄存运算符*/
+ s2 o$ y0 d6 t. X9 A; |7 F+ O$ ]# j7 H* X    InitStack(opnd); /*用于寄存操作数和计算结果*/! k# g* M" s8 d
    memset(buf,0,sizeof(buf));" k; A8 z- S# O) `4 F1 q- c- F
      Z) y/ N& N2 K5 k& S4 f4 U7 H
    printf("Enter your expression:");
0 g$ w7 p# u$ b' b1 ?) k        
1 M* f1 a3 \3 ~! C$ ~- Z    opr_in.ch='#';
/ s/ }$ u- u+ w! z- \' B    Push(optr,opr_in); /*'#'入栈*/
/ @0 P+ L' V4 h2 ~6 z/ ]) @    GetTop(optr,opr_top);+ a+ C3 E! t+ s/ M: G
    c=getchar();
+ U' k* h9 i) E% S, a# e2 o    while(c!='='||opr_top.ch!='#')0 @4 I* W4 e8 T
    {5 X$ `8 C! V8 u, B, N: V
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/7 y, Q# Z: s5 F( v6 J- P7 ?
        {* ]7 b. f& L6 f. E3 D6 j, g" j
            buf=c;$ \  y  j: x; t; M% X& w
            i++;
: g9 U7 N7 K1 @, E0 P            c=getchar();
/ d6 {& ^4 Y" ^% k" x! `        }( n+ r! }. w0 ~$ o/ w% A" A
        else /*是运算符*/& `* t6 q5 l- L1 B9 ~+ j
        {
: i% |2 f! ~' D2 D+ I( t            buf='\0';
* n+ [/ l! X* y" o            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
* P: i+ k# d( Z9 A/ o% m6 c$ N7 A& Q- d            {' |  y1 }" U5 V5 ], b% ]
                 opn_in.data=(float)atof(buf);
; u7 B9 o) N  @                 Push(opnd,opn_in);
% s: }( d& _0 R                 printf("opnd入栈:[%f]\n",opn_in.data);
, t* a) @7 w: [7 G" |4 p5 o                 i=0;% `9 V2 ?5 F' I( ~/ d
                 memset(buf,0,sizeof(buf));* {! W' Y6 K; ]4 k5 @0 T) I* D
            }! g% s# u3 k6 v) `4 ?: k4 @5 ~5 w
            opr_in.ch=c;
1 D+ I- [. Q% {" ^/ Y            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*// W. T" n1 M0 _2 _
            {( w' I, ^4 s0 e' s
                case '<': /*优先级小于栈顶结点,则运算符入栈*/; H& c$ [9 t+ D5 j7 F' z
                     Push(optr,opr_in);
- N% b; X: A. X! u8 X# k* R                     printf("optr入栈:[%c]\n",opr_in.ch);$ L/ o/ e/ [' f0 r5 n5 A9 D
                     c=getchar();( N& A/ b2 I* a5 q) x
                     break;
/ h& ~4 [" k0 p' \                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
. v0 E1 I; X2 k, S  T7 E+ P                     Pop(optr,e);+ r' j+ s0 i9 ?$ h2 d
                     printf("optr出栈:去掉括号\n");
4 M' s+ V' n5 f# q$ {8 E) s                     c=getchar();
: F/ n5 v4 A$ O                     break;2 _0 ~( L- C2 j1 ~  r# R$ }5 r) i
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
  q2 Y2 f, W7 C% L$ ?' s+ G                     Pop(optr,opr_t);
; [$ k' F2 x1 o                     printf("optr出栈:[%c]\n",opr_t.ch);
* V; z& d" m+ f8 J                     if(Pop(opnd,b)<0)" x" ^  X) l" ?7 t
                     {
5 @6 D1 p7 r5 V  I) F1 r                         printf("Bad Input!\n");* p) Z$ P3 A1 W9 P; C
                         fflush(stdin);
: A* z+ N% c* F0 C# `                         return -1;6 u' w; I) q- x1 D% I, [+ L
                     }$ {6 J7 E- |# D1 @, ~) B
                     printf("opnd出栈:[%f]\n",b.data);
; @4 r) P& d( V4 N8 r                     if(Pop(opnd,a)<0)
/ m& f. G  U& V                     {& \$ C) ?) v5 R9 D& k9 q) j
                         printf("Bad Input!\n");; r; G% {9 \0 n4 F9 ?1 U4 w
                         fflush(stdin);
7 t5 J, h, }4 D2 U                         return -1;2 i' r" O2 Z9 U4 P! a  d
                     }
. d' g8 S9 l! z                     printf("opnd出栈:[%f]\n",a.data);
+ z; B9 O5 r2 b/ C* l, v, k- z                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/( K* M; d+ K& c/ i
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6 M6 ]% J- t7 ~
                     printf("结果入栈:[%f]\n",opn_tmp.data);
  d" v4 ~. K# V                     break;' J+ u5 j4 E; O) ~) H# W* V
            }
7 X* m. m5 o+ c1 H' [  U7 o        }
2 _5 m" n, K5 I9 e7 |        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
4 v+ H) }; E; Q' _! Y4 l    }5 t! ^5 a7 v* n+ b7 F1 ^6 \
    GetTop(opnd,opn_tmp);0 T: R0 l4 z3 l9 W8 V
    DestroyStack(optr);& z1 R- Y3 D# }6 H+ k
    DestroyStack(opnd);) n5 C1 ^5 @7 R1 m2 y
    return opn_tmp.data;5 c0 r& t; q7 g$ e
}
9 Z! W3 L6 ?; m/ C2 r, D' f* }
  l; m: D2 W( a8 D1 Pchar *killzero(char *res,float result)+ A% s+ ~: a* m  y  a8 U0 E/ Q
{/ {: B7 R$ O& u: Z+ n$ \/ r
    int i;& v9 N* v! A: w$ e

$ C( M. D5 h' R( A; e: n! W    sprintf(res,"%f",result);& b! b) R. y1 Y
    i=(int)strlen(res)-1;) m) h0 b' A* J2 p
    while(i&&res=='0')
- e6 S4 s, i: M* _- A$ C  ^    {
  {6 B2 y% I4 s        res='\0';* Q: ]1 @" F7 x/ Q( m$ z* H! u
        i--;( T6 G2 M' j, K0 S/ Z
    }
$ j& W5 b) c3 O& {% f+ C8 X    if(res=='.')
/ e2 g+ ]* }  {1 g$ [' J        res='\0';& H, k1 }% D  n+ T+ t% X7 t/ q
    return res;$ C$ i! v- b( k0 e4 }* n
}
$ }+ k0 B9 F3 e. P# J. a+ `- ~* k, e, Y- e; }9 j
int main()
( c* E: _) R- f7 j1 ^$ g{
. i; D$ @$ ~  i" p4 H1 p1 W1 j    char ch;$ L, B; ~) j+ g! a
    char res[64];
* y! P" m3 i. \2 u3 F    float result;
, Q8 p# s, Q$ w, u    while(1)
7 d7 t( p; U/ H$ ]    {
  r' f/ {9 r. M2 i: u7 }, E9 h        result=compute();2 q1 Q( D/ j9 H' S0 a6 ~
        printf("\nThe result is:%s\n",killzero(res,result));& ~$ J% B8 W4 s4 J6 L" Q) z
        printf("Do you want to continue(y/n)?:") ;
, y- V2 n7 v' l        ch=getch();7 ~7 F: R& j& U
        putchar(ch);
3 r. n8 R3 {# V: ~2 W, }& `' e        if(ch=='n'||ch=='N')
  z8 ?9 B7 ~% x1 ]% q  t7 F" g            break;
3 R" r. V1 d4 H8 o0 M7 g        else
" K; Z" K4 ~3 P5 n            system("cls");; A3 E; T0 n! T; X6 \: |+ _
    }
9 Q- @3 R0 T) i8 f' i0 q! J& ?    return 0;
9 A& A5 e/ _4 s4 A- O+ m: ~}
# m; O# k% a$ E' {

7 C. }' |% W9 j[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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