返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.5 m8 v" F: o8 [/ X# h* G
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=' j4 C, d5 B, B* ~+ j1 F
/**************表达式计算器************/
1 R. |4 ~6 b0 B7 s#include <stdio.h>
' M) b. M( ]+ o1 W4 X#include <stdlib.h>- R2 U' Q% P" Q
#include <string.h>/ z. M0 y6 C% P8 N4 |
#include <conio.h>9 W5 C7 e) {3 _3 |/ L8 \
#include <malloc.h>
! K  _/ g5 U$ |' U& d% m( M
1 Z1 h$ n- y/ G  d' l#define STACK_SIZE 100
' Z& F3 c& C4 V) R7 |9 P#define APPEND_SIZE 10, N- p/ ?+ x3 w0 m, v6 d$ a

$ M8 C0 {1 Y+ E4 F: }. Y3 ?struct SNode{
$ D1 a- V. k* I& h    float data; /*存放操作数或者计算结果*/) [3 Z1 a  Z) w# W  C5 h
    char ch; /*存放运算符*/* A6 h$ ~( Y- Z' {' Q# D& S
};9 `* \  h/ Q9 _$ {; X

) P7 b  ~* `; A6 w9 v, Cstruct Stack{4 I& ^" h- K# {. v3 Z4 D+ r
    SNode *top;
1 C' B( B7 B3 r) }3 |* k- B    SNode *base;
6 `1 M0 W3 L' L; f3 s+ @    int size;
3 E0 j  C# Z3 T5 M$ c: {};
, E* n2 N" _+ l
. _4 _9 W$ g2 b1 g  q/*栈操作函数*/3 Y1 {: p- A+ E9 \- n# c
int InitStack(Stack &S); /*创建栈*/
- w2 \. ~0 r& V' v+ ]( |int DestroyStack(Stack &S); /*销毁栈*/( y0 [' ]" ]) T
int ClearStack(Stack &S); /*清空栈*/
3 G- z, d! M4 u, H- z5 u1 dint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/7 e% S+ E( v7 O$ V* V
int Push(Stack &S,SNode e); /*将结点e压入栈*/
( l* f. U" O7 f2 _5 O% Hint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/) b! y9 |% m) T2 u" B

3 k) \+ L/ B4 K2 s" O, x/*表达式计算器相关函数*/
* e) Z% u  f( _9 ~, Zchar get_precede(char s,char c); /*判断运算符s和c的优先级*/  z# O! r% t9 i6 z4 J1 ~" x
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) y/ h6 |+ y; k7 Z+ Q- ~# k8 {
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/6 U( k; y9 Q" i9 A/ q. @
float compute(); /*表达式结算器主函数*/3 Y2 B7 _! A; y2 [
char *killzero(float result); /*去掉结果后面的0*/ ! ]: n: U7 b+ l. P) V, q2 Y

, P& i  w: ?$ D& d( Vint InitStack(Stack &S)
+ p. j2 j; d0 V* g{
* H8 O9 J0 ^1 X) n8 c    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
; u  ~1 W+ |8 W    if(S.base==NULL); A6 {4 R, A4 E  r( x. i! z  `
    {
& e, }& x+ ^0 H# P. c2 |2 O, [        printf("动态分配内存失败!");
+ [! @9 ?: U& r7 a0 x" \, ?        return -1;
4 X/ g' Q) p5 Y8 {3 b. W6 B6 |" ?    }6 g( }" [9 t, \7 S( m
    S.top=S.base;
" o( J4 S, s; O0 {% I# R    S.size=STACK_SIZE;
/ n! u9 ]8 y- d, f3 `; K7 |    return 0;, F7 `! d. u* x" y
}) ^6 w9 T# ]0 H% a4 E# W" x3 x
9 b" Z( O  X1 r5 s
int DestroyStack(Stack &S)
/ s! n$ I- P8 l: E* E' Z4 t3 V; S{
, l* m" V' t  ]  p    free(S.base);
: B. N% w6 i2 d9 G    return 0;  l; X. s0 T+ p% p$ V; F
}; _" d/ T9 d2 s5 R7 R  w1 h

* j( }/ [3 _4 a7 _int ClearStack(Stack &S)
# M# F+ \0 j9 W7 R{
, l% Q9 H' M0 ~0 @    S.top=S.base;
: t2 O4 t/ K' D; i& Q2 G5 K    return 0;3 @2 B: A$ t' N8 J* ]
}6 F, Z1 p# U# a; U- E" j

- T2 c* |9 h. j; z) ]int GetTop(Stack S,SNode &e)" c; w1 j5 n, D1 k& h% M( B6 m
{% {( @5 R1 q) b3 \$ n
    if(S.top==S.base)- z% V8 L) N, H( I0 J' S4 k! _& l+ i
    {
# n9 B5 T5 Q, F2 Y        printf("栈以为空!");7 u$ `* r3 a9 [; o7 t
        return -1;
2 c6 `( O4 w) e; O6 o    }( z% F: v# s) C4 f& w) U; r
    e=*(S.top-1);
* z; v# l7 L/ K5 g) g3 m$ z- y) S    return 0;
7 ^3 }9 Y8 f( p8 y  y2 U, }}
& O, o+ Z; W7 z$ o7 K8 D0 H4 r$ w) ]* u
int Push(Stack &S,SNode e)* ]. n$ F' x0 b9 V$ P. S, w8 e
{4 A# [" P: ^2 U& J9 P- z1 Z
    if(S.top-S.base>=S.size)
' [* j6 v9 F* F2 a* q9 a- v: z. r    {; W) }( s, l' ?  m; y8 V+ |
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));2 C# w; m8 X# T4 V& {: k# \) F
        if(S.base==NULL)
, Q4 r7 {- X& T* B' @, O        {) e4 M3 g) I+ ]  C. y
            printf("动态分配内存失败!");8 r! p4 ^& O: y) \: j1 K
            return -1;
+ b9 [+ ?, o3 s        }& v. ]9 b& [9 E0 w2 g
        S.top=S.base+S.size;
. B( Z" c9 H+ `, d& ?9 X. S        S.size+=APPEND_SIZE;
7 z8 f4 C+ ^# m- f$ |    }# P0 `# @! k: K; M3 D
    *S.top=e;5 n4 L$ X! b) |- u
    S.top++;
% D. g) G& U; I/ i9 J; [! o    return 0;
5 Z" W2 T! g' x0 n}
$ E! V3 U( t8 H( ~$ ]* y
0 [. z& o4 |$ I: X. Uint Pop(Stack &S,SNode &e); V) v. g3 B, q. R
{
+ ?/ \- ?, e3 f% C9 L    if(S.top==S.base)
* F. w6 E/ ^, R$ r    {
, g' d6 R: ^6 i9 p/ c4 n        printf("栈为空!");; X+ M$ l& c' \% ?/ G! b
        return -1;9 f% x. T3 f4 h: K
    }* R7 \" L- Y! g! {/ r6 J, ]9 }
    e=*(S.top-1);
  X6 _4 S8 x3 H# H/ N- u    S.top--;' w- q1 Q9 ^: g, V( S3 j* x, {
    return 0;5 `& q# u8 m9 J$ ^9 y1 J
}
' ^$ K( m  L% C; ]/ u* h+ G( l2 X0 b2 h2 F9 Y7 m; |
char get_precede(char s,char c)
( B( f# _! D- V- V- d! m{
; S* ?9 Z; x0 ?5 n    switch(s)5 W/ R5 Q. P' P, b5 R+ O8 c& `
    {2 T+ v% r5 [2 O1 H  w3 n
        case '+':                 9 c1 |1 f! W) Q  ~7 r
        case '-':
7 @9 w# J7 W' `             if(c=='+'||c=='-')
0 f, o4 a& ?6 z                 return '>';
& Y  C# A! }2 A6 P             else if(c=='*'||c=='/')
) {. I# c( ^. A                 return '<';
3 o( d. M: T, m, e             else if(c=='(')
. R7 g, @4 H1 E7 D6 z) O, z                 return '<';7 d5 j9 H- X9 E8 q3 Z4 v) F: m; b
             else if(c==')')8 p- E/ p& A- J7 S  \
                 return '>';
2 X* [9 Z9 ^' d             else
( z( I4 F4 Q) M3 F: a& V                 return '>';2 e! B9 ~5 y) M  z
        case '*':( c7 x& x& _, [( r# h, Q7 O
        case '/':
, [/ b# U+ ?6 m; `" Z6 v             if(c=='+'||c=='-')
+ Q$ o" H7 i# M6 s7 C. H3 l                 return '>';
; h! I9 A% y' C6 P0 R" x             else if(c=='*'||c=='/')/ a" Q( c( W% Z9 f9 ?  C3 C; G3 t
                 return '>';8 n8 ], t5 `6 Q" c0 h! _. I
             else if(c=='(')" m. P! b5 T- z& e
                 return '<';
+ M$ F; Z- B7 N& R$ U, E- F) \             else if(c==')')
' ?; A+ o1 i  w; ~  j  @# }$ B                 return '>';2 P. R/ N8 o; E
             else8 {# O) S. p! M7 g
                 return '>';
  a; R' n$ i, h        case '(':
2 n2 m) l. u( p$ [1 q% q( G$ W& j             if(c=='+'||c=='-')
! H4 P9 i! W2 Q! E+ x                 return '<';0 Y! A+ l0 j  x; q/ v
             else if(c=='*'||c=='/')6 {* s4 ^- V  x2 Y* ?/ f
                 return '<';7 F7 s6 K  W4 |0 A: H' c7 Z0 Z! w
             else if(c=='(')9 q# e- T3 @5 d2 i, U; H
                 return '<';
  d  d" E  A/ j             else if(c==')')
" T0 a5 C: \  J4 o' A. m, x                 return '=';0 W: F  D# ?7 W3 j0 @9 q) j
             else
. g( p7 Q+ \9 E5 M" w                 return 'E';
; |( w2 }% [+ y* @/ G        case ')':* V! G; a! ]) E+ e/ J/ F" N
             if(c=='+'||c=='-')
( i- t) ~' r2 F* A                 return '>';: L) `9 m: }; E! J- n- B
             else if(c=='*'||c=='/')
9 @$ O; Z/ D2 w1 w                 return '>';# b7 E2 H/ R8 ^2 Q% [' Z
             else if(c=='(')' }* |4 ^. e: ]5 n
                 return 'E';
$ j% j& `# A/ V! y/ v/ ^             else if(c==')')
, G* y) y- x0 c3 Z4 b5 Z/ l" @                 return '>';
2 {; Y0 ~* ]0 \# h, y9 a  m             else/ }* P# r8 O/ \+ c( q* g
                 return '>';2 T6 z/ v0 I' e% \% v- J* Y/ n
        case '#':/ V6 E% m; }- n) y
             if(c=='+'||c=='-')
. v  Z  g. `* h7 \, g" r2 `                 return '<';% q% p( q2 R: }8 @3 Y' r: p
             else if(c=='*'||c=='/')
; t! e, q* j& L- G$ o+ R                 return '<';
- F! [/ Y: X  ]4 ]: ~             else if(c=='(')+ z" Z5 e0 H! w- W7 S) A& U' {: T
                 return '<';& g) g7 e7 }4 K; |6 f
             else if(c==')')
. i$ A$ f! P: A3 t! R4 q                 return 'E';: M' F( z) {! @, F& Y4 k
             else
, B2 i5 k* F0 j0 U! G                 return '=';" w4 e# d8 @+ s# r4 e
        default:1 L* B% v$ {8 ?$ @" R0 n# b
             break;
5 X2 K1 n. Y! p7 k    }% ^5 w9 \& R5 r. F
    return 0;   
! D/ o. o( k1 k5 a- z  v6 |}
/ [9 \( V* ~# }0 @7 _0 M) i! @0 M' \
int isOpr(char c)2 ^! d$ |$ n3 @
{
3 R- }$ w: d# L# L) l" I6 d    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
7 r2 ~9 @& g  v  c        return 0;. G6 q6 m; u. t0 }1 ]: _6 K, j6 L, f
    else
/ v: o0 h" w6 h) V& t  Q        return 1;
0 e- S9 P* t& A# F5 ^& v0 [}
3 \* g6 a( Y! L8 t1 N& ?
4 [- U/ x* W, G/ jfloat operate(float x, char opr, float y)
8 d4 l. J! n: h+ F3 S. R{
7 K; H2 ^! ]; B) @    float result;
6 Q8 O9 h- U( y2 r9 C    switch (opr)
* C" C2 T4 ?, N    {
: k' \8 k4 K- D/ t4 r5 p" M  d! d        case '+': % S. K5 t( P5 c$ a
             result = x + y;9 S" ]$ l2 E6 k1 m
             break;
* u8 K! ~  N% z. l        case '-': + S7 _* P4 Z( ]$ ^4 ]9 }# d3 s
             result = x - y;6 P9 C3 ]4 x# B- O3 q
             break;$ Z5 G! u) }$ l6 U+ d9 h6 i" O* X
        case '*':
9 ?) x* U2 d% G# p             result = x * y;
& ?! ]% X/ D+ V8 w7 k0 g9 f" C. a             break;% A6 l- b( e  g0 n1 h
        case '/':
& H" r7 l9 m& k+ ]6 H             if (y == 0)
, y' d7 h# j2 N4 N! N             {, G: W0 L$ `7 v! y
                printf("Divided by zero!\n");
) h( x3 t% X' y                return 0;7 S5 A) n) T/ c  X. C! Y
             }: K( G+ [0 \+ y  J
             else' [- [4 i+ N4 t3 r
             {
4 `, c3 [% g1 l- h. `0 }                 result = x / y;- w0 x6 E& W) B4 a9 ]
                 break;
8 {5 V' [" j+ l# i! Y0 Z* \$ X             }
4 K# ]& `/ L2 J# \  _& k8 T6 T       default: + B, Y" w1 f/ O# A8 k3 p" J2 x- f. V
             printf("Bad Input.\n");
8 W6 ~9 N/ h- `1 ^8 r3 z             return 0;
9 T  r$ {. z) A    }# L5 n- F% A% a: f$ S0 T
    return result;
6 I+ r0 s6 M6 U8 D5 B3 \7 V}    7 `/ n$ g! j& v, O5 D

6 E/ C3 [; L1 U3 `8 Afloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/9 J, }  b0 R) j8 S$ j' B7 D' ^& \; z
{; ?" p' J- E$ F2 @/ S
    Stack optr,opnd;
9 y% ^& h( o; u# A6 P$ }    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
, ^3 ]& p" k# S$ e* ?% j    char c;
$ E7 X! b9 F- x3 q& {    char buf[16];
7 L8 l0 c  D* E' ^4 Z% c1 g    int i=0;
2 L1 q: t3 s/ c  [1 C   
+ k6 a. k8 I) y1 Z! g    InitStack(optr); /*用于寄存运算符*/4 X( ]2 }: r0 |
    InitStack(opnd); /*用于寄存操作数和计算结果*/$ x1 n5 _' P2 j& J
    memset(buf,0,sizeof(buf));0 ]" `/ ^2 d% @$ b! I# t
   
. s7 W" P3 \% i! D! c* j, V; V    printf("Enter your expression:");
+ ]$ H7 {! |5 `        / p/ q3 L/ V+ R* A/ Q
    opr_in.ch='#';
+ X, i5 ^; M  i" v    Push(optr,opr_in); /*'#'入栈*/' o5 I8 E2 I% U" _
    GetTop(optr,opr_top);4 u( g1 \: [) H0 K$ W: C
    c=getchar();7 O8 J& z9 F+ x  O
    while(c!='='||opr_top.ch!='#')0 X# y: b* p8 ?( m" b+ O
    {4 r/ a0 [7 L, Z7 s$ {
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
# X; p1 N0 {: V, ^- C5 N; c        {- N2 ?/ M& i7 z( `5 J7 ~& d
            buf=c;0 b% R* b+ i* s* c( @
            i++;1 b: T  E& u% K( `, h
            c=getchar();6 `) |8 K6 x$ @% {. n" f
        }
: k% P2 R5 [5 Q. M' a* t  I# w        else /*是运算符*/7 p/ I4 t5 {' q; w! L
        {) @% c% n$ G/ u# x/ K# u) s( Z# J
            buf='\0';
) L' ?: o# n  W, ]% i+ x( s            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/- B- I. O2 ^$ `" {2 @/ e5 j
            {
. o0 ?# a  u2 P) @1 e4 U; Q5 o0 J                 opn_in.data=(float)atof(buf);
' V9 g- A" J$ T0 t                 Push(opnd,opn_in);1 R7 Z& J' b+ Y  U3 g% V" Y  o
                 printf("opnd入栈:[%f]\n",opn_in.data);6 k; y4 X! n& V* S, E" Q! \2 E
                 i=0;2 c, d( o$ X- J
                 memset(buf,0,sizeof(buf));0 ~9 K3 N  C6 G5 {
            }
- c! N& Q7 l# F& p3 w8 D1 V' Y            opr_in.ch=c;
! y. f+ L! m! Z; W            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
- r: I( o% W: j7 C; ~$ h) r( y5 P            {
( y9 P8 J1 g9 ]6 _5 R3 [+ A8 c# F                case '<': /*优先级小于栈顶结点,则运算符入栈*/
7 x; T9 E* W/ l9 W# T                     Push(optr,opr_in);
5 K) ~; ~8 F3 E+ J. j# U/ W8 w+ x) l                     printf("optr入栈:[%c]\n",opr_in.ch);) p+ ~6 E' b6 n$ p2 t  D
                     c=getchar();% q' }! Y0 z& ?* h
                     break;
8 g9 X, G+ L2 p& I- z. c# h                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/1 k5 l, z( Q7 [- b! k* K
                     Pop(optr,e);
5 R3 A4 _+ X8 E                     printf("optr出栈:去掉括号\n");0 G% m6 I! f0 T/ }
                     c=getchar();
! m2 u/ Y. w! ^2 g# |' K* H, N                     break;
- ]! H' v' ?( \                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
; O# L  q! K2 t2 |% @9 r0 S                     Pop(optr,opr_t);( _# k% R9 R( y8 {
                     printf("optr出栈:[%c]\n",opr_t.ch);
; E0 }+ L- T4 F- [: ~. p, P                     if(Pop(opnd,b)<0)
9 v9 N3 g) S# \% h                     {5 V3 T$ I- ^# D  v/ ~) x4 Q
                         printf("Bad Input!\n");, i% u' r. P( t8 |9 X# O
                         fflush(stdin);
8 N9 T: J; c" ?2 n2 R. @" F                         return -1;
; ?& `5 K. h6 T3 |- p                     }2 o* H% m- V( _
                     printf("opnd出栈:[%f]\n",b.data);
! m4 e" Z6 j* j7 m) \% F                     if(Pop(opnd,a)<0)
9 r# ?; M4 l# _                     {
$ I2 I5 P9 @+ D* G* l                         printf("Bad Input!\n");
- P2 d2 Y- M7 f. l, V4 r: s  I                         fflush(stdin);
! [5 _# T$ u( J$ w* G                         return -1;2 F/ d5 n! \* y) x1 n1 @9 C6 m. y' E
                     }
6 ^* y/ G  q" K                     printf("opnd出栈:[%f]\n",a.data);
) n" _4 `+ y- r0 k- _4 K                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
% _0 o; O9 S! c+ |                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/: H) j, o) i% K$ ?: S( b5 D
                     printf("结果入栈:[%f]\n",opn_tmp.data);
+ @2 K' h" u* c$ M/ K1 ~                     break;' n- c) J  S9 M
            }
) q9 T+ f) f! f- d0 m2 X4 p# [( L        }
" F' ?$ b$ O: N" y+ ?& _9 c; w+ p) p        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
  F8 \! F2 w/ N- n# }# [9 M    }
. M$ H" i3 M- o4 f, n    GetTop(opnd,opn_tmp);5 \2 y; Z3 _: T8 B" [
    DestroyStack(optr);9 t. P# @7 V9 u5 n
    DestroyStack(opnd);
7 n8 n; |1 A- {) }& g7 b    return opn_tmp.data;
, D. E1 x  L' h/ K' h; p}' [& K+ @( u' t! m( `9 `
3 {+ V+ v- O: ]
char *killzero(char *res,float result)
5 b, W1 a' N% K! e{
  W( b! p" F7 J% K3 }! }    int i;4 N  r7 q, M- w5 I/ V3 ]# v
4 u+ Z7 ~* `+ H/ Y+ @9 S# E
    sprintf(res,"%f",result);+ s& E7 X; v9 b- S. f, n, _
    i=(int)strlen(res)-1;$ [8 C1 R& ]! j# i( P4 o6 X& w
    while(i&&res=='0')+ ^. R% f3 X' O, s( s8 I
    {& i% H" i" J' s6 ]8 S/ l: N
        res='\0';
) A+ @! x9 T1 D) s0 ]& i/ q4 B4 P        i--;# v' ]3 O( a: ~: \
    }
$ C! i/ l  H! `% n    if(res=='.')7 Z+ ]1 j- _6 f/ [
        res='\0';' R6 m! r$ D; C* [' |) f0 G5 N
    return res;8 a2 b5 u/ A* M1 Y8 @
}
, U6 ?5 I% E) j  ^  G) P, G; U  B2 \$ W7 `9 n" D" n
int main()& a6 B6 h, c- L& b+ j; b
{
' D" |: P8 k: s1 R& L2 S$ r    char ch;
+ L- m0 j9 f1 `& h    char res[64];( `4 M- E% D% H" P
    float result;
4 v* K% O( Y, F. k9 M    while(1)" p, x5 n9 W, w; y4 Z
    {
5 V. q" r4 F6 V( C  E        result=compute();
8 T# o( ^8 F6 s        printf("\nThe result is:%s\n",killzero(res,result));. ~. q2 w5 A! T* h7 M
        printf("Do you want to continue(y/n)?:") ;
- F9 I: C9 \$ u9 x9 z% Z        ch=getch();
5 G4 R( g; b6 Z  R, |' u% ^; s        putchar(ch);+ R, y- F7 v3 |! Y" n+ o! C# k1 q$ i
        if(ch=='n'||ch=='N')9 D1 X5 {* O/ D  z
            break;8 I- m+ k8 `* |( i, F0 d: V9 T
        else* G9 r4 a3 w3 d9 _- a) X
            system("cls");# V0 {6 [9 G% S( j4 s8 R
    }
) l2 w" i2 ^" I+ R    return 0;% X* G1 J2 E+ P0 X
}

8 z  B. a4 f& U! [# o: i. j0 `0 Y- Y% K: Y3 ?
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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