返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的./ O9 w9 ]& Q3 I, @: x
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
: l) q! C: {, C, }. u/**************表达式计算器************/) ]' k$ z" j! w
#include <stdio.h>8 z* I) V: q+ s* L+ N
#include <stdlib.h>
# e% u4 E. C8 y/ G' t) T9 y#include <string.h>4 S7 x( D" Z9 `# T+ G/ x' b
#include <conio.h>! I5 e3 i5 A8 {$ ~+ i% z- {# _
#include <malloc.h>
* E  R# M, W8 ]$ y- e$ _) K  g( W
#define STACK_SIZE 100# }, P% u7 }4 i+ G
#define APPEND_SIZE 10- g$ o" _, O( v7 E1 g  M" V

6 {! T1 x5 I& rstruct SNode{
2 ?+ P, ?( y1 _, \% J" I: S* ]# n+ N# j    float data; /*存放操作数或者计算结果*/4 s8 \1 d/ M! l( q: h/ |% w
    char ch; /*存放运算符*/+ h( M) ]: k7 @- T7 r4 A% L
};; e" C; ?. v! L, h! l4 M% M

# w- v% g$ _- e! {; z+ H) mstruct Stack{2 W4 D+ H( d/ s+ d4 \0 R1 x
    SNode *top;
- l* x3 v, B1 u( x1 u    SNode *base;
0 \' H3 p6 {! p9 x+ C    int size;9 u$ e0 a( Y6 }: l  f( m/ W
};( S( O$ z6 V: M

7 ^) M% v1 T7 U" @- U/*栈操作函数*/
3 j4 b9 l/ N& w& C# W' }) tint InitStack(Stack &S); /*创建栈*/
; n) B- j0 s# ~/ x+ |int DestroyStack(Stack &S); /*销毁栈*/
# {) a; e0 \7 ]6 I* u5 Vint ClearStack(Stack &S); /*清空栈*/
( N3 b" I" {9 n1 d& O7 `- U4 G; R* @1 Tint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/! P, S0 }5 B5 i' W8 |2 _
int Push(Stack &S,SNode e); /*将结点e压入栈*/5 _7 H% F4 B5 O3 K% ?
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
8 w, ]1 w, N( W4 _# f. ]2 J2 N/ C) C& Z0 i
/*表达式计算器相关函数*/2 m* `9 X$ F, c1 V
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
5 S- Y6 K' ]5 Y6 Bint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/! P: Q1 \3 A7 _/ u6 \0 l8 h7 s
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
4 N! d) f8 S1 \# ?2 q0 ~( [4 Wfloat compute(); /*表达式结算器主函数*/- \: Q4 [- j9 V; ^+ r; w" g
char *killzero(float result); /*去掉结果后面的0*/
' r3 }7 t8 \: g  Y6 f1 @& Y! r% Q/ x0 r6 c
int InitStack(Stack &S)
; Q- y/ ]2 Z3 w2 V{  Z+ w% D7 _; d# z
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
* G, [! w# u1 U, |, d' N    if(S.base==NULL)3 }8 D0 R+ w; i
    {
1 Y- L7 ]" b) W) r- g        printf("动态分配内存失败!");  L# I0 h, m$ C3 }0 s/ o4 a. o' H
        return -1;. T2 }) ]( V5 v6 d! v4 R; |* \8 P  S
    }
; X5 r3 M' l1 k- c8 C    S.top=S.base;
8 X" x' y& `5 v* s) Y( m* |. f    S.size=STACK_SIZE;
/ @0 v% ^. y" Y8 N- Y! {    return 0;
& q* `0 N" E3 j* s) N( a}+ p% m% e" `. e3 N# l+ U- F8 U
2 m$ l7 J& m- I9 `8 @4 O# Z8 ~& X
int DestroyStack(Stack &S)1 u7 b/ g( q+ @, j
{
2 ^7 ]  d3 d- C) D: x) o* H; j; o    free(S.base);
/ k. a4 K& f1 A% d  D    return 0;% N$ S! f- e# A7 \% N' a
}- R0 V& I* G* ?3 M. Z

$ g# u7 q$ {5 Iint ClearStack(Stack &S)
1 l4 [5 l, e0 ~5 w: W2 X2 T{5 W, I, T5 _" v+ P3 B3 `) E
    S.top=S.base;+ K. c: u8 V8 e, |
    return 0;9 F8 Q* B+ x- f. O6 t3 P
}3 p8 I+ g* K/ ^: c% f+ d

& K0 f, f# I1 L% u. B1 F+ |int GetTop(Stack S,SNode &e). f% Z% C: }' X% r4 Q' U
{
. x# `6 j" W! {9 h: B: [2 Z' b    if(S.top==S.base)
  c7 e2 P5 E- S2 I' v    {' W. J8 g- ?. @& \  w
        printf("栈以为空!");6 S" s" E$ u5 q5 x* r5 j3 g( r
        return -1;6 p- p9 K" j8 g
    }
' ~, C& Y7 J; b. r0 l    e=*(S.top-1);6 ?! Q; X- ?! V' \  [
    return 0;
3 p* a# K! ]/ x" x; }}- s$ V- o6 y. k; g' U$ K% c2 H
8 N1 u) z" ]. ^# {9 ~3 _% Q
int Push(Stack &S,SNode e)
' A+ {8 _9 E$ e# V" I{$ Q% ~+ H8 z" I/ k. w; Y
    if(S.top-S.base>=S.size)
" @6 q) J( M* V& [1 q4 d8 P" d    {
% L: w  ]! I4 @        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
, p0 W( I& L' `! L- ?4 f        if(S.base==NULL)
9 f9 z( D. |1 z1 k8 ~  i        {
" e3 t; K- d9 I" F* s            printf("动态分配内存失败!");
! q7 m4 A3 ~! @, H  t& T' }: a            return -1;, G) C2 X' ]9 \6 D- K0 i* w; n
        }
9 D9 M2 R9 l) r) L; _( r  k        S.top=S.base+S.size;
: B6 ]" R" b. v; g        S.size+=APPEND_SIZE;
( c4 e8 G* b2 l$ J+ T8 P7 i    }
7 U  V5 [' Z) s    *S.top=e;! q9 R/ C) i! ~: O
    S.top++;$ k' B- s- L) Y" c
    return 0;
6 H6 n* b" c; s& T& b8 a5 `% C" j}( M! K6 j1 e* k
8 b# i. E$ U! U# e  W/ I5 Z
int Pop(Stack &S,SNode &e)" V0 R( ~6 U4 p) E. M2 a3 a5 ]: ^% S
{
: d8 _/ P6 Y* |4 u    if(S.top==S.base)
: Z5 }7 G% P! ~) }% t# U    {
+ ~/ ]( \2 p) m7 E, x, _. V4 L) I        printf("栈为空!");
+ ?1 V! l! M3 Y# C0 {        return -1;
5 j; A  `& M& L# X) [    }
% @/ ~% U# H" a; z    e=*(S.top-1);; Z% i- A; w! f/ `* \+ p
    S.top--;
! z/ R9 U' k+ x2 r/ `    return 0;- I8 K1 k. x- q* U
}. g# F/ n9 U$ k1 e9 H2 j& R% p
+ v* g- ]* ^2 {; l( l% a" s* `
char get_precede(char s,char c)
# r3 T8 `  s+ v0 m" b4 p/ K- k{% y) x( B8 U+ G  V9 t& }- w
    switch(s)/ h, G5 P' D2 e; F4 X- T: [
    {3 d3 L4 N4 |* w1 }  W# F& j
        case '+':                 
* N# p5 r3 ]5 ?9 W        case '-':
, u0 K  \3 M1 a/ ]% F- U             if(c=='+'||c=='-')
: X; m& P6 q: y! b: L8 S) }                 return '>';$ o6 q( o' I1 [2 x/ Z/ r  ?
             else if(c=='*'||c=='/')8 O$ J" k% t- h; N
                 return '<';! J$ A5 p$ F  H8 S3 r  p" _
             else if(c=='(')
( j2 Q# z' Q" N' m/ i% Z6 T/ r                 return '<';' Y; e* e5 u" N: P8 L: y! l, e4 e2 U
             else if(c==')')* M4 e) o. n' l4 Y, O4 s
                 return '>';, a1 i' l( u5 l- S
             else / i/ H4 e9 m( q& m) q' ~
                 return '>';) V" K+ G1 Y+ G# V( |
        case '*':
3 z2 f! c6 [( l        case '/':: {4 G# i, Q- ]/ i, D
             if(c=='+'||c=='-')
) t& ~; G: l2 g( P+ n  B' p4 G8 _6 X5 u                 return '>';
( q% V1 [% X/ ?" v             else if(c=='*'||c=='/')" ]: S4 O+ @& o
                 return '>';
* V. [0 E6 r/ G* j1 @& R             else if(c=='(')
. A- d/ w8 }- M! ?% m) |# J: {                 return '<';& |8 Y1 h8 o- l& P9 |& t
             else if(c==')')
# b# s0 a* A: x% P( Y1 R' E3 j                 return '>';
6 u: J$ \7 B2 b, T             else$ H: m! ^7 r; v( \0 W' l5 R
                 return '>';! |# c# G* e2 \5 _0 \
        case '(':
4 B2 a1 V0 b) y" I" |3 z3 B7 y' p             if(c=='+'||c=='-')6 ~7 D( e: A- s# t
                 return '<';
, N) C8 {: g5 e/ A7 N' u! U             else if(c=='*'||c=='/')
- m0 X+ [% X4 s* z7 J: B5 j                 return '<';( b! Q# f$ i0 H& J3 T- c" G+ W  r
             else if(c=='(')! S' C# w1 h( i
                 return '<';7 |* P( |+ F% b7 P0 Q
             else if(c==')'). V3 M+ c* T7 e: r: S
                 return '=';
( ^, l7 m: G6 M& N5 J4 |$ c             else
7 \! z% Y) N# D" ~- B* c* M+ M                 return 'E';- A, U  h7 m: u7 w" y  L
        case ')':  R2 P8 A6 d- i. L8 ]
             if(c=='+'||c=='-')7 v; M, v; u% }. m% Q( @
                 return '>';/ v8 i% H  D+ q; }/ r
             else if(c=='*'||c=='/')
2 W' A! R" R6 x" `                 return '>';
7 L" n) c! R5 O$ O& ^1 V/ H! Q5 g             else if(c=='(')9 ~+ U! g# c+ U: n1 O* b  `
                 return 'E';% ]3 x) R' y( u
             else if(c==')')/ P. ~5 _. d/ A/ }& G$ @$ C
                 return '>';
  R, ]0 b9 z; D( q% H. Y             else  A& F( T5 e. U
                 return '>';& [& r+ `" L3 z1 I4 o; i
        case '#':
" `" e, s; F6 |' P( D, P5 i6 S* o             if(c=='+'||c=='-')
8 d$ y; {  l$ z2 s                 return '<';9 e: ~3 x( k( }* N1 y0 m% Z. g
             else if(c=='*'||c=='/')" ]. B& P- P' f7 c
                 return '<';
/ }. W: N) ]* X! w             else if(c=='(')1 |" ^& h7 s1 K4 g' f
                 return '<';  h2 l( u7 R% \. o2 A
             else if(c==')')$ ~% c2 p% b6 u3 j2 l
                 return 'E';3 R+ J7 a* k, Y4 n: Y0 w1 w
             else  X) X0 F7 ^1 {: I: d' X: D
                 return '=';8 s8 G* N, J+ g2 m' R8 w' n
        default:
& ?& C5 p$ |0 q9 Q1 h+ ?             break;
; l. }+ L- L( n) }: b( {    }: a9 Q( j' d) m& z/ e' u, B( D
    return 0;    $ k. o. F6 a' |% q( W+ E
}+ {$ ^% M4 P! Y! F
" D# s  X& p6 W  d
int isOpr(char c)4 |9 R: j: R2 Z4 p' z6 V
{1 |# V+ p: L, ^& h2 f
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
' J. M: |. j% a' S( \6 b* H- ?        return 0;) Z& V% _+ [$ a& ^. W  ]; K# [8 s
    else 2 E1 E1 G3 }( J! ?! j4 {
        return 1;1 Y. Y; k( f" G0 P% ~3 |
}
5 ^% @1 j2 P) {+ A* w% i6 J. z
float operate(float x, char opr, float y)$ T3 O" U' x' \6 [  r( Z" }
{/ q0 U2 B  T( l2 ?% @
    float result;% ]( \. h( l2 }; T; ]" z
    switch (opr)* T" L( j# ^. V. k! g, z* X5 [
    {2 j! O; k; h2 ?+ _! K
        case '+':
- T) `9 H! ]/ b% n  A             result = x + y;% q0 l8 B' s( }" f- u
             break;
1 ?% h5 i" Y. m4 j# }! |        case '-':
* W: H- f- d: `3 M- `/ Y             result = x - y;
; g" O' n. t% o" s7 K  E             break;- y& E; c; a" n1 k; O6 {0 i
        case '*':
; H3 ~6 }, g$ I& c$ `8 ^             result = x * y;
$ D& h( Q/ h# F, E% x$ T2 o1 m! P7 e             break;
7 K" L. ]2 w5 {( U3 j7 W        case '/':
0 \2 l' Q  h! i1 N  h; V) b             if (y == 0)
0 n: A3 ~2 @2 d' j             {6 |& M9 Z. c& b+ [. @" B4 _; J
                printf("Divided by zero!\n");: Z) c$ I0 \1 Y. ^  _/ ]' y; s
                return 0;' C. K. H0 c- z! N  W+ F- ^
             }
1 U+ G: Q( ]4 T, s1 m             else
, x" m, C( _  Z! J             {
5 P! c7 b+ B5 p* @* _2 g                 result = x / y;2 w' [- g7 y% `6 q* N' c
                 break;( \( a0 ^1 f/ m  C$ @
             }: t$ [; K# W7 o- v) Q! r
       default:
, ^8 B  Z4 M" D+ h/ ~             printf("Bad Input.\n");
  m$ K/ ~/ Z0 p, M             return 0;: }& x$ R& ~2 O, p
    }
' ]. H; u7 Q) \( W, h. D    return result;
( b) n& l8 m. j" K  i& t9 T$ @}   
9 V  e/ f. w, \2 w4 J5 A* [& c- C1 g! x4 ~; a: ^; T
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/6 [1 e" z: c/ a0 z. w
{
$ W* h4 z# y( q: p$ i    Stack optr,opnd;
' ?4 F) o# v; I( `    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
+ ^# V/ {+ y# T" q4 F- A2 m    char c;
% P! `( f$ S- ~( w, ~( }    char buf[16];
9 S( ^- N; B# w. B    int i=0;' F# p7 C3 U1 s
    ! ^( W9 S4 v! V4 P
    InitStack(optr); /*用于寄存运算符*/
2 I0 ^) D7 ^8 g" a- k3 \1 G8 {    InitStack(opnd); /*用于寄存操作数和计算结果*/
! M2 J* B, ?) z3 r* M    memset(buf,0,sizeof(buf));4 ]1 }5 @* u8 \. s
    $ }2 k5 W9 U7 i  ?: v  i% y
    printf("Enter your expression:");
0 Q& @8 {: i% x& D* |        
' _3 v, G! n- C1 A! S    opr_in.ch='#';' S) t6 R0 z7 r% q) M: t2 X& W8 f. I8 j
    Push(optr,opr_in); /*'#'入栈*/
* |2 Y! e5 w1 M' j    GetTop(optr,opr_top);. {3 b; b  I  [/ Z! b- |
    c=getchar();+ }4 R6 \( D7 d
    while(c!='='||opr_top.ch!='#')/ `0 r  B; r8 [- b
    {
7 x1 x% {& z  \& ^8 F        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
# g* ]( s- @: R. Z        {' f( p$ k# m2 ^6 S# i5 G
            buf=c;
3 W1 w( N  j% q+ x            i++;
% v: e" h! p: @3 j0 ~, `2 c            c=getchar();
  w5 X0 e7 C9 U6 P% ]* R  l1 p0 @        }
5 \! |/ W# P$ s( [( n: _- T        else /*是运算符*/
8 j8 n( i7 `" _* J2 \6 ]* v        {. G- o9 @( d1 h6 y
            buf='\0';
; Q2 U, [1 k, \            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/1 U+ a8 }& j8 x2 S* `
            {
$ O9 A$ G; p. w* r* a                 opn_in.data=(float)atof(buf);
5 X& P& k0 S- \( W                 Push(opnd,opn_in);
, m1 Y  d' L0 E+ P' r% R                 printf("opnd入栈:[%f]\n",opn_in.data);
' @9 N/ M% y0 d$ K- ~                 i=0;  R1 c/ |9 u8 R7 Y& c' W
                 memset(buf,0,sizeof(buf));% @9 d8 u6 z  K+ J# O; a  r
            }
9 w) n# ?! S" d, V, S- p* r: s            opr_in.ch=c;
. ]/ Y- D0 L8 q& z6 F0 T; s6 u8 L9 K            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
) j6 z: X7 m( L/ V$ r            {
4 G# q: H* [" t# w4 o- Q                case '<': /*优先级小于栈顶结点,则运算符入栈*/6 i4 X4 ~0 f1 U
                     Push(optr,opr_in);
5 H( X2 i, b+ c. g: G                     printf("optr入栈:[%c]\n",opr_in.ch);2 r' |: J+ G: g0 z2 m
                     c=getchar();
. E2 r& T, L# R% {                     break;
8 u) U5 X5 s* K+ a( N                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
. m6 E/ q, h- a                     Pop(optr,e);
5 h, W. b6 V4 S* w- W                     printf("optr出栈:去掉括号\n");+ |1 R6 l* I- ~; X6 v
                     c=getchar();; v! F' T' {# J! m
                     break;
8 ?  W4 O: D4 U) `                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
5 |& c2 `% A; E$ h5 O                     Pop(optr,opr_t);
7 ~8 O1 Q3 |2 ~% h( z, p                     printf("optr出栈:[%c]\n",opr_t.ch);
# [* E0 F" b& Q' b! t  @6 ^                     if(Pop(opnd,b)<0)  y1 k0 B5 A6 W4 S5 a
                     {0 @" Q/ b& E7 d" l! |- l* K: J& u6 @
                         printf("Bad Input!\n");/ s% }) X8 u9 b7 d
                         fflush(stdin);
* F( Y. P' b/ a! ]% A! `7 N% p                         return -1;. i4 r6 P2 O+ f1 N! A
                     }. i$ S% R# q$ F1 q
                     printf("opnd出栈:[%f]\n",b.data);
+ z' a- d, Z, K! ^! E( l  K                     if(Pop(opnd,a)<0)( D! \5 @+ X. W* N& J  Z) e
                     {
4 M9 x: v2 F/ d' x                         printf("Bad Input!\n");
1 O0 A* x/ @$ Y! a                         fflush(stdin);! ]0 U$ N+ ?2 V: y0 A
                         return -1;
! }2 [" g0 z8 g; }                     }( o- Y6 E0 K* H& u3 |
                     printf("opnd出栈:[%f]\n",a.data);+ l. X+ c! P( b2 Q, E
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/$ L: p+ [/ v2 a( h
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
% o  u/ s& E, i* V& v                     printf("结果入栈:[%f]\n",opn_tmp.data);- q* _& \1 y) @5 b3 d
                     break;% Z. T8 {- H( s2 l6 ]5 D" Z8 ^
            }
6 D4 b8 p. }) ?        }
$ m" X4 d: n% C. ^        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ( g  g' v; H) f. o8 X' g4 X
    }
0 b$ k" j0 S6 R* w& w! }    GetTop(opnd,opn_tmp);
6 C" M" a" j$ a. D# n5 w7 J    DestroyStack(optr);
) K# y: H( I! Z  E6 T- |+ p, s6 j    DestroyStack(opnd);$ ], q2 S1 ?3 J5 U% O& x1 L  I
    return opn_tmp.data;: R9 y( X# P2 g& M3 |* @
}
) K4 b# l4 Q: Z$ w  |" `% ^$ e% S: A( G/ ?$ E
char *killzero(char *res,float result)8 D7 ]; n$ [# r5 i- }4 C' O
{
; U3 r) x2 t  X% U, E7 {6 }% [    int i;
/ U$ [. L6 a+ P; C: \+ F% |% Q2 B
    sprintf(res,"%f",result);
- p# [# x& B9 U# H# v: u( Z4 |    i=(int)strlen(res)-1;
! O. s! g# J( W# h    while(i&&res=='0')4 v6 b" P/ `, i  y( e* l+ j
    {
; X: m5 {7 t3 f) T( o/ }3 D9 J6 T        res='\0';; x; @+ E' ?) J; g* [4 Y3 q
        i--;
- h& B) ~3 l( c7 h; k    }: w& t3 ~7 m: C/ D
    if(res=='.')
6 a& w( U% z& r7 n8 K        res='\0';
- t4 O( E% ]; Z% a    return res;
9 h$ F+ M6 X/ P, w. ?}1 b+ R" C! M! X9 Z1 G
- m, ~' j: y5 y; s4 ^
int main()0 Y* |; [, a9 ~# [
{
8 z% ]% c2 R0 k& M    char ch;3 d9 t8 [* N7 w& k5 G
    char res[64];
1 D! J! R2 d# A$ T# H5 `    float result;
+ X+ \$ f: P' a9 v    while(1)
) E; g3 X) C6 y    {5 c5 O; q1 M: p2 i5 }( y( T
        result=compute();; I$ U  [1 H& c5 M9 R) S
        printf("\nThe result is:%s\n",killzero(res,result));
- G8 a: [& W, {  z+ U, _/ D( O" C" J        printf("Do you want to continue(y/n)?:") ;
! V% ?# Z  e8 W        ch=getch();
1 z6 e1 z' Z' o, u- X        putchar(ch);
# I' \2 D6 I& }& `        if(ch=='n'||ch=='N')
4 J& h, s3 K: C, F( V/ w            break;
! k$ Y  N* ]+ `: @4 T7 I        else+ E! J6 a, h: u
            system("cls");
" B' f) `/ R4 [1 Y! a    }
9 A4 }6 P& K# t9 P2 b8 ^0 s    return 0;
% Y8 G9 I5 k$ a. f* |" B2 J}
) j4 Y) Z& w% r* P& O- ^% V
, R" b9 P+ L/ o+ p
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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