获得本站免费赞助空间请点这里
返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
  _9 j9 v. ?4 Y& `7 z$ C# G程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
9 D/ M6 J  J4 m4 O% L( i6 ?- X/**************表达式计算器************/
9 Y. L( o4 O- e& j#include <stdio.h>
. A7 Y- u1 ^* p* x# N& _: r9 _$ `#include <stdlib.h>
5 D; W6 o0 e* Q& C) ~# b#include <string.h>7 F- D, e8 O7 p2 h  Q1 @
#include <conio.h>
  B# n; p, J5 R2 M  k! y#include <malloc.h>7 H; y& k# C6 W9 q  u

0 h) [1 J$ l4 Q  J  e$ r#define STACK_SIZE 100  R* H; i( p9 u5 R8 y
#define APPEND_SIZE 10
, N  M0 R( g+ c! k7 L9 Z+ e) P8 Y
/ _: h4 d1 K% |! ]& q" C6 estruct SNode{1 ?' \4 v2 d- d
    float data; /*存放操作数或者计算结果*/8 g# U* n: _9 |' R) G0 M
    char ch; /*存放运算符*/
  u5 Z3 F+ h. B6 S( d* e};9 U! _3 ^# {( w5 M4 y% X
2 q* g+ k6 |+ p. Q
struct Stack{, G# H" r+ D4 ^' d* v
    SNode *top;! b% k8 x& @  e. L
    SNode *base;$ k4 e) }# h- Y; y2 x
    int size;" ?! P! A% d7 u2 V) l
};
% t2 B1 b& c3 C- v' [5 f1 ]3 w6 n" ~( k
/*栈操作函数*/; O. ]1 Q8 j, d
int InitStack(Stack &S); /*创建栈*/& C  o- t; D' M5 B( Q. ~# T
int DestroyStack(Stack &S); /*销毁栈*/+ D4 [  W/ @7 K
int ClearStack(Stack &S); /*清空栈*/1 f5 U! y; I/ {/ D/ o& z# X) [
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
& W6 t% j9 e7 }& f4 Vint Push(Stack &S,SNode e); /*将结点e压入栈*/
- F. Q% a4 Q- O3 |) Q& j0 z1 `+ f+ wint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/2 f  c9 Z' x: V# }% F

" Y& F/ s# k7 e# Z& B9 n4 o/*表达式计算器相关函数*/7 B4 S( ?/ ^. E( S& L% b
char get_precede(char s,char c); /*判断运算符s和c的优先级*/% n9 h; v% l# M& t4 L+ M$ [
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/% w0 }  N9 k; b* O) m
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
" f1 {7 g1 d, g# y) J# ^float compute(); /*表达式结算器主函数*/( S* \3 c! n# C/ |1 z( B
char *killzero(float result); /*去掉结果后面的0*/ , a" |) N% D* \4 E, K; c$ `/ [  l
# G' L9 |! O9 q7 D1 m9 D6 ^* ?9 `" N
int InitStack(Stack &S)
3 N% E  y6 {" c" r% B) S{
+ q7 x: j. p) J. J; ~6 Y    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
6 A3 U# d6 p6 A! l    if(S.base==NULL)( I# T' y: x- i, f" r( d% M, f
    {
" [8 W/ Y6 \) F- \( f7 A        printf("动态分配内存失败!");3 e" q! N, N/ u( q: j) ?) X- F
        return -1;" }3 ~2 W) n" P; s  D6 H
    }/ |0 n% |5 f& d# |! @5 b
    S.top=S.base;
2 ^' A! w; P% X    S.size=STACK_SIZE;
5 `7 L. k% U) |" I0 l8 K4 K    return 0;0 x  x+ b+ E* G, j; q
}7 o4 C" D+ L4 r! V) P) ?! N
+ D& P2 [2 r6 u" @7 x( Y! _* W: F' v
int DestroyStack(Stack &S), J, U% W' ^' i
{. r/ K5 a8 `0 @$ Y
    free(S.base);
  X5 J% a) n7 S- m# o# r, Z    return 0;8 G5 @, x$ x& C4 b( W: g) q
}
2 a* A. o' w8 `  P  u& B& o# L6 B; w' v- B/ C, O5 U) v
int ClearStack(Stack &S)
( ?$ c8 t1 Q5 @" G! j9 `0 R{
7 x' l! L6 s5 L+ m( a+ {    S.top=S.base;
! M( W4 c( w, z# t2 g    return 0;- p8 G+ f7 v" o" w
}
) a2 P  [) T& Y) F( z1 z7 h( G/ n2 e! f9 W7 T& f
int GetTop(Stack S,SNode &e)6 ~0 s' A& Y9 m) f. M
{
. Y2 X; P. C+ Y! k- \    if(S.top==S.base)) X  R; x) S" \2 B7 z  H% f
    {
* g' I& A, S) T: a6 l* {8 x+ G        printf("栈以为空!");
) S  j7 W; \3 n# o        return -1;
2 Y" {- F3 v/ J4 h! K$ y    }' y* D3 g) ]/ Z) ^- h0 P% H  R# i3 @
    e=*(S.top-1);8 q' R; k8 C8 H+ x; W8 z% p0 V4 x
    return 0;' w; ~9 |8 f9 t
}
  S/ U& Y% K* R; [$ P
& ]( S" O0 y  q# }9 P5 T3 aint Push(Stack &S,SNode e)/ B7 u, b1 P. P$ Z; ]
{
( t" o& W* V) G% Z! P( ~5 s    if(S.top-S.base>=S.size)
/ E4 j8 {9 Y) Y& a( C5 j    {
4 n/ G. Z" Y# ^1 }2 m8 t        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));2 F, q0 w4 u% h$ t
        if(S.base==NULL)
! c7 E% I6 T  }: v        {
& D1 S' ?2 w8 x2 u: s            printf("动态分配内存失败!");5 v1 ^" X. z6 I* |6 I3 u
            return -1;: x8 s; W0 V; V
        }
3 C- f$ B! ?3 [+ g7 t) j$ [/ E        S.top=S.base+S.size;
% I& R- k( U- y" Y# s9 d/ O        S.size+=APPEND_SIZE;4 g+ X+ L) {+ U; t+ |, i6 d7 C
    }# S* l) Y& c; M8 M& K# u
    *S.top=e;- E5 K& s4 i( D* r
    S.top++;; N- u0 m# w7 N5 L1 l
    return 0;: l( o0 E! a7 ]  }
}
. |7 F, S" a9 d& v& D) R6 h) r+ `) X; k- W% H
int Pop(Stack &S,SNode &e)3 J. a* h9 q+ G2 [: e) g0 V
{1 ^  v' h. v) T. \+ c2 r; w5 P
    if(S.top==S.base)
4 h% r$ |- R8 N/ \' d- B" J- @1 [    {
1 L) a  X' h$ V, v3 _6 e# h# H        printf("栈为空!");/ }# l. J, Y8 n" c9 P' z
        return -1;
  i9 \: g) H9 f- h: Y    }* k/ k$ v: f7 P8 R  Z/ g9 j
    e=*(S.top-1);
8 B, V! k; S+ |4 ]  x" k    S.top--;+ ]7 R9 W& W4 z$ Q/ q: P6 T% B9 }
    return 0;( O# E, l) V- i* ~
}
! M/ X1 N2 k- b0 M) i$ a. ~
3 X: h3 m; B/ C! q6 l2 e3 uchar get_precede(char s,char c)
8 ~4 W8 {% r* F0 J* R{
5 D9 }  V1 P6 L; `( j* J7 K    switch(s)
3 B% O( ~) F' ], i; ^! p' z$ N    {9 t9 o: X# Y7 Q' w! A( j) W$ q: ~
        case '+':                 
0 g6 Z" b/ U1 p7 L. h- }        case '-':
" V( J( R' B  {             if(c=='+'||c=='-')/ z3 s1 U/ c" f- g
                 return '>';. }4 A. q+ h* @/ J0 r7 |" p
             else if(c=='*'||c=='/')
+ o- X& ?; e7 X/ ]- f                 return '<';4 D% t) ?/ M6 a) ~+ i+ {5 B
             else if(c=='('), `2 t1 }4 u% @4 g$ i3 Q7 q
                 return '<';) W- Y' b& Y$ M8 c6 F
             else if(c==')')
( J1 K& S. D* X                 return '>';; n8 `& A/ V  y) S9 `
             else
8 G7 Q2 L9 H6 n7 y! C; t' U8 u                 return '>';2 i) V, Z* {# q2 {+ o/ v
        case '*':
& s# c8 h* N+ a' ]: m+ A5 b        case '/':8 X3 z) M3 [4 y) K$ r
             if(c=='+'||c=='-')
; K& `% a  h: I. M2 F, Z8 `, R                 return '>';
4 i4 T0 |8 C9 S( l/ B4 o- v             else if(c=='*'||c=='/'): p% v) c5 j# o: c
                 return '>';- c6 p- U& c! v
             else if(c=='(')+ q1 y0 }, v+ `! O+ ?, j
                 return '<';! w. {% P  t7 I" m$ d( L
             else if(c==')')
5 {+ C5 g: z* i# Y) ?                 return '>';
' {: b& i( h$ j: Z0 p: a             else: P7 U2 Y! Y5 Q
                 return '>';
$ E# l9 v% ]* F1 ?1 K; r        case '(':
; O8 h! L3 [+ X! O5 U+ d             if(c=='+'||c=='-')$ o, U" F. h" y5 s) f' y
                 return '<';9 D8 m9 K% A* n9 j/ g8 q' @9 L
             else if(c=='*'||c=='/')
8 T5 ?7 D" U, K& q                 return '<';$ V9 U. T, [4 `$ O8 l% n* ~) Z
             else if(c=='(')" B- K6 {# }  ~
                 return '<';6 z% g1 F4 o$ E! o1 u; s1 _
             else if(c==')')
3 h# _3 ]) H: r4 q6 @. {1 R                 return '=';! {" l* a7 z3 f' |. h
             else* j5 d; N9 @0 C5 E/ X. m- `
                 return 'E';5 s( V' |: n/ c
        case ')':
+ k; U3 {' q4 _& s5 g# ?& ?             if(c=='+'||c=='-')' o% t' s- t# r/ j
                 return '>';2 O3 C" c& s- f8 p/ ]* s
             else if(c=='*'||c=='/')- A) D  d* k1 W) Q8 G& M1 U; I
                 return '>';
% O( i! i6 Z/ e             else if(c=='(')
9 m# t" e/ h' e4 T                 return 'E';
3 T% c% ]5 m( E             else if(c==')')5 j0 e# C' l# [: f
                 return '>';0 l' q6 w- A7 }: \
             else8 Y8 p8 |! m( L
                 return '>';
+ ~* ?, c" u3 M7 x- B: K        case '#':& l) K4 C/ e6 L; K4 I9 U) O
             if(c=='+'||c=='-')
& N5 a- F+ D  H                 return '<';
! A/ o6 R! P2 ?# I' W& k& c  a! @( M             else if(c=='*'||c=='/')
% l: o  o- {1 x7 ^; w, ?8 w                 return '<';- \& i1 F8 x# c3 b1 [
             else if(c=='(')
1 c: x' k; @# m) N  _/ h+ Y4 v                 return '<';
  g" l7 u4 y6 k' c  I5 Z             else if(c==')')
# A3 {) F( @3 k' D4 C* p% P  h                 return 'E';- G6 j/ t# [" `
             else3 ~# x+ c, y, J+ H8 a
                 return '=';, \& w" j! V7 c( }: D
        default:
; K, q* A- B* k7 h5 g9 b             break;& l: |' B, \3 n' ?% B
    }1 k3 o& D( o1 E
    return 0;    ( G# {3 ]( e, C' e9 L
}
' m# \/ }% h. E/ u9 T, H1 a2 e$ R+ x) @
$ m. Z. ?4 |. p7 M$ Lint isOpr(char c)
$ F4 E, M9 q+ P{( W9 [3 o- {- V8 n4 ?. J
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='), y4 x1 `' w2 r$ V. d- H7 m& }
        return 0;/ j3 t: p) s2 m; g* Z$ }
    else
) @( X; _; r5 @9 _( d, ^3 n        return 1;- N: N' q( |* H0 x+ [
}8 G: \* T: I& W. _
5 a& b7 T" e1 d: D7 d+ U0 D; o
float operate(float x, char opr, float y)4 Y  ^' s* q  u# h6 H' V
{
* e# H" V- I. [) G. a# F. |    float result;: M; a! ?: J: `8 m) e8 H9 A$ e8 F
    switch (opr)1 q) @1 y$ _+ O% A1 V' n$ k& Z
    {; e8 E. ?' \1 P0 q; O3 B4 F, `! p
        case '+': & Z1 s* s- f- h: i0 |
             result = x + y;9 x( [: i9 n9 _
             break;
' @2 s8 u: A6 ~  T7 O6 E9 x1 f        case '-':
) h. z" d- o1 u; i: A) }4 R  Q             result = x - y;; `* T; |) a$ `+ p& P
             break;
) H0 J8 b4 ~7 f( C' i  n        case '*':
3 @" S3 o- v% m  z             result = x * y;
, r, w1 v$ x" V! `             break;8 I, V( T( T8 }) T2 a* g6 i
        case '/': ) u3 P! Y  U) Q: ^
             if (y == 0)
' K* S4 d5 ~* s6 ~             {
& x: N+ |6 M+ I% b5 M2 s5 ~5 V                printf("Divided by zero!\n");
1 v. }, Q; c2 M( ~4 t                return 0;( V2 p& F% h6 C& b4 L+ h8 J# V1 x7 u
             }4 E; K: S3 u6 j5 K( d; @& o6 h
             else
5 l- f1 t/ s; ?5 Y1 {             {7 a; u0 x9 Z5 `6 g  y+ _. M2 l
                 result = x / y;
* @. f* J$ G0 P. O8 `                 break;. i% d* L8 L7 F4 T' g" s! a
             }
$ ~- m8 @7 M0 x: Z       default:
/ c; r, U5 p: R. K! ^! I             printf("Bad Input.\n");
) W" F; A0 Y/ S$ m3 M: ~2 C' E) d$ c9 t             return 0;4 X' B; }$ T7 v4 J3 O. c
    }* N# L7 h. e" q
    return result;
  |) t  n/ n2 S7 E}   
  ^& u* z& \7 |" u; u, T9 b
! ^0 f8 Z) N) V+ _! |  Y1 Mfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/) ^2 c* O& Y( P" t) b* M! T6 I
{
  S, s. D9 N4 k- ~+ I    Stack optr,opnd;& D7 K3 w# g; ]* ^# e$ v4 Q  v
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
" K! t4 Q) d+ q    char c;' p& @0 |- U6 l1 @+ t) S
    char buf[16];- Z% ~6 K* W1 e) @% P  X+ }
    int i=0;
9 n) ?% S' D8 `& d   
# K. V9 D5 T! i% @& q    InitStack(optr); /*用于寄存运算符*/
7 A8 s' c# R( I$ E  D6 o& g7 ~    InitStack(opnd); /*用于寄存操作数和计算结果*/
7 `/ |0 I/ @7 r0 G8 f: {    memset(buf,0,sizeof(buf));6 h" G2 V1 D' o+ M
    % W# S. V  a! I) P0 h
    printf("Enter your expression:");
# e% D/ f/ P6 g- t. y        9 I6 c  }8 P) H% _" a6 o( r
    opr_in.ch='#';
2 T: n6 N- t* ?3 r4 T    Push(optr,opr_in); /*'#'入栈*/; F* c' l9 k0 ^. t2 I8 M) d& E
    GetTop(optr,opr_top);
- M" J8 `4 E) @, `    c=getchar();' M, a9 T  Z* e* Y
    while(c!='='||opr_top.ch!='#')# P1 q2 `# h, X: Z! W2 n
    {
, Q1 N2 |: N" @* g% W+ E$ O        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ \" y+ T% e- ]7 I8 ^$ x+ |        {7 C/ v6 B" N2 Y5 K
            buf=c;) i) T. i! r9 B2 [' R
            i++;
. Y6 q, \6 F; i9 _            c=getchar();  q3 J# f/ p; B- z6 w+ }/ I! V  r
        }3 H  h% S1 X9 p
        else /*是运算符*/
- s/ L# v$ t  x" g8 e' K        {
8 {9 `& u2 k9 a& p. d% Q            buf='\0';
( l. @- U4 X9 i/ E" L            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/: m" O, `* I1 A5 M
            {1 G( }0 E8 `4 C8 T1 A7 p
                 opn_in.data=(float)atof(buf);" ~/ x" l* ?$ X1 ]7 r
                 Push(opnd,opn_in);7 q% ~6 r. K% u
                 printf("opnd入栈:[%f]\n",opn_in.data);
2 Q, u4 u, y9 [                 i=0;
) N* G# |) V0 ?; l                 memset(buf,0,sizeof(buf));
( Q: n* S4 [" |4 E  i9 Y            }# F: l! [# j7 P9 ~" U1 V
            opr_in.ch=c;
3 [$ b/ B8 e" U) j            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/% e6 l; D5 P2 y! t: z& r
            {
4 t& `" G+ X0 G9 r5 b                case '<': /*优先级小于栈顶结点,则运算符入栈*/& G6 B7 h7 K2 h: S" C
                     Push(optr,opr_in);
. O8 _9 D/ z- r                     printf("optr入栈:[%c]\n",opr_in.ch);% w1 x: y, h8 i6 B8 x! d% s
                     c=getchar();* G4 ^8 A' `! Q& z3 y8 R" |
                     break;  \1 ~4 ?4 u5 }' V
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
( v. ?2 f" ~( p& N$ {                     Pop(optr,e);
- [9 `% t5 p3 Y8 S" a/ X7 a3 r                     printf("optr出栈:去掉括号\n");3 D) h$ X: X* E( k6 e
                     c=getchar();+ k* }) k# ~/ W+ T+ E, A5 L/ |) l
                     break;
+ K1 r% y+ y; c4 G0 }; W; s' p                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/: E/ e  Z: k& A/ ^( P( J
                     Pop(optr,opr_t);6 O2 {- f6 A: V
                     printf("optr出栈:[%c]\n",opr_t.ch);
9 E* W1 V+ ^; O+ E' _0 D. v/ A                     if(Pop(opnd,b)<0)+ r4 N4 d/ F2 {$ I
                     {
  _, R2 M; f' l# w1 b! P% I" f                         printf("Bad Input!\n");- u9 D+ J$ _: {2 n' |2 f
                         fflush(stdin);
( t+ Q: Q9 u5 `1 {8 u0 Y7 T# C' J                         return -1;
4 c% @( ?& g3 `6 C0 I# z                     }
) F+ i  @8 c) u9 C                     printf("opnd出栈:[%f]\n",b.data);+ Y# x+ \; ~/ F( L
                     if(Pop(opnd,a)<0)3 g1 f- n' p& c" f3 W
                     {0 Q5 \/ I- u1 r4 C! O
                         printf("Bad Input!\n");
9 }7 M" J7 M7 f                         fflush(stdin);5 Y) `* W' K7 i9 k' O- @
                         return -1;
! c1 `3 J6 x! i" U9 B! q                     }
: D4 S7 r+ z4 m1 c                     printf("opnd出栈:[%f]\n",a.data);
3 u7 L' J+ b4 Q2 y7 }1 p0 v1 X                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/6 J" H0 ~0 w' I. W3 l5 A, U0 ?# y
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( i2 z8 P8 S" J: Q                     printf("结果入栈:[%f]\n",opn_tmp.data);0 e- b5 p0 j; E6 }' f
                     break;$ r1 h7 o. O$ @( j7 A# S
            }7 \! V6 [- u& y5 T0 {
        }9 n1 k' @5 G2 f6 C1 f; I
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                - b# @6 l% ]; T1 ^
    }
; E' z3 q" @/ i: Z5 D/ ?& h. z    GetTop(opnd,opn_tmp);, o9 _2 N% }3 ]; t3 `
    DestroyStack(optr);# Q& F; i- U) y$ _  Q- u
    DestroyStack(opnd);9 L6 S) b  u( O
    return opn_tmp.data;
" A7 N1 Z1 J4 @! f. e/ F5 _6 `}; J. R6 R/ P( S; }
! j4 K; ?% R' H2 t4 g
char *killzero(char *res,float result). @: g0 f7 W( X; V
{  N5 H/ Z, ?) @1 F, S5 k1 w
    int i;" O4 E0 M2 Z7 k1 W
: k; S" q% m) I* `! V
    sprintf(res,"%f",result);
2 _! E) g: c% A" r    i=(int)strlen(res)-1;
! u+ k8 m0 g3 ~" O. C    while(i&&res=='0')
- J& O5 w: B2 H2 y5 S    {+ x0 Z( ?# n8 y. j4 p
        res='\0';9 w! X& c4 ^: k
        i--;
$ m# ?' M+ l1 f7 s: d' d    }
" r9 _1 T5 J6 a2 U( m    if(res=='.')* x% w6 c! t( R% Y; @
        res='\0';9 B' a1 N# k* c! a8 Z7 i
    return res;9 w' j' ^* N6 |+ M) @0 U
}9 l6 M3 p4 ?; t' @
5 q1 `# z8 x! a( j6 y- U( m, B6 u
int main()
8 E* S' Z7 K" u2 H9 ~8 t3 S$ v# E' i{
  w3 K8 N) O& s9 b    char ch;
) J' B2 @! I4 v    char res[64];
" L9 M' d8 [0 j7 G    float result;5 I8 R2 j- l7 M8 ~& w* j
    while(1)
  o1 B" i& G  x+ N  g0 T    {
1 Z: s; g& h, @5 l- b! d+ T        result=compute();1 K( s) o) N+ C! ?8 q
        printf("\nThe result is:%s\n",killzero(res,result));
6 ]" Z8 P( a8 y- o( _        printf("Do you want to continue(y/n)?:") ;
: s) z+ V) N" J6 E. S- D        ch=getch();2 \  B% `5 `; a6 b
        putchar(ch);
( Y6 [' i# u$ M# Q/ r. c5 q; `        if(ch=='n'||ch=='N')/ _5 r  T) G" ~4 C
            break;
6 \, M: M1 V! E* f0 Y4 _        else
7 ?" _; j1 b, n( |- k) P' B! Q            system("cls");
  M6 \, [) h9 `: I. \$ m    }% P8 d+ x- b2 b# J% C7 i
    return 0;' l, S* v+ m& v) i3 d" e
}
7 `( Q* x; y3 B1 Y- X  s$ Z' T

7 o  Z% r4 S; R[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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