返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.' e! f5 h( Y) l  c& f0 {
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=2 l: _9 ^) v/ w, ]
/**************表达式计算器************/
4 p/ V' A+ [" A# ?3 S#include <stdio.h>
5 \, k" Q' A1 T#include <stdlib.h>* C4 ?) ?) Z$ j0 |& a
#include <string.h>
! X/ r2 {6 y& A#include <conio.h>
; ^, W9 h5 n3 O6 T$ |#include <malloc.h>
$ Y3 S5 q* R* m% N' _& H' x6 Q/ y$ L
#define STACK_SIZE 100& I+ L2 h$ y; X* B( x
#define APPEND_SIZE 10
, ~% N! o1 h# ]& Y, b+ p/ N
" ]! k! N- W4 g  w" `3 c+ ]# f+ ystruct SNode{, S0 G# F* V: a5 ?: n1 r/ o8 K
    float data; /*存放操作数或者计算结果*/
4 p: I" d6 G* W    char ch; /*存放运算符*/  s( Y9 t/ J  V1 n7 A* X
};& r7 F: E( n4 v

( x" W. ]2 k% z( Q3 A' G( [struct Stack{4 S! ^" m  o! u$ Q5 a* t  l
    SNode *top;
+ h" e3 j3 c, T" [4 L0 m: S' Z    SNode *base;% H7 V" y, u8 U9 @
    int size;
4 t( O# \. h+ v" `- ]! l+ i};9 j8 U2 R# s% p1 C" t

3 L& }6 P/ x/ L. r3 T. ?; \/*栈操作函数*/# k2 ~6 G2 c. e+ T& z
int InitStack(Stack &S); /*创建栈*/4 E9 V5 l' R' r- q5 g0 ]
int DestroyStack(Stack &S); /*销毁栈*/
4 r; E% F+ d" o6 F0 A2 Xint ClearStack(Stack &S); /*清空栈*/  O% e' y  \8 {1 X
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/' c3 F" v6 f1 S" K( _$ v4 x6 Y
int Push(Stack &S,SNode e); /*将结点e压入栈*/
0 U9 s- n$ d6 A! e) |, ^% I" T. _int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
( B# ?0 W: r" V# o2 F/ w
" _3 G( p2 W) _& U2 i7 z3 C/*表达式计算器相关函数*/
) b7 w3 ~& V# t) }7 m8 {) @/ Rchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
" e* ~4 N; s- ^int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/( L7 L9 }8 |$ o! c. R* x
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
% e0 o0 N/ K9 ?float compute(); /*表达式结算器主函数*/
6 I! e) B2 a" |8 ?8 _char *killzero(float result); /*去掉结果后面的0*/ ) o7 B, c3 i) K- c& U& x) s

! f+ E0 a% R' P- Yint InitStack(Stack &S)
0 [- y; P# Q3 S: ]- Y{3 k' P! m0 R$ K: b- D# H
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
% L% r, e8 w7 k    if(S.base==NULL)
3 l+ y" i+ B/ x# N    {! a1 K" D6 ]) X
        printf("动态分配内存失败!");" Q3 W* R! Y3 I* s. l  Q% A( s
        return -1;
/ t% u0 A+ ^. \8 E& p    }
( D# {" Z* f' w* {$ s# s6 ^$ q- H- |    S.top=S.base;( a8 {$ P2 z0 b% p2 N: c
    S.size=STACK_SIZE;
8 H& F1 ^) e; h$ ^$ ^5 E: p    return 0;
. p. v) A/ }* M}
" t/ O' X* |" s2 S* Q/ E, t
3 S  E9 h3 D; K7 H+ \7 r. Vint DestroyStack(Stack &S)8 ?) w! j% }( Z" P1 ?1 ], o. m
{# o" S* i- u" K6 o3 h6 l0 k
    free(S.base);
3 E& H6 |7 Y& s$ G% H' K6 d- \    return 0;
& ^7 t- G6 v5 L2 A7 J5 z}
& g8 I6 g, `$ ?; H) Z8 |
, y$ Z- m, b4 g' R; ~; Nint ClearStack(Stack &S)
* v; v* |0 [0 r, B- j{- F. D. Y  k+ E4 K* ^/ |; S/ d' a
    S.top=S.base;
9 m* @1 _3 N- N  ~" p. ]. b    return 0;
! R0 l, n. Y( r3 }0 m- r5 z$ U}
, m  G6 j7 v1 _9 T0 R
1 X* q) {! i7 n7 @2 oint GetTop(Stack S,SNode &e)7 [! [0 U' O* _3 b
{
5 N1 I" s5 _6 z2 `    if(S.top==S.base)
2 x' F' ~6 N( V( c. i    {# B: J" _  X- \8 C1 r; F8 j
        printf("栈以为空!");
7 T! Q0 i6 m/ Y- V" s        return -1;7 M/ g- k6 z9 g5 n* q+ V! x
    }
' H& p( u' E1 K# X; ]+ w3 P    e=*(S.top-1);  S; }! ~9 N2 U
    return 0;
# Q7 l7 a4 _8 S" e}
# ]; s5 ?0 P4 X) O3 @. ?8 s# y
, m  m" @; l  s/ N3 d* Mint Push(Stack &S,SNode e)
* l* A3 t" Z6 W: b8 J0 v6 c. W{7 a5 V2 V! i5 ~$ r& Q4 _
    if(S.top-S.base>=S.size)
6 q( x& V, j7 p6 G    {- B6 N: D( E7 F/ O$ Y
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));: X& a* z. ]' O) A$ p. G1 b
        if(S.base==NULL)$ Q4 M$ p- K8 Q
        {
8 T. r6 \, a/ E! C4 B$ R% }& X            printf("动态分配内存失败!");
7 Y" X( @2 Z! m+ }/ r4 n# y! ~            return -1;1 `; W! Z3 N5 o  g0 ^  c
        }
# w: \: H1 Y1 ]+ o* e9 v* ?        S.top=S.base+S.size;# ^7 N* Z4 u9 P* ^* c( U, `
        S.size+=APPEND_SIZE;5 j; O, `) ^* g, f! l# Z
    }8 @) |9 e; A# A0 w
    *S.top=e;
" C' g$ T( W% h    S.top++;
/ j4 f+ a, J  {8 c) v( u    return 0;/ T) r, _( u' P3 L1 j- {' {
}
: f5 R' E- Q' g# R* w6 t! U- `. Y3 A$ r6 z0 E
int Pop(Stack &S,SNode &e); f7 |" f: Y) `+ g3 L- ]
{' |" O5 d2 N; r- z" z
    if(S.top==S.base)
3 b/ v2 k+ Z* _- c( E    {
/ L' b0 ^3 @! L% C6 [& s        printf("栈为空!");
- a3 G& H! F2 Y* N" G7 S2 T        return -1;
; H3 A2 J) v5 m: T+ R: e2 ?    }& Q+ D0 k* D- ]- f6 w1 M- y$ [, c' w! j
    e=*(S.top-1);; e& K2 R& _  L- Z% m( r
    S.top--;
% k/ o* i8 ?4 p$ u$ c    return 0;
# j; \- v$ C: N! Q, k1 r9 [}
; J3 E) _0 v8 b+ ?: }& v5 `, W1 @/ ^# D6 r% t2 V
char get_precede(char s,char c)% b+ h+ c' L! T# H
{
2 ^5 v6 n; |: N; ]  K' R    switch(s)- i/ z/ J& s- b! {$ w" t, e
    {, _2 e5 P# V! Y0 {  J- x
        case '+':                 2 O4 l% y5 [& Z% r2 m! s! T3 ^7 }
        case '-':; a/ ]) R$ t7 k, X' ?
             if(c=='+'||c=='-'). w3 n' s. {4 D/ B: L4 w
                 return '>';2 i  _" U/ B) V9 J
             else if(c=='*'||c=='/')0 o  U  w4 \7 h
                 return '<';8 s! N! {  u  G6 A3 n# |
             else if(c=='(')
" `4 S3 {8 l* p                 return '<';' D, E* ?- L7 L- E6 b
             else if(c==')')
+ p( ^/ T( c% r                 return '>';
9 t7 M. k- |* m- C2 x( v% b. N# e             else 9 [! ^) N; {8 q
                 return '>';
- C# w; Y' E2 u+ j0 [4 u6 m        case '*':
9 ~4 L) A& s( y        case '/':
# F2 Q2 |/ k8 v! R) R             if(c=='+'||c=='-'); W' S" _: U* `2 M9 ~, Z% Y( R: r
                 return '>';& Y0 l6 w9 g) U5 u
             else if(c=='*'||c=='/')9 e& j9 f/ `! }0 F1 q9 l  v
                 return '>';" B+ m' f/ F! h* c. [& T! ~
             else if(c=='(')0 N$ Z: M# ]1 Z1 i8 R
                 return '<';9 O+ x, U/ I# {2 k6 s8 V0 ]
             else if(c==')')
$ G! M7 S2 R, x9 N# c: X                 return '>';
5 n3 k/ j9 a1 Q             else. K  r( R7 ^( _. I# G
                 return '>';
! R- L& k+ }, H" H" k, }        case '(':" F4 f; @$ x6 k, }& u
             if(c=='+'||c=='-')
( a- h3 M1 i2 W' w9 K; G0 B+ q                 return '<';) C0 U; d6 Z$ H3 p$ K, `
             else if(c=='*'||c=='/')
: p- b7 x( u& _! ~3 E) ?% y8 k2 T                 return '<';
, ?3 @5 d5 s; S* B! Q5 a# L2 T9 W) N             else if(c=='(')
- [! t& Q  @) |                 return '<';4 D" R# m7 e+ a# p  Y. j2 y
             else if(c==')')+ g( Z) j1 J3 s! B
                 return '=';
0 Y2 D/ {# a8 Q  K% _6 o4 u2 h             else% p- ?7 O; I0 D
                 return 'E';
( T' d* w8 m) \7 b+ T6 |. R        case ')':
( ]$ w0 C& w) @: S" V2 Y- Z             if(c=='+'||c=='-')" p0 i9 x, C& G9 Y8 _
                 return '>';
  V9 B  m' e- Q* R0 \, b' K             else if(c=='*'||c=='/')
. H( j3 @* I; u- a6 f                 return '>';1 {- ~/ a# m8 q4 m3 A/ O
             else if(c=='('); f6 p' Y" K9 }- z
                 return 'E';
5 D: [+ l9 p5 P+ J+ o* l9 y2 i             else if(c==')')& ]7 S/ p4 T* n7 l6 H1 q
                 return '>';
7 S9 p" m/ ]8 C" F  J0 `" [$ }0 I             else
! t6 X1 A0 c' K0 z                 return '>';; r, z& s- {7 N; n
        case '#':
6 L2 w6 ^; I/ l: P  J             if(c=='+'||c=='-'); k. p5 R8 [/ V# X- ]* l9 W
                 return '<';
4 N1 Z! u" u1 c" h             else if(c=='*'||c=='/')
2 D. k8 z! x3 T                 return '<';' P; [) p" s& |4 Z# _, Y
             else if(c=='('), G+ S$ ]1 m, W& U
                 return '<';5 g1 O) Q* k' H# x' a
             else if(c==')')! L- M+ k! _9 X- C2 h8 M
                 return 'E';, _: V4 o3 T# h( W# n1 r( q
             else: y$ s  I$ s6 H1 q' ?6 U
                 return '=';
- L, d- [1 Z. F' N) z$ ^+ y        default:
# K' [! y7 U1 Z5 }) e! @             break;
+ \; S  H% L- Z    }
, @2 S! X+ r/ x% Q7 M+ c% _9 }    return 0;   
7 ]/ a9 f+ f* D  b) O  Q& ~}
- f* c, l1 j! J0 y
( x. B  l5 K# X- F; s/ m( yint isOpr(char c)
% e8 p$ ?$ O3 i( ~$ y, c{! @$ v( g) a  B  |7 E! T6 O
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
5 k2 b1 H( s, y        return 0;
: H  z- i5 ], I8 ~) o3 o! H& I    else " M: y0 R" M1 b. d( J% ]! K5 r' U
        return 1;
% }4 E( W, A3 _5 w  s}
7 R9 `, x  C( h' a) i; c% O, a0 Z+ g4 `5 i& h
float operate(float x, char opr, float y)
9 w& y% I# A" |2 ]{$ b' k- ~- B4 Y4 l. e% u  A% \" v( c- j
    float result;
% {# X! i& w- @( W* T    switch (opr)" f& ^' ^# |; M. q2 C% K
    {
0 O4 v) ]$ e( V$ K4 Q4 z9 G        case '+':
4 Z2 t/ s- M) ?' @8 [3 x: l) Q; b             result = x + y;
1 c6 @- w- ~3 b) k/ O! a& o+ A( i7 X/ G             break;
2 y( c& W6 K$ L1 I. U# [* ?: K        case '-':
6 r7 I( |2 I4 |/ ~9 a" o' ?$ l/ E             result = x - y;) L3 R6 @6 L% w. B
             break;+ ^; N3 X! _4 D6 L6 ?0 o
        case '*': $ ~) @. Z+ i9 V( G1 @
             result = x * y;3 @8 o+ O  P& Z
             break;
* W) x2 ?0 X4 x0 a  x. G7 H        case '/': ; D) b" t, i0 H8 |4 {+ P
             if (y == 0)
5 d, S* ?- f; o2 G5 A             {
1 Q2 H3 V( r2 E1 ^4 ~                printf("Divided by zero!\n");
8 S" W7 \; j  J) c! {+ Z, ]                return 0;
, q) e. x/ t! j4 |! O1 @             }
5 S4 B1 X! \9 w5 D3 j" K* c             else
  A( T) y+ d6 B; e2 y; g             {
# C* p- i4 D& W# n4 C6 D                 result = x / y;
/ G+ t8 K, b* ^8 M                 break;
$ k$ y  g/ O0 `4 \             }
4 z+ w- [% e0 ^9 y       default: 2 i$ ]! c  l4 G# `
             printf("Bad Input.\n");
& F6 |6 f+ o6 c, ?5 l; x             return 0;/ r; }* M- Q- P: W) F9 C+ {
    }
. r) D, f- l, N    return result;
# j) c  s3 F  _, J6 C}    ) T1 O+ A  O4 v7 s9 d; o2 l
0 @* T6 _: e% X
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/" f% v7 D/ }! D" O& q. f! o/ X$ O
{
3 h$ A7 C) M) s9 P3 P/ g& a    Stack optr,opnd;. `$ z3 u- [% }3 d  {. m
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;: J6 g' x& B. B5 x
    char c;
! y- i1 c5 `5 q. b    char buf[16];* l5 D! l  }- \% z! O  _6 k
    int i=0;1 a* d* ?" a1 t
    ' _1 F2 @4 N- g5 a' Y) n- ~' o7 Z3 l
    InitStack(optr); /*用于寄存运算符*/5 [5 {  f+ e$ X1 k
    InitStack(opnd); /*用于寄存操作数和计算结果*/
8 b7 K& \& S+ ^% a% O, E  R8 C    memset(buf,0,sizeof(buf));. D; B! D7 a, N% T- w
    " e/ j" v  x: ~3 @2 p' |
    printf("Enter your expression:");( W2 L3 N, H" x$ P+ K' I% ~8 H! V
        
: g- h2 W& s: m, [4 j3 `3 Q4 J2 f    opr_in.ch='#';
2 {7 r3 a$ z% |. c1 j; g* i    Push(optr,opr_in); /*'#'入栈*/
2 a8 D6 \4 n' w+ t8 [    GetTop(optr,opr_top);. s8 F# p$ ^2 x- f" v2 Y& \
    c=getchar();
- p- e8 D( f5 o. w' e$ p; A" G    while(c!='='||opr_top.ch!='#')$ U1 e& P2 A6 D+ L2 P, e  R
    {1 t& }6 N5 r3 I; a  v- `) T) D
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/( P7 g; k% Y0 ^
        {
! g. s6 s* Z9 X6 b            buf=c;
) n- q" M  p. p" e- m* y& z            i++;
, H* P; j, N: `            c=getchar();
# N6 w8 g4 ]% p% ]1 z        }
2 m* V( z; r8 {+ H        else /*是运算符*/6 Y1 @) g* N6 y& I  }6 a- H
        {
: z1 n9 A& S  R9 J" ?. x            buf='\0';
7 A  J9 w# ?4 O* m- u' z/ h            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
2 \, g! W' p/ j) T            {# d" H1 _1 F* `4 J
                 opn_in.data=(float)atof(buf);
2 T/ M2 ^5 h# i, S, K; k                 Push(opnd,opn_in);/ s/ P8 z) k4 H1 g- d
                 printf("opnd入栈:[%f]\n",opn_in.data);6 k; ^: m/ p( C) b
                 i=0;2 z  m" U8 o0 f0 I8 j8 q, i
                 memset(buf,0,sizeof(buf));
4 t9 A$ r! g* u7 H2 u7 b  x6 S            }' c1 r9 W/ i: ~8 ]7 E# ]
            opr_in.ch=c;. J& M7 u% K0 p+ |, @/ P" u) g
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
& E$ J! B6 z1 ~& K+ ]6 A% i; p            {
3 }% w5 y3 O) R0 e9 H2 E                case '<': /*优先级小于栈顶结点,则运算符入栈*/
; [+ `& u: C% ]. Q$ v$ b% [, B$ m                     Push(optr,opr_in);
& W; B" y7 X' `( ?( [. G2 b                     printf("optr入栈:[%c]\n",opr_in.ch);% ~, X: K( s' t  h; Y
                     c=getchar();5 m) Y0 X! _1 d
                     break;6 L4 W# F# d, s4 }! a
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
( v0 D& X) u: N( B* [+ O                     Pop(optr,e);
5 C# T3 |& X$ ~: }# P                     printf("optr出栈:去掉括号\n");. F# b6 g  Y4 N
                     c=getchar();
0 t. ]2 @" U5 k+ x, E7 V6 B                     break;9 V. y) q" C0 e# O: I, [/ I8 g3 E
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
3 Y2 P  N* Z4 j5 ]! J& b. W                     Pop(optr,opr_t);
- v6 [4 V5 }& \                     printf("optr出栈:[%c]\n",opr_t.ch);
. D1 R; d8 f1 e2 i! K. m+ H  x                     if(Pop(opnd,b)<0)
% Z- b4 _' ]6 E7 `                     {9 j5 k" [9 h: V  s& W1 h1 l5 u
                         printf("Bad Input!\n");
; W. }* z; }, T' j' k0 l( l                         fflush(stdin);
5 Y' {" t; w; J! |' ?( n: {( Z: S                         return -1;4 [: t* v- o( J& I9 a
                     }, c8 P" \8 P  F% ?4 c: Z
                     printf("opnd出栈:[%f]\n",b.data);
9 v1 c3 C" E+ y* j) ~5 O! P                     if(Pop(opnd,a)<0)
6 A( x! V& i3 h* w                     {  o3 n0 P3 i, |- g( w5 b% g6 H$ [
                         printf("Bad Input!\n");, X- z" r% c' r- v0 v) B7 U
                         fflush(stdin);- z$ ?/ ~( ?% T! s
                         return -1;
" K3 m$ Q! ]$ z; q; W4 P/ `                     }+ R2 }+ |% L- F* M2 w- e
                     printf("opnd出栈:[%f]\n",a.data);. [! i3 w, Z- f5 G; _
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/  i% U4 t) v+ R, I' S1 G0 r
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/% J; E3 ^6 M- |9 i9 y2 {8 }1 Q
                     printf("结果入栈:[%f]\n",opn_tmp.data);0 H* ~3 Q: K  ?, k  g
                     break;5 S* }* ~* Z3 \1 U) k4 {0 e
            }
+ x) F' n* o9 L# {4 d        }1 N+ ]4 \1 x" E0 C) V# T5 i* X# U2 [
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
7 _4 L9 _+ g6 K8 _9 e( E" b    }
" {8 _5 |1 ?3 ~& q, N* }    GetTop(opnd,opn_tmp);
) c6 h: ?4 R( `, }- @4 R2 R% U    DestroyStack(optr);. I8 w0 u8 _, i
    DestroyStack(opnd);
& i: w% \9 F- H3 X9 w    return opn_tmp.data;
+ I: C' `% U5 X6 ]- A}7 ]; I7 n" z$ N7 }, h: _( I0 d5 x
$ I& N8 w8 u% i$ e
char *killzero(char *res,float result)/ E/ {' x9 S( m9 ?) B* q
{+ M# l& q. y6 Z9 ]' e. g+ [
    int i;
; \; y8 i* ~' Z8 }9 j
, W0 X4 N* q5 }! U    sprintf(res,"%f",result);4 O* a! w3 [6 j8 R1 l# i; W
    i=(int)strlen(res)-1;
/ ~+ D9 d* y) H* d    while(i&&res=='0')% g7 H) X& P" d' ^
    {
6 D& D% N# G1 [; }        res='\0';6 i5 C- h  r: x7 i- W: w7 r
        i--;1 n8 v' [) ?4 }+ k1 Q( p4 I( c
    }$ p# m" m) P; ]0 S
    if(res=='.')
. G3 A5 \. c7 P6 f( a2 [& Z        res='\0';! {- l9 h9 X: j" G& w  G7 h' R
    return res;
: J7 o) }9 ]8 s4 n. w}
0 h" K- S/ w" d
: v8 R+ c9 k# I% g& m# M* M* Qint main()
! x# |1 w% }' ]+ @. X) O{9 R" o; P( O  ?% J4 [
    char ch;
4 v& L* C4 ]2 |5 \: b    char res[64];
. `9 G: [% Y& F. @    float result;5 i+ l1 ^5 j( j* W! p4 z
    while(1)0 d8 j4 j& ~; [' `0 i1 {
    {7 I( z' ~7 y4 J% t# y0 ]8 b
        result=compute();& |- \9 N6 g7 A* ^  L
        printf("\nThe result is:%s\n",killzero(res,result));
1 w- O6 f  Y1 h* B6 {' p        printf("Do you want to continue(y/n)?:") ;
8 X' |# e* R" Y+ P: g1 y        ch=getch();
& p, x2 F3 ~' P/ e( |  G; [        putchar(ch);4 k6 Y  `: \  C5 N! o  j6 N) {
        if(ch=='n'||ch=='N')3 `, ~2 c& D6 H% o: Z* n. c  b
            break;) t9 @# n& ^- ], ^4 H
        else( {+ |5 z/ M. X7 K, C7 W0 R
            system("cls");' Y( F' F7 H7 C
    }: B* D% f. k: t3 @  r
    return 0;
& J& m  G  R- t/ y0 ^+ j4 ?0 o- L}
: v1 Z1 n" g7 D4 x+ i" v2 B( o8 d) h& ~$ N
; c# Q$ ~1 H$ T6 P
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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