Board logo

标题: C语言表达式计算器 [打印本页]

作者: zw2004    时间: 2008-1-21 17:17     标题: C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
0 C4 u4 b' o0 s程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
7 e! q9 X: A* F) t. S/**************表达式计算器************/3 A4 ^/ ~7 G/ r1 d9 Y
#include <stdio.h>: x3 M& i" T3 R6 ?5 [
#include <stdlib.h>8 }  E5 O" i& o9 n- C2 b
#include <string.h>
8 S# B0 |1 a! U) v  n$ z0 Y3 F#include <conio.h>
3 I1 P# r, I( U. O/ B#include <malloc.h># e! Y# I! `$ O7 {) H

" P! G" d) I' @' Z; c#define STACK_SIZE 100
& f+ t2 K# m: B$ O' z#define APPEND_SIZE 10
, Q3 T0 f: z4 B" v, M
9 _0 I( q- j/ K5 mstruct SNode{
# C: r9 m5 L/ G) e0 t    float data; /*存放操作数或者计算结果*/, B7 N* r5 e) W. H2 F7 ]+ ~
    char ch; /*存放运算符*/8 p' b; Z( @, \/ C; p1 H; \
};9 K5 t  b/ E- q# H& C& h( @# x
; i- S- L2 M1 u
struct Stack{
" Y' ^0 ?! {6 M3 Z* m    SNode *top;
0 B' W  l; d  t# ?4 i$ M& i    SNode *base;4 i) h  u  U4 G
    int size;. ~' [" m+ M% F5 v; R
};6 c: X) o/ \. N: J2 I6 ~1 j, Q- l# T
& d# I/ @/ p' J6 n& I( A
/*栈操作函数*/6 ~1 r& j3 O  E( {8 g
int InitStack(Stack &S); /*创建栈*/1 B" x2 Z$ `) j
int DestroyStack(Stack &S); /*销毁栈*/
2 |" f7 i! T/ H, o/ x% L0 [) yint ClearStack(Stack &S); /*清空栈*/* s3 q( T5 c  c' Z% g
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
$ a) U& d! s1 ^: v- Jint Push(Stack &S,SNode e); /*将结点e压入栈*/
5 r0 Z4 I/ [/ W/ aint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
- N- W; t7 ~, M+ D5 `$ V. a
' {! a; M% H) k' q/*表达式计算器相关函数*/1 [. q+ G1 u; @( b7 h
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
, U( y3 }. v% A# ^int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
) D' H6 w7 y" x: e1 }, t# K! ofloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/2 j) V. |9 b7 j' N8 I+ Y/ T. p) O
float compute(); /*表达式结算器主函数*/  j  F4 U5 n: @
char *killzero(float result); /*去掉结果后面的0*/ ) a/ p0 |) V/ M& a

3 t% t1 k' c- H% L( Gint InitStack(Stack &S)( F+ J8 Z- ^' f7 O- i
{6 L! I$ S; ]8 y2 \* S- o; L# R
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
  t* L* L# }5 ?8 `+ ^; G( p/ h& r    if(S.base==NULL)% j* P' l# K; S  v, k
    {
' W7 j1 c; D( L        printf("动态分配内存失败!");" U- {  z1 e: \& A* r
        return -1;: F/ w1 v; A1 Y9 A) |* A( s# W: p
    }5 z6 V9 J: x; N& O
    S.top=S.base;8 g" z& S/ q9 C5 s% T
    S.size=STACK_SIZE;
3 l0 |! F5 s; B* W1 s    return 0;. |/ I- h& m' }- ?9 ^9 {& Y: G9 ^* {
}& O5 E) n# \& k% G* a
( w; G5 M' l' i, m
int DestroyStack(Stack &S)
; P( ?/ U% w  p& i) @  A{
  ]; W; ~& Q9 ]0 W! K2 {    free(S.base);
* p! e; `% \+ }5 Y& P5 e) l3 ?    return 0;
. q* n7 k. p$ q5 h  t}) r9 w$ a% a+ m; _$ \" P, l
  i6 Z/ I7 r$ h7 b6 }1 Z
int ClearStack(Stack &S)2 i1 _9 b' |' o
{
. N& z& m- A6 a8 _. R    S.top=S.base;
0 F; {' W5 h4 W) o- \* J& k    return 0;
- C, V* t# w( ^( C& b}
+ |+ V0 A( k* r2 O2 l# Z/ u+ Y; J4 P% @. K$ _7 i( {, F( i9 @
int GetTop(Stack S,SNode &e)
9 `% d3 f: g9 Y{% w: Q' s- i3 c7 o; m( k% p
    if(S.top==S.base)& }9 m* v) T  p; p* ?; D
    {1 x7 ?) V: M' z- Q, n+ J
        printf("栈以为空!");% G' R! P2 e+ C
        return -1;
4 \& C& C. C8 z    }9 e4 Q2 v2 Q1 V# @2 I. `
    e=*(S.top-1);
9 j, K, Y# x! f8 `& W% c) A$ Y    return 0;/ o6 y( u' Y1 }3 c+ O0 R# z: A( k
}' P% p" B  V# X
% K; n+ n: ]3 l; j
int Push(Stack &S,SNode e)
$ L$ f% S- ~' I2 I9 v  s/ w{: e& t$ W9 j# x- H' O
    if(S.top-S.base>=S.size)
* h' i' c3 o. {1 b' Z    {
9 g7 R& g+ ^- O  u" k        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
5 a, O# t; P4 p9 g+ X/ G* v        if(S.base==NULL): @+ G& w# z" ?7 N; D5 `& Q
        {
  v( S0 J! M" b! d3 i0 ?/ m: a; h            printf("动态分配内存失败!");9 I  a/ M8 c" ^) h9 O1 \
            return -1;
- F: E% Y  Q; P' B" N6 A        }
  a3 m" }9 ^' J& m        S.top=S.base+S.size;* }% }2 O) {* l% ]8 M5 T
        S.size+=APPEND_SIZE;
" U: S+ T8 R  p4 f# T4 `    }# ^: j# _# C$ I+ g+ x5 X1 i6 v4 Y( o
    *S.top=e;3 k. j% W+ A: [* H; O* k3 j2 v8 o
    S.top++;6 J  a: Q7 N' `* v  X8 Y4 A; }
    return 0;/ L% ^9 ^' X7 q. C
}& O, d- M) O( h4 v/ w
" w8 H8 c7 o- {4 ?% p" m
int Pop(Stack &S,SNode &e)
+ |; \8 u$ G0 u{
  Z3 M1 K7 U! \+ H4 K3 @/ W1 d    if(S.top==S.base)' |; z) Z' |) k! e: c$ e
    {
1 a% J  E& E4 G" G6 Q3 c        printf("栈为空!");
# C7 j9 w( A9 P: K; E) I# `( A5 F2 P        return -1;
+ q. O* o7 i7 V  U    }
& R5 D% f/ _! D/ d1 ^; l0 y    e=*(S.top-1);4 k0 d" Q- z% C/ {5 V# R
    S.top--;
* f( Z2 {$ c, q: N" {& h: z' c    return 0;5 p) z  Y+ J- }! f
}2 [  i' g. {$ m9 ~' z+ _9 T; b
4 I$ _+ b. r4 y4 Q" W
char get_precede(char s,char c)9 t! `! S. V5 l3 B( \& D
{
2 n+ Y; k4 S6 Q; m; I8 ~+ g% q    switch(s)
3 H% N) |1 X8 }' n# C1 O; s    {
2 C, U1 F! i% |  Q' c        case '+':                 " p  M; m! t- T# A  x# u1 \& d
        case '-':
0 @# l  A+ h; Q: Z8 I0 B% @# m. j             if(c=='+'||c=='-')
0 c' ]' b+ l% H$ [, K8 F. ]) `( F                 return '>';
4 J% z# P# k$ o/ K' K/ h3 u2 A             else if(c=='*'||c=='/')
, C  d& `: K$ [$ f7 i+ I                 return '<';% ~, k/ E% P% u% Z
             else if(c=='(')
5 y, J5 V8 V# {# \  ^$ N/ B' |6 ~                 return '<';
- V/ `- H% h% B5 z% ]: n4 e             else if(c==')')4 O: e# ?- o2 k2 ~1 i
                 return '>';
: p. F$ M$ }! G- l             else % n* J  P7 M  v, |
                 return '>';
& o. v! v6 j9 P5 W        case '*':1 R6 O+ j7 |* H: g7 v! `0 f
        case '/':
% D2 ~0 `2 ?' h* _+ \# u             if(c=='+'||c=='-')
+ g" R' B) ^% D2 G# A0 L9 S$ X                 return '>';
* g/ g" F. Z/ V, d             else if(c=='*'||c=='/')% E! F( a6 W1 l7 R' h3 H9 ?$ d, s
                 return '>';3 G2 m: {: [" h8 H/ O
             else if(c=='('). W- _/ f2 h+ D+ s1 q
                 return '<';
/ m' O$ V; [+ _' _* J             else if(c==')')
4 B' \$ O5 S% x. c! L. p                 return '>';* o, Y% O  X+ s" p
             else- L; N# _! ]( z$ @
                 return '>';
) l7 p+ k  b) @1 S! j" r& X        case '(':2 j4 t, E8 t$ i+ [& b; @* }% \. Y9 _# [
             if(c=='+'||c=='-')+ L* L% q9 F( E9 m) n1 g" p. e( g
                 return '<';
; s  J2 T5 n7 i4 `             else if(c=='*'||c=='/')* ]' Q0 i5 R* y  }, c4 k0 t
                 return '<';# j' f: `' n8 ^0 {  y0 I
             else if(c=='(')
8 ~. H! D" Z" f) }8 A                 return '<';
1 c7 o, l, U: c4 F             else if(c==')')
6 P. l8 N2 _+ s* _) Q                 return '=';
# z, U/ l3 `2 H' v/ Z$ _8 G- Y             else& p2 P2 N. p7 X  }8 C
                 return 'E';# k7 h4 j3 ]5 l1 q# I$ ]( k+ v
        case ')':
# c- F$ L  |% G" l. t             if(c=='+'||c=='-')
0 \+ h* U$ q1 g; k                 return '>';, z, }, Y$ E1 h+ F) D
             else if(c=='*'||c=='/'); ]' o& G) k4 [/ a
                 return '>';
% K  t  a. M3 Q* h7 C8 Y0 ~- _             else if(c=='(')8 m& `' @/ ~! q* ^, ^2 [
                 return 'E';
" U' o, p4 q4 P, {/ ]5 B             else if(c==')')
  f3 g# p; E% H1 J0 g. r( G                 return '>';  \: A+ A' [9 o' p5 S: \
             else
& t1 M/ t1 ?. f7 W; `; ?6 \; X                 return '>';
8 R1 z/ }* ]/ z        case '#':
; U  n+ w- Y6 W$ @0 f& g             if(c=='+'||c=='-')4 c4 S) N1 k: l
                 return '<';( L0 Z5 h( s9 o! [! X- \* a( A
             else if(c=='*'||c=='/')
+ w& G0 i$ L7 o1 ]0 @                 return '<';; o$ l: i, n3 b7 x  r/ s
             else if(c=='(')
- n. j- d# Z; ]) y5 X" ]9 F                 return '<';* v, Q1 m( z9 i
             else if(c==')')
3 C2 K0 _  [# z% L" Y                 return 'E';6 j' r, C& s8 Q! M  w8 H
             else! t7 s8 p6 {7 o6 |/ w- T
                 return '=';
) }. O$ L# U- j( l        default:+ d7 X6 Y9 O! R
             break;
3 [* R7 J7 h- ]' }    }& Y8 x% ^& ~3 ?4 k/ j
    return 0;    . b4 ~) S; C. C' ?) |  ], J
}. P& N/ G2 Z: k8 S$ ]% C1 ~

7 B% n: H3 m  T% ]. S5 c$ W" y8 c0 lint isOpr(char c)
8 b3 ]0 A. Q# V/ N3 g2 c- h{
9 }% y* k0 N4 i  D: x    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4 C$ C1 Z7 Y" S* ?" l        return 0;
) T, ^9 Z8 {' ^0 K    else
4 D( X3 t4 @+ K        return 1;' g/ c2 b% p/ B, e
}
& F) G' u# `0 c2 ^3 Q4 W0 V" N& h4 i* l7 K' `
float operate(float x, char opr, float y)
! A3 t2 N( ~9 j9 f$ g0 {{
; t6 H5 I* Z$ ?! L    float result;
+ w3 @  f/ W, q* U! V3 e    switch (opr)
; p% K# b. V3 F) `+ E  Q" ?8 u    {
4 g2 U3 s  H+ h  \+ w4 i7 \        case '+':
/ s) I- `/ Z) u4 {8 C# [1 v  V( C             result = x + y;
8 S  x, u& c+ e7 Y             break;
. F& T. \0 h5 O7 o  ]3 F6 P5 b        case '-': 4 I4 A+ ?, A7 }' t  Y6 [0 @1 \
             result = x - y;, k) B: e, h- \$ u6 y
             break;
! b" B1 p( q6 w        case '*':
( [7 A$ k$ f: G; _/ x( q             result = x * y;
' k# g. _2 g3 q+ v3 t- L             break;! n; l  |; y6 d& x7 R  r* ^
        case '/':
* e, D- \6 v" ~% ^# e             if (y == 0)
- [  p0 @  O6 i             {" t7 N# |. |) A9 p8 k
                printf("Divided by zero!\n");) T: m. `0 p; z5 H
                return 0;
8 Z; g1 K/ C8 Y$ z% K. w) ~% Z             }
  e( }  s) m2 f# E1 z- e8 d             else
, ^( t* {# Z; q, X1 }& a- g             {
# W; `% V5 A4 R2 `9 h8 H                 result = x / y;- ], B9 o$ @& b- F0 H5 t+ H9 L
                 break;
% ~) E* U; S: w- G             }
# a# B7 v4 p8 a0 K. f* N1 B0 h       default: / V( u9 H' ]  C- L
             printf("Bad Input.\n");
3 H6 Z3 Q$ h7 V4 A' C+ _! c% B! H3 C             return 0;
9 l2 H6 C8 [4 P    }) F7 o' I, s& h$ P
    return result;
+ m# ^- _* O7 b}    1 \# G5 M7 m2 o

+ @, e) J% E% Q: Gfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
+ v+ K7 g+ [0 S. ~% e{
7 ^( n( B, |* z    Stack optr,opnd;$ O. f0 ]/ {( u1 T  O1 w; H% O
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
* B6 @4 w* Z% |( B9 ]( f; x    char c;
, Y9 C* x) M% E+ R% b; b2 R    char buf[16];2 {" S5 `7 z# }; s, {+ `
    int i=0;
/ Z1 r! F' S0 J( K* J, X    ) C( B' z& D: l8 l
    InitStack(optr); /*用于寄存运算符*/) s" W. g$ e$ \; K
    InitStack(opnd); /*用于寄存操作数和计算结果*/
) h; t8 T8 E  R/ _, r3 ?    memset(buf,0,sizeof(buf));
0 g$ K" V3 U* ]$ M1 `; k+ E0 [4 A7 c    ; W" i& J# u! N9 f- ?$ m) a
    printf("Enter your expression:");. [; W! _3 {! c
        
& z0 y2 \; N; K7 z! R+ C    opr_in.ch='#';
# C) y/ I% m. U2 P  w5 l6 B5 J    Push(optr,opr_in); /*'#'入栈*/
1 F: {6 G+ k5 G6 g4 J    GetTop(optr,opr_top);
- r. _" [( i- s+ b' ]    c=getchar();: Y$ O: O6 z7 Z3 Z5 f7 S
    while(c!='='||opr_top.ch!='#')
0 m- s$ L) S: z6 d% e    {% f) `. G1 F4 p+ |
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*// U0 ^+ k; v) w6 O0 Y
        {
3 C7 t) R" G( I$ O; a8 s6 t            buf=c;
! @; Z/ V. ^$ r6 \& y) e. I% ]            i++;. n5 V# x# I! a
            c=getchar();- t; O* y) n: B) X% A, n
        }
( Q' X" J5 w5 j, t7 E6 z. K1 ?        else /*是运算符*/
* D( n  P; M0 W$ o2 M        {
: c( l0 @3 @/ P% W7 T" v            buf='\0';
* r: o4 s2 m' K1 \( |. m3 m            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/: M% A, Y1 T( v6 @2 E% P
            {
! O' Z. L# @; ?$ c. |9 ~                 opn_in.data=(float)atof(buf);5 @  @! ^$ M- L+ X
                 Push(opnd,opn_in);
4 _1 }3 G3 b- ~                 printf("opnd入栈:[%f]\n",opn_in.data);
  z- ?" P7 g0 C/ k9 J                 i=0;$ a  o, f" v/ M
                 memset(buf,0,sizeof(buf));
0 w) H3 z; `0 w5 D& Z7 S, h            }
) v3 N9 M8 h# D) z            opr_in.ch=c;
" n3 I! r! {  M* k0 g, P* Z            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/" [8 M- Y* H& b( h+ R% {
            {* K; d2 G" Y8 m0 r9 I+ n/ e2 v
                case '<': /*优先级小于栈顶结点,则运算符入栈*/' C/ ]0 S! A( W! d" M! t
                     Push(optr,opr_in);
* j3 A1 [6 @7 [2 R; _7 W                     printf("optr入栈:[%c]\n",opr_in.ch);/ y8 g) K9 R. E! e+ M5 |* Z
                     c=getchar();
6 D6 m( a& R3 j9 A* U                     break;
6 X( h. m5 s0 w                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/: N: X8 w7 p4 N2 z8 I! T& Q, @  V
                     Pop(optr,e);
) |% t9 ^; b7 M6 }                     printf("optr出栈:去掉括号\n");
8 q/ A* p6 v# A- m7 T                     c=getchar();& W" E$ T3 q8 L0 H! p6 b
                     break;6 k! W. ~/ a: H* J* v  g5 x$ y
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
/ j0 y' ^1 D( r- }, _                     Pop(optr,opr_t);* B# Y; L5 g0 F4 m, H
                     printf("optr出栈:[%c]\n",opr_t.ch);
6 e. `- f$ x2 y) k* f  z: V                     if(Pop(opnd,b)<0)
5 Q- f  M, v3 G7 \( m! E                     {
# W2 j/ M0 q, p. q                         printf("Bad Input!\n");) p& D2 U! `2 k7 |$ j5 j0 `6 _
                         fflush(stdin);
* ^6 r5 }9 ^0 |6 q! S                         return -1;# J8 ~/ z5 d* [& e) V# s6 p' s% L
                     }
3 R: k6 N9 }$ M$ \                     printf("opnd出栈:[%f]\n",b.data);! X$ C" }! r! E* q) j) [
                     if(Pop(opnd,a)<0)0 p3 E# [( _- z" o; g
                     {
7 K7 A3 o6 a% A1 E                         printf("Bad Input!\n");7 }2 P, ]- k9 K. H
                         fflush(stdin);4 D8 y) S! e, s
                         return -1;
. Q+ R7 R  {$ {2 ]. N6 H; D0 j                     }. c3 p* C0 i0 u* F- F3 l1 A* G- n
                     printf("opnd出栈:[%f]\n",a.data);- K' ^! ?+ C) _( t4 E
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/9 [& K0 D1 M# p. X$ t- }# L& ?+ s
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
8 i& u% t; W6 a( t6 f! q                     printf("结果入栈:[%f]\n",opn_tmp.data);, `% n* ]; [* U
                     break;. Z: \0 q' n1 w; S$ J
            }
3 O7 ~; V& @1 }' `, w& `        }+ z; [' p: K, U" ~7 I
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
; s9 n( U3 _- C6 {    }
4 U$ H, D! Y& [! ^+ G& |' a    GetTop(opnd,opn_tmp);
. Y7 |! C. ]4 L- R8 n" V) P' p    DestroyStack(optr);
( B5 }7 R) w- N, }    DestroyStack(opnd);" g& Y- H) m5 P; }, e4 c
    return opn_tmp.data;2 J3 s5 U% C1 j5 N6 x1 {4 W3 a9 A
}9 l' U1 J' X8 z1 I) J" ]8 q
3 ^: U  e/ ]( K6 v  q# ]1 F
char *killzero(char *res,float result)
7 W* Y( H/ X) e{
! E; I+ K* g3 o& ^. k    int i;
! H- [, H) W* n7 c% r
; p6 b. v7 `3 J9 R1 ^- {    sprintf(res,"%f",result);
$ q3 e, {# m: x* Q2 J5 s    i=(int)strlen(res)-1;
! L0 p0 L$ O* G# \* P8 S    while(i&&res=='0')0 q- X/ ^# Y2 U
    {: i$ z/ v) `* K- B" E
        res='\0';4 D9 a9 B* O# \; H. w
        i--;8 I. x7 t# ~7 v: M: T" `
    }+ d/ s+ G, s' K6 K) q' }( X+ s& s
    if(res=='.')% z& ^3 K3 K, K9 T1 N4 a
        res='\0';9 J; h) C: j6 H; W8 p
    return res;3 Z  e) O  s$ S9 l4 k1 N% Z# G
}
+ w! v) E( {/ ]* m5 G
" V5 e- u  a8 U* ?8 fint main(), ?3 i  C0 N* m* X
{
2 b" m; s  L) g    char ch;' m1 F2 I- p" h0 M" n
    char res[64];3 S' Q4 X8 Q6 p; p7 L0 c# F; D
    float result;" w* y: Z) L% Q9 I5 m3 ^8 ?( H
    while(1)! r) z1 j$ @' `* ~
    {  G1 F3 d3 y# \! W6 I! I# O- p
        result=compute();3 o4 N0 q0 [& I. j+ {0 U
        printf("\nThe result is:%s\n",killzero(res,result));
- I; [; a- O) B+ w1 z        printf("Do you want to continue(y/n)?:") ;( {5 L4 g5 E2 O: N" W2 R1 g
        ch=getch();
5 }8 `1 A& ]1 A        putchar(ch);" k) t) y/ A" Y9 E3 }( ^) ^. U
        if(ch=='n'||ch=='N')0 G' m" A* Z. F% f8 v
            break;
& A& L$ l& ^2 P$ J' k        else" r' l, l: _1 I; c; f
            system("cls");
  G* P0 g( I3 t" x6 i( K7 B" @1 j! t/ F    }$ {* c0 L* s1 @5 D: t# K
    return 0;$ O; [4 w1 E3 i# }/ X6 A5 p
}
$ I; ]- Z0 h4 K
- Z. v: K/ G$ M8 g
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




欢迎光临 捌玖网络工作室 (http://89w.org/) Powered by Discuz! 7.2