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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的., P( q- I9 y1 H2 I5 V8 T
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=4 P, f, j+ R7 ~! H
/**************表达式计算器************/9 d& m& N9 V& L$ s: I
#include <stdio.h>' c3 u) t' ]. u4 h  v
#include <stdlib.h>
, v& b9 u* S$ a* b#include <string.h>, c8 \2 Q9 T1 Z# a
#include <conio.h>
  c7 q! G6 m0 w  z* ^  E#include <malloc.h>3 B) i! [5 u" g; w( X3 y9 \" a
) i5 L) E; ~2 d$ o
#define STACK_SIZE 100* U2 n* ?2 N' |/ w
#define APPEND_SIZE 10
, }0 v, Q1 G8 \$ a# E% o7 v1 a& E# f- t0 M( y/ F
struct SNode{: G4 O9 h: Q+ w2 i. `
    float data; /*存放操作数或者计算结果*/
3 B) |& u% R' P4 N$ e' ?: Y: \( G    char ch; /*存放运算符*/
' r' n: w7 @, F" p0 y};& x9 K$ l2 v2 r) q- @: S+ C

* z  M4 `3 L/ [* \; }  Dstruct Stack{
/ u7 E: M/ r" M0 L; f. r    SNode *top;
: [: ]" x$ N5 C( s    SNode *base;
" y9 {# O0 j: S; t4 d    int size;# S) a& k* l9 C! D( A4 z5 K. ^
};
* L9 h7 d9 Y, O9 m2 u/ k; I2 P1 C% S( I3 _' a# p
/*栈操作函数*/
8 ]3 m0 y7 a* |* Sint InitStack(Stack &S); /*创建栈*/* t/ K7 l& ^# `! T% L' t
int DestroyStack(Stack &S); /*销毁栈*/
5 j$ h% I6 v. e4 |* a6 i7 Jint ClearStack(Stack &S); /*清空栈*/5 j6 a7 C3 U& _
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( X, M& o! n7 P! y1 w% ?int Push(Stack &S,SNode e); /*将结点e压入栈*/( `$ M! l2 u* }6 w
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
  K' v- K4 A& c" f5 ~0 B9 h% u# G) \3 a' a
/*表达式计算器相关函数*/
- `6 ?+ _1 a; Q& M* ~" Pchar get_precede(char s,char c); /*判断运算符s和c的优先级*/* v7 R: a! J2 m" V
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/$ d' G: q9 Q9 p; {! M& i6 f$ S
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/- z" e6 u; [0 h' X# u( R
float compute(); /*表达式结算器主函数*/
* p4 b8 Y/ K. Q( r4 G2 f. j) hchar *killzero(float result); /*去掉结果后面的0*/
: ~1 k4 _/ {3 k, n( a. Q
9 g/ d1 R7 b  L( k4 cint InitStack(Stack &S)
" t, [. q2 y4 M6 N; a8 C{
* A- |0 x7 g5 G$ w, k5 r( ^. T    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+ C5 l5 _( E0 m8 Z    if(S.base==NULL)2 A; D0 f! J! K1 ^! Q1 k# |# ]8 W
    {
7 f# T* `) n* p& M: i        printf("动态分配内存失败!");
$ v5 Z( v2 i) k% ?5 @5 I        return -1;) z7 N# S' }, [6 ?1 b
    }9 ^# J- I& p2 Z
    S.top=S.base;9 S4 K+ w# {9 V) u1 Q
    S.size=STACK_SIZE;8 r- K1 {0 U: ?& t2 X
    return 0;
4 |$ M7 V; [  \1 Q; [3 w% P}9 V. t3 Y3 k7 Y7 @  I
7 v  i, n4 e$ A% M0 Z+ J$ H; X9 u
int DestroyStack(Stack &S)3 g' ~. c% v2 v9 M
{: O; w  _& }: T. X- [# |
    free(S.base);
, O& l$ g' }! f0 L0 o* s+ L    return 0;
# G" S0 @% [) S. _. [5 P}# e# _; ]& M+ k: E

* m0 @$ z8 {6 U: z, c, Oint ClearStack(Stack &S)' U* u+ G: V  d. K: l
{+ \3 j5 Y- {% @2 U  T
    S.top=S.base;6 E1 D9 y- t/ M6 Y2 s8 F
    return 0;
# N; W2 z+ p+ F" d: h! S+ w- {}& V& K. D6 t* L. z0 T' ?5 R5 A
8 c" {3 ^3 S% |# q) z" ?! Q
int GetTop(Stack S,SNode &e)1 Y& n" y/ K, X
{1 f) [7 f+ Z. g" d7 S
    if(S.top==S.base)2 R( Z6 J* T7 r+ ^: t  b
    {5 K, t: e# h/ Y% X; T! \, x& U
        printf("栈以为空!");
3 f4 O& u+ L% S; j        return -1;/ C: D" g& x# T' Q: T" U
    }) E0 j; v- k$ Y3 b
    e=*(S.top-1);' G" @; T3 I6 _5 o9 q% z6 I+ c
    return 0;2 r# A" s2 F8 u! C  M$ s8 _1 O
}
, f; l+ J4 a) a& G+ j: r: N6 M# T: h7 {& Y! L  ?
int Push(Stack &S,SNode e): ?  x  d+ @1 I) a% P# p* _
{
9 ]! y) e3 p; p- J. d    if(S.top-S.base>=S.size)
7 ?  X5 X2 r2 U" f5 j    {) m" U5 |1 W  B; w; ?* M+ s7 q: g
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
! N: A1 @( P2 r' A- i5 \        if(S.base==NULL)
" i% u# E' ~1 e3 Y: [; r& b        {
3 [* ^& q' j! @8 B. g8 e1 F* p5 k+ Y            printf("动态分配内存失败!");7 M* T  }2 r% c- a9 d
            return -1;& w$ O/ O6 y+ V1 @9 ]; ]' E) b
        }; F+ {4 |. z6 W5 X
        S.top=S.base+S.size;
9 e# D. A/ K, a6 Y# r        S.size+=APPEND_SIZE;% g5 B3 E- Z/ z; ?% Y& E
    }; X9 S- _, b0 l" Y& M
    *S.top=e;
$ A& P6 M$ ]) G, _. w3 z& y    S.top++;9 U# t" N% q* s1 a9 _2 t& D
    return 0;2 _& P$ P9 F3 P  _6 v0 a
}
9 s7 d& o# z4 O" T# b* _
% ]3 x& }* |, T4 ?! \1 bint Pop(Stack &S,SNode &e)7 [! H5 H* w$ M) q- `
{
/ F' c+ e( J# Q% p, q    if(S.top==S.base)
) I! H9 T3 V! j8 _; C9 U- [    {/ t8 l1 K: f) p/ R! A
        printf("栈为空!");1 m1 E4 v6 R+ j9 T5 d3 c
        return -1;, m, n$ {% u7 K! G9 @/ j8 e
    }
/ U2 P, B4 S9 U' V    e=*(S.top-1);
% l. ~1 O4 o0 z  e8 }9 F    S.top--;% {- J* }8 ]' [  F% R* {
    return 0;- I' U0 v* v7 I6 ~* z
}
4 B' Q" {3 {4 ]6 \% q; x! O5 U4 ]" \
char get_precede(char s,char c); a# Q9 Q( V+ t
{/ M+ j  R/ i1 M$ x! M: e% r. k
    switch(s)
) g# ]4 U/ Y3 O  r( P; L& f    {$ R" n) L; V1 C! ~, V
        case '+':                 , }' l6 C$ ~. i8 h' R0 r
        case '-':2 ?% l& Q: |/ F" p3 V0 _9 P2 g* l
             if(c=='+'||c=='-')
: X- |: S; ?& }, M                 return '>';
7 s; _) I2 j+ X1 B             else if(c=='*'||c=='/')
, n( z2 s+ O/ _0 X% J$ f                 return '<';
; F/ I  w& l- N. Z& J             else if(c=='(')& W# o+ R- a! ?) q
                 return '<';
% P0 _/ _) o7 |- J7 Z) E- q) D# R             else if(c==')'): X$ e( i. z9 a, g; O* f6 j, C2 `
                 return '>';
( J" j1 y. V" Z) P             else 0 z8 i9 W# y7 c9 O
                 return '>';/ F! Q/ h4 ], g8 g: N
        case '*':
) a. W0 x" C6 {+ ~* d        case '/':1 h( T; y  L- i1 z4 S& H5 }' ~( r# U- C
             if(c=='+'||c=='-')% j5 b5 J0 F* j; [; U9 G( P
                 return '>';: o0 A9 j( s- p. B# c: E* ~
             else if(c=='*'||c=='/')8 i' h0 i( ?' N# y' `6 v- i0 ~6 V
                 return '>';& E! d, J8 s+ k& n6 l  ~# f8 N) |
             else if(c=='(')
6 b4 f) v7 u, n( G. e* \* M5 |$ S/ R                 return '<';
, L3 q2 P9 s( M5 E/ a             else if(c==')')2 V. }$ x: P; Q2 K! }+ |
                 return '>';2 q9 {! x. K& h: q6 b
             else
; F1 M1 {3 a, ~) s0 Z                 return '>';
+ S9 z& V6 a% `$ U' H        case '(':* c" O; q1 R% x* q7 f
             if(c=='+'||c=='-')
' W0 u$ z( J) t0 Y8 Z/ y! I                 return '<';+ j' o+ }0 y; Z, E! I2 w
             else if(c=='*'||c=='/')9 U$ }+ Y& \9 C; O# `6 J0 z) w
                 return '<';
5 L+ B0 k6 Y* |2 [             else if(c=='(')- `- ^  N% C* L/ d8 J8 N$ ~
                 return '<';
5 [8 e% c5 ^7 O! G; W+ K# K             else if(c==')')
0 X$ z. T3 N- C) z) ~                 return '=';4 b1 V) R  R) W. i5 M- f; Q8 l; _
             else
! J5 G9 {- `8 k+ M                 return 'E';! @0 B2 B& s. h  u- O; s
        case ')':% ?+ W7 c9 e* f+ I7 S
             if(c=='+'||c=='-')
. z; w4 [) _$ k. ~1 v5 Z3 D                 return '>';1 E  k5 J5 e4 @; {% T
             else if(c=='*'||c=='/')
+ _/ z2 U3 B( Y, ~6 A. W3 `                 return '>';8 }* X; s& F2 j  h4 Q
             else if(c=='('): o/ l6 T* c4 `- n6 j- G. e
                 return 'E';+ q" e. [  W/ a: c
             else if(c==')')* n: o5 Q; V% K) \5 ]2 X  c7 p" w
                 return '>';1 K/ \6 D$ M1 @3 X$ w
             else1 G4 L4 ?0 r4 A  _4 m
                 return '>';/ l6 @: c# R1 M" p  E
        case '#':; S* U: {. M3 V. Q2 h6 b5 N" O
             if(c=='+'||c=='-')6 _; d5 Y% o0 T0 S& {. K
                 return '<';: I' k, j8 t5 i8 \8 Z/ ]
             else if(c=='*'||c=='/')
: D0 ]' n% _3 z4 Q! X* d+ g% U8 L9 w                 return '<';
/ P' G% D% P* U1 n! N( [' w7 v             else if(c=='(')% z' L% u" h* l3 s& E. S' A1 _
                 return '<';% T7 }: ]0 f) i1 v' Q8 k
             else if(c==')')
6 g2 e4 \- b0 R                 return 'E';8 S  J: ~" z* E: r. G
             else, D' s6 Z5 r) I! ?! F- t
                 return '=';
3 c1 B- ~# M' Z. Z        default:& ^- Q6 U$ C2 M) f1 Z3 m
             break;
2 y" g- B5 W4 T3 T$ j    }
9 m& F+ ~- B7 N3 F) _0 c$ ~    return 0;    1 W. s8 o2 A( ]% V/ {8 R2 _
}2 M$ M; S' h) J6 N

" J, I8 e' w# w9 b/ n' Qint isOpr(char c)
+ Z3 A# A, j/ e# E% i+ ~3 J{
- k0 `4 E. O- h( O4 l* L- H! V7 a    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
2 E( ]0 t3 ]3 \+ B4 A4 \5 C2 F) h        return 0;
+ b+ C9 e1 A' X) n% O  A    else
/ r: t4 i: l( J- r/ T, P        return 1;) n6 ~- r6 I8 E- L  r
}
" ]4 J. y3 P$ M7 \  s7 ^, }4 j. f4 t- M0 ^
float operate(float x, char opr, float y)
9 {+ k0 z& W/ ?, `+ a8 Z{
: n- C1 x# s: n' ^2 N2 T    float result;6 L% X& A4 y# U/ r, b4 R& [1 j
    switch (opr)
* p+ _. p- ^" l  z; O( w& v    {3 a: \2 E6 F  d& S; d4 v+ R
        case '+': / R4 M, G5 X# V( p2 q1 A# y5 W' q2 G
             result = x + y;3 [% e! S3 ]2 B& L% y
             break;
- G' T3 x0 c, N; E        case '-':   [) g0 v9 Z  p+ _2 d
             result = x - y;
, t6 s: \6 m$ q             break;2 v. C# k* R1 l& T
        case '*':
0 V7 K$ o5 @5 ~1 t, s+ @5 k9 {) W             result = x * y;
) y: O; D, ?3 |4 P. Q/ I             break;
# J) I2 Q/ ~0 T( |        case '/':
) v4 l- X) S. z# m             if (y == 0)
2 h2 f5 V) ~0 i( r* Y             {3 a, x1 N) B1 q! L/ {
                printf("Divided by zero!\n");5 g% f( `% X; {0 R5 N) x' a& h
                return 0;
1 `1 q  `  R9 `" b! T             }
9 \2 T- C: m" G) _! W2 \8 Z             else  T$ c3 T, d& B6 \5 K; Y
             {
' t7 C. d1 c2 P+ u, B                 result = x / y;
2 s% s' F( m  c+ k0 n7 f: j                 break;0 A4 s& Q/ {: s% h+ \
             }0 i* _* M) a+ x2 s% u, z* Y1 p$ s" C
       default: 1 v. e' t' F+ R& r' j
             printf("Bad Input.\n"); - V7 M% L4 V* \5 z) H3 r: R
             return 0;
  q" w3 s" ]* F1 l    }7 {4 H9 U/ i6 t( X
    return result;1 U; P; F6 E& |: ], E  \
}   
# w& o' X6 K, j9 ^& s2 J
9 S: `' Y* g: b5 B7 lfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
) }3 T3 O" x5 `" D$ ^, ?4 ?; p{+ F5 \7 C# x; u5 O) ]# @
    Stack optr,opnd;0 @2 S4 L: T6 q* C+ E& Y" H' P9 X
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
+ k; F# \$ N9 P    char c;
  B( l2 R4 k4 O. P: F2 r2 ?    char buf[16];& O$ f7 G+ M+ g$ d+ d
    int i=0;
% @' H/ q! @; p1 [( Z2 M& b3 p' {4 A   
: t5 I  D9 W3 \4 F' ~    InitStack(optr); /*用于寄存运算符*/. E+ F/ W0 U+ Y: m
    InitStack(opnd); /*用于寄存操作数和计算结果*/% n- k, h5 R/ O) G$ J
    memset(buf,0,sizeof(buf));% @4 U  s  R& ]# E, m* X
    6 |5 u! _1 E( ?% Y
    printf("Enter your expression:");
& ?% O+ `- d- L0 ]3 r3 h        * z' H) Z+ Q" w* \8 u
    opr_in.ch='#';) o1 @; ]. k( K3 z9 w
    Push(optr,opr_in); /*'#'入栈*/
7 C7 L: G7 d7 ~' z. i    GetTop(optr,opr_top);* Z0 T3 u  U: K5 S. ~- y% N% H
    c=getchar();  \# t! e8 X' U/ T; a  Z
    while(c!='='||opr_top.ch!='#')+ S9 }; J" n1 M
    {
6 _/ D; N6 o' N        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*// L9 K. n" W$ x" X% |2 T. r
        {
6 m# S, i8 ^, {+ U$ J4 N            buf=c;5 Y7 [& p* x1 C3 Y4 F; L
            i++;8 [8 {' y, t2 }6 _
            c=getchar();
& k9 M8 G0 E! j! \6 |        }) ]. M- u" t- g# V* T- p) c% p
        else /*是运算符*/$ x( I: e( }5 i0 p- q- X0 A! w
        {# d9 p) Q, |  [' L- u5 Z
            buf='\0';
0 F; [, W3 p$ J            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/* {* d+ H- ~* J2 G2 q+ K+ R3 u
            {
2 R. o  j) U* [$ Z9 m7 w2 j& H+ I                 opn_in.data=(float)atof(buf);6 l: T3 O7 e6 p3 Z
                 Push(opnd,opn_in);8 [7 k8 A* g6 A0 ?
                 printf("opnd入栈:[%f]\n",opn_in.data);5 q) O( o+ |; y7 \
                 i=0;
' l5 u  x3 K3 J9 m- O7 T: r                 memset(buf,0,sizeof(buf));
+ y  n* b5 C8 ^8 U% [7 |' ^$ w            }% X6 C* q! ?7 j! t6 T; z2 P( x
            opr_in.ch=c;2 F) m* B' h* r) ]' Z$ @# X
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
" g- N0 [' ?# J            {1 w+ A* z" ^. g& _( D8 i8 Q
                case '<': /*优先级小于栈顶结点,则运算符入栈*/' [6 H1 w6 E$ B4 t+ s
                     Push(optr,opr_in);
" q$ s, C$ u: _$ p6 K- y' e8 O, Y                     printf("optr入栈:[%c]\n",opr_in.ch);4 [4 N/ S  t3 z! N+ b
                     c=getchar();1 i$ S/ x: ]4 U2 w4 F% \, J
                     break;' x0 |* Q- u/ f+ t' g
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/$ Z2 d$ E+ ]& y+ p: x
                     Pop(optr,e);
% X9 i+ h/ m0 R0 s( s                     printf("optr出栈:去掉括号\n");+ g$ E/ E: V% }7 a( X
                     c=getchar();
0 L. M) b/ E1 j; C+ k                     break;
" u. |4 A8 [! K7 W) ]                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
% h8 t+ K7 ~$ ?7 P                     Pop(optr,opr_t);
6 P5 m" I% C; v% }) _                     printf("optr出栈:[%c]\n",opr_t.ch);. U- ?* J1 I9 b# c$ u: M# z3 ~
                     if(Pop(opnd,b)<0)
# ]4 n$ ~6 j' r                     {
; w& E8 D4 }( I" p5 d/ n* ^: T                         printf("Bad Input!\n");
: b' A2 C7 I- X                         fflush(stdin);
/ J' b% ?# V3 j                         return -1;& h; q9 ^! l* |: z! z8 n
                     }8 E2 y' n5 Y9 [) H, P8 u
                     printf("opnd出栈:[%f]\n",b.data);4 l  b8 q) \6 A# [1 K$ |! @1 N6 n" K7 s
                     if(Pop(opnd,a)<0)
- C0 Z; B, s  ^9 Z  b3 ^                     {
! S  |% U& I7 h2 j- x) I2 R                         printf("Bad Input!\n");# Y2 S3 H( o' g2 l" M  |9 i
                         fflush(stdin);
0 \- k1 t7 [- B- e# S' y* F                         return -1;2 O2 M: b! A1 T! c  R* T
                     }
8 t/ q+ F6 w) W% {- {0 I! l* y                     printf("opnd出栈:[%f]\n",a.data);0 m. Z1 O" w' M% O' S1 ~& |. T& H
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
! V+ x! {8 F% z! O6 V  W- ^  \                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
4 Z% g; U9 l% m) k8 Y                     printf("结果入栈:[%f]\n",opn_tmp.data);
9 N+ P/ h) z% V3 ]+ S1 R                     break;
2 R' q7 g2 V$ ^" a7 N+ m( J            }
, M( t( P. A( c) I0 n        }
, y) V5 ?/ `; A) H# x        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
/ d5 S2 @0 j' y    }4 U" U  f+ c1 b1 U
    GetTop(opnd,opn_tmp);3 n5 ]3 y( R1 X# }$ C
    DestroyStack(optr);) E) U; |2 H& K& B/ _. Q4 b
    DestroyStack(opnd);7 m& {# C. z; ]
    return opn_tmp.data;) V* s, {- E+ ]/ j4 N; c6 {
}9 b; n2 |% s3 b: Y/ z: c5 ]+ }

6 @6 K4 c7 ?$ o+ Z4 Fchar *killzero(char *res,float result)
, f: E/ n- i( L4 |$ S{
& \* B5 F4 K7 [    int i;
  o/ Y( J+ ~; I( }' {3 w# L  g5 J6 X7 [  v4 D" S8 _
    sprintf(res,"%f",result);9 E, Q2 L: p0 P6 Z" e8 m8 H! T1 i# m
    i=(int)strlen(res)-1;5 a" G: Y1 J( Q" `- b" c! j
    while(i&&res=='0')
8 H$ `; J$ }4 g; h0 p* |( {' c( ]8 ]    {
3 R8 W* p# ?- H% H4 Y        res='\0';: o$ T4 F, H) A% }
        i--;5 Y' U: Z% [8 u, R8 }  V
    }) E, I; V: L1 N, U
    if(res=='.')% e; q) X& V4 l
        res='\0';
6 `8 F) {" {- n    return res;9 [  s9 P+ W- ^" X" U
}
% ^$ ]+ k, x8 H  S
! i+ I9 N/ A4 a2 lint main()
+ m# R; A! V* Z{% i* h) _% c7 Y5 ]
    char ch;/ H& q: f9 m" L  _6 X7 a
    char res[64];7 n9 I$ W1 G( S* R. i/ U; m
    float result;
/ G7 y2 l2 F! S    while(1)! ]3 K( l7 s+ R
    {
/ F/ U! c: y! ]! J% k        result=compute();. J- M" p2 [" H
        printf("\nThe result is:%s\n",killzero(res,result));
* I$ m! \4 _* A        printf("Do you want to continue(y/n)?:") ;
; L* V3 A9 q# B; y/ r* Y        ch=getch();! U( p2 y! c0 q6 H0 @, q
        putchar(ch);4 a1 P# A1 d6 y) }( G  i2 Z- b. f
        if(ch=='n'||ch=='N')
- b# z* b4 G1 ^* `$ j; k! W; v% {            break;0 x* g8 E  S' D' m+ H# g
        else
% c, {  g* _/ `3 L0 c            system("cls");/ ?1 @. W* j! E% r- K
    }
* u% U' i2 a3 j& f1 m    return 0;
( u& ~6 E2 L( e0 v# O! ^! Q# g}
  H3 |# u- @  `7 }0 q; i* p2 O/ U

8 k- v* i3 ?8 g[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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