返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5 o8 I) [8 `. j  w程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=3 @+ {9 f9 Q5 V6 P! y, c3 h
/**************表达式计算器************/
7 t- E! m) k% Z$ m( F; o9 B#include <stdio.h>
  m1 d8 _" J; J# f3 f, L* X! h#include <stdlib.h>, D6 _: P5 i4 y( w; k6 {& d: N" ^' x
#include <string.h>  x6 N9 |! T( a& h
#include <conio.h>$ f: h, w2 A0 f1 Y
#include <malloc.h>- F/ \, t$ x+ \7 g; b3 k. n

  A! m% X- l$ W7 u! ?& t# w* n4 k#define STACK_SIZE 100! J0 I' i& [0 _- x) \+ G* k
#define APPEND_SIZE 10
- O* W! e6 Y, }/ ~3 b% `# `
+ {8 e# |1 p# l7 Zstruct SNode{8 a5 w; k8 Z7 [7 y6 C
    float data; /*存放操作数或者计算结果*/3 }. O) B$ i5 f8 V3 e. z
    char ch; /*存放运算符*/! `, E7 R: X) [; u+ ~. I* N5 c6 m
};7 t$ }. z  I/ ]# R1 b5 n. I
, l& P4 N* N8 w; I
struct Stack{
( \$ e- L6 A8 v/ K$ f+ \, o" I    SNode *top;0 A$ e6 ^  `  w8 @; P( s; v
    SNode *base;
9 f6 q5 J" a" b7 n    int size;
& e) Y9 D7 b" t. Y};5 t% O8 L) n' Y
0 V! A) o8 l0 p+ U9 W" x" @4 k# A
/*栈操作函数*/- f# k' A# h3 ], [$ W! S# N3 e1 B2 V, j
int InitStack(Stack &S); /*创建栈*/' I9 u( r8 @( L2 l' T3 k
int DestroyStack(Stack &S); /*销毁栈*/
1 \3 B- c6 N$ v& s6 g$ Hint ClearStack(Stack &S); /*清空栈*/5 D, V  z  `) ?% E# V2 k$ D1 f" W
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/" M3 j1 G5 f/ s1 t+ {
int Push(Stack &S,SNode e); /*将结点e压入栈*/
8 p9 V% ]: u" f7 ?int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
! u) m0 {  m; U: I
9 o4 U$ [, e& V, P/*表达式计算器相关函数*/0 F0 L2 q* O0 S8 h5 ^
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
9 M3 W- K! o" ?- Y! Z* `# Yint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
8 o& ?: e9 d0 Efloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 o) k& y' w: E3 g% J0 b! M( k  m+ h4 efloat compute(); /*表达式结算器主函数*/
; O% _  }! W) _/ D$ O1 U3 o6 Jchar *killzero(float result); /*去掉结果后面的0*/ 2 O/ ]8 Q" ^) L( S3 e
( J+ b' \% \4 n' \; \8 O0 [
int InitStack(Stack &S)
  |5 A( U* `& U7 w6 _: s( V{: K( v2 f0 |- m; ^
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+ o- D+ b2 R/ O: M6 e
    if(S.base==NULL)- w: S% O% b) |2 `, J% u4 ~1 O
    {; P4 ~' G4 ?! {7 A. v/ _
        printf("动态分配内存失败!");  W& E9 l; R4 Z9 y; H9 H7 c9 f
        return -1;
& @5 j' I7 M( }" D8 x9 W    }
6 |% Y, Y4 w' v  I    S.top=S.base;
0 a6 @2 m4 b7 o8 `6 \# e5 F: M. \    S.size=STACK_SIZE;
4 j' A4 Y# |$ m    return 0;& @$ S: b- R5 ^  {& _
}
0 s3 l0 p! V. R; G5 t$ A5 _
0 K" y5 N- Y3 x4 P7 C7 kint DestroyStack(Stack &S)/ s, R$ H5 I* T1 c( \2 Z
{1 ?& a6 `9 A: `/ a. D& R
    free(S.base);
+ U1 i- I3 Z0 T3 R, e7 D- y3 d    return 0;
  b* ]7 W: H/ M8 x- N, N0 S" r7 Q}8 ]0 Z. q) n% b. b2 I

) o) `8 [& d5 p0 Q( r2 h8 T* U7 jint ClearStack(Stack &S)  w5 j, A$ Z% ~' T. l* F
{
/ |# D' T$ e$ F    S.top=S.base;
/ C9 ]% m$ `! g& j    return 0;
2 [: q6 C" ]5 Q2 b* O}
4 w' l' v3 q8 R3 z) S: B7 J+ y" Q5 x' W+ Y: `% S4 m
int GetTop(Stack S,SNode &e)
$ h& U+ L! g! a! `* `9 l6 L{
  f6 n" N0 o. M7 W) p    if(S.top==S.base)
. g, R% C$ }! C/ X$ U    {
; r8 H2 d! O0 x        printf("栈以为空!");
* ~! r& O0 K. r; P! t& m        return -1;
8 _# f+ Q* B1 [! A# H! I4 ~% u6 t) k- n    }
( D+ g" T% ?3 A+ Z    e=*(S.top-1);& u% Q! ^$ ]& z; T$ j! `
    return 0;
# \8 B" h% I" A$ |* _( |% m9 F}9 z, |9 \1 O9 c: O7 k
6 `% T3 v% t; F' q, o& U& `0 G: J
int Push(Stack &S,SNode e)
# [! O8 M. R9 z' T' ^5 C6 L: k{
- d+ d+ h3 S4 [! \( w- S( w    if(S.top-S.base>=S.size)
* A* z8 J% o/ v7 w# l( |# r' @/ v! C    {5 V# C5 y0 P/ X7 c, b
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) ~) H# R# Q6 Z6 U- h        if(S.base==NULL): Y, F3 y4 S; q0 |% [6 k/ y  m3 u
        {
  c( v5 C1 N1 o7 m# t* X, B- s; r            printf("动态分配内存失败!");( D/ I9 m# k3 t* A
            return -1;+ @2 _  f2 D' [
        }
/ L7 f2 K8 X7 H2 [, w; {        S.top=S.base+S.size;0 ?' K2 z- q* R( l; s$ d
        S.size+=APPEND_SIZE;
) E. v+ Z) v) }/ X    }. p) R, {% H% _7 T
    *S.top=e;
4 n* Y' L8 t) O, V1 A  O! @" p    S.top++;0 r% V! t% C, r# H
    return 0;6 @$ e8 `" T- Z! H6 T# ^/ J: q
}
& W; Y- [% |5 Y' u$ l$ O
" U+ Y8 A1 H9 E- @int Pop(Stack &S,SNode &e)% c- f+ B% M, t
{' \8 B3 E. S: p+ y7 v
    if(S.top==S.base)! ^4 R, e: T0 G2 ~
    {
# T' H: j. @3 T9 c1 y* Q7 O. j        printf("栈为空!");
" A# @/ V' m( o  _7 c, ~' X. ]        return -1;
0 |0 p& T8 ?: D" n: N7 S$ _0 B( [0 p3 r    }3 F0 r% N. W/ K8 u3 X+ k- g4 R
    e=*(S.top-1);
- G( F2 f  v+ V2 J( z, {; _    S.top--;
  q" l' B' l' W    return 0;
! J% ?. h( Z/ P/ N0 U, y) M}7 y9 J; O2 |+ M% ~2 ]

, g6 |) b( o% R, L3 \) Z0 ?. p# G. gchar get_precede(char s,char c)
% k9 t9 c9 {5 u( |% h5 u{
, p. T, _; G# a    switch(s)
* c% M( @/ k/ U* s' D' G+ ?, {    {2 |+ d3 `, }/ a9 d7 V2 J) C$ ]
        case '+':                 
& [. L8 f  I% T2 V        case '-':
0 X6 g6 D& Q. }8 C) M$ ?             if(c=='+'||c=='-')% I! J' @+ o# N0 c% r: C
                 return '>';
5 R" d/ `# A: j( T8 `: g( V4 @             else if(c=='*'||c=='/')$ U9 w8 R0 r* X; B/ x
                 return '<';% C! s$ U1 K: z2 o' {
             else if(c=='('); k) ?$ ^4 I7 G
                 return '<';
0 |0 @; r4 c) g# L             else if(c==')')8 @4 [% h( E' v+ T5 q* G4 X* b
                 return '>';& q( w7 m# |7 C- Y7 ?
             else
3 Y3 [# m+ a/ E$ E7 `3 {  @                 return '>';. Z5 i4 `) V8 c3 W
        case '*':
9 j3 J$ q& C' i9 T% q7 l        case '/':
. x* a& x3 I- B- b- Y; @0 W             if(c=='+'||c=='-')7 [9 L" S) {; `8 o. b) V
                 return '>';& S5 F0 ?/ j0 q/ a2 G" @" w
             else if(c=='*'||c=='/')6 g8 V0 \1 z8 Z# n
                 return '>';
8 P9 }9 w9 g; r# S6 R             else if(c=='(')8 c- b$ r9 W0 V, }+ p8 @2 b" E
                 return '<';* \. I6 x0 h5 x( a/ V
             else if(c==')')
1 m- O0 _& [( t& K* n                 return '>';6 V9 G' \- s+ V, E% X9 q
             else
. H' M+ z5 C" r; h                 return '>';" \3 I; v5 C$ |8 C1 y" i: B
        case '(':- T" [  A* [& x. ^- s# D6 A
             if(c=='+'||c=='-')
0 J* g7 c" @  e- x" \8 w                 return '<';" g' }2 y8 ?( ], {7 v; E
             else if(c=='*'||c=='/')
1 C1 E: C/ u7 w! C* q  k                 return '<';
: S2 l# k4 c3 D$ s/ U! D             else if(c=='(')
! j# f+ s9 \  E                 return '<';3 q1 R0 P- ]- T- w
             else if(c==')')" R: H: {4 |: M) N6 f% H. _) `
                 return '=';% F& v, p# p- `/ R, z+ P3 n
             else" E' Y  Q: r# Q- Y
                 return 'E';
- B0 l+ v6 j8 n, G# q9 ^        case ')':  R8 B, n$ N4 J" J) \7 y
             if(c=='+'||c=='-'): E& N# B: y, i8 o0 |1 n
                 return '>';
  i$ T* n( M# x; Z             else if(c=='*'||c=='/')
/ y' `! t8 Z: N  M) ?; Z( F                 return '>';
9 Y- k2 j7 F" Q4 X4 @" R/ _  [             else if(c=='(')' d/ U+ {5 J7 ]0 p
                 return 'E';
6 n) B% w3 T. p: V             else if(c==')')
/ C) r; {9 N( N1 R0 h2 t6 W4 T7 |5 u                 return '>';- J: F; c+ |) ?; ~! ]5 I7 }
             else
3 l9 |, j, c& A9 g  i" _                 return '>';  k2 ^2 R5 i# [3 q" s. k
        case '#':
2 T6 v1 e' g. w: V4 A             if(c=='+'||c=='-')
, l8 a0 w, A9 S0 K                 return '<';
% B6 D/ y' S1 ?, c* V$ f! y             else if(c=='*'||c=='/')
. N& p- R' I# T                 return '<';
8 i9 F( D  k9 e* ]  U/ l3 R% ~             else if(c=='(')8 j  P& i- Z! u- d  t/ n
                 return '<';1 j) O* g" N$ G6 a, y; j
             else if(c==')')
0 M" _7 f0 Y3 }* Q                 return 'E';
$ j) n; b: |! x+ @4 J3 V             else
. m( c, F1 @/ i/ d' q. v                 return '=';
+ @8 J' m; e2 S0 K7 W4 u        default:
  G+ B) e; d" Z0 p. M6 q             break;, V+ Y# {& J4 U3 |' Y
    }
: g0 d$ C5 `& O( ?& S    return 0;    3 a1 c  y1 A$ _4 Q/ z( C
}0 F, o4 |- F2 r8 Y/ P; {

, Q# h# \2 ~  O: U* R' t2 H& p, W5 j. C# hint isOpr(char c)
- ]) U8 V& y' Z/ `- \{" ^$ C$ S$ w8 t* S
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2 m5 \& k5 `& ^" W6 l5 b, S; a* y
        return 0;
5 O* E% q. V2 L    else ( V$ v7 A/ ?4 F
        return 1;
" h- X8 p, U& {6 N/ x8 ?1 b# V! ]9 I}
+ z. Z/ Z; W7 m' l6 T4 T4 ~' ^) [
float operate(float x, char opr, float y)
- h' b2 A& S  T0 {1 B# r7 v{" ^" ~* K  R, a# l. g
    float result;3 Z; i& c8 ], Q: q
    switch (opr)
. N4 w0 ]" a6 ^8 q    {2 A5 {6 U1 I; ]6 E8 S2 t+ N& T% g
        case '+': 2 T# S7 d9 g+ _* g- E
             result = x + y;
. v/ A' c# `7 z5 U* [9 j8 ^             break;
/ |, K0 o; A- ?        case '-': 4 x% D' @( D0 k6 ^# S3 l0 T
             result = x - y;' C" E& {0 I7 t& ^2 D- u
             break;
: _% x3 M/ _& H( b+ v  q, R% _; f9 w        case '*': / j; K& N% d% g8 q* w+ I
             result = x * y;
( |7 n7 s: k1 Z, ^" C0 @             break;" F( @! @4 \( @  p' ?! [' ~6 d
        case '/': 4 k1 v5 K% j& w4 k/ @
             if (y == 0)
6 s* l/ y3 w. Y& k8 \3 N) M0 K4 W             {
# x) }" @2 D) T2 Z                printf("Divided by zero!\n");. w3 q7 c6 v( ?& @9 a2 F! O
                return 0;
$ d0 G8 v1 `/ {+ I             }
6 w5 O# F% I( D2 _% d% o             else# b5 v; k/ S" B0 L% [5 W
             {% m. e5 y3 c! }6 t9 r9 i
                 result = x / y;
$ j2 E) n- `- G7 b# ^# D9 o                 break;3 O# O3 e. [( K- Z
             }% s; w. M" S2 o; R
       default: 5 A) T1 d3 q9 C* N& a
             printf("Bad Input.\n");
  z: M% [* w& m  Y             return 0;
, L$ h8 X$ @6 i    }  t1 Y! h) r+ H8 O) H+ l5 g1 t4 H
    return result;6 V& s- ^3 X7 \, f( n8 q
}   
/ ?' j* p; r+ S' Z; V' Y7 Z, h3 H0 E. O& r
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/! n( }# ^3 P, d- y. }. F1 j
{5 C' O+ |( Q- y  F/ n) Q! z
    Stack optr,opnd;
. J' d; M* j) r    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$ c8 U* @+ E, b. A3 G; X
    char c;, t0 m* t8 H) Z6 D
    char buf[16];
2 b8 x  x% [9 d$ r- D( O: V- k    int i=0;
% E; K! i5 x, R, f, h1 w% f    " h+ z  `$ c9 \4 g1 D
    InitStack(optr); /*用于寄存运算符*/# {/ b8 J* w( q* [( P3 R
    InitStack(opnd); /*用于寄存操作数和计算结果*/- \, J$ |0 c* y/ F
    memset(buf,0,sizeof(buf));/ [4 x- @/ t/ A2 [! t
   
5 W3 i' J! C# h" V, F6 \% }5 l    printf("Enter your expression:");8 G. V2 g7 d( E  F% Q
        ' z  s; V  z, F# u" {" M9 \- t* ^6 u# S
    opr_in.ch='#';
% X" F! \4 k2 a/ Z    Push(optr,opr_in); /*'#'入栈*/
! Y& t. M9 k: b    GetTop(optr,opr_top);4 C, |% Y9 m5 }8 Z1 b% C
    c=getchar();) c+ Z; b2 x) v( x) M6 k( i5 H
    while(c!='='||opr_top.ch!='#')
' p; }: Z7 j$ M- C" D    {
* z6 H+ @- `* m7 c$ }  w        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/- ~" _$ Z8 W2 _( |5 g
        {' w  N+ `: M" s3 ?/ d% _
            buf=c;
: {$ c) E4 h+ [+ C$ |            i++;3 Z8 G& Q, B+ `1 [4 d
            c=getchar();& M# F0 F( a6 a- i. f" j
        }
$ k- x  ?( h0 _+ ]' C        else /*是运算符*/( u0 h, x9 W  o. h8 K7 u) V
        {
- v+ }$ y6 |) w' C* {5 W# p5 X            buf='\0';
* Z' M& j* f% U. P5 o3 D            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3 l: }9 Z/ L# L( Q
            {
- S3 u8 C. z) Y  I4 m) B                 opn_in.data=(float)atof(buf);
; k! J$ _( U0 G1 E3 u: ~                 Push(opnd,opn_in);) m& G& C# P) v
                 printf("opnd入栈:[%f]\n",opn_in.data);) W$ P. z3 p( @
                 i=0;! |0 z) f8 n, b/ T+ P$ O7 P1 q9 e
                 memset(buf,0,sizeof(buf));# J0 b0 x- G; w" t7 g
            }
! d: [' G5 c$ A% X9 \            opr_in.ch=c;2 @6 L0 J$ g( P$ G
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
8 x5 G1 t; K% Q$ l            {3 y/ q$ ?0 A3 i0 E6 b$ _
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
5 {, Z% A2 D. N/ z9 x- F3 h$ E0 u                     Push(optr,opr_in);
7 g% h0 [8 b5 F3 r! g. I; R5 N                     printf("optr入栈:[%c]\n",opr_in.ch);
. R! F/ x: L8 K& D! r: Y; k                     c=getchar();3 x( s# S4 v: g! M4 U0 ?
                     break;
, [2 }8 E" O% `. D8 M; C3 F                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: d% X0 \) ]4 c! g                     Pop(optr,e);& @7 `7 Z" z6 y" i# f
                     printf("optr出栈:去掉括号\n");# G4 B0 A* f" B$ d+ n6 p( v
                     c=getchar();
7 N  B+ B) l/ w                     break;  s# N& f  Z+ m5 O) x  B
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/- m# L$ t% {. g, F
                     Pop(optr,opr_t);
7 a" \5 p" x3 d1 y9 o7 A( }                     printf("optr出栈:[%c]\n",opr_t.ch);
5 w7 B. P" _6 v/ L- K9 u( _                     if(Pop(opnd,b)<0)
- T& T0 J. R1 z4 M; A, \                     {1 h5 o9 j( W' Y& R  Q
                         printf("Bad Input!\n");
, I% z* d" J" a5 `+ Z, v: r1 c                         fflush(stdin);
4 H6 _- ^9 P! T8 o' }1 X                         return -1;
- W! ?, X  @* H% w! P! c- `                     }  g" y1 z+ k# \/ S
                     printf("opnd出栈:[%f]\n",b.data);" P1 v$ c8 i, p
                     if(Pop(opnd,a)<0)0 e# O. Y, u  b7 E/ \3 A1 ?
                     {
0 R6 z. D1 I; U/ [# U4 c                         printf("Bad Input!\n");( y% j0 ]- q0 K& c( y. M
                         fflush(stdin);! f( V' H$ f' ?
                         return -1;
: R9 }) l; q9 q+ I; G0 Q( ^# q: T! t                     }+ w3 G7 L( o' m6 B3 Y
                     printf("opnd出栈:[%f]\n",a.data);
/ E, x4 y" r4 @& {                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
2 n6 S6 C8 V- E( I# N0 h  z$ @                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/  U+ m$ i4 M  r$ Y
                     printf("结果入栈:[%f]\n",opn_tmp.data);! @2 ~* v: r+ v$ i2 b8 h( X
                     break;- q  I: [1 w  f" _2 A' l9 m0 b( L
            }0 n: `: W  w/ N- j- b0 z, |
        }' B+ g# B: B- c# H
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
1 O% M$ Q. v1 W7 _" i" T9 d( q& d5 `    }8 A. O! k1 N& ^# u4 _* y
    GetTop(opnd,opn_tmp);* {" ]6 r* x% R# `8 v: |
    DestroyStack(optr);
+ e3 u$ e% G; J9 {1 x0 r! g" ^    DestroyStack(opnd);" `- B9 C4 [; U/ y2 b" b; u* L
    return opn_tmp.data;
. K& K) x' G# I4 L/ a}5 Z: Z# a$ b2 s; {; M2 ^% o
* A4 I% Z2 B- B( N" |
char *killzero(char *res,float result)
$ J& n; p7 `9 X, S: }$ `{" y# r" `  G# c, N
    int i;
) n/ t6 i0 S0 K, N6 F2 R. o4 s: p2 n' U' Z2 t
    sprintf(res,"%f",result);/ h8 ]2 m& w6 C+ F$ L
    i=(int)strlen(res)-1;
" S2 X0 w, d# g$ D$ u1 |    while(i&&res=='0')
) g/ @7 X9 e0 G5 n, e    {, }  r; w% ?8 z
        res='\0';  ^$ n4 I) J7 c3 N. V( Y% {
        i--;$ r5 p8 B; n2 [( B' F* [
    }8 \$ T6 J# {. v* {
    if(res=='.')& W& E! R# m/ a& S9 k
        res='\0';7 O/ ]8 ]3 u4 T. E" p
    return res;
( o1 E* m8 B7 M- L% H}
& m% {' W; a- x6 ?" B
2 ]% e3 _+ K* s# z+ l' ^int main()
- u* X. ~0 P. ]3 C6 r$ _7 k9 Q1 e{9 z) R8 }. z$ h  ]0 b3 p: y7 T
    char ch;
' s7 \7 h! M7 v* e$ \7 V! w! P" W    char res[64];
0 _- w: j! R  b2 J    float result;
: u/ O! r; O+ M1 E$ ^( [    while(1)! W0 I% Z$ K0 h  J
    {
' D1 L, a. r: I& Q: A1 z        result=compute();
/ g" n0 Z+ |5 m- Q& g        printf("\nThe result is:%s\n",killzero(res,result));$ J+ Q. \" E6 f* b' P& A6 `
        printf("Do you want to continue(y/n)?:") ;; h+ N% }, R8 J$ p
        ch=getch();0 @" v- P- j" f
        putchar(ch);
" p' U) Q+ B2 H6 m# R6 @        if(ch=='n'||ch=='N')
0 O, k* l0 q6 W. ]9 x* E            break;
1 ^8 z; y2 B9 w, D        else
& X. Y  m* C: ~            system("cls");5 {. a( }4 h& I5 ~7 h! }
    }: Z& }' H! V0 B2 G. U( b
    return 0;" u( r0 h$ c; F7 A: d- G8 y: W
}

, \2 l+ y- G* W0 z8 a$ x9 m: e5 n2 I5 K" v) q% A
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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