Board logo

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

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

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.% [7 e. C* C- H7 b' M: q
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! Y9 |" L0 K# _6 M2 L7 @5 @/**************表达式计算器************/* l( n" r* x$ I/ C" c
#include <stdio.h>
) H# G8 G5 Q' @#include <stdlib.h>
* R4 P, G4 A  s+ F0 ]#include <string.h>
5 ]* h# g& b$ j$ ?3 P, ?) @6 s+ y#include <conio.h>( z, {9 g. n- K) ]
#include <malloc.h>5 N6 R4 J5 B1 D8 {1 N
! u- [2 B+ W/ K+ |/ z$ W+ t
#define STACK_SIZE 100( D) x; M1 `: G5 h6 x8 z4 g/ l
#define APPEND_SIZE 10
0 ^% _- ?0 v/ [, ~6 c, c$ ]3 [0 h4 K1 i4 ]* X# i  q
struct SNode{
. D% r4 b0 [8 R    float data; /*存放操作数或者计算结果*/6 k! S7 k5 U/ l: }; `0 M4 ~
    char ch; /*存放运算符*/
+ k5 x! A5 l3 D) g};
+ o% _  z+ k3 e3 ?: t7 @% a! }* I9 P7 y% x$ Q% n' X
struct Stack{
- y( u$ I& L. C0 b; W& D; l    SNode *top;: d7 A' O$ E' o$ D
    SNode *base;
( B' I4 p. _' B    int size;: T2 i$ S! i5 E# o
};1 `9 `! q  B0 ~

( Z8 D  q, N* Y% V9 N" A- D/*栈操作函数*/
" |+ _" R- I' ^5 F2 C% Tint InitStack(Stack &S); /*创建栈*/
0 n- e, P2 c0 F4 hint DestroyStack(Stack &S); /*销毁栈*/
, o# e& @$ g  ], iint ClearStack(Stack &S); /*清空栈*/; {& `- O2 n& Z* r' M
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( |) _" j+ J) J" a9 c$ n0 Cint Push(Stack &S,SNode e); /*将结点e压入栈*/
4 U* q* `1 H/ x$ E5 P/ Nint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/0 S' O1 e/ j/ C) m  {9 Y0 L  P
- G9 m& F4 v/ P; M/ k, s
/*表达式计算器相关函数*/) Q: R* [( y# N4 Q" c
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
0 U4 X: q  P2 G( \" ?int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/& J( b3 P- k  r1 ~
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
% V! f: ~2 C4 E! \7 p+ hfloat compute(); /*表达式结算器主函数*/& j; U0 ]; r2 A4 f+ D
char *killzero(float result); /*去掉结果后面的0*/ 7 ~, Y  c4 w8 Y  g7 ]5 N
% u( Q# s% g5 c( V% q: C( c8 B' u
int InitStack(Stack &S)4 ^* c! o( g* |! N( \% N5 S
{
( D% @- ]8 I9 B, e: x8 Y    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
! M, P2 E, e  v9 V    if(S.base==NULL)
: i* R* \* O3 f  n    {
) t+ q2 K; s3 T( a+ Z        printf("动态分配内存失败!");
! X( i0 Z- `4 D" T: u        return -1;
9 x6 T# {& E- V5 y* g2 t8 w* B    }
& S2 h9 p1 ~$ k$ t' Y    S.top=S.base;
$ {* Q9 _5 v3 v0 l* ~: h1 i( N1 a    S.size=STACK_SIZE;1 p- M' {$ ?7 o$ s- J% r. |* d8 {
    return 0;
! m6 x6 J$ ]- i( P) }}- Z' w) H; f$ [8 x: v7 w
6 ]1 I5 d6 [6 U
int DestroyStack(Stack &S)
# l% C% j- H. }+ A0 F' Z{# V& w* L' G2 r8 P. ?5 M( n* ^9 k7 l
    free(S.base);9 e0 a0 h& G9 v% V: T
    return 0;
6 r0 c( f7 q7 X% I0 I7 M}
4 O+ H2 b0 I" Y9 B7 `$ z0 W% Z4 i
int ClearStack(Stack &S)5 [  W1 i& l; p! |3 k1 H& y8 s
{$ x( P8 L7 Q+ ^# p4 M
    S.top=S.base;
: q# }, q! Z; H9 p: t    return 0;) {) t! I. I' N* p
}' b% W" A! |& J1 r5 s* K

# j9 M; d7 P. e7 U2 S) f. x( p8 aint GetTop(Stack S,SNode &e)
% J0 m1 S, h! `/ \# i( ?{
1 z$ p+ a" O5 _, u    if(S.top==S.base)
/ T) N( b* G2 I9 m2 {$ J    {" K  K  s: w6 q
        printf("栈以为空!");
$ @% n- N6 K; N# [; P# ]        return -1;* \/ S0 q9 f) ~5 F! L/ u( S0 C
    }
5 ?$ N: @' s5 v4 F: G$ S0 Z    e=*(S.top-1);: l7 R/ b/ F4 n0 d. s
    return 0;6 \9 h$ _) B- r. J) U5 y
}
+ [9 G5 Y4 {+ M" G) w
! F( w8 O. S3 v+ Kint Push(Stack &S,SNode e)
- b  f! I9 j8 S" j2 i/ o{+ z4 U1 [% U3 f) C) _8 N
    if(S.top-S.base>=S.size)
) I4 W" }9 L. {" [7 h" F    {
7 C; [2 q" j% b2 z        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
. A1 N7 {2 g# l. E+ @3 r        if(S.base==NULL), \% C' b" x& y; R. h
        {/ c. |$ D6 J/ o4 r7 s0 R5 c4 j
            printf("动态分配内存失败!");
& H6 {- [- x* Z, f$ i+ c$ Q, S& `            return -1;+ d0 p$ o, j6 c- l
        }
& g- N  v  _3 r/ _9 ]. @        S.top=S.base+S.size;
! g! D& R+ n' u! Z1 P        S.size+=APPEND_SIZE;
! l# p, {; j9 c7 j    }
1 r& r* U  L9 l2 K7 n    *S.top=e;
9 F1 a9 Q0 ]) ~/ J% W# G% o; S    S.top++;/ f! {+ y5 |1 q
    return 0;5 y5 n/ v4 Q- Q, V! K. s* P
}' j) t: ~  o' k2 f% S/ P
1 I# Q* s# w4 J; j+ m3 u
int Pop(Stack &S,SNode &e)8 V/ @: e" X  d
{
/ @/ m: \6 ?. H  E3 O$ |- F    if(S.top==S.base)$ g) n& l) Y# N( m) E
    {! l. U4 G  n0 b& V
        printf("栈为空!");- {2 E4 L3 H2 |1 E% |, \& X
        return -1;  x; f6 v; ~) A. N0 e7 c. ^
    }6 J. L# Y+ Z3 ~: b* z* ?+ ]( A! ^
    e=*(S.top-1);/ B7 ]1 {) C  s; x5 }
    S.top--;
5 C, k: ~" K( `: s0 T! V    return 0;
% q1 P! N4 V& S}. A6 o. c2 I: [4 H/ ]
2 a5 c: n, n. x3 F. q+ z
char get_precede(char s,char c)3 m4 y% R' I3 H3 e- |- m( X2 g, v
{
$ D* Z8 N5 X# D; d: w: z    switch(s)
" Y" J5 J5 o9 ]4 f3 O) g" W1 x    {3 D0 m9 J: w. b5 |, n1 g
        case '+':                 
! x0 K5 l/ D) C+ b2 R        case '-':4 E9 @( o8 q( q, E
             if(c=='+'||c=='-')
/ A  s8 _1 p3 d0 j* |% M$ d8 d% y                 return '>';
) H; q( c# P! L0 \. Z/ G             else if(c=='*'||c=='/'). l% b- q3 L2 ]6 q- k
                 return '<';  y+ j* V& h- P5 Y
             else if(c=='(')
! Y2 I$ C5 F2 Y2 p                 return '<';; p) m8 X0 T+ |2 h! O( e
             else if(c==')')# `; o' k0 [- K: U$ n* s
                 return '>';
! u9 |2 u: \' }& C: o* B             else
! W7 b4 K1 ~% S7 D0 t( H                 return '>';
3 q, J2 y, O/ S" D# ?/ Z% Z        case '*':6 t, |7 f0 [5 a4 x! W  m
        case '/':
5 H& a1 F$ q3 f             if(c=='+'||c=='-'): q9 Z9 F: m- }3 T) w( Q3 j8 O' h
                 return '>';
: b, T; i$ |# J6 c: h0 N             else if(c=='*'||c=='/')
& I( U7 |; M: @  Q* F, j                 return '>';" ]9 j# J9 y* w% l; o6 _& N) ^% s
             else if(c=='(')0 I5 ]+ ^: ?  c: N, T( A
                 return '<';) {: E! J: t; P0 u
             else if(c==')')' a" k- v- L0 b+ h
                 return '>';
# u/ X$ g1 T6 n( g  G6 j             else# m  C' S/ f3 f, E. ]$ r
                 return '>';1 B9 Y! d3 d) @& D0 R2 @5 S
        case '(':, f  ]- i/ M8 k
             if(c=='+'||c=='-')3 H- R; Y9 G7 A; W! X) y
                 return '<';
. R! i# A+ c: C" y             else if(c=='*'||c=='/')& J. i, a/ E1 Z7 {6 T
                 return '<';
9 Q8 }# e) W1 Z) T( r" Z- \, |             else if(c=='(')1 A% x# n$ ?: V# |+ f, O- h$ R6 y5 p
                 return '<';  P1 f# w" x; F7 G1 W( d7 V2 k3 Q( D
             else if(c==')')4 d0 g% w+ t. c
                 return '=';
# b2 k% Z8 j9 |! L! Q- J             else
- u/ T& W, N- _. h                 return 'E';9 U+ e- T% U4 U% B9 |" I
        case ')':
4 z4 W2 }4 _: Z# v; X3 S             if(c=='+'||c=='-')
7 I$ Q: u  D! Y3 e3 K                 return '>';
; C1 Y- {# J, t# l7 W9 ^             else if(c=='*'||c=='/')# o6 H5 Y% R; H( v( H* T  n
                 return '>';
1 z+ N6 q% [/ `. H( S/ K( Z. w3 T             else if(c=='(')- W2 j+ V4 _+ U$ Q' R- h
                 return 'E';/ D. N3 r% ^7 j) V9 B* H8 [% m3 U) A8 w
             else if(c==')')
. p, Z' `) X; |0 s6 G. j# R                 return '>';
' _9 w# s3 U3 r8 J4 t. M" o             else
# A% S/ e  I6 v, S                 return '>';! p- E  b  S3 g" K0 i: n1 ?
        case '#':8 ]* [+ D( A: q
             if(c=='+'||c=='-')
3 Y+ `$ i: E' A3 a                 return '<';
% o( c" [3 [$ Z( }) ?8 u' {             else if(c=='*'||c=='/')
0 [! U* S  M7 H2 O- ^                 return '<';7 r; c& S9 T# z. G; g& I
             else if(c=='(')
6 U2 E  {; d: P- U3 Y' Y& K5 t                 return '<';
/ @* d& f5 y$ i( Q+ H0 p             else if(c==')')
8 @% i5 }. O  U& ?& e% [- M3 |, f                 return 'E';: [' ?0 E2 ?. S$ t
             else# Z) @- Z% [- F% A* _8 }) e
                 return '=';
9 s6 M0 ~+ J, {, m/ a* _        default:
+ I, _5 o7 T1 }             break;
0 O* r$ e. v; W    }
7 v3 o' y! f+ N( H* O, w    return 0;    6 C1 C- g* n4 X6 U
}5 p1 V6 [. y: m: k% ]8 i6 G
+ K+ I5 V$ {) Y+ b+ S3 p/ Z2 a; p2 Z
int isOpr(char c)
+ o3 S$ F; H4 F/ A6 Y4 X9 a- h! P0 a{
3 M5 Y  \; p0 w& u. \; v    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
* x3 {3 n4 _; W1 A3 b/ @        return 0;
/ L! I# w3 B) i+ C: ~) A    else % D; A5 j6 L4 Q; s9 |% K3 h. a& s
        return 1;
4 ~  a4 T& o- r8 ?' D}( y" R5 K2 E8 D& G8 c6 p
6 |2 r/ L4 o4 d
float operate(float x, char opr, float y)% W; M4 i5 l# J8 u+ ~+ Y9 _# F9 B4 q
{
) J# R& A" w4 ~# G, o/ i3 ]    float result;, c4 V6 H: K; n: K
    switch (opr)$ a4 S! I9 u* H  n3 d# Q
    {
" \$ [, q/ ?+ O+ |. |4 \  p' I8 o        case '+':
4 Z$ @4 u" A# N: Q6 d; ~, _. Z             result = x + y;* u" m5 d0 Y- x5 h0 S0 @/ X& k5 |
             break;2 I+ n8 }* H- V- z6 \) K, P
        case '-':
, S  b. h! Z2 t             result = x - y;: _, U9 o6 G! U+ f
             break;# ^4 ?; d7 J3 J0 m& Q
        case '*':
' t" _& P; S+ [! L             result = x * y;
# ]$ }/ _% p; C. s+ k. ?/ I2 U             break;: `- J! u$ c( U
        case '/': 4 R$ F$ o: [: I' s) X
             if (y == 0)
6 g. f7 c6 |  C8 Z/ [& u' ^' T             {
2 w, Z4 p# k: k& @  M  D" u6 ^( \                printf("Divided by zero!\n");6 J% v8 n9 {/ N, C! I1 T
                return 0;
& f% D1 q* f6 o2 X0 m: g) |             }) h9 T4 Y8 {2 U+ S% r! @3 ]
             else
* `9 x0 E8 `/ ?' y             {
3 N9 A6 ]1 M& K- J9 P) f' X0 Y& C                 result = x / y;, C1 S  x# }; G: M2 V7 R- U
                 break;
6 W/ l. a$ Y, ]7 L; e  |             }1 }& U( C$ |7 B/ {
       default:
- s6 I% I4 r; h- [             printf("Bad Input.\n");
9 D2 _% G" `! w2 B# v3 X             return 0;
* O+ r; L: T3 p* f( B1 t    }! i. B& N, u) ^1 b( g9 A
    return result;
4 d9 Q) C. d$ ], w& Q  C$ I# y& p. c}   
, u; r; J' D2 {' o1 K
/ O. [1 K2 q* I( Ufloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/$ ~  A* E" C. ]  H2 }- d7 B' j* h* R
{
' `9 a; W4 \7 A, E    Stack optr,opnd;
; u9 `" Z0 N  j0 S$ k  O    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
) w0 o6 y0 O/ Z2 d    char c;" d6 |. r# a5 o4 @- o: c- U
    char buf[16];
# J* p& R7 G. l6 K! {8 i& r    int i=0;
$ R0 n3 k1 ?% ^: |6 ~- F1 P2 z    & o, t. ^3 }/ o9 c) e* T, P( Y
    InitStack(optr); /*用于寄存运算符*/( B6 J4 Y' i; f0 O8 ]
    InitStack(opnd); /*用于寄存操作数和计算结果*/- ^; P9 u  N* p& t! _. k
    memset(buf,0,sizeof(buf));
4 B" H) H9 @; E3 V; X; N   
. f1 y' }; @5 ^5 e# P1 n( V    printf("Enter your expression:");
5 U; T7 T1 K' ]" O        
  h4 E/ n+ |4 j5 v% p; G    opr_in.ch='#';7 ?7 K8 ?0 w/ v- H5 L
    Push(optr,opr_in); /*'#'入栈*/
7 q9 S! i. ~" H) L* V    GetTop(optr,opr_top);8 t7 H& P! |. L* p3 i
    c=getchar();
, s) \1 }7 J8 `. X    while(c!='='||opr_top.ch!='#')
3 M. f+ l- u. p3 D    {) z! |5 v9 Q8 x, D5 p! B0 n# x
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/; }2 ^# x; E# ^( T+ X5 ^
        {3 d( }2 D" i  k
            buf=c;. s# o8 Z% q. \& c* |5 L
            i++;
. ^; Y" G$ R/ w; v0 ~& a            c=getchar();% ?! g- i" o  s/ m  j, }
        }  \' F% \2 B$ s# T; X
        else /*是运算符*/
8 J6 N0 Y5 N) {6 W        {
$ M4 y: }9 E8 D            buf='\0';9 Z  e2 H, E, j; I+ \
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/& i) |* g8 w4 D) I) o, ?# M- G- B
            {
1 H- }4 R' A/ v8 Z                 opn_in.data=(float)atof(buf);
1 c9 o1 B! q& h5 Z) `, E& C                 Push(opnd,opn_in);
6 M0 y& C7 ]( {. Y; z$ r  T                 printf("opnd入栈:[%f]\n",opn_in.data);
  l7 M$ z2 `( x. E  o* f8 y                 i=0;9 c: b8 H* p* A/ @# M6 _
                 memset(buf,0,sizeof(buf));
( p: ~0 k. w/ B! U% y            }
6 [& s4 g( S2 W$ P3 k; s' ?            opr_in.ch=c;
, O' ~8 R6 ?2 c+ O7 |' b            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
2 k4 B  i8 ^3 ^7 _0 w, i            {
$ A6 P0 o( n" l! O' S                case '<': /*优先级小于栈顶结点,则运算符入栈*/
5 W9 I0 B0 c5 a/ n                     Push(optr,opr_in);- r) T9 X: Y+ F; `' F  R
                     printf("optr入栈:[%c]\n",opr_in.ch);1 F, Y4 P' m+ U8 l) Z" n
                     c=getchar();
& b, h+ A0 u/ {1 R/ D                     break;
3 M  n9 [4 i- ^$ e! e8 K                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/+ P3 d0 P5 G' F8 D
                     Pop(optr,e);2 y8 w1 ]2 N' p
                     printf("optr出栈:去掉括号\n");: ~+ B: r. _: U+ `9 w2 B
                     c=getchar();# b1 F! G% M0 r) Y2 w- c" W
                     break;; Y1 e  t6 i& \. O5 e- V
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
+ x' D( U! j/ M6 b3 E                     Pop(optr,opr_t);+ m- ]0 D' ]  z, P& g
                     printf("optr出栈:[%c]\n",opr_t.ch);/ w6 e0 D+ B/ ?/ O
                     if(Pop(opnd,b)<0)* ^9 B6 s$ `/ E- _1 g1 y
                     {0 z4 F4 I' m0 C* @# i
                         printf("Bad Input!\n");
- g: k5 W8 ?) Q5 S9 ?8 z                         fflush(stdin);% T$ V6 f2 c% o- w: g3 S
                         return -1;; X9 n/ O) p$ }+ `
                     }
# V$ ?3 h* }2 Z$ k3 ~# o( b                     printf("opnd出栈:[%f]\n",b.data);
8 {* ?* k! p. Q0 ~' W7 s. e# X6 r                     if(Pop(opnd,a)<0)
0 ^4 O) U4 Z* n8 _$ h  `' P                     {
& X2 }, G% v9 U8 l! \                         printf("Bad Input!\n");
* @/ h( s$ E' }* a                         fflush(stdin);/ J1 \5 B; Z: R& F
                         return -1;5 z# R! e% ]4 q/ |2 M4 o% g
                     }
  S0 \$ @. h. @9 K                     printf("opnd出栈:[%f]\n",a.data);
% C( B7 L: R' I. \( p9 h                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 O* F! S$ _2 L) [& u$ k$ a$ s                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
7 C1 d, S  a$ a3 @" j5 r2 s- b                     printf("结果入栈:[%f]\n",opn_tmp.data);
4 h0 B  T) {6 B2 w: O$ M7 H, B                     break;
5 M: n0 X3 E$ |/ G( f  V- o            }
6 H/ e% P% P) n5 N6 p5 X        }  P' J! G" I8 i0 V/ V* O5 c$ u
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                0 x* j8 F" ]  d1 m. o5 \9 {
    }
* y/ J9 c+ g( ^" O9 N! Q0 G- c    GetTop(opnd,opn_tmp);% n$ T; i6 z1 ?8 Z6 A9 q
    DestroyStack(optr);
" J5 W7 }2 X3 j& \- C+ N& s    DestroyStack(opnd);% G- ~2 Y  f9 L! ]; w4 F
    return opn_tmp.data;
2 \6 D1 q* ]/ c8 y1 q}
6 F4 f, U* {" G# `
. U) c) t% L4 W% kchar *killzero(char *res,float result)
  E1 G( b& ?! w{) b6 e! Z# o( Q: u1 N( N
    int i;7 H& \( R% X+ }' Q$ Y7 C: O5 N- G
6 |9 e) b) A0 T9 x6 e* r0 z
    sprintf(res,"%f",result);2 l! ~8 e' L- x. `
    i=(int)strlen(res)-1;# \0 p* y' C, N& l, `1 F; W
    while(i&&res=='0'); q1 p4 l# f) K
    {
% h) C$ S" T( W$ J4 d        res='\0';* j) x; [" ^5 k+ }' m
        i--;' o4 v: w! b3 b
    }
" |( v( m) Y: Y& j    if(res=='.')
  G' M9 X& n$ x2 n        res='\0';
2 D! U1 Z4 m* D: d; X    return res;
9 c2 f) A2 u! n- R}
9 `. P8 S3 b' A$ A( Y: C
% X9 O, ^! C0 I. a$ ^& Uint main()" y: L) I4 S! _) z! g
{0 }  }8 ]3 I% }& z; M, d, ^1 |
    char ch;
/ t3 A3 ^) a) R8 Y* C9 J    char res[64];
0 U$ Z- l/ ^! N, d    float result;
' U. M( C& p" V4 \, e( \3 [% Q    while(1)! |7 M$ e7 L% }1 H8 d' P. Y; Q2 i
    {! f& {# Y7 k/ E  @: x
        result=compute();
$ b- o+ R! F  w        printf("\nThe result is:%s\n",killzero(res,result));' E  n9 X. ~) {) e
        printf("Do you want to continue(y/n)?:") ;
  y; f9 A' `2 w) Z" \# j6 c        ch=getch();: a+ Q+ K6 `9 ?( O4 u3 j7 b
        putchar(ch);
2 o/ _7 C- C  v; r  C        if(ch=='n'||ch=='N')
! E+ T0 t% M8 z! J            break;
9 O( y7 t1 I% S' }) E5 i# m. q        else
! ^/ p. ]/ Y' I. K7 l/ ^            system("cls");
* v& w1 `* w, Y. B1 C    }. p- {$ _5 o9 u# W5 A  A, C
    return 0;
" A1 L2 z( i, ?4 _/ {& p2 C; s' K}
3 d: {8 F: B& w" E0 h* K5 {4 P

: X# ]1 i$ \0 x. ^5 @* B7 Z1 G" }[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




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