获得本站免费赞助空间请点这里
返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的., P/ \5 O4 O2 t5 ]( z
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=8 X5 e! ?8 E: r
/**************表达式计算器************/; \2 |  U6 U! {: u$ g$ _- Q
#include <stdio.h>
' |4 K# @7 R8 B#include <stdlib.h>. Z3 p  \( T) o- i& ^, f  D
#include <string.h>2 U; y6 p4 U/ o7 x4 k
#include <conio.h>) t* F5 ^) o: S; t
#include <malloc.h>2 i" J+ k' m+ j+ c  G* F3 D

8 Z9 N1 a  \0 q  d$ f5 }" f& A) }1 F* L#define STACK_SIZE 100$ j( ^6 ~0 ?' K" L, L4 \! L# J
#define APPEND_SIZE 10
9 {/ e2 G0 _+ ?: X- G; s, ?/ G4 O- l/ H/ Y+ y
struct SNode{2 ]5 J! v( I, r, M2 Y$ H
    float data; /*存放操作数或者计算结果*/
4 t' D: X  z: |8 g+ `    char ch; /*存放运算符*// N7 q  a+ ?2 d
};% Z/ i; ^. G3 G5 k0 q) ~9 k  p! t
( P- {2 s* u/ K1 u
struct Stack{
' r* d0 f/ ~  `6 ~" r, s& c( L* S    SNode *top;) ]1 u8 g) \: Z  Y% O  f9 i
    SNode *base;9 q: `  p! n* C" E
    int size;, U# l: h! h' g6 h6 V" a; Q. C
};/ m: g  z  i$ E+ U
1 N- d/ |# _: q/ G8 q3 B
/*栈操作函数*/# M, a/ F, J. K8 W6 ~
int InitStack(Stack &S); /*创建栈*/7 ?" c8 h% Q. M
int DestroyStack(Stack &S); /*销毁栈*/
! i" W. I' H2 ^9 Z* D$ nint ClearStack(Stack &S); /*清空栈*/5 f/ S& y5 }3 _  H! k7 J* u7 c
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/! n4 Z% K" S2 n- T1 a/ T# A5 E# h0 D
int Push(Stack &S,SNode e); /*将结点e压入栈*/
& S$ d) F/ i8 y2 H- Q6 mint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6 J) h4 r3 f( [. B- N
% J6 D! u0 B1 i1 {: x7 g/*表达式计算器相关函数*/
$ n7 N# N+ K/ q0 n' D0 A. J, }char get_precede(char s,char c); /*判断运算符s和c的优先级*/
( E5 k& Z# t# N1 V- K2 qint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) W7 n% p; s9 d6 ^
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/: N0 j% K# c& Y( o5 v' V2 @
float compute(); /*表达式结算器主函数*/0 f$ L2 m8 I( L1 }3 o/ U9 d. I% Y
char *killzero(float result); /*去掉结果后面的0*/ ( u& m/ }) p$ \6 `; f* P. e+ v
: p! q% E- p  s
int InitStack(Stack &S)8 {/ X( A- y9 |# Y8 N, z
{
; s: n# n( Q8 N8 B7 f    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
3 X' ~6 U# i* \8 ]% C* I    if(S.base==NULL)
3 x) ]' P: E/ W6 W( D    {
- r& t; W: Q! @3 C        printf("动态分配内存失败!");# O' D. T+ N  v+ y
        return -1;, d" @/ H; t- h
    }
7 Z% S5 F8 H4 c    S.top=S.base;
/ R5 g1 q; y+ m' e    S.size=STACK_SIZE;
/ n; h/ \& r6 ]; A9 g    return 0;
- s& u/ H' k0 G3 a6 z9 D}+ G1 |! b+ P% D0 K% Y9 a5 w

  `5 d, p0 D6 _, @5 r; E* Aint DestroyStack(Stack &S)* z7 a3 r% r3 H) {; K9 ]* Y# X
{) V- w+ t# z0 K; T, P" ~( h
    free(S.base);6 T9 L: R' ?- G0 U$ s
    return 0;
2 I+ T& L2 h+ F}
8 Q0 l! b( {1 B9 `4 h
7 r8 q* j0 [6 F8 u$ ?int ClearStack(Stack &S)
5 u: d( k' D/ b. x{
. r/ }7 c' b8 C/ R: D; v    S.top=S.base;
6 k! |0 V+ L2 e5 |6 k9 j7 V8 m; D+ F    return 0;8 o, I9 h# g0 `8 w
}
7 A% F( n  P$ {2 f' @
0 }4 h% y- F8 n* c2 I6 Gint GetTop(Stack S,SNode &e)
, V1 E  }! V0 T: M1 G/ C{
( s2 _, ~  |. }    if(S.top==S.base)5 v( V! f1 Y, x
    {# K6 C$ j* r) I  L( t2 v
        printf("栈以为空!");
4 R. A% U, m+ l3 c) X        return -1;
6 \) p* r# g" q9 H+ i0 o5 \    }
8 g  z7 B/ [  H. L  z    e=*(S.top-1);: |. z4 S3 K  I5 G
    return 0;, Z2 Q, J8 Q; y# i4 f) d  D
}
2 D, I& D7 ~7 l2 l$ u, E5 m1 u, Q6 ~- U9 a$ l' ~( A: o( m+ f& Q
int Push(Stack &S,SNode e)
# t0 x. A: H" l{
0 B) M1 C' D8 w2 u8 V; }# r    if(S.top-S.base>=S.size)) `0 W3 a$ R# S& W; Y4 f
    {
  c) Y4 S/ l- ?  i0 _' W        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));: n& m- s1 K: H0 P
        if(S.base==NULL)
! ^' Y/ ?$ }% E2 G! X        {5 ^$ f( @$ }) {
            printf("动态分配内存失败!");% `! m6 e* k, b. {
            return -1;; z0 I5 W9 h9 q# G
        }' a/ p& V0 u8 O- K
        S.top=S.base+S.size;1 E8 D0 A8 X5 |( M" G
        S.size+=APPEND_SIZE;' C& ^! x6 a- |$ i  v2 T
    }
: ^: u) T8 d+ d    *S.top=e;3 B" R( F0 Q, J$ I' o5 M
    S.top++;; r' ^% C6 e" J- t! n/ h
    return 0;' v2 P! P2 H, B6 k$ E7 ^
}* o! O7 c# h- f6 s& }
$ z7 h" }( h! R: r
int Pop(Stack &S,SNode &e)
+ }% H5 D7 L- _8 A& ^& d{
7 E# S+ _/ q- J- u; j4 P    if(S.top==S.base)
) k; _2 C+ ~1 m! z7 y" T+ j8 D    {
! G# y  e6 K3 M5 C/ ^6 T        printf("栈为空!");
% ], c% R4 H8 o& C3 M        return -1;& O- t* X4 D! \2 e, e( I3 @
    }
2 D1 _; g9 x/ g& T: u/ p    e=*(S.top-1);
: d. _5 k& b/ m$ p' j  d    S.top--;( I! d5 p6 K5 H2 {" z/ ?4 ^
    return 0;
( ]" @1 L3 u" X9 L$ T" Q; a1 h+ E}
/ \8 I. e$ i: |* @0 }- a$ l4 Z
( Y- w" K& F$ q  Y  a* Pchar get_precede(char s,char c): A4 {8 p' Z% M; n
{
+ N+ |. |* |. ~7 B; F+ z    switch(s): K/ c: w( e( N3 J7 `
    {: Q' d! M8 T5 a+ P! L* h
        case '+':                 
* c* P' o& {7 t4 @$ c        case '-':
  H! m+ s8 V6 y% h4 u) y             if(c=='+'||c=='-')
7 M+ r$ ?: @/ L8 ?                 return '>';
) H" g+ \2 M  |! ~             else if(c=='*'||c=='/')! Z4 d, X# N! P9 G# `' m) r
                 return '<';
1 E6 B" [* P1 u4 `3 P/ l             else if(c=='(')+ }; v* w  Q4 B* l# ?8 [& E! H2 S
                 return '<';5 P: h3 X1 R5 k
             else if(c==')')' _2 r0 U; j  b$ o# v- C8 k' W
                 return '>';7 }" S2 {! N! t2 b) [
             else * O/ g& s" ]# r8 T3 T+ C7 O
                 return '>';$ E2 }) {0 i' n) y
        case '*':
* X- u! h  b7 [; B, w2 S1 j, E        case '/':$ S  N+ M5 e) c! y) Z  w, R
             if(c=='+'||c=='-')
/ U9 n0 `% F9 a. l' h                 return '>';+ L. G" t7 A! n4 a) E) i3 a
             else if(c=='*'||c=='/')
6 C7 h- _; ^; |6 z9 Y/ x7 [8 Q                 return '>';
" N$ V5 ~/ S8 A/ M7 q4 p  ^2 Q1 z/ _             else if(c=='(')
6 A1 X5 a& v4 D4 L" F! s                 return '<';
, t* q, p6 P5 ~  }" @- E             else if(c==')')3 w5 R3 d' e) m& f  n, J% ^
                 return '>';
0 y6 ^! \/ ?" g$ h# W* D+ o             else7 a4 b1 T+ N+ C
                 return '>';5 R+ ^# Q; F$ [, |: z% n4 H2 `3 G, j
        case '(':
* k, w# v) Y4 W0 S" x0 W- h             if(c=='+'||c=='-')
( F5 w7 E4 o+ G" @                 return '<';
6 l+ E8 z$ {9 F8 g7 M             else if(c=='*'||c=='/')
% u% w! V/ i: e                 return '<';
, o+ N' h/ W4 G& x! d1 _" E             else if(c=='(')! g! Q1 B& p- i- T5 Q2 R4 A1 w
                 return '<';; {: w9 g  K# P0 b
             else if(c==')')% k' ^! u& V$ V+ _! [& l4 ~
                 return '=';5 ~3 g. O" F( M1 p' O$ q
             else
1 g3 f. ^* W7 ~- s8 ?1 ]; r2 Y6 M                 return 'E';
+ T( g% o" T6 l! s. T/ u        case ')':
- N* a  |( E+ W0 E, E9 F$ e/ A             if(c=='+'||c=='-')* |$ X" f: c6 N2 A! X9 i* M
                 return '>';
, O# y: L) A- J$ h: G3 [             else if(c=='*'||c=='/')! E6 g5 k1 k% {' J1 b2 {
                 return '>';0 I. ^! P0 C# I4 J
             else if(c=='(')
+ Q! i4 t$ j! l8 d                 return 'E';! o9 e% \' A( S2 n& ^" T$ N5 n
             else if(c==')')' e& r% ]" V' e* R% [
                 return '>';( M# ]* f* x; r: s: k5 G
             else
; Y5 b: H/ V$ L  a2 F                 return '>';
, l& G4 u9 S5 d  d5 e8 D4 k        case '#':
. n# `, i* {+ L' {# _$ ~             if(c=='+'||c=='-'): Q1 v3 R) K* c- z: Y
                 return '<';+ j! a. S5 L/ o; v4 c: r3 S# ~% w
             else if(c=='*'||c=='/')
; L( G( a' x6 Q1 O# A                 return '<';
0 k! Z3 Q: _/ r. G) r& e             else if(c=='(')
, }6 @/ J- X( u! i- B$ K8 E                 return '<';; H4 h4 h0 Y! F5 K
             else if(c==')')
7 n! X, r. T6 ^' d  b                 return 'E';' S+ R; z, C/ h: \) p4 F+ F
             else
3 E- G( F: L8 F& T                 return '=';
- H$ R3 L9 r5 r  K3 ?        default:0 W2 g* ]* X' b; |& h
             break;+ O0 q  W/ ?. L8 P* b3 Z  k* r3 f
    }
! j% v- D; o# u6 Z0 M    return 0;    8 c# z6 u# D0 K8 o
}4 Z; y' f' y0 n  o, w% l

0 Y: X5 G. A$ g9 }2 y9 }$ Uint isOpr(char c)
, S5 e6 t; G! V; v{1 Y3 f0 ]* v: h1 m/ Y% T5 X
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')+ y, Y* G8 X; Q. X: [2 N
        return 0;
% l: c  A$ H! E/ B) p1 K    else " b6 D, Y2 z' r. K2 G6 ^
        return 1;# f( z3 x& {6 z" M5 ^3 }: c( G! H
}6 c7 A4 m" m2 E3 Y# C
  _% y2 D% u, {+ }
float operate(float x, char opr, float y)- T/ C& @0 b/ @+ }! b  t
{3 @! E, A8 z4 Q. w2 G; A
    float result;
: m8 b/ L' r9 G8 W0 g7 f1 F! Q    switch (opr)
$ Y- J6 U8 e" S' C! U' x- E2 o    {3 \/ K, ^  U" d1 N
        case '+':
9 G  B4 v( j! S- _0 H             result = x + y;6 g* ~% K( l" r: m
             break;9 l: C: ~) D1 u2 e. i/ j  p: P
        case '-':
% q/ d$ L' m$ R, X: o             result = x - y;+ W" U  E' V6 l5 J' [
             break;4 u! O8 @/ L0 F- [1 {/ B
        case '*':
1 r: Q$ z; Q. k, w+ U2 O             result = x * y;
/ Q" s# [6 [- @1 _5 q0 q: C1 E             break;( i. x  ~0 p+ F# @
        case '/':
4 y' M5 `% ]1 Z. x5 g' ~1 Q: P             if (y == 0)+ x6 u+ X  R5 f0 Y+ X% ?
             {
/ `. s# A6 d& w                printf("Divided by zero!\n");
0 B# \+ r3 E; Y' ~! |# [$ u, [/ W2 I                return 0;
8 k* N7 S: V$ f             }
; Q/ p& X/ S& Z! W1 ~- R             else
2 B( S; U0 w  h( l3 d1 q* O             {/ N2 s+ ]- W' Q) f
                 result = x / y;
+ Z9 |- w. ?; v. p5 P4 [# C- b1 H                 break;
6 k8 k3 S8 M; u# _2 m" Z             }2 V; L$ s  A% h
       default: * e; q6 m) ]/ z7 J2 {% j8 ~) [8 m0 C2 _
             printf("Bad Input.\n"); ( e& B% g1 e- q
             return 0;+ I2 u+ G& _, K( d
    }2 T4 L4 x: ]# s
    return result;  r- I. W+ L8 s9 ^1 d' M
}   
6 q+ `# Z' w5 E. H5 Y4 o; L, I! a/ @/ G- ]0 D
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8 o7 L  h- l3 Y  U7 i* D2 b7 z0 |{6 U# c4 N' {  _1 M# y( Q
    Stack optr,opnd;
' Q5 X7 M5 L- Y    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;" m5 z3 w0 B% S1 S7 b
    char c;4 W- M/ B" T1 N9 U' g( B
    char buf[16];( O, u5 `4 o1 T5 t! {5 o
    int i=0;4 r. U3 _; q2 N9 a
    7 H5 L9 ?# l, b" W1 q2 c. {! K- e
    InitStack(optr); /*用于寄存运算符*/
& h3 ]- p1 j8 V8 N2 I7 `    InitStack(opnd); /*用于寄存操作数和计算结果*/+ v; X- G' K0 `% o" n
    memset(buf,0,sizeof(buf));
& r' i5 v$ D8 L1 }0 R, J    0 X# X* j2 f& S  {, k/ K. ]
    printf("Enter your expression:");
9 ~6 A; p4 K( n$ p; u        , P* `" I. ^7 B$ r, A
    opr_in.ch='#';
1 R4 k& S% ]: p    Push(optr,opr_in); /*'#'入栈*/- }) A0 n) }# |+ k
    GetTop(optr,opr_top);" N3 N* @4 v0 [* r6 n
    c=getchar();' K/ w4 U  ~1 L1 q7 F' r
    while(c!='='||opr_top.ch!='#')
" g' h3 j8 I. C; f/ P* P/ _    {
1 |$ D! `7 P* ~% q        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/: [; r$ B0 `5 B2 P
        {
& [% U' }: |. p            buf=c;
5 G- A$ O  m: ?; ]) I            i++;3 h& @  p0 t2 I/ ?* K
            c=getchar();+ H4 [) ]+ \1 v$ d9 }2 k* a
        }
1 R( {+ d4 ^3 @, F5 y        else /*是运算符*/
/ a0 G( P6 [+ ?8 y' F: P        {4 O/ }7 h6 d- [; B8 Z, q" |
            buf='\0';  ~. {! V* X9 j) @/ L
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/* X6 u: u) a( x9 Y6 t/ c/ x5 q
            {, M- d- T4 Z$ ~( [
                 opn_in.data=(float)atof(buf);# n/ L+ I& {4 F! n6 [7 o
                 Push(opnd,opn_in);
* u* M* v+ }4 i& z: R. `! G                 printf("opnd入栈:[%f]\n",opn_in.data);
4 ?( V% _- J0 H$ T8 v) L0 [1 x                 i=0;
: K9 z- |  w; p- S" x" m                 memset(buf,0,sizeof(buf));3 t% {7 Y6 l, }! M8 ~
            }
. L) E- Z1 g$ k- r6 O+ v            opr_in.ch=c;
. z8 h5 J. n. x4 A0 l            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
3 B1 L8 q) S- S0 ?( }$ o3 ^7 ^            {% e, ?0 Q/ R; @# y
                case '<': /*优先级小于栈顶结点,则运算符入栈*/: ~7 V7 Y$ T/ \' B% k6 Z. s
                     Push(optr,opr_in);/ p# `* F- P  S
                     printf("optr入栈:[%c]\n",opr_in.ch);
, h7 ]7 r( t- S3 p. U                     c=getchar();
: q/ t5 l6 ^5 h% I                     break;
5 Q0 R4 u' t3 D0 S) l                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/6 b# P6 L, r4 X; z, ]8 L
                     Pop(optr,e);
/ Z& Z9 v1 N, L4 R                     printf("optr出栈:去掉括号\n");
6 a5 u: F4 @3 z) N- w                     c=getchar();
! ]# }4 d/ P( g7 C" k                     break;0 ^5 C, U5 Z6 r3 r. h
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6 U) G0 r' a% c7 K                     Pop(optr,opr_t);
' y& B1 K. [- U4 h. ^0 j                     printf("optr出栈:[%c]\n",opr_t.ch);
) c1 t& f, a2 `% h5 t% |2 q                     if(Pop(opnd,b)<0)  L5 s8 x# s* h% g2 C
                     {
7 ]" g5 u2 U0 A% j5 }& s                         printf("Bad Input!\n");
. g6 a8 v' _! E( i+ q                         fflush(stdin);, \$ W' F/ ?+ M1 l3 {
                         return -1;
/ D/ I3 `0 s# M                     }9 {7 Q+ H; b0 p4 A
                     printf("opnd出栈:[%f]\n",b.data);9 w: }# F2 U; j6 g" S! @8 I) `
                     if(Pop(opnd,a)<0)/ m2 j0 x2 K( P! z  Q
                     {
4 o! o3 F2 O& i" D# c* K3 D2 Q9 q* c                         printf("Bad Input!\n");
. D% Y) N" F( W" z                         fflush(stdin);
4 A# x" D' o" ]                         return -1;. e  m& X$ _) i0 \
                     }8 A+ u; D. d0 ^0 j4 k
                     printf("opnd出栈:[%f]\n",a.data);
  z, }$ C9 H, _0 ^" Y                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
8 C1 a  z2 L# P* M, T1 n                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/) p6 D% t+ q. C! R
                     printf("结果入栈:[%f]\n",opn_tmp.data);" K0 F6 O; J8 P" K) A  f9 v
                     break;- m) I: U; C) `
            }
/ V0 `% U6 L( g& \. U  W6 L: D        }: ~6 d1 q$ i& N8 x' j5 O
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
* w' O, ?0 P" b8 S8 T    }
4 C4 B" C. q5 Z+ h: {9 [    GetTop(opnd,opn_tmp);; z( ?- N7 _5 D/ Q* h& u
    DestroyStack(optr);* A+ J8 x( B1 E$ A
    DestroyStack(opnd);
, a) v4 `: r3 r) h1 l    return opn_tmp.data;5 a3 F: P' c4 F' ?- ]. [1 h
}5 J6 I8 S: n, U. Y2 |

8 B% v/ ?' A/ ~/ zchar *killzero(char *res,float result)
; R9 @6 s( a9 J. q0 x{
- b  v) Q& Y. S. h+ s5 W- M    int i;3 e8 P: e% F  I% _' q' t1 c$ ^

/ s  S6 g& b; m) b  _& s& V    sprintf(res,"%f",result);  |# ]. r* Q- S  y* k8 P) Q
    i=(int)strlen(res)-1;# k" N* G/ [4 {$ h
    while(i&&res=='0')
, w  w& Z& V" {% U- I9 o4 J! E    {
1 {4 u- S- k/ L        res='\0';
& ^' }2 }& ]2 H, w9 A$ z# X& Q        i--;
1 U# `" [. P% F* h; t! D0 M. u    }
1 ~& K( s8 p$ x( \( P: \    if(res=='.')
. j4 Q3 r% U. ?9 P4 t8 s        res='\0';
+ m- Q& [' Y. E, W) D0 A    return res;
/ p1 o9 m1 g1 n  _  t}
' P: M2 }" U4 N: ?/ L: e' Y
" H5 F4 F, O5 D  c8 qint main()( V# k2 a" x1 d, @+ \
{# {) _* I1 Z% g4 l7 i" v0 k
    char ch;
3 @2 s3 p- G  o3 u    char res[64];$ w; `, k4 B  E9 {6 x8 o
    float result;
% i; h# ?1 R- O. m' k: j    while(1)0 w! _7 r2 K) i9 Z4 K  L
    {
4 T+ U6 |9 p1 G1 p        result=compute();
  i# ~+ G+ |: D. h6 f; I3 Q        printf("\nThe result is:%s\n",killzero(res,result));  y# ~2 Y0 q% b
        printf("Do you want to continue(y/n)?:") ;% R+ p2 U, u/ s- R$ \9 A
        ch=getch();
8 ?* e6 ~" y0 f+ r. w& i1 w0 ?        putchar(ch);
6 z% j. t# q9 n1 a& w% U& B        if(ch=='n'||ch=='N')
* K5 }$ F: q$ |            break;  f0 {6 Y9 R, f0 f3 i/ Y& ~
        else6 U3 v0 `" E% [5 V. Z5 N4 i* d
            system("cls");8 B! x7 z0 w/ B, J( }
    }
' R) L; @/ x5 G! B' P, ]    return 0;
, J) X" P1 o7 U}

4 J5 W8 w/ x4 `# s% X5 d
1 l6 N7 E8 H( `4 n/ D: G[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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