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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
- L9 f" G9 v( g! p  f$ P0 o程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
8 V; e' d! x% }$ f) m9 \/**************表达式计算器************/
/ l' W; O7 H# I! w8 o#include <stdio.h>
' M7 p) [& m# R2 `' O. z4 @2 {#include <stdlib.h>
& k+ W3 w/ B2 k- j  d! e# p3 x#include <string.h>; a  p5 }6 I2 d1 t" G
#include <conio.h>
) e# S/ ?9 y. f7 N0 ~- `9 Z#include <malloc.h>
1 X  }. T, ]9 D4 c
6 U1 {. f8 p8 d/ Z# [4 k6 R#define STACK_SIZE 100
7 f# K" `$ K" }( }' ~#define APPEND_SIZE 10$ J: P; T8 e) r! |4 F( S  ^
' A4 B$ `# y$ O  ]
struct SNode{6 q5 X7 `6 C' x! E8 h6 A- L% I
    float data; /*存放操作数或者计算结果*/
6 h9 _4 n$ E# E& t5 y# [7 T    char ch; /*存放运算符*/
; r% I7 y4 f5 m& [};
# a+ m0 W& d, x+ t) d) c0 [2 e  i% s7 z2 m
struct Stack{
9 J; P7 k5 j9 v! s7 n8 u4 T$ }    SNode *top;
7 H( W! T& v  Y/ ]  `    SNode *base;
% e  q$ I, E7 Z4 l+ t4 O9 ?    int size;- X2 ^) ]7 L& z0 Y4 x
};+ M6 D- m; P* G" i# C$ ^+ L0 r6 J

$ W, \9 n2 x8 ^& d& V- l1 Q8 _! Q& o/*栈操作函数*/
/ l; z/ x2 N' vint InitStack(Stack &S); /*创建栈*/# G; U% T; p' o  a! i7 N
int DestroyStack(Stack &S); /*销毁栈*/7 W! D4 d9 Y2 K$ ^; c. i" n3 Y
int ClearStack(Stack &S); /*清空栈*/
, u' c; f: U! j5 x1 A" p% [int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
% o" D( }4 [% M3 J' N# R& Xint Push(Stack &S,SNode e); /*将结点e压入栈*/5 _  ?5 b% ?3 h7 v& d
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
; g# W& N2 D$ Z. t& {
, W1 i. b) [% o6 a+ `- m/*表达式计算器相关函数*/
3 Y  ]7 x9 l5 H- v" g% u/ `# uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
! ]/ B( ?0 f% p' o( o  fint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/* G$ c! F  W: j2 z2 X- ?+ k1 `* u) q
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
4 N5 E1 n7 b( K, p/ afloat compute(); /*表达式结算器主函数*/
, k2 B! ^# n* F8 U9 i+ |) O1 ochar *killzero(float result); /*去掉结果后面的0*/
: N  m+ \; i/ M$ u+ n$ L  A2 _' @) ?9 g* G/ e1 `
int InitStack(Stack &S)
0 g4 w# M0 G0 l; U/ k{6 P5 q! C( r# B9 E# }# [
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
3 E. Z; p) n5 |1 T- i4 |    if(S.base==NULL), Z( f3 ?6 j7 g% N* E
    {; a9 ?9 y3 E* {
        printf("动态分配内存失败!");8 k6 K! l% Q" ^5 n4 f% G6 [0 E
        return -1;
/ ]3 F) f: g0 O% M7 y% L    }
/ O4 V0 S, ^5 d& X: \    S.top=S.base;
3 A2 q& L0 T- t0 Z- D2 x3 o5 n    S.size=STACK_SIZE;
* U+ l6 ~0 r# I* }- L* o- j    return 0;
& k$ M/ h; g0 R6 h' P& Y$ X5 y' n}
/ L. v" _! ?% @  w# ?! q  w
% u) s+ t( e4 tint DestroyStack(Stack &S)
) @5 e4 b2 M: q0 z; R' l, c{+ T! J7 ?' _* }# R2 w9 z
    free(S.base);
0 P% e. W& D) Z* {    return 0;
0 b' V- O+ \3 g9 V3 g# r}
. d" _' @' A& g& H
. v7 z/ Q; ^) Dint ClearStack(Stack &S)
) n+ g$ q5 Y9 _" B3 ]9 [{7 G2 q8 {7 z) c* Z$ D$ H
    S.top=S.base;
- `. t1 k0 C# D) T% S7 z  D    return 0;* U5 Y% W* Z; f* {1 g( d3 t
}8 C  W3 A( x$ v1 Q8 n" n

" B6 [' J) y" mint GetTop(Stack S,SNode &e)
+ E/ O8 k2 i/ b& ?+ t# W{
7 z  m. X. Y4 q# n! A( h# y8 N    if(S.top==S.base)& S' S3 D2 V5 [  y5 O
    {: ^0 C9 `2 z$ F( X' L
        printf("栈以为空!");% k7 p" @  l& B7 w
        return -1;
: L% M2 h1 {' v8 O; D  s# C. d    }/ D" l$ ~4 W" Y5 |- g
    e=*(S.top-1);  Y2 h& K% L. V5 j7 s
    return 0;
% F5 [9 v7 n" H2 M$ a" I/ \/ M}% @$ p& C; R: o5 I; v
/ n# @' p( }: u- m9 O3 Q
int Push(Stack &S,SNode e)
+ n3 u+ B3 [) z6 ^{5 a  [: B% O- ~3 p, {" `; Z
    if(S.top-S.base>=S.size)+ u' n! C$ R$ u6 D, k
    {
, r9 e4 h3 b' ?0 u0 k: C        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
  ?9 R  f- r/ d  b9 d        if(S.base==NULL)
" Z6 k4 ?3 \# q% |+ X        {
: A! O$ v* b/ R% S, ~& ]            printf("动态分配内存失败!");9 Q9 u7 Y1 @8 |* r2 T: k
            return -1;
) j$ s, }% r# i/ w! {        }; \6 L% J( T. m" h* a9 ~
        S.top=S.base+S.size;( e$ v! b% |' ], y  J% `! i
        S.size+=APPEND_SIZE;
+ F( r2 y) [5 [) v1 v    }4 a: d0 {# N4 [, r$ F
    *S.top=e;  `! B4 s( [9 O5 I& ^: Z& p$ }. e
    S.top++;
) F7 a4 i% c. n9 a: L( P" x    return 0;
& t! t' W" {8 `- Z3 O9 w}8 a* K' h6 }# u  a9 F' M: }' \

8 a2 d  r5 M9 Kint Pop(Stack &S,SNode &e)
9 T& {* u# `5 i{
9 Y% T+ T& H7 v$ {2 M1 w  _    if(S.top==S.base)
- d  u( }/ h! _, _" B; V    {5 t: x% K# M; U' |0 S% l( U
        printf("栈为空!");  R# v4 _8 {$ @  a) d; v
        return -1;
- }+ C& f" S3 }; C1 ^- X8 [1 Z    }
# y2 ~& g7 N0 z; D6 g    e=*(S.top-1);
7 Y1 l- H: ~, j% T    S.top--;
( O1 s; t9 ?6 `9 i6 |9 M    return 0;
6 d. @! w8 w( x7 b) z}, L+ O/ C$ H$ `$ U8 J- _
# ]* p( W/ K1 D( |
char get_precede(char s,char c)' O: O, ^: v9 X* C
{
& T+ r, v1 i% ~9 u# @3 y  B    switch(s)9 B) n) U' d# f+ W% N! l# V
    {
7 Z: N1 H, `- e* N  R6 N        case '+':                 % j$ s6 W9 D7 T- f# v5 f6 W
        case '-':% l7 N; p2 r4 i
             if(c=='+'||c=='-')
/ T/ V' C& I" V; H                 return '>';7 L' Q' q$ z3 t
             else if(c=='*'||c=='/')/ I8 N+ x3 D: d; P* S( I; ^2 t
                 return '<';
6 K( p, {0 X; v5 Q1 a7 `# u) C4 P             else if(c=='(')9 }5 \( \; V& R  K
                 return '<';! T8 v2 R1 J8 @" a# I
             else if(c==')')2 h% E) q, f- B
                 return '>';. O3 Q% N( }2 z+ D3 B" r5 g
             else   A8 g+ U3 ^3 k; I, s
                 return '>';
+ [# Z, `# a5 r        case '*':
  W2 J# q/ {% d; M/ ]' p( k& w2 X        case '/':- N6 S/ u; M5 d% h! I8 K. \
             if(c=='+'||c=='-'): V+ @- B* V. _4 a- m
                 return '>';9 t5 x6 e, S( I6 Y
             else if(c=='*'||c=='/')
$ E! {/ a- g, }: b                 return '>';
) ]5 `+ C" {( _* Y             else if(c=='(')
: b2 Q) d* P# b; M4 E" {                 return '<';
% a1 n* o. I8 d) Y! R2 T6 a             else if(c==')')4 k+ L# ~9 r& a9 N4 j
                 return '>';
3 B4 u! ^& H. g9 N+ G9 F             else' s4 }/ S  M4 E& Q" O3 c# A; `
                 return '>';
- D1 h0 S) y2 U( ]! L% m" S        case '(':
/ W+ b. |' o! H* ~4 z; _* H             if(c=='+'||c=='-')$ O0 D, S% ~3 K# ?$ g
                 return '<';6 l( ^1 \' r& ?' x: d% d1 m; C# W' Y% f
             else if(c=='*'||c=='/')
1 i$ l0 r! l, M1 o5 [  y" z( v                 return '<';
! D  S1 h2 P0 o/ ]! Z             else if(c=='(')' K3 N1 F6 G7 Z1 W4 F* _
                 return '<';) ]* C) j4 p7 b* w
             else if(c==')')
: V3 |3 _* V- q# G, {5 v: ]                 return '=';# @! j  A6 [% I- p* C1 D: [9 D( a
             else) _1 @% W6 x0 J& K1 {6 S) G5 E% c/ p- V
                 return 'E';2 w8 ^5 A% }; E0 v
        case ')':6 o( t5 A, {" j* f7 r* J
             if(c=='+'||c=='-')9 U- h& q2 K! [# M3 A2 f+ U0 f
                 return '>';7 J0 ?9 H* t! Q( a+ L0 \7 x6 ]
             else if(c=='*'||c=='/'). {4 v' Z0 m, G8 [
                 return '>';
' @; J4 u1 F2 v6 M% m/ B             else if(c=='(')
9 Q6 R  b. m! M6 Q1 ^# I                 return 'E';
& ~# `+ r5 y" t* n5 [4 Z& K2 [             else if(c==')')
* m7 g0 ]) b& ]" R! \- Q$ P                 return '>';
& H, ]1 h- h& F! L; _( p% K             else
  S5 G2 c7 b* t% `' c. V( d7 O4 e6 _                 return '>';4 l6 f2 f( w9 Y) p. l5 l
        case '#':/ @$ n! o7 t/ w6 d9 E% g. F
             if(c=='+'||c=='-')
/ o. o: R/ X2 }$ L9 o# p- U0 l6 O5 K                 return '<';
7 ]5 ~$ R" h- C3 t, ~             else if(c=='*'||c=='/')) {, J5 K1 [# d7 i
                 return '<';# I. n7 f9 c' P
             else if(c=='(')
6 K/ f  @3 s3 U9 x- u' H, M4 Z                 return '<';- {9 v' |- |0 w* ^; M, Y, I, @6 j
             else if(c==')')4 x- L6 b3 U' [: Z5 b9 o$ R
                 return 'E';
& h  G( M2 {; D5 E- ?             else
* x1 q' ~0 ]% U5 R, i                 return '=';* h( I0 I& E  P
        default:# s5 t8 ~# J3 c, ]5 k. s* J: o: d
             break;, n3 @3 o* ~  p0 w4 s/ s  I
    }5 G+ B7 y6 F7 _+ }* b- ~! U4 A
    return 0;   
8 U8 ^0 V! g8 u}
& {9 w% w' P$ \- N3 G9 Q& F6 N7 H8 t2 V$ t0 I
int isOpr(char c)
. ], s3 G; H. @0 ^/ q{
, N6 l' E. ^2 `$ ~    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')8 k7 f  ^1 V0 v
        return 0;
+ g: u5 c9 {1 M  S" `1 X    else
( W0 S/ }  Z1 [) r9 U% f        return 1;
, |6 Y- R6 ?  j2 e; J) w% P' @}
/ i6 ^( p% F; b3 h' H% h" o9 f0 b6 r$ {, H4 N: p2 u4 f0 y
float operate(float x, char opr, float y)
1 I9 j4 g( Q. f& h{
) ]3 s) z* V; w9 O    float result;
  e: K, t) d- @9 u. c    switch (opr)  C1 l3 p% |( K) T; U) w0 ~) B
    {' c% L9 C  {' e
        case '+': 2 A9 P- W. @) c: r% Z; d7 c4 k
             result = x + y;
( `# {  U3 O/ {5 ~3 B8 `3 M             break;) ^# b- u: _/ i, _& J6 E
        case '-':
9 u8 x9 h0 _- u' N             result = x - y;
4 M' n$ J. U3 A/ ], R9 I             break;
! C, i& s& N# G9 C        case '*':
7 ]8 f  W  A" s% |5 v6 a: Y             result = x * y;
- z  K+ a) E" D3 ?0 \9 E             break;
: ^7 [, b2 k+ {- b2 b/ j        case '/':
. W5 |- O  F: J8 Z7 J             if (y == 0)4 |0 c" }  i" x) M( H3 h
             {2 D4 ^1 M. a1 q; z( y$ S" N
                printf("Divided by zero!\n");+ Z; [/ p/ H0 G
                return 0;
7 ~) A7 ~2 s  r$ l             }
: |% n8 Y) D0 Z7 Y8 V             else' x% }, D& n7 \8 Q0 n( E
             {
/ g- s6 v8 c1 `7 G: ]                 result = x / y;+ v7 Q3 d- e3 c+ j) }4 b0 |
                 break;
! g9 J0 C5 \, O8 z             }" B  d) U$ @" P$ }" u; R) k
       default: 1 J* Q6 a) o( Q
             printf("Bad Input.\n");
, d& l( _# A: P  A             return 0;
' P4 L1 \; _- r* G    }
2 M2 o5 g. S% g  q    return result;
7 g9 D, L9 N; W0 }}   
2 f" B% S4 t  g9 ]' ?4 b7 @) k
# {- ^% J7 ~5 I: c% R  m: hfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
" b7 l- }) G4 k1 U- M{
5 o/ `0 n! P+ s! k- O    Stack optr,opnd;- P2 r2 L6 E( b
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;& z) [1 l0 r' G2 F+ I1 J/ g& h
    char c;
; B& Y# K/ g8 n5 `    char buf[16];
( l& r4 Z  X; d    int i=0;5 u3 J( I0 f9 A, h; E; P* ]
    ) ]) z9 H! _& J4 e& ^7 I  w
    InitStack(optr); /*用于寄存运算符*/# ]) J7 k) Z- o7 Z3 ~" M( ?  h
    InitStack(opnd); /*用于寄存操作数和计算结果*/; g( j& s6 n4 F. N0 X' |- ]
    memset(buf,0,sizeof(buf));
. |5 {9 J) }" \( d+ }0 \2 v    0 Z# {/ ?; P& r( P1 l
    printf("Enter your expression:");
9 K: D) l5 K  T' A9 a' Z5 B        " w2 g  d1 y0 A+ n- ^; g
    opr_in.ch='#';# ?: T# h1 D# A
    Push(optr,opr_in); /*'#'入栈*/
4 u0 K5 y, o+ [3 r    GetTop(optr,opr_top);
. Q9 V$ K/ Z7 i9 V$ e* g# |4 }4 L    c=getchar();
" k2 w8 B. K) G    while(c!='='||opr_top.ch!='#')" m' F/ a- _$ ?- d
    {% \9 m: T- U& O& L. [' g
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/$ Q* I) u- c" I; a
        {
& j8 ], H. C+ ]            buf=c;! R+ x: P; m7 P! ?# u9 ?
            i++;
5 C- n! y  [0 A: y& U. p            c=getchar();/ S* Z2 i7 @- [3 e
        }
# l, `$ t9 L, l8 c, s- C        else /*是运算符*/2 T. S9 e9 j( a% K9 G+ W1 y
        {% C$ @3 Z$ w7 m& @, c
            buf='\0';* U& [3 J! c& R! v
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/$ G. m- C. [( g0 ]
            {
: y/ x0 v4 s! _# y  k                 opn_in.data=(float)atof(buf);/ A2 A7 y. e7 q/ G) J
                 Push(opnd,opn_in);
+ L) o, N/ ?9 r2 u                 printf("opnd入栈:[%f]\n",opn_in.data);
7 k+ T+ _, M8 u                 i=0;% H6 @- P+ c6 x' m  q7 `, [. W
                 memset(buf,0,sizeof(buf));. I4 ~6 s+ u3 V" n: {. O% k& V
            }) I; L* O, q6 y* ^
            opr_in.ch=c;: S8 b* R: k6 ?+ I" v7 k$ U
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
+ E- D" Y  Y3 e* g+ U3 C            {
( Q# y) f* T3 S  P3 d                case '<': /*优先级小于栈顶结点,则运算符入栈*/: S) A1 k- u1 q, A) }
                     Push(optr,opr_in);* z4 w5 p1 }* X! T$ o  w" c8 {
                     printf("optr入栈:[%c]\n",opr_in.ch);, x9 z7 W" u# A. Z. C3 k4 q
                     c=getchar();  s; l' O5 p& i/ M% e( d
                     break;
' c  d0 m9 g0 M* x) W# T                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/- [7 C5 z: S& F; D2 ]! y" T1 R
                     Pop(optr,e);; Q5 x1 ?) p4 _/ r# V
                     printf("optr出栈:去掉括号\n");
0 i( ?. {  R( L) b                     c=getchar();3 O# F$ h) t5 O
                     break;" h0 ^" g" f2 C6 b* t4 k8 x3 v
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6 p: @; r& U5 X( ?8 t6 T, g8 X% s                     Pop(optr,opr_t);# O+ B7 ^; [) u
                     printf("optr出栈:[%c]\n",opr_t.ch);
' \5 C8 p0 ?6 \$ J3 v                     if(Pop(opnd,b)<0), Z" g0 M7 K  u( s/ f
                     {
8 J2 H# d; c1 H, k5 t! a- B                         printf("Bad Input!\n");* H: K1 {) R! x
                         fflush(stdin);
0 R, Q: z: x% m& K9 {, z! C                         return -1;* W5 Q, r, f8 g- y# P
                     }
. p- A; X* T+ B                     printf("opnd出栈:[%f]\n",b.data);
2 I2 ?; T- }; J) l& S                     if(Pop(opnd,a)<0)/ B( Y4 m1 n) r# y; O! {$ f4 D
                     {6 M0 Z# ]  X  Q; `1 j4 h
                         printf("Bad Input!\n");" X( `, n5 ^" x# s+ ?' u6 r5 \
                         fflush(stdin);
4 R- E: C  `/ s) _1 m! u                         return -1;
' p8 {/ t& m" h" `+ R                     }
( R) Y* l; S; b* f                     printf("opnd出栈:[%f]\n",a.data);
/ a, ~4 N0 J0 c; b                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
+ C9 x/ L$ U- N  `' m                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
$ D$ r- J( f' T- M1 e. l5 `/ t                     printf("结果入栈:[%f]\n",opn_tmp.data);
( L0 t( _3 `3 y2 e+ U                     break;
/ ?- i* m  D8 G/ @6 H; p            }
8 b  b5 K8 E. B5 t& O9 U        }
) W5 F( E7 q; V        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                6 l. n' p! X# I$ ]; y3 m, f0 q/ Q
    }+ W. K# n9 P5 r4 M' l
    GetTop(opnd,opn_tmp);
7 \2 \  n+ n" W" v4 K5 N% E    DestroyStack(optr);
- r( l+ j/ Q' f    DestroyStack(opnd);4 b5 D, u" t4 K1 _; J/ f4 ~; R& g
    return opn_tmp.data;
, |2 m8 u7 H0 f9 F7 z4 R* i% C: g}
1 e  F. Q& Q0 `1 T. ^
5 I: G, l) `& N1 [6 n/ }2 X8 ^) I+ nchar *killzero(char *res,float result)
) j5 g" Z  e# u  M$ s8 Z" N{- a$ ]  n8 d; V) i
    int i;- G- i7 `1 ~- p
4 g& U" V" Z% _6 B8 X' D0 E
    sprintf(res,"%f",result);
3 R8 t& w* {4 Z; J  t9 B& f    i=(int)strlen(res)-1;) V( n, Z% U+ s5 i) a0 x" x
    while(i&&res=='0')
. S* A0 B: F& P7 y  ]    {# Z2 U6 w* s# B
        res='\0';5 @! L5 U0 }' Q6 O( `. E7 L
        i--;
3 L* a$ p2 N6 U6 G; H0 n5 t    }
" z: t  |. ]- d9 H% b: P    if(res=='.')" C( g  k0 I0 V/ j% ~
        res='\0';
0 ~- R, T3 {/ v5 x" y    return res;, Z( R: n- a/ g
}! y1 l8 V: @% v" g

" D% x# L3 I& N/ x' K2 K' fint main()% q- L4 _  P+ n4 J, A
{; Q  t5 F) b+ [+ }1 C9 S" G* W
    char ch;
. K! q- o' v6 O: Z    char res[64];
4 k/ v. t: n9 d( ~& w    float result;
( c( @2 b. R. y* L; o; s    while(1)0 U1 }5 t: o8 k. `
    {8 Y$ t# I2 t6 {2 p- m
        result=compute();
5 ]  P3 R- ?, h! X- |3 v$ e% k        printf("\nThe result is:%s\n",killzero(res,result));
$ m: Y& J& c; [        printf("Do you want to continue(y/n)?:") ;
: i" {) A; N) |0 x, A" r        ch=getch();* i# Y# G- a  {/ `* J7 ?# e9 D  E
        putchar(ch);2 }* ?: a! P4 a$ ]% i( z" E/ _
        if(ch=='n'||ch=='N')
$ ^  L6 d9 X9 E" v, a3 U            break;3 Y% }( C. J% j( v
        else2 R% t( N; t- n9 q1 y2 N
            system("cls");
% I2 i/ m" s, A$ K, R( K* H1 @2 T( E    }4 [1 a* o4 l& q3 \# H& z- k1 G* T
    return 0;
2 ^( T4 a5 Z. M* k( U( ]}
4 P  N' R4 B5 y" t( T+ m

7 f6 q( x5 f8 [! S# ][ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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