Board logo

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

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

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.9 k1 _& s6 K% \
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
2 D, ]: \& X7 x! {0 p& N# O( E/**************表达式计算器************/) r9 P3 L7 E9 X! h
#include <stdio.h>$ W4 p% B+ H! [* V) W
#include <stdlib.h>
; X: ~5 P3 z- N8 i4 _#include <string.h>0 k; S4 B7 ^1 N" h
#include <conio.h>0 k4 Z& p% [+ o( _
#include <malloc.h>
8 q8 M7 t- G# M+ `( a. Y9 F' n/ {5 ~- d" T$ R
#define STACK_SIZE 100
3 A/ R& G+ Q) I' M#define APPEND_SIZE 10
  r4 b3 ?8 y1 u4 ^* C8 [: H9 Y* D1 x+ d) @- ^! _3 _0 D
struct SNode{" K* E/ c$ q. Z; r1 l- U
    float data; /*存放操作数或者计算结果*/+ b- m% O/ Y( @! ?( Y* d
    char ch; /*存放运算符*/" u0 n+ Q- R, G) i# n
};
: j2 P5 K, o3 y; q+ k3 ^% l
& }' O1 m( I- ^- d( v' d( n, f5 Wstruct Stack{& x9 k! X( U+ V. h
    SNode *top;
' a: t+ A& f2 W% q$ u    SNode *base;) U' K1 ]7 |5 `0 s% ]- Y, z
    int size;
9 X3 R2 J; Z' C};+ T3 [' \; @5 k( Y: K1 ^
+ b. \  w: V# O2 P9 ?8 w
/*栈操作函数*/
* n( p7 D( Q) B  ~int InitStack(Stack &S); /*创建栈*/6 R. z; l, }+ }  s
int DestroyStack(Stack &S); /*销毁栈*/
/ W- k9 |8 u( F& o& g$ pint ClearStack(Stack &S); /*清空栈*/
# z3 P1 }+ ]5 Pint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/( `3 R/ L* U( R" V% w3 z
int Push(Stack &S,SNode e); /*将结点e压入栈*/
' A( }/ f  J8 L, i3 j/ b( b& eint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
' f2 p2 F( R6 j) T. `; S; }# Z# J1 L+ t
/*表达式计算器相关函数*/  ^9 a8 [; R" x% E4 {7 `
char get_precede(char s,char c); /*判断运算符s和c的优先级*/0 I% \1 d) q( [# K3 ~
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/( S& s1 M# l" ^' w
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/% ~6 E, r7 |. r% U
float compute(); /*表达式结算器主函数*/
7 V/ a3 T7 w* _% p  a: y. vchar *killzero(float result); /*去掉结果后面的0*/ ) k" r+ [  E! D' O) o( ~4 W

0 j$ Q7 I5 J. E. v, Sint InitStack(Stack &S), A$ E6 V; T% r5 d" r1 e# F0 u
{
- P+ m- x) }) ~2 ]# q2 M3 h$ R/ a    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));2 L2 W+ U! u, s0 @2 ~  W. e
    if(S.base==NULL)
) C$ i6 \1 m) ~) _4 N$ [    {, \7 h5 Z" y4 ^+ U' B! Y
        printf("动态分配内存失败!");4 W+ l0 u" u& h' ?& h! ~
        return -1;
/ O" h) e. M, {3 l# z    }. n1 K4 @. H& K+ W. V9 q) c
    S.top=S.base;& }; |2 g: F6 c" ~7 l9 Z/ U
    S.size=STACK_SIZE;; c( }7 B) [$ B3 j4 c8 ^
    return 0;7 G- K9 t' y7 N& m
}! t; f; C' c, s6 _) U0 e) `
  G9 }0 q1 n* C% n% I4 @5 `- i
int DestroyStack(Stack &S)
2 y0 L- c* x* x{
7 r  o4 Z" J0 D3 e9 f- _4 l    free(S.base);
0 K( R! G; W" j- [- c: u1 H    return 0;
9 H/ k5 [' k- m( j" s& B}
: _$ D! g3 T3 _) J3 I; T" [5 L3 `" w. z) k' M+ p
int ClearStack(Stack &S)* ^$ w) Y$ ~5 P4 u6 S5 n& Y! L9 W
{4 \9 D) M0 _) k; [  n2 d9 V) ~
    S.top=S.base;. K. \1 F6 d. |. j
    return 0;: g, q5 C: X) M8 J4 y. \; t
}
/ R( ]( N3 C7 c9 J, t  `; o+ X' ~
5 K' g- [( b4 W- kint GetTop(Stack S,SNode &e)
5 v# ~4 T0 \3 d' I' U{
! T8 |; p6 _. ]  A8 X    if(S.top==S.base)0 q4 c  {+ ~( ^$ y/ R
    {7 L4 k5 O& s5 F0 a" h
        printf("栈以为空!");. E$ N8 A: z% S7 z( R- o
        return -1;
% m$ r: _! `  J& b% Z    }
2 [) `! X  D" \1 p    e=*(S.top-1);9 }  T; t. K$ u2 h5 ]% y: R5 M+ Z5 |
    return 0;* ^3 f" K; R( S# V- |
}- b1 |8 F0 {2 [8 H' k

4 h) I  l4 |3 ]* t: I* \. zint Push(Stack &S,SNode e)# ?0 y' L9 L4 ~: a8 }3 z" e1 w8 u8 |
{
1 V- D' I9 f+ ]! L7 p    if(S.top-S.base>=S.size)* P0 H, o% R" Q9 s. n, r# J
    {
4 a) Y- t3 E8 l$ W        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
/ ?+ v- W! I$ L        if(S.base==NULL)6 B6 [, V$ n  J! M! S! N2 h9 U8 K! c
        {
+ Q) `: H# w2 g1 L/ `: j5 w            printf("动态分配内存失败!");2 F% y% o9 R+ s7 I
            return -1;
  J2 G  @$ O, R1 I        }
8 D; A: F8 Z5 G4 }% E# Z        S.top=S.base+S.size;
8 w6 o& N% _0 c( w2 M        S.size+=APPEND_SIZE;
1 h# k# l) Z  ?) Y- R1 S% s    }! O( d- v3 D# ^1 }  I/ C. c
    *S.top=e;. s. H# M: w# C  S  ^
    S.top++;, p: ?8 T* ]4 j" h7 R: y. R
    return 0;7 O, K1 P# v9 T( w9 a
}
0 k4 t- I8 z' ?" [
! a1 m. R. l8 D8 ^* sint Pop(Stack &S,SNode &e)
; z% R) }6 A' V{
& ], j7 b4 E; `: n) i+ l    if(S.top==S.base)
2 M+ y7 E. ?, a; D! q/ j- K    {" F$ l; G! b6 X/ c/ s
        printf("栈为空!");/ f: d/ O" b' |. m9 [1 w" Y
        return -1;
0 l8 w5 ^8 J8 {  E7 G$ G    }
, _; r* e& W! y" u    e=*(S.top-1);
, V" P. j- G) k9 O7 \    S.top--;
, C( z& G* J! ~0 K7 w    return 0;& {) e- F; ^, m0 H* F" P2 a
}
% ^& Z& ^' p9 {2 v  }7 ~- Z$ g$ x( I+ y3 L( R* S( Q, l
char get_precede(char s,char c)1 S7 @' S9 g7 Z3 ^2 Q
{
. X8 K- b7 h5 C- B7 V" f    switch(s)
+ P* {9 A) |1 k$ M5 g8 \    {
- s" l7 J- v" p$ t+ D. m) y) K        case '+':                 7 l0 K1 W/ z; V
        case '-':
$ |& ~/ }) b0 B3 B4 Q1 O5 ]9 @  D, A             if(c=='+'||c=='-')8 l: K& a0 a3 X; p# P# J4 V
                 return '>';
3 D) d& ^; e- {3 m4 s! W% I# }( B             else if(c=='*'||c=='/')' E4 X; c; N8 R; [% r% U
                 return '<';" k/ O( s( Q4 L6 [, J
             else if(c=='(')
: l' D, t* d) ~( ]0 X  b8 z% H% z/ E                 return '<';8 e$ ], Q+ A8 ^0 A( s6 T1 K
             else if(c==')')" x+ u2 s& l) l
                 return '>';
; X  A. s/ t/ b7 y! w! P1 f7 r' {. R2 a             else : W$ d, Q: Y6 r, \2 [$ o1 V5 K
                 return '>';
' T3 s4 `. R3 B        case '*':& m; N5 _' z- j# e" L( `
        case '/':" `0 A/ `" f% [6 c6 l
             if(c=='+'||c=='-')) h% `; Z4 |$ I8 X( f% b  H6 q
                 return '>';
" S; r2 `6 [! l2 z- S  A             else if(c=='*'||c=='/')9 W4 m  _& O+ c; X
                 return '>';; ~1 s3 [$ Y2 R9 Z# t0 q/ U, {! u
             else if(c=='(')
4 B: N, k$ `/ \1 j) I9 o                 return '<';
. s) C% w+ [8 a% y: H. V             else if(c==')'): _. B: i7 {( N" G- H
                 return '>';
  S7 v4 L4 c3 e: z% `1 z0 U             else) L5 L& D) Z/ H0 U) C- R0 g0 L
                 return '>';
* _- u; `" o+ ]* g2 i, f5 W        case '(':
! V) j5 ], ~  \* l& _6 d             if(c=='+'||c=='-')  x+ D& d) |& ~& l0 p
                 return '<';: J" Z/ i" H1 @+ |" [0 [4 ^' A9 N- O
             else if(c=='*'||c=='/')
2 h* q# L+ n5 k1 Q% v                 return '<';; i- V) ~- Y) l! `7 r9 b; Q
             else if(c=='(')  \& \$ E5 [7 u; o( c! {
                 return '<';
- m& e4 d) Q6 b             else if(c==')')
$ @5 W  N$ Q' v6 S- ^1 A; B3 C. C                 return '=';
$ ^; ~% w6 n7 y, w1 J$ J             else
3 F+ u0 _1 I5 d                 return 'E';
/ p9 X& P7 o2 ~: c2 t; B$ ~        case ')':
' B  g8 W3 }, [, J2 i1 }- N# z& t             if(c=='+'||c=='-')6 }+ F. K! X% A, I+ i' a) [" p9 h
                 return '>';! ]9 S3 X) D, U& h) _" w4 F
             else if(c=='*'||c=='/')
5 m5 B9 |( b9 t6 O) E0 v                 return '>';! m$ \- H, e3 o3 w: K  E- L, c7 Y% C
             else if(c=='(')
( m3 e9 f" @4 H) o+ p                 return 'E';0 j- _9 S1 K! R; S* S
             else if(c==')')
& a$ v5 Z4 w/ {5 v8 \5 X% v7 [2 A                 return '>';
5 S: v( v  E$ D9 f             else6 z$ ]' R6 a/ U" ]. q; W" n' G
                 return '>';; n/ N  y$ t% _6 I- q
        case '#':4 H1 {# ^1 e. s- w: j* g( x, s
             if(c=='+'||c=='-')
9 Z7 f5 R; Q/ i5 g5 K( l                 return '<';
) K' L$ u9 @( G             else if(c=='*'||c=='/')
  G4 `, T1 n; z& E- O, ~                 return '<';1 O6 L( f+ g% L; \* U: i
             else if(c=='(')6 M, u3 }# ?4 V
                 return '<';
+ n+ t. y/ d9 }7 ?% x$ \             else if(c==')')
8 |! z% e6 R0 N. }                 return 'E';
5 H( Z! F3 I+ V5 T1 l* L4 W0 w             else
( Z: b2 X2 S: V. k# z# }                 return '=';8 `8 W$ [* U5 ^' b
        default:
3 j- t6 f2 _7 q+ w) p             break;8 N. K& X  O. U* C0 p) t# E% j& x
    }
9 Y7 |. z  e1 Y, Y  ^    return 0;    3 W" c( @- {7 I7 z
}/ o) I6 A  n1 b( E9 n
1 j" S* U( k6 I* I
int isOpr(char c)' g% T# n+ z/ b7 H
{
; Y9 b+ |5 \' Z6 c- g    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')5 [- \! B1 l+ o2 \2 T
        return 0;
9 k1 i: U5 @2 B" A( o1 l+ |% l    else : i& m9 \$ m) M) l
        return 1;
1 \3 f) A% k' y9 n}
7 t0 B1 ?4 h* z& ~8 O' p; m; @& b+ I3 Y8 z6 r$ c* u
float operate(float x, char opr, float y)1 k# L7 _* u1 _* l2 d6 h2 Z
{/ W/ X" X6 e: l# w- s
    float result;; v, J9 k# f( X  a* Y' M# k6 T
    switch (opr); _) q" t# `! P6 {3 c2 L! ^* ~
    {, H0 i$ j( n4 z& m  s/ }
        case '+':
! t4 z9 l* ~7 m3 R; @             result = x + y;6 s+ H7 y# T( ~0 D$ E- y! G
             break;+ z( X9 u9 h( m, l. z' t
        case '-':
: f$ G8 R. A+ i             result = x - y;
- d, w1 p+ x' n0 Q4 b% `% C             break;
, H1 ]7 a3 z! U" H4 d        case '*':
& g- e  D; z' F             result = x * y;
" W, \, Z3 G$ c  D& L6 [) x2 x             break;" t) v4 L8 P5 n8 p, f
        case '/':
. k- y6 W; ~: F( Z             if (y == 0)
- Z' m; r8 f& e4 @             {
3 c+ [# e1 S3 N" J8 B/ t2 \                printf("Divided by zero!\n");
' b* {# a% w+ W$ W$ V( @0 a                return 0;
3 \* ?7 Z+ N. w# \) [' h             }2 z& B9 Z" G$ k% ]7 ?& H. A
             else: g* w7 r: E1 x+ K9 G3 W9 L, g
             {
* X5 j9 W0 T( }4 x% L& W                 result = x / y;5 S0 c4 B% T" X" ]! H
                 break;" ]& z* X7 d- U0 @6 p. Q
             }
* _  p! n( g, b. n' H! E       default: $ [) w) A5 y8 _% m* t) @) g
             printf("Bad Input.\n");
$ \3 M: {" w& D, `             return 0;+ M+ Q$ N+ t6 r9 M+ U  T7 K/ ?2 J
    }  d6 n7 C- @  D. p& V7 C
    return result;2 E! c- |$ i2 j' n' @+ W
}   
4 B  r8 }+ P" D& l+ \+ q6 N. G  j
, C6 d5 x* f3 {float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8 k' ^' x+ g9 B{
, H8 v7 S( b1 Y2 Z4 b4 s5 K    Stack optr,opnd;
, `  _1 ^5 Y9 z2 m( \5 F    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
) [, [1 n/ ^$ ~; Q/ c/ R    char c;# }2 x1 q4 u7 H
    char buf[16];) ?! s! o' Q) R1 B( |1 e
    int i=0;
. ]' b3 R8 Z: |+ w' b   
1 i0 I, ~  y) X: u: E) t$ [# ]; G    InitStack(optr); /*用于寄存运算符*/8 [5 Z: Q) ?' `& w/ W/ A% k
    InitStack(opnd); /*用于寄存操作数和计算结果*/
' k1 v. ?; P8 i( D4 c; t6 z    memset(buf,0,sizeof(buf));1 j9 `( U% C( g+ }
   
- v) c7 }+ {! y: w    printf("Enter your expression:");
9 w1 f2 \5 S/ x& X        
' H. l) S4 ~) B: q+ e9 {2 {# x2 @    opr_in.ch='#';6 Z' y: }% N2 }, z# K  E
    Push(optr,opr_in); /*'#'入栈*/: ?( u4 J  {5 l4 t: Z6 [
    GetTop(optr,opr_top);$ j% _4 X: [) c; t# Z
    c=getchar();1 Y+ K$ j# ]$ }: v) f9 m0 `
    while(c!='='||opr_top.ch!='#')' A# d( a/ u# ]! e$ e7 P+ B9 ]
    {
* H9 Z% O0 X. D4 J        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/$ Q' B& ~! c/ R% U3 n  B3 `
        {
  P' G, v" ]( v; b; l4 f. [9 E            buf=c;! T: \. r, @# Z9 q6 X+ m
            i++;$ d3 b% C5 ]7 B' K3 R
            c=getchar();, \, n9 D9 }  \  R# b" x8 H
        }8 P3 [( Y* W- r! p3 I
        else /*是运算符*/: z7 j" b  o  d: f; \
        {
! l4 w; X  B0 d% `# G! i! m/ c            buf='\0';
3 _! ~7 j, a* f+ `$ ]) j; M            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
% c# ^7 a5 _% ]* p            {! t* {4 V" P- ~" H
                 opn_in.data=(float)atof(buf);% R. O- m) m/ g0 n/ c+ h& M# ?+ K: H
                 Push(opnd,opn_in);. z/ U; z" Y0 T9 _) j+ W( O
                 printf("opnd入栈:[%f]\n",opn_in.data);
  V0 W/ b  H3 M: C1 o' e( T2 ]) A! P                 i=0;
- z* R7 m( Z" p; f. a                 memset(buf,0,sizeof(buf));; c! j0 q5 H6 H; S# @
            }
. s% k) b8 _! a6 x  p7 \            opr_in.ch=c;
$ N+ D" v% q7 U- e, H            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1 X4 I  G6 A/ M+ J) u$ W- A            {
2 ?; o5 w/ m8 W) ~$ n% {                case '<': /*优先级小于栈顶结点,则运算符入栈*/
  {5 v5 R, g" H                     Push(optr,opr_in);1 D! W! ^4 b/ R9 u- p
                     printf("optr入栈:[%c]\n",opr_in.ch);
9 u( ?5 M+ p9 A; Q' W- S                     c=getchar();
/ V6 }9 w$ g% F" k: v                     break;8 l5 L9 }, R/ ~
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
4 b7 m& o  w" k                     Pop(optr,e);
  c3 j0 I" {; ?4 r2 j7 [4 u                     printf("optr出栈:去掉括号\n");
+ I( W  s  p0 R9 x% k                     c=getchar();8 |9 C. E( E. u5 O
                     break;
- n3 S6 c7 `- Q                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/0 j  U# H# {- c
                     Pop(optr,opr_t);
$ K' J' ]8 H8 H6 X% E) ^                     printf("optr出栈:[%c]\n",opr_t.ch);! K. J  a" X4 p
                     if(Pop(opnd,b)<0)
5 i3 c8 E' |5 T. h1 U# Q1 [                     {' f$ `" P+ c* `5 ^( M) l  b4 V
                         printf("Bad Input!\n");/ \8 h4 E  Y5 v2 p4 [6 d
                         fflush(stdin);
# h5 M; T1 Y* [  j5 A; `: H                         return -1;, Y  ^* g  s4 w4 V$ n5 ]1 Q
                     }3 K+ y$ c; i/ O% H2 K
                     printf("opnd出栈:[%f]\n",b.data);
$ K: R1 _  _4 i/ f3 N                     if(Pop(opnd,a)<0); \% }8 B+ \# {0 U
                     {
+ |4 y! w; W1 A9 C                         printf("Bad Input!\n");2 ]. Q% ?2 ?9 ]5 e1 X) ~/ ]
                         fflush(stdin);/ A0 G  s- @" y; O# i# c
                         return -1;8 {6 s& U- P! Z0 A, r
                     }
/ x0 g/ Q! [5 F                     printf("opnd出栈:[%f]\n",a.data);
$ u/ e3 J& h! T                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
+ ^+ l5 s+ p5 E9 |                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
. w" S) @3 w. O; q: `' J* k                     printf("结果入栈:[%f]\n",opn_tmp.data);
1 B: L) c) p0 a' z3 g                     break;
( i4 q& l" Q$ d& t" W3 i$ C6 J. T            }, {) X: H4 B! c1 u, m7 J: s
        }5 g2 L6 Q* f/ b. Q
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                  L  m0 P) W# d! s! l
    }5 R& w# @/ ]' ~. |; `$ p, Q! W7 l
    GetTop(opnd,opn_tmp);* Y& k0 P) \/ G* `( n, y+ Z" K
    DestroyStack(optr);
) [# t5 h8 T( h" B    DestroyStack(opnd);
/ ^; I, w$ v7 {( {+ j    return opn_tmp.data;/ j4 j' ^( B$ |, o% f& S
}
7 j) Q/ o2 m' b  Q  U# [; q/ G  G2 j  ~; d, Y* ^% F3 l; e5 ^
char *killzero(char *res,float result)3 T' l3 c6 J8 ]: c- o% g+ _
{! p% L0 K( J$ }9 A/ D# u4 @+ Q
    int i;
3 U1 P, {2 u2 z1 M5 p7 M7 ?+ r0 e" l; o5 V' F6 n
    sprintf(res,"%f",result);
, U% V3 I8 A0 h  B) g. H  h    i=(int)strlen(res)-1;% f5 E+ f2 ], h8 v" o0 B7 O
    while(i&&res=='0'); b7 q3 e- |: a
    {
& h' X# u# c1 }" F, A/ S# S) _" P        res='\0';
9 h  f8 X6 K" m        i--;+ v9 H: c1 d+ Q9 [& H0 K; Y; l
    }
( D6 w- I  s9 K+ n9 o) L6 t, I    if(res=='.')7 u$ X* Q2 B, D, [* q: I8 T( g: E
        res='\0';) F& t! }# @2 r( j- o
    return res;
/ z7 Q# t& w$ e5 I& u0 _}
# E1 j8 g: b# e! m  b
7 E8 Q! i+ U, n0 \  gint main()  F8 M( P1 C+ @
{
9 s: {9 C' `* g$ c    char ch;' J. J/ [1 ?3 x( g1 v  w5 ?
    char res[64];
( E4 o$ I  ?& C! {    float result;
! C9 Y0 {/ E2 i3 s    while(1)
; t) Q) V, J9 P3 C2 a4 @' Y" }    {% v5 P7 I6 l+ U  X+ K$ u
        result=compute();
; a! z* k6 u( Y: }9 v- L        printf("\nThe result is:%s\n",killzero(res,result));
( E7 L2 M6 X* K( t# M% B7 k2 R* `# J* [        printf("Do you want to continue(y/n)?:") ;% b  M  z1 n* K5 @" a9 d
        ch=getch();2 W) i- S- o% `' |" v# Y
        putchar(ch);
. |! o, L$ L( r5 `; |        if(ch=='n'||ch=='N')( E4 e! r! }' Y/ l
            break;' n0 r: ^; ~+ r, M
        else
* q, n! \0 c2 R& v            system("cls");" J' V# K; m! _5 Y+ y3 U
    }' v# W- |! Y' Z( h
    return 0;+ d9 w! P  ~+ O! t: P0 \9 Q  D& C1 C
}

6 d# ~$ i& c: x; E6 l
) Q' e1 L  v8 Y( P+ \% V[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




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