返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.1 `7 \; p7 m3 t/ S) l/ T
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=# v9 S' \- ]# W  u; U: D0 e
/**************表达式计算器************/0 R- e  t5 ~8 U9 `$ j7 L+ B* [
#include <stdio.h># g$ W7 P, D$ |! i! A. w
#include <stdlib.h>
6 A; o! @7 R9 d$ j! n#include <string.h>
5 i( b8 a7 z; A! P# H! `8 u* L- e#include <conio.h>: [1 K) _7 p9 S2 I
#include <malloc.h>1 T) `1 c7 Y9 T  J
/ L' J' I- ]3 @, W& |  }! }1 q$ n
#define STACK_SIZE 100' W: W* R. Z3 i+ @: [
#define APPEND_SIZE 10* T/ p% z5 i. \( w
. C. o0 N  s! s, x
struct SNode{
$ C/ [. K) e. D* y; i    float data; /*存放操作数或者计算结果*/0 M) x  J% R" N+ X) _; l' z& N
    char ch; /*存放运算符*// Y, C/ Q: K- _- m& _
};
  }0 G" f2 W5 h& t7 N
/ Q" ]% d; S8 u4 E. S- Dstruct Stack{/ b* u. |: u# C# m9 h- n' @
    SNode *top;  {1 k, d# E% I8 j; u& l/ o, R
    SNode *base;+ K6 z' z" U2 K% \$ J4 c
    int size;% T6 E( [) R" T7 ]& W' A5 K
};
6 ?: p& _, @. Z2 V* [, _& a" @  i& K, k2 R
/*栈操作函数*/
( H4 t7 r  x$ n/ p. Tint InitStack(Stack &S); /*创建栈*/
- R6 v6 J  |7 L* a1 N  Gint DestroyStack(Stack &S); /*销毁栈*/
- `3 K* L! A: |7 W7 j2 [2 \int ClearStack(Stack &S); /*清空栈*/5 P1 C$ Q0 {* t& G
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/" K2 _# E" |9 t# I  r+ E
int Push(Stack &S,SNode e); /*将结点e压入栈*/7 H! E, ^- Q! S
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
( P. w8 ~  `9 s4 h9 l; ?8 R- m  {3 u, L  S
/*表达式计算器相关函数*/: A1 g1 @, F1 a& Q
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
: f1 w/ d3 x/ I1 H: z4 dint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
' g+ F* L5 x. J; }9 O* M: mfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
- |. q  l$ |, l& vfloat compute(); /*表达式结算器主函数*/3 N2 j( v! v' g; f$ `
char *killzero(float result); /*去掉结果后面的0*/ * x, n5 i, g" ^) V$ \

" C# H3 H# X6 w: }3 m, j& ?/ Sint InitStack(Stack &S)0 {$ ~5 q0 Z! O! c  {, X- c
{6 q3 x3 {0 M* N# u. v
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));. b& G' {+ \, K1 ]# z" W3 p% X/ ~
    if(S.base==NULL)
0 ^1 v, N8 C9 @" l! n$ `- J! t    {
4 m/ L, C# `! N2 Z; Q4 [6 A        printf("动态分配内存失败!");6 s  }1 i/ [2 s0 k, ^5 P9 p7 V
        return -1;9 _" N" ^8 x4 \% L2 s3 d
    }. K! U8 T+ ^3 C$ @, l* g& k( _* m7 \
    S.top=S.base;
# c* \( O, D) Q# W    S.size=STACK_SIZE;
" b1 U  b* u( Y: M5 P    return 0;* n5 Q. m8 [" L( }1 |% Z9 [
}: V6 h' E1 T, ~3 s
) W. z7 O+ |+ i* l8 k9 p- M7 b
int DestroyStack(Stack &S)
8 b8 m# m7 d6 j5 d4 H$ L, |{! T2 v- |- {& ^9 J
    free(S.base);$ S: g. B; y4 S  N6 F& c% V
    return 0;
6 O) Z) }$ C& h  o% E* o}/ e7 z0 F8 q, W

8 b% \4 T: Z: M& P+ ^4 o: s2 dint ClearStack(Stack &S)6 @4 m, A' w6 w' Z
{
$ L+ |% W/ j" K8 }    S.top=S.base;5 y/ w; W/ |2 t* I; e
    return 0;; U/ o( c, a* \
}9 @' ^9 V! |3 Y

# {* a) a4 w" ~1 e" {int GetTop(Stack S,SNode &e)! D' Z/ f3 [  j- r) C+ Q, N3 t
{& R+ y- e* p0 {! |9 q% ?
    if(S.top==S.base)* @2 C) \' K  A; y$ U! Q
    {
5 ^* Z( ^4 k. o  i4 ~% R' D+ K        printf("栈以为空!");
4 r+ y( ?! J% l9 |" ~7 T        return -1;
+ ]) N" S  g8 ~8 U- N& i    }: [% n; h" F$ v* A
    e=*(S.top-1);
4 K" S; v; z4 V) F, t- c8 V    return 0;
9 A* a" D- q) n5 l! i% _}: k- R1 Q8 q$ W' |0 {$ m8 j
) h  E  }8 Q7 T8 Y8 {
int Push(Stack &S,SNode e)
  a+ G$ ~  a+ h' G{
$ S  t1 j( j+ I! }/ x+ @" U0 ~) @% L    if(S.top-S.base>=S.size)
( \3 h6 f( y$ G7 I; F. t' n    {
( t% i- l" {/ H1 h4 y0 A        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
+ P% ~1 ^6 H: O        if(S.base==NULL)! n& I- O% r4 ]" p* m. s
        {2 L+ b% s) X# _: `, U8 ?0 [
            printf("动态分配内存失败!");3 y4 L+ x' D2 {0 R2 u9 F
            return -1;) N  R9 w2 t+ G5 |3 \. V9 J5 X- ?( @) q
        }, j" U; i- Z3 P) d% [
        S.top=S.base+S.size;7 c1 I* L# B8 I$ ]; D# D% |
        S.size+=APPEND_SIZE;1 R3 F2 H: F! A
    }5 M; R! ^+ F8 O4 Z9 e
    *S.top=e;
8 u; _4 L+ L+ U+ Y3 O) t+ E    S.top++;) p  }) Y" O) y3 l
    return 0;$ b8 Q) W; U3 o9 [3 m
}
* ?5 _6 C/ I' F9 |  S4 @3 k; O' d) P" y1 Z
int Pop(Stack &S,SNode &e)
4 v  p! J! U- N{
1 B8 \9 r5 M: ~  b) |1 ^    if(S.top==S.base)) l* H4 z4 x/ {7 _* i' L
    {; v# U1 O2 \& E9 X: g7 C
        printf("栈为空!");5 G' l' O% x' B5 m+ N( Q0 _) |
        return -1;
0 b) N* o3 c  d, v4 }, e% q    }
* v; U6 k* S: t& i    e=*(S.top-1);/ u9 g5 S) Y2 I- I3 n
    S.top--;
7 H) G) i. ]- O& V' i6 B2 T    return 0;
, u2 ^, J8 }9 f% L# j}
8 ^' b# G$ m5 z0 W3 c$ v
; g8 [7 F- p9 zchar get_precede(char s,char c)
* M3 m& O2 Q1 x% x( t9 l- {{& A2 l) W; B) J, e' D& {% c
    switch(s)
" p6 y1 i- ?' b" ]3 `8 Q3 `- H    {! g+ V2 L; W2 a4 ?) Y9 e! X. l
        case '+':                 
% O. Y  Z/ G/ T) c  B0 [        case '-':
/ |. _5 W, d/ c* C, T- q) O1 h, e8 ?             if(c=='+'||c=='-')
  b5 b3 _+ H/ Z* k                 return '>';
! I4 m8 f5 }4 V             else if(c=='*'||c=='/')
% _3 {4 z. m4 E                 return '<';! F+ D, s* F, E: F4 c: J
             else if(c=='(')( J3 ^5 y3 h8 @& n$ L
                 return '<';
8 E3 y8 [& V9 Q# t: d             else if(c==')')
( G7 X2 |9 `. t6 @                 return '>';6 Z, `  N+ I) C0 @! V; j+ {
             else 4 I6 Q) A6 G! e3 Q% }
                 return '>';  r) J4 ^; [" Q* C9 }
        case '*':
8 W- S$ W+ w) v4 l$ V        case '/':
  Z( I- v- L% `+ f% E             if(c=='+'||c=='-')
6 X: W9 Q; D8 q' c5 {, k                 return '>';
1 w# @3 l7 y6 ]& I  G; r' y, i             else if(c=='*'||c=='/')
$ R8 M& C) q$ P, k$ u& J6 E1 j                 return '>';
/ t+ O2 _8 {# f! N" v/ M0 Y( S             else if(c=='(')! {& G( A4 G1 @4 Z; n: M" t2 S
                 return '<';
8 h3 e" [0 |! z4 r             else if(c==')')5 ^+ K3 j& E8 N% j
                 return '>';( f) u" u" Q1 S, ~* P- I
             else  |1 ^" k' Y( D$ _
                 return '>';  u: }2 _2 W1 p* U
        case '(':
: k6 H% t0 ]7 c" w7 H             if(c=='+'||c=='-')# P* r7 o: N* a4 W5 C
                 return '<';5 g# {. u; J  A( n+ K! e2 J( S3 i
             else if(c=='*'||c=='/')
8 M0 `1 R1 a1 h, x                 return '<';4 N) i5 J: _$ g( a. K
             else if(c=='(')
  t( B2 E$ j' Q$ f) v* n. `                 return '<';3 R! ]% o3 }, I
             else if(c==')')) Y4 Y2 N% ^% Z' \
                 return '=';/ ?7 c8 q1 G& u
             else
: [' T0 \1 C( c6 y/ E. H8 N                 return 'E';0 a+ r/ G/ ?6 ]* _
        case ')':
7 O  s, c3 J) u             if(c=='+'||c=='-')5 O$ n& c2 V7 v0 i# y/ `$ t
                 return '>';) ~, o' Q/ S$ \
             else if(c=='*'||c=='/')
( s9 G, H. J) q( x                 return '>';& j# {! ?, Q; A
             else if(c=='(')
, |' \+ o/ X; z8 p) b+ N                 return 'E';
3 @9 v/ D1 i7 ?( `             else if(c==')')
  D) E: r! Y" m$ I                 return '>';
# V- c( [3 P' P* m) f; z3 X             else
* k% J0 K3 G# K# h) n5 M$ @0 w' N; w                 return '>';
' Y- n6 `% Q9 b" ?$ k# K! W        case '#':' _$ d+ k* t) o
             if(c=='+'||c=='-')
& X: G2 e8 m8 X4 l$ z                 return '<';
. D' X- L% N1 h# ^             else if(c=='*'||c=='/')
- S8 N9 @; V4 f8 w" Y2 `8 L                 return '<';1 v9 W- |  y9 p
             else if(c=='(')
! s2 g+ U9 L% i) V/ a0 B0 y: h# s                 return '<';% z0 M+ C: F# L7 w9 e  Y
             else if(c==')')8 i" R4 {# Y; b
                 return 'E';  h: @, x' r: g% M' t* M' {% h
             else
! V6 @. h  J3 p+ S. u1 M                 return '=';
( }7 {2 O6 U& ]/ ?5 W3 p7 M  [        default:7 _7 @, H& K( [
             break;; k9 ]6 |4 B9 ]( ~' }
    }
& ^8 {( Y& f6 }  O  s    return 0;    / q9 g. b1 n/ S% ^; ^) m$ V8 K
}
! ?/ u9 O- d' I& I% n
5 w; h/ t+ h% k- L* Xint isOpr(char c)4 K& s3 w4 Q/ \
{
* d: [# ?6 p' ?5 Q6 a5 g    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
, a" _/ E5 x6 |* h% h        return 0;5 E) E8 W; g; m$ \$ `$ @. m
    else
1 X2 c+ e% _& Y* y+ f( q1 R        return 1;
3 d8 P- X! l/ `2 i" H; Y}
4 A% I$ c& V. @- Q- J' ~- q' [. n! c2 h4 i: u" e
float operate(float x, char opr, float y)" E( \6 D# x7 G) g
{7 G( i3 I& u& |6 l
    float result;  Q* a2 q2 `1 c; O1 j1 z
    switch (opr)
" P, ^  i5 G0 a+ e5 [0 u    {- F4 Q& d. h: e$ _% P" [
        case '+':
! |* \6 _  B) G# k             result = x + y;# K- r: L+ ^! n4 ^% y, x; _% [, e' k
             break;* E! c0 p& U  a  x
        case '-':   V9 B8 _! F; I
             result = x - y;
1 ]$ c, n7 S) F* [4 [% U3 w. t             break;0 ]! k! |4 @; E6 M
        case '*':
1 D6 b0 D% U/ N0 o) o3 j$ v) b             result = x * y;
: E- F. P# [* Z" n5 w7 `" \             break;
# b3 l' P6 _* ~+ q( T$ k- q        case '/':
' \3 f/ b: g& u$ A& z             if (y == 0)0 O4 f' f: Z' W+ V
             {
4 L. I7 L/ F. U' L8 U$ a                printf("Divided by zero!\n");
% Z4 @0 o! S: F" z                return 0;
. [' O7 w" N2 c* r6 Q             }+ |' s, d0 e# ]
             else# S+ M* u2 Z: ~6 r/ P1 G2 ~3 M
             {
( p0 g8 P. U: Q& w5 s                 result = x / y;( w5 }; t9 M" t- k1 y
                 break;- {% P9 H3 ?$ ]4 w
             }
: g( i' `) u& x7 [1 u2 A       default: % s9 {- Z( ]5 @6 J7 L* _
             printf("Bad Input.\n"); 8 u1 d4 f' g: I6 T2 V. p9 X" \
             return 0;
' }( Z/ ~- |; Q" t" Q. A7 G    }
& r6 `1 z8 s: s    return result;. ~+ y. f) ]1 q: l8 {9 L$ Z( z
}   
0 q1 K. x) L0 r1 n% W9 g3 ^9 U, K3 m# k1 u% m8 F% p' F
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
2 E% o5 v2 V; {{3 s2 y5 r) Q- [" Q$ o
    Stack optr,opnd;
* A6 Z! d1 m4 E: u& X% r    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$ Z4 a2 o. Z: J1 N6 `
    char c;
6 P  n3 m4 G* N% k& w/ _    char buf[16];: B: L6 i( T8 g8 Y) D  Y& q. Y
    int i=0;
7 u" D! t/ m# z$ u% i    1 T: N6 x1 p$ y6 m' I+ Z, }5 W
    InitStack(optr); /*用于寄存运算符*/- v6 x2 l, K. ~1 K3 g2 e, S
    InitStack(opnd); /*用于寄存操作数和计算结果*/5 G2 c; \' a! U; V
    memset(buf,0,sizeof(buf));+ t7 M; U7 t+ p+ X0 u
   
# q3 `9 h9 k' T# _    printf("Enter your expression:");9 S( z0 D1 t3 q: P/ Q$ v# e. g
        ; |1 c1 D: `3 ^- _5 ?8 y  T
    opr_in.ch='#';6 ^# i4 [; V6 ^- Z, q
    Push(optr,opr_in); /*'#'入栈*/7 {0 N6 T6 j& B: O0 W
    GetTop(optr,opr_top);
& y/ ^* z; Z; z: g3 ?    c=getchar();2 R- J7 Y; M# ?* t0 e
    while(c!='='||opr_top.ch!='#')
* Y- m1 K3 A. ^7 t0 i    {# {% x" q% ]1 K% ?! m4 s
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/. v+ u  X+ R' r$ B, r
        {
* [" X  p! j* H$ N0 N! r4 r0 O, K: D            buf=c;' e7 F- a3 J9 ]
            i++;
8 W! r4 w, f9 Y5 L8 d5 s            c=getchar();
: E7 G5 ~1 z& W        }
# u. ^  I6 ]3 t) L1 L7 v        else /*是运算符*/, X. L; z' y! B1 U4 F
        {; p+ t" [0 E: c/ y
            buf='\0';2 z$ I0 u% `3 j7 B8 q4 P
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/( E8 w1 {1 k$ f3 v, r
            {" u* A6 L! J; w8 l# t7 L# [4 }
                 opn_in.data=(float)atof(buf);
, Y6 B5 g0 V% C( Q/ q2 @4 y                 Push(opnd,opn_in);
1 I) d% @" y! P0 K# p                 printf("opnd入栈:[%f]\n",opn_in.data);
8 _% A) L- A% e# R6 E, \+ S! T: R                 i=0;
8 R1 t4 a4 z) V6 M! b; @                 memset(buf,0,sizeof(buf));, }" n* P4 `0 y
            }3 i# k* F( L) a  s, e3 l8 k
            opr_in.ch=c;" x: t5 f+ A" s
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
( {& }& @9 @5 Q( j; H            {2 {+ {9 d7 b& ^& }8 f4 G2 o
                case '<': /*优先级小于栈顶结点,则运算符入栈*/7 Z, C) z, |/ V$ w7 q/ p( Q5 E. K
                     Push(optr,opr_in);
6 q. l; _) ]( s) w  b                     printf("optr入栈:[%c]\n",opr_in.ch);
  W. L0 U4 e* u( n) t, i6 H                     c=getchar();
: ?, V4 y9 L: Y- F                     break;% r8 z" N" }' X- H
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/$ W3 f8 U; T, I$ @" Q- a
                     Pop(optr,e);
; I0 M, p5 r4 G7 O! D6 Q                     printf("optr出栈:去掉括号\n");! ?% e! Q( \6 M% z& T' [
                     c=getchar();
9 Z2 K5 r9 X$ D# B- y                     break;
4 U& B/ r. j1 J4 H# \                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
  y7 H2 ?  s9 [  H                     Pop(optr,opr_t);1 L9 v3 Z- M3 W, l9 H0 H& u& J
                     printf("optr出栈:[%c]\n",opr_t.ch);9 Z# V$ [& c( b6 k
                     if(Pop(opnd,b)<0)
  A1 |: e( Q/ u                     {
" |; t$ u) j7 \! D9 m* A                         printf("Bad Input!\n");
1 C- Y0 m2 p' e( T" G+ w4 p                         fflush(stdin);
) Y. b- c% y' N/ T4 Q                         return -1;
& ^2 t9 S% J, I/ z2 K                     }
3 j* V( w% i9 W' n2 l4 K                     printf("opnd出栈:[%f]\n",b.data);2 X1 k  x  l% ^! f4 I
                     if(Pop(opnd,a)<0)
" v6 G4 H( Z) x4 {8 w+ C                     {4 i8 A+ s& v! A, Z3 A
                         printf("Bad Input!\n");2 d) j* q1 [4 F
                         fflush(stdin);/ h* @5 a' c" t5 o2 H& j
                         return -1;
8 q2 y! C9 A: _: w1 G: v                     }
7 r0 s/ Y$ ?1 [. J6 K% E  T0 `- L& }                     printf("opnd出栈:[%f]\n",a.data);
. T* a0 R! t0 W2 O5 h                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 n; Z4 G1 e1 S! @1 |0 h- n' f                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/4 t( J, \1 ~& ?; s( R5 c# w
                     printf("结果入栈:[%f]\n",opn_tmp.data);: l8 f8 `* S, y  Y! @
                     break;
0 J- U2 `: Q' m            }
, S, m% T6 r" b! M- V- o        }
7 Q5 h% U4 j! N  Z1 Q        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
2 I. `0 y$ t6 z- U6 L/ t    }2 d* V1 W: g+ R! b/ a/ x
    GetTop(opnd,opn_tmp);2 S, P  q: _, {+ }, ]* `
    DestroyStack(optr);
/ C5 s& ?  F: M; p- u% ^* `1 ?3 i' J: S    DestroyStack(opnd);
, ]1 a: R6 E3 G: u    return opn_tmp.data;1 P6 |) L1 J$ K  x
}
; b# T  G, ^3 \' x# e6 r% ^0 `+ |: e4 g
char *killzero(char *res,float result)
8 ]' T  Z  {" |% e9 K$ @{; N6 Y" n7 }4 Q! C* R3 {7 `
    int i;
5 _1 x( x! |9 e& T3 X3 _0 W" m3 v& W
    sprintf(res,"%f",result);) y6 `/ Q, `' }# Q5 P1 g7 Z
    i=(int)strlen(res)-1;
: O5 x- r8 J! z; X- g# t6 m    while(i&&res=='0')
% Y  p0 h3 h, b9 f( N8 U    {
6 R9 X, m6 f# V3 u4 n, R        res='\0';, `$ G+ |3 B2 {
        i--;
/ T& x$ |& F* V& x/ y- U" [9 A0 O    }. ?* s4 k& j* J, C8 o- D
    if(res=='.')
# Q# V1 C# D& g8 X/ Y( c4 F' B: M        res='\0';/ I6 y( o4 z& l$ g+ k. N9 ~" s
    return res;
% R$ [; V- M% c# ^3 ?6 L}
' f3 a0 I: k4 D, j6 R
2 o! T. f1 d" ?) M; Mint main()
) x2 r2 E+ g0 W{
) u- L# h! b5 }1 X    char ch;% J- g5 w% ~4 a$ `# O
    char res[64];
$ U: t, i1 K( P/ [5 j3 B    float result;* e9 l: i; J0 _
    while(1)
! S6 e+ {4 g# D; H    {6 H" E; t& v% S, u
        result=compute();6 ~& n7 E" Q3 `  G: ?: v. s, X
        printf("\nThe result is:%s\n",killzero(res,result));
" o+ |- b& L1 x/ @0 n! m        printf("Do you want to continue(y/n)?:") ;1 t6 {* w1 f! t! _8 D
        ch=getch();5 n  d+ O" u6 m- v7 N  M" q# c2 _' s
        putchar(ch);4 y. y0 J/ G1 K/ M- `! @) T
        if(ch=='n'||ch=='N')
/ {! d7 `5 w8 a3 v6 H8 F3 o) P; h            break;3 n0 U4 D) E& m, }, W
        else+ Q- q/ F9 q) Q! l
            system("cls");4 ^$ }4 _3 z8 t) t& T% Y# r
    }, T! [( I5 V/ h& ?1 f
    return 0;( H( h, ^" {$ X$ R3 x0 E2 q$ E
}

2 M) I( v# G! Z4 M' L  B1 c4 {* Q0 ]# H: p
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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