返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
' U* S. b! m$ S4 z: _* t/ b- {程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
8 X* A" h9 Y, g% ~  y, h: M/**************表达式计算器************/
0 g- z& }( ~  O5 T; j#include <stdio.h>
" W8 \8 r+ f7 n8 r& s#include <stdlib.h>9 p$ }* |' d1 W7 I( f( n
#include <string.h>
. c5 G3 i! g+ l5 ~% s3 U#include <conio.h>
* ~( C: Z  s" v#include <malloc.h>/ e& A/ v0 N) e% C
1 k, a0 I8 k, R6 U: Q3 h+ V* u
#define STACK_SIZE 100% [1 f" L6 F( o# q" O
#define APPEND_SIZE 10
6 y8 r: p& R0 p* @3 E6 K; R) z2 l% ]7 \, ~' U% D/ Q
struct SNode{
: u9 S* Y$ p4 \, E+ {    float data; /*存放操作数或者计算结果*/5 N6 e8 i4 D( W- [# G; P3 v* S; H
    char ch; /*存放运算符*/
5 X: o- ?6 k$ g6 ^, R};" r- G9 Y# k/ I

/ b4 _, N( w: R. M& Gstruct Stack{% m, C" B% z: s1 r7 r
    SNode *top;7 t- s, f1 M7 O+ j2 ]
    SNode *base;% j5 H4 S+ l; |! n6 ~( E8 h
    int size;
. L: F' c) }8 C. R! p};
8 G. j; ?* X" L' j1 p* `) t' q" \! z6 [2 w- m2 H4 z$ }% M
/*栈操作函数*/; v0 B1 }0 E, D5 _) l/ g" I; a+ T
int InitStack(Stack &S); /*创建栈*/
1 \! Q9 @1 `  @  aint DestroyStack(Stack &S); /*销毁栈*/
- S% H9 k/ B& ?, X( J0 c0 N9 Iint ClearStack(Stack &S); /*清空栈*/
- A1 v$ n; \: }! X4 L$ l: \int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
/ f% b4 c0 A- J/ T, i# y4 c# q" aint Push(Stack &S,SNode e); /*将结点e压入栈*/
+ |- O  s+ c: P! s  }int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ x+ a& O$ S# ~3 B8 \' }+ m
5 K, |! j7 [: i1 j/*表达式计算器相关函数*/7 H( |* f2 K# O, C7 X
char get_precede(char s,char c); /*判断运算符s和c的优先级*/  ]% p: B# W1 t2 _! N3 v$ c6 ~
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
. k. c! e5 c& p# W3 o$ T7 Q& Nfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$ C: H2 S, @* v  C# T3 R+ G
float compute(); /*表达式结算器主函数*/
  k9 C$ g: H1 l6 q# K9 a! Rchar *killzero(float result); /*去掉结果后面的0*/
( y: Q2 k+ I# Y8 r5 s
; ?0 u" ]1 S6 G8 @int InitStack(Stack &S)
# \  {; ?( F) h5 E7 S- T{! {9 I* A) o# F8 x0 r* V7 M8 r
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+ F3 ?' H6 S' N% v' l    if(S.base==NULL); s6 t4 u! m7 U4 {5 n6 _4 W
    {+ S% V) F/ @/ ?( T
        printf("动态分配内存失败!");/ U1 C' q. Q4 g0 O% P$ [
        return -1;0 e- g9 Z3 l8 O6 Z" N2 [- K
    }
7 M3 G9 j; g1 q" G! ~! e2 v    S.top=S.base;
5 q1 R! d' A. |* e. J# v- h    S.size=STACK_SIZE;! r) B7 }5 l8 A( c& a6 f* V2 Z; \
    return 0;4 r% u0 O' I- ]4 z' j
}! [1 q% W& }. t9 P5 I0 e6 p
1 z# [% Y! D0 \6 h) g
int DestroyStack(Stack &S)5 _8 W7 V8 N6 a7 G* Q2 k2 G2 ]
{: j3 _' q: R( m  C! o
    free(S.base);9 g5 _) q: Z) A' E; }$ x* D9 g' i
    return 0;# _# x9 X$ V. J3 W0 I1 }/ e. U* k9 d
}2 j& r0 y0 H& ]+ R/ h5 B6 J

( u! M& i  Y) Q* o( r1 uint ClearStack(Stack &S)
4 V3 r. I) h3 w9 Q* M{+ L4 [/ _- r' s" b1 L
    S.top=S.base;  u/ q7 h( [8 t7 n' O& O$ O7 F
    return 0;
) c4 R' y2 s# ^) _( Z. o) O% S}7 Q) }' k# X$ L; \0 J! m

5 d5 Y* E) s: V& pint GetTop(Stack S,SNode &e)
1 N# o2 J7 Q$ A5 z- v" R{
# m" O" s* M( |$ t) W    if(S.top==S.base)
- Y7 ^8 d0 d! z3 b, S* R3 Q, q    {$ }+ e- }% N& q8 `6 `. r
        printf("栈以为空!");
: a) D  q# h( `) N5 F4 v5 q        return -1;
+ C4 J% m5 y+ q9 p/ V" y' Q- P/ r    }
( j  C  b5 g% F; T1 k    e=*(S.top-1);5 K& [- S* I+ a; Z* s) u# l
    return 0;
3 g+ \8 B6 C1 V5 A3 F}$ b" B% z7 y" N: e1 H* U

- e# _% V0 {# O9 Fint Push(Stack &S,SNode e)
, z$ @% }  H0 c; t  \+ c{
3 q8 W, L- m) W- z2 @; u, b    if(S.top-S.base>=S.size): F" n4 h! U8 t8 J! `& p  g" c
    {
. d& U+ P2 d5 D' |+ S& I        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
0 y7 w+ E* C% X0 w$ B) C        if(S.base==NULL)  G1 w) n% q+ e5 x$ I
        {
* F9 k' c' J0 m$ {* ?! V            printf("动态分配内存失败!");/ x7 d8 t( J: Z: `. @2 Y  a$ X+ `$ t
            return -1;$ D2 s+ V* g" d9 D- _
        }" r/ P( V! Y+ _, _) K+ S) m, [
        S.top=S.base+S.size;
1 T9 B( ~+ m# f        S.size+=APPEND_SIZE;- H' Z0 h1 Q7 s7 j5 H
    }7 c! s6 O* r) @* d' A
    *S.top=e;- j5 S! u- s% W' d: ]2 U
    S.top++;
5 _+ W$ g( U& m+ d    return 0;) x- K' f% k, _6 r$ \2 p
}
0 Q) p$ r0 I* ~6 X* ]: r* f; Q$ N, g
int Pop(Stack &S,SNode &e)4 t, Z5 N. }2 @! [
{1 X2 b" \& i" P6 h3 H9 d: J
    if(S.top==S.base); ~- S3 c' @3 j1 E; Q, t7 D
    {
9 w9 p* R' D; p        printf("栈为空!");# V+ x. y! I2 U; N4 z/ `
        return -1;
3 K9 S1 m; M$ s- ?* q( g- H) L& {    }! i3 _8 Z% c4 P6 x2 f
    e=*(S.top-1);3 o* b& L6 j! c+ Q
    S.top--;+ \$ I; H$ p; y$ i( K& L# m7 O1 L% M6 J( d
    return 0;
  j2 ~+ s* _0 z" i  b' n3 x}
4 H/ Q7 G3 S1 b5 s3 D2 |) m7 g: C2 g1 t. V5 U# M
char get_precede(char s,char c)% c/ T- L0 l% x+ S
{
7 l! y0 l: E3 `% V    switch(s)1 N8 o0 f. x" E  f" f& t7 i  E
    {
* u+ Q/ n, M% D" z/ l0 r        case '+':                 ' R) s" a4 d3 V
        case '-':
: R) T; O! n! K$ E6 m. d) m- C             if(c=='+'||c=='-')* k& _; l. m6 J. y2 {* g/ v1 A8 x! r
                 return '>';5 K- t) L$ [6 \2 d/ ^7 {& L
             else if(c=='*'||c=='/')$ p2 }& |# |6 r7 \* h# m/ j
                 return '<';' y( c+ l8 P# h  g0 j- j2 U6 @
             else if(c=='(')2 s, c. h6 K& z9 I8 }- }
                 return '<';
) O( V/ E5 q: r             else if(c==')')% i6 J! t$ I7 z- a( W3 Q
                 return '>';
, O+ K# s! z" ^/ W4 C! L" B             else   Y7 h6 _% ^5 W+ t6 f/ [
                 return '>';! @; |. m' |% }. ~* c0 \
        case '*':
% X$ o* _; o7 c3 s/ G: p6 K        case '/':& X9 P8 V6 Q; W) [7 V; C
             if(c=='+'||c=='-')% D# X- r9 u+ E$ O* A
                 return '>';
+ b. e& [5 X- T! w8 o0 ]             else if(c=='*'||c=='/')6 K! U4 i9 V' ~! y2 o7 y# u
                 return '>';
* M$ Z9 i! v1 I0 A4 [             else if(c=='(')
  @, |7 [7 o6 I! n. V                 return '<';
, m7 |4 W$ A- W/ O6 L  Q. h             else if(c==')'); T& C& f. G5 {6 w" t3 B, G6 ?
                 return '>';. K8 Q7 Y( C2 K/ k: |% x) X4 W0 R
             else. q$ v& Q0 N4 B2 t
                 return '>';
. q/ P9 t# a: u4 _) a        case '(':$ d& ?5 ~( j# g  P
             if(c=='+'||c=='-')" f7 H9 r7 K: i  J
                 return '<';# W2 i8 X  ]8 r8 v- l. V: w
             else if(c=='*'||c=='/')3 D- R7 R: W# T! S
                 return '<';; v3 ~* u' p6 c# {! n. O0 F" F
             else if(c=='(')9 U4 G6 [' t$ V& G
                 return '<';
5 t' y; A& N" @4 g) Z             else if(c==')')8 C4 j( Q# z* s
                 return '=';
/ U5 C8 ^* p2 K+ J* b" a- w             else
$ o6 O1 Q* z2 J' @4 Z. q, p. F+ o                 return 'E';6 }6 \& }8 Y& N; _( i+ n9 ^& ^
        case ')':
- D" F* T9 X; l             if(c=='+'||c=='-')
. u0 n- d: U3 h+ P4 o( A# k) g; C0 t                 return '>';0 y- i" D4 a5 n6 G+ B& H3 X! ~
             else if(c=='*'||c=='/')+ {8 _1 ]" R2 z
                 return '>';" ^, N, g% U. v& F! y
             else if(c=='(')
5 ]2 E6 ^! Y" `  ^                 return 'E';
: t8 p+ ~; V$ E& r. S  U. U7 Y) Z             else if(c==')')! k# `; ~8 L3 r3 X% j5 W1 N* y
                 return '>';
5 u5 Y" ^3 V  d) i% z8 T$ |1 j' k             else. O5 D, `  _6 Y4 Y7 L
                 return '>';% u" U. Z# i* q3 ^) a
        case '#':
: f+ p. f( Q6 z: V! ^             if(c=='+'||c=='-')" a0 X. A8 ^( o0 x, i
                 return '<';& w* |" p! p1 K# ~
             else if(c=='*'||c=='/')
' n0 A1 R7 l; ^                 return '<';% K6 C# p/ ~- n
             else if(c=='(')3 x' f4 r7 U3 U- N9 l, R5 X* e
                 return '<';
, p  @- f7 y. B+ X$ z: ^3 g- |             else if(c==')')2 p/ r5 l5 _, l; y0 q. m
                 return 'E';# U" V' ^% S- {# a4 p4 A9 [* `! [
             else; N2 ]- @4 X0 t; [) m% z# d# k
                 return '=';/ N% y, w% Q, W, U6 V, J
        default:
2 c. i: b7 {, l' }             break;
, R+ L- ~+ _) F$ h# r    }8 [+ c4 z% D; _4 r6 \
    return 0;   
- `* @; ]) ]6 X, m( H}* I1 `/ ^. L5 r$ g: A

9 F* M8 x8 H8 ]$ a9 Eint isOpr(char c)4 ]# i1 |" R# ]
{: q4 r# a, D1 T' Q6 `# F# Z8 D
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='): Q5 w( [; O3 e' |1 G5 s
        return 0;
8 Q1 ^% s) u9 f0 J" F& t2 k    else 6 U2 u- Y( p% H2 @1 e* j
        return 1;4 G$ s( h$ B- }2 I1 }# C, O, h- K
}0 }7 h2 x- m0 m  ^2 X
7 J! k, r, @+ z" m5 @. k2 T# a
float operate(float x, char opr, float y)/ L% }9 f; M0 D  t
{
" E; A3 H9 W9 m3 Q5 y; h    float result;% @0 z; ?$ S5 L$ H# d+ G! e( _  p
    switch (opr)9 a' G8 U! e. l$ ?3 W# `& m
    {2 {) S* x: ?$ `& u/ @! a: L
        case '+':
# J5 O& c: H( d& K* a             result = x + y;
/ G. p  D. w$ ~/ f& r# y: f             break;) s' P) [7 k" |, u* a8 I/ w7 x
        case '-': 8 i4 K( r& g! J  y# A7 N
             result = x - y;- T7 V8 `: I9 c3 f8 c
             break;
# A7 b+ L8 G  |4 P  n  Q+ H) o        case '*':
( q' o% w) S* S% C6 Q* w1 d             result = x * y;
$ _$ u1 B2 G. [6 B# g1 A: h( Z             break;' i- S$ Q  l- [1 J
        case '/': 0 H3 O: v" \* G! i
             if (y == 0)
6 X1 Y7 X9 o  Q, Y5 ]             {
* M- `* ^, K- r# d. @' W                printf("Divided by zero!\n");# U! H$ i$ N, @) Q8 [
                return 0;) U7 t- N* Z1 m1 \
             }
  X# y; N- C' s! _" l# w             else5 t: E9 L( B, e: ?* h# @2 w. i! N! P
             {
, ^# m& a/ m# f0 z3 L0 k                 result = x / y;
% _" C( y/ \6 |% S) E3 s" N                 break;% `4 W& R6 n7 @6 n
             }
; F; R' J2 O- B/ T2 F( S. V       default:
9 v% E! u+ c& X# i4 \1 ], `- p             printf("Bad Input.\n");
/ `: Y  Q1 w! a) B8 a& E& E             return 0;
& D0 }; G3 i8 M" N) h. B    }3 [& ~- v8 J& ~% w0 D
    return result;5 G" H  y+ R7 g7 e# E7 b
}   
; W1 a% g1 q5 L9 @/ M6 M( ^4 Q7 {8 N2 `9 U
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1 m: Y6 Z6 [5 z8 c
{- j% ?5 [, A$ u5 g
    Stack optr,opnd;: h: Q, I* C1 F9 r
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;0 {. G& p1 b$ I9 B) G4 ?
    char c;2 W) D0 h5 q( k! }1 m+ f& T( H
    char buf[16];
" b7 l! `( U) @3 r# e* L    int i=0;
4 \, ?( a5 t7 Z7 z; c8 k2 f   
1 R' {0 l! E3 S2 N6 A" r/ M! _    InitStack(optr); /*用于寄存运算符*/2 m4 P3 l3 V9 U0 `
    InitStack(opnd); /*用于寄存操作数和计算结果*/! H, n4 q$ R* T0 t4 z; N+ J
    memset(buf,0,sizeof(buf));
) b# _2 x; q: `) Y7 c. H; V    8 [( A* v) U# p1 k
    printf("Enter your expression:");
* ?* U( v% p' q5 [        , L4 z2 r' \% u. n! C( M$ e- ?( r& H
    opr_in.ch='#';' P* _. }' l6 u* p  W- c4 v8 d
    Push(optr,opr_in); /*'#'入栈*/- _; F' k) w0 U
    GetTop(optr,opr_top);  w; W$ B6 V4 M/ z
    c=getchar();
, Z7 w5 \- c8 E3 `$ P$ L7 c' ?    while(c!='='||opr_top.ch!='#')" W) ^5 r& w! G! w
    {
1 w; {4 v0 E+ _5 m+ c/ D        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ q, g/ ?( @& M+ @! ?9 }2 y        {
( W7 V6 X, J# P- S2 b# k            buf=c;
5 a: F! G1 M. t' m7 T; {, @            i++;$ x5 a: P: D' w$ F$ R& y% a% @# H- ^( Z
            c=getchar();
+ h- O2 O8 j% q$ c" U. Z        }! j% o- j6 G( [; m- V" A" ~; h/ H
        else /*是运算符*/
! B  R! Y) q6 n& [: e6 p        {# A5 E, G3 W( z
            buf='\0';
3 w* \* U  s/ r* I& g4 |6 [/ s            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
7 y' b7 b% X6 ]9 }            {
, C+ c& O! Q6 v! @                 opn_in.data=(float)atof(buf);
0 Z0 m) @8 B7 E# N  o- r( H9 i% N5 \                 Push(opnd,opn_in);1 n' _" y7 w6 w5 |5 l$ e/ {! @
                 printf("opnd入栈:[%f]\n",opn_in.data);
+ e3 S/ g7 Z: B1 y                 i=0;
- Z/ }- N) s' r1 ?) I& ~                 memset(buf,0,sizeof(buf));
5 u; E' B. E# B            }9 b6 z) d" C4 K4 |+ c  {- g+ _
            opr_in.ch=c;# o% l  e9 Y9 e: c
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
2 ^3 B0 O) l7 Y2 b# A  m6 e            {6 d$ I: c( V$ W" Q/ [* ~5 O
                case '<': /*优先级小于栈顶结点,则运算符入栈*/: H( k7 v% ?. J- L- \
                     Push(optr,opr_in);
% Q( K1 b, D1 y6 O/ n' R7 q9 l$ g                     printf("optr入栈:[%c]\n",opr_in.ch);
3 {3 ^6 j/ n3 D/ x                     c=getchar();2 a/ }% Y, W) C, d
                     break;, u- }. J2 l, P# S5 o( j. o+ T
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/0 {4 Q/ y1 F( `6 Y
                     Pop(optr,e);
- V* n5 T; C! U                     printf("optr出栈:去掉括号\n");5 e1 @, D. M; [0 |3 n# K3 G
                     c=getchar();1 w% }/ K. F; w2 L
                     break;
) L2 y8 f: f9 d                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/% M6 ~8 M3 `% y( ?
                     Pop(optr,opr_t);
% ^& m, L8 I0 E( a/ t+ T2 d                     printf("optr出栈:[%c]\n",opr_t.ch);
! W2 V+ K- V* L$ o% n                     if(Pop(opnd,b)<0)" ?# v4 s7 q, j5 j7 U
                     {4 W: d* y$ V) n. Z4 ~, ^
                         printf("Bad Input!\n");! g4 Y& E' b1 [* G& i
                         fflush(stdin);, p/ A. f1 r3 m- i
                         return -1;
! P7 {& `2 c9 f! h7 r4 Y                     }( N! @- y* Y/ N: R( V
                     printf("opnd出栈:[%f]\n",b.data);
5 v  z* A( i" ?9 f% @                     if(Pop(opnd,a)<0)
  x5 n1 t7 t# b5 U8 k0 O2 o2 I  A                     {
& A: }9 h8 A, a                         printf("Bad Input!\n");
' `$ ^! T9 d' s1 e, n                         fflush(stdin);
: _" o3 a7 R9 x2 C                         return -1;1 V- D6 ?- e5 |7 ]: M3 z% y( P
                     }
' \& m4 ~/ x( i. k# d4 q( }. Z                     printf("opnd出栈:[%f]\n",a.data);' p7 G0 ^' L4 p. _" Q7 C7 q9 s
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/$ Y' I8 K; y3 I. O% W
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/- y) q2 t0 |% N% ?. }% _! o
                     printf("结果入栈:[%f]\n",opn_tmp.data);8 M" i* M' [6 z2 T  L* Y
                     break;( q; |4 D4 P7 U
            }! R" ?) ~1 Q( C" g" j
        }1 ~+ [3 T6 P1 }' F0 |; T3 u7 b+ z* z
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
, _1 c9 K2 r: R( [2 _( {    }& {- [5 g& g4 F) w. s. U: ^
    GetTop(opnd,opn_tmp);
" N3 F" D1 s8 v: j* m    DestroyStack(optr);7 Y  W/ Y% H2 t
    DestroyStack(opnd);
- R! ]. y0 l0 T; j4 Y  ]$ ?    return opn_tmp.data;9 t4 d" v2 z. `, Z
}) U$ {# c) e9 k* F/ M* Z' I" w# s9 A
3 ]# t: e- W% g4 ~& w& x) w
char *killzero(char *res,float result)% t0 t: ~. C% F
{' T/ H/ m3 Q" Z
    int i;( T) O$ G+ P1 y0 G5 \  g
' l! z7 j8 m3 r9 [) @3 |/ ~- P( j
    sprintf(res,"%f",result);
5 C- h: v! r3 l1 E" {    i=(int)strlen(res)-1;5 s8 [# I2 [4 s2 a6 L4 a
    while(i&&res=='0')
5 ?: k7 A3 i( l- N    {
4 }% P4 }2 g1 X1 f+ p5 z        res='\0';9 i; o/ p  q2 i
        i--;
" f+ ?$ e8 ]# W9 w8 c! p    }
( z4 i! K+ a) }9 O0 E+ V" I    if(res=='.')
) {; L! Q1 d# u% }; n2 s        res='\0';$ x, e9 P! j+ Z  g! r, t
    return res;* Z: K9 ^/ `! i* S: A2 z
}
- L! |- b/ ^1 a; o( v, G
; g% |& B( e. Bint main()9 p7 u8 g4 I* D3 A! s
{
- s- A; S( m* K- F) g+ ?/ Z. }    char ch;
1 e+ ^6 V$ b) P9 L6 D5 c    char res[64];
: W, b% k# r' V* F7 p9 c4 X    float result;1 b  E/ N: j9 B
    while(1)
" [+ Y/ b7 i. G& b9 _; ?* f0 C/ q    {
1 Y( p3 m* A3 ?1 e8 D; B        result=compute();! m9 Q, q. X+ X' H& h. e
        printf("\nThe result is:%s\n",killzero(res,result));$ z: Y1 n# _# C+ }& R/ G0 l( N& u
        printf("Do you want to continue(y/n)?:") ;$ H- Y5 k1 G8 P/ f
        ch=getch();9 v- b% E, [3 a) L. Z& c' k
        putchar(ch);
4 ~% l. e2 z/ ]2 ~. I# m4 U9 E$ ?        if(ch=='n'||ch=='N')' {9 h, R) X# Z; @
            break;/ h) U. b9 ^  D( B
        else0 S4 V& b: c: |
            system("cls");% K4 }! Q" ~% N7 V7 f2 F, f
    }
9 P/ K7 {" ^/ I- F& I8 N0 [    return 0;% X0 L4 l. f& K8 b: c) `
}
2 T+ [+ g" c2 d! f8 \
) Q" k* H; z* l, d
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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