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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
- P9 p8 T  A9 e" F: m程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=6 G/ k( ^# w( e2 f/ I
/**************表达式计算器************/9 I( h, ^" H% L  c6 W: U
#include <stdio.h>
# @3 k  Z' |% [2 j& A) q' d" \#include <stdlib.h>) \& X9 H4 n8 [2 L  o! r
#include <string.h>
+ d1 N5 O1 l! j# T0 t#include <conio.h>9 D# y/ p0 T/ a7 i' b. L1 G, r! x; }
#include <malloc.h>1 g4 s* t+ p2 Z4 u9 ]
5 A$ u, }' U; a# Q5 }3 J
#define STACK_SIZE 100: Y4 ~2 m; j$ @  l! W, U+ x
#define APPEND_SIZE 10
3 L: {9 e1 A7 G8 ?" T: `# ?# P
1 e6 Z  v4 c; Q: Hstruct SNode{6 c' R% X9 l8 e2 O
    float data; /*存放操作数或者计算结果*/
4 x5 d) x) q5 u# f3 `7 o    char ch; /*存放运算符*/
5 x5 T! `3 o% g: @+ U6 o( b};7 H% G/ i. C2 y( ?
* j. Z( W  ^$ q" T. v% u
struct Stack{. H; N* V& p* p% z$ `/ ~' l2 D* u4 ~
    SNode *top;% }# k  ]" U. b' N; [5 p! q4 [
    SNode *base;
; v) o. B" n0 O6 u& u+ ?* L' Q    int size;8 d. ^8 n7 M  J* J; {' T1 a% @. [
};- B! `3 q4 ?: n( ?5 y" W

! c9 a7 H1 F0 z0 n) J& M/*栈操作函数*/
: o4 b  w+ D5 t8 p' H- [3 _int InitStack(Stack &S); /*创建栈*/
% r/ j; L) n, N2 Xint DestroyStack(Stack &S); /*销毁栈*/
  z4 U9 c! Z0 b) D8 iint ClearStack(Stack &S); /*清空栈*/
4 I) h" K) ]! P/ Kint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/( f7 w' f# s! t1 O& H( D( R
int Push(Stack &S,SNode e); /*将结点e压入栈*/' V9 C- x) s0 h6 Y% q' N
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
4 B/ e2 ^3 R7 w) K' i5 h0 q( x& s
" |$ Q, d+ M2 g  K) e" N) c/*表达式计算器相关函数*/
& k! B, @3 I9 {2 I( @( `char get_precede(char s,char c); /*判断运算符s和c的优先级*/
6 y  k1 ?5 W+ u" Z) N) lint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/' ?3 k/ d2 m! r4 a  t- r$ k
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/4 }0 d0 |- B% K# C& S2 \& \1 p* x2 ]
float compute(); /*表达式结算器主函数*/6 X: |( A- N/ W8 X: X
char *killzero(float result); /*去掉结果后面的0*/ 8 p) \+ r8 r5 D3 X: S7 A

9 }& @: W' q1 |3 z% ~$ _$ i8 l3 ?& xint InitStack(Stack &S). Y: o2 J) A( X; j# Q
{
7 w) \2 j1 }# s' t    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));# Y! {0 D! d0 D' H
    if(S.base==NULL), i/ [. Y4 m4 R7 N5 h
    {4 x  C( Q2 ~/ l4 I, J' O
        printf("动态分配内存失败!");2 ^0 t; B: Q, B. t
        return -1;
; Z. v$ x( J9 s: F( z/ d- w( l    }
! Q2 A- I. v$ i0 v9 p" R    S.top=S.base;$ {/ N6 D# W9 D
    S.size=STACK_SIZE;
$ y* V# i3 u. S% [    return 0;
* [9 K7 c; I' g% u* F: K}
3 ?! g1 o( R0 [! g7 U! r( Q2 \# U+ w* w
int DestroyStack(Stack &S)
! z( A& F- h6 C4 u: h{
' Y& @3 z, b7 E1 e: a    free(S.base);
9 A! q% t7 B  X; O1 ]7 P    return 0;8 V- c5 V( O% O4 o- N" _1 Z
}
. S+ H" L7 E- |: M" f, I  p, r1 e2 z  Z) B
int ClearStack(Stack &S)
* T! |# A7 L7 y  L. _+ E+ G3 ?{0 F9 x* T* S* j, q& z" K# x5 G; h
    S.top=S.base;8 j. X# n1 ]/ U& e0 I1 X2 T
    return 0;
1 t( E# q# i, D. |}' _6 M3 D2 F+ }

3 e2 o4 J6 X0 y# U9 j) o9 F7 m/ @int GetTop(Stack S,SNode &e). g  h0 A. ]6 e$ ?6 U7 }0 d
{6 ^( E' D' E" e
    if(S.top==S.base)6 |. O* j3 ~8 q. \! Z* t! I
    {! L$ U0 a( P  ~- f$ Z
        printf("栈以为空!");
1 }4 }: _4 x7 Y7 E0 z( L        return -1;
8 {0 X4 N5 B5 ]  z' j9 x0 Q: R    }6 u$ Z! M5 ?+ b) [+ ?' y, u
    e=*(S.top-1);6 x' }; ]3 B0 W" d- r) }* e
    return 0;0 }; x- _7 T, ~2 d) m
}
4 S: d4 o3 O/ t5 Y
; v0 F  f; v6 |4 r# v2 w3 V9 A: a5 vint Push(Stack &S,SNode e). V% f) r: N$ A
{
+ ]( H  M. b5 g+ t    if(S.top-S.base>=S.size)
# p( [3 m0 u- `. t    {
, F* N% E, A/ V! B8 n* ]        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
' H1 q. Q/ J8 r" d5 i0 l  q' E& k        if(S.base==NULL)( |% J# E6 [0 Q5 J. c# d* r* t
        {
) E  ~* L% |# g9 W- s            printf("动态分配内存失败!");; i; g4 ^: U- [& E
            return -1;
# ]. \3 ?0 ?; l! y$ W! C  b& Y4 l        }
* a6 }" l' i9 F, q; G* H! ~        S.top=S.base+S.size;
/ n1 [, L5 p6 K3 J3 {  P0 ^. z2 x        S.size+=APPEND_SIZE;7 ~1 @$ E& g" ^1 c! T
    }( S" d# t% D0 N$ s
    *S.top=e;/ ~. ?* I7 O! w# s4 g
    S.top++;
- t7 u: f3 c8 {, U* [2 ?; |6 x    return 0;, u% W* B) ]1 Q" l
}
' e" c3 n0 e7 F1 \
9 `! C+ F, m8 o1 J" S% h3 Hint Pop(Stack &S,SNode &e)9 u& J8 j% ]6 m) L- D# N
{+ e) |3 q: o8 t* ~" \
    if(S.top==S.base)4 ?, x. S* K* ?: A" S+ C
    {
, Q% B' y& X* s! {/ E: C* F% s        printf("栈为空!");3 W9 O; B" ]. C0 N! v5 n# p- g3 A! x
        return -1;
+ z/ ^' U2 a$ q& s! @    }! ?; x& m4 e" p) s' b* e% r/ d
    e=*(S.top-1);
5 k7 f' w) E+ T1 g: @" E    S.top--;; b) O# Z1 L5 }) ]' B9 T& |" N* D
    return 0;
8 Z9 v# M9 I7 K) t) H, d" J4 s}
* M+ [* L* w5 a" g9 t
- e2 U4 t' g, I& Y* ]& Hchar get_precede(char s,char c)
: U0 K! H2 c3 o5 m5 v7 C( |{
3 z1 D: a' P9 X( Y    switch(s)6 s  s" `4 q; @9 T$ z* H& h
    {. ?) K/ X# v' U0 [& P. S
        case '+':                 7 h9 J" n. x& f" E0 A
        case '-':! h+ U+ v' {8 E/ \% }
             if(c=='+'||c=='-')" f/ {' W: q7 u1 Z" R$ k( n1 J$ _* l
                 return '>';+ s' j6 M3 y$ v
             else if(c=='*'||c=='/')6 a- P9 `1 E' d9 H" g: [4 {
                 return '<';7 s$ t5 }5 s; q) w  k: p$ I
             else if(c=='(')  O( b/ D; M% b7 U
                 return '<';
0 K+ w$ X6 |; s: o+ m( Q) x1 H             else if(c==')')
7 L/ |  ^4 I1 w' K( o0 X: S                 return '>';8 j) X! U. n, g) Y8 [
             else
7 W, c) ^  o" n0 Q: M, m6 L6 O                 return '>';- p% K1 Z" d# I) S
        case '*':
/ c- [9 Y! i7 |' `) \& `! O3 p        case '/':6 `4 N( B5 J0 p- t) k! q
             if(c=='+'||c=='-')* |. r' A( u2 o' [
                 return '>';1 g0 [5 z9 O* Q9 ?% Y
             else if(c=='*'||c=='/')4 R* \, t4 P! Z7 e( w$ R
                 return '>';9 V' q' e4 Z4 g  X
             else if(c=='(')% x& t& |% v3 B) D
                 return '<';6 C3 W) b/ U4 O8 e
             else if(c==')')3 E/ j( j8 A; i0 ^9 q* ?
                 return '>';
! i' u3 K* O! W1 ~5 ?* N" h             else
2 U& I; h) q. D6 t- I) O) O5 `                 return '>';
1 g# I, l9 L6 g. V        case '(':$ d! {: J4 J2 g& c% e# z- ~
             if(c=='+'||c=='-')
. i+ \5 [! U8 A2 F/ J                 return '<';6 `) R9 g& w. K3 P) r1 N8 P  y
             else if(c=='*'||c=='/')
. ?, b8 ^2 D6 p: ~, q! F. w3 R/ k6 `                 return '<';* ^8 z5 p' s: s
             else if(c=='(')$ L3 B) F' j9 ~% T6 d- z
                 return '<';
2 ?2 [6 ?$ F8 M( T, L  D# R             else if(c==')')
5 J6 d9 L/ L# ]                 return '=';3 E" T" ~7 B# R4 s# [% P
             else. l- ^' v  o# V( K1 e$ D* N7 Y/ j4 T
                 return 'E';
- s9 a) |5 ?1 l- O8 h        case ')':
$ x" Z, I- Z- T) ]             if(c=='+'||c=='-')
' d3 H+ C" a' I; h, k$ c                 return '>';
& c. x" Z5 \3 z$ M; ]5 B" l             else if(c=='*'||c=='/'): Y- v8 _% K9 V2 Z! H# K4 g
                 return '>';
- R/ i  l, |9 a             else if(c=='(')  n2 w& B5 Q' z# A& f2 }* a$ d- M5 C
                 return 'E';
0 F6 S0 ?9 J4 ~  r. }2 {& G             else if(c==')')" s, {2 H+ b$ P: Z
                 return '>';
$ s  q  W  {2 i, F$ n$ i8 g             else
9 @+ C  a0 c3 G1 G" I  s% M1 w                 return '>';
  K9 B  Z" x' A- {* y4 s        case '#':( o, Y+ M4 A  v5 m+ I' b
             if(c=='+'||c=='-')
- u$ }) a8 |2 q; Z- d                 return '<';
( O( o. l2 t3 z, B" H' |+ m9 B- g             else if(c=='*'||c=='/')
) B+ }. j5 g, r' Q- I$ T                 return '<';( g( j) ~3 b6 J0 O/ M
             else if(c=='(')! n  k5 n7 t4 [
                 return '<';
+ X0 J" ~7 z3 x6 X1 J3 M. A8 i             else if(c==')')
  |& m, ^! A1 N5 Y7 z, a- `                 return 'E';
* z2 A4 ^; O" d5 e1 W9 m             else8 Y1 {$ h" C3 R4 O. d' S0 _
                 return '=';
8 n- O, W/ V- ?3 U0 U        default:' B) B8 Q: [8 B# S) m4 `/ X
             break;
8 W) a  l, d' E; v; R/ E; E# u    }
3 s( j, y, v2 v; q    return 0;    , e" U) L0 I+ r
}8 ^# u+ S' o4 _% r% I. c
2 r$ g7 }, h1 h" p" |; B( M
int isOpr(char c); I5 W  q$ K7 W- o( z
{
+ S7 H8 l. q+ B# c- x4 O: X% {    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2 z4 ]; c3 a$ \" J9 U8 n3 e
        return 0;
5 T9 d8 c7 X7 N7 |$ l5 p+ j* S# }    else
7 [: n) w" j# \, y7 Q1 X        return 1;
8 M) r  \( \/ `( r6 B. F}, `# J7 b7 M* _( ?' s$ k! D/ }

: O" Z' T4 V$ c6 x, ]float operate(float x, char opr, float y)
$ ]& }/ f" b" |. f5 \( T{8 n- g- C! C# @  g# j
    float result;1 f5 U9 B5 k3 t4 H' ~* N$ ^
    switch (opr)7 Y7 a% c; |, p8 H* ^+ N; P
    {( j0 z- O5 n# H4 @4 Y3 f
        case '+':
6 k) M) Y: U4 b# R$ p# [- k             result = x + y;
. E, n1 I* L' n# G; _" Z             break;1 X" ^  S# g2 _2 o, g; u' {
        case '-':
9 o2 |9 ]8 z7 m% t             result = x - y;& b; C! G( q7 ]7 r" L. c
             break;
6 c+ ?( x/ b7 A7 y5 r        case '*':
$ D9 O5 M/ f! z" ^+ D: i4 Z             result = x * y;
2 E- p: A3 i" Q" D( K( X             break;8 H: p, n; w% }$ R3 R
        case '/':
' y- ^4 G6 l) V             if (y == 0)
% B7 b2 f0 R& h$ h/ x             {
. P5 @  O' d- F$ u0 B; ]3 |                printf("Divided by zero!\n");
/ P3 L; Q$ k2 v                return 0;9 g5 |& I- i7 d6 q+ t$ g( {# _
             }
" A& Q, F8 l, H# g# E& q9 l             else- R& I# h$ [# i( X" Y' |: M
             {5 w  K5 d3 _( v" T
                 result = x / y;+ @7 o% B# ]4 H% e1 ?7 I
                 break;
& t0 n7 D$ c& N4 Y* [" |4 k- h             }
; n+ P9 W/ k) G; d2 n1 ?+ L       default: # w# k5 n& Y* q: B) U4 y0 r  h
             printf("Bad Input.\n"); $ D9 R7 U0 \! A$ i
             return 0;) u1 ~. G! Z6 J  ]' X6 v- b
    }
/ J- g, H5 |3 o1 p    return result;
" `& m6 O4 D$ P8 p}   
1 z! {3 _6 F! E4 L; x
  D4 ~- r+ s1 }: gfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/2 I. B6 ?2 h7 _" h" e6 z6 B5 B
{
3 Q. Q& X- X4 L  A    Stack optr,opnd;3 }3 U, v" z. N5 N
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;- X2 E0 Q6 E- Y  ]: \
    char c;
8 s0 A5 D: \! L: ]    char buf[16];
. |, E* M$ s7 t: P0 M    int i=0;
% ?/ m2 y/ c) ?4 f3 W   
8 R$ |+ {2 N: ^0 Q9 e    InitStack(optr); /*用于寄存运算符*/& |0 r9 F& M7 F% q9 p8 e  H  s
    InitStack(opnd); /*用于寄存操作数和计算结果*/
0 B$ g4 Q  j* F# F/ m    memset(buf,0,sizeof(buf));* ?& N' \3 a7 w
   
/ f$ U+ F* S8 R8 ]6 y    printf("Enter your expression:");
7 q% d# b& Q9 B. G6 O* d        
/ j5 o: W: C2 z' @, J; b7 u    opr_in.ch='#';
3 ?6 D" f  v) y; X    Push(optr,opr_in); /*'#'入栈*/6 x+ p( R* a# [
    GetTop(optr,opr_top);( l) A0 t6 s. l( Z; h  [0 t# h
    c=getchar();0 W+ j+ _% @1 \. z) R( M8 b
    while(c!='='||opr_top.ch!='#')
9 e8 m5 r7 S4 }0 P2 I8 c; i# R    {. B* |& s9 v& f
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
/ E$ d" b+ I( A        {- d8 N2 I5 ^- |: [' v& T/ q1 H
            buf=c;+ C5 r+ s: C) {) z3 H8 k$ w
            i++;
% g: B# V/ D& a! W# `) q5 b( A            c=getchar();0 B; T- g5 [2 B8 G2 ?0 J+ z, {0 _
        }
" [2 N# b- T( e+ s+ A, U6 f        else /*是运算符*/& t8 k; i& K6 I
        {/ e/ L) {2 @, l
            buf='\0';
( Q4 E$ _0 j0 V0 l            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+ r1 H. ^  a, q0 o- b" }
            {
0 f) u4 Z. g6 V% Y# Y                 opn_in.data=(float)atof(buf);$ a) k% B7 o8 o. X) B
                 Push(opnd,opn_in);" p& B. b+ x  A7 ]
                 printf("opnd入栈:[%f]\n",opn_in.data);; D& ]  L' r; J& ^9 `
                 i=0;. B; Y. I* }/ P- b% u' C7 Y, q9 b; c1 y
                 memset(buf,0,sizeof(buf));) C1 v4 [2 X: C% v
            }  @3 b& Z  ^- s9 Z9 |
            opr_in.ch=c;
0 J: @( x7 h$ s  I6 n2 h* ^! N) U            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
2 ~$ B6 s) _. w+ H# l% y. w/ V5 }1 W            {
! C& i6 q1 I7 \6 L! T! v  w0 i                case '<': /*优先级小于栈顶结点,则运算符入栈*/: m8 }# }+ F7 N1 \; E! m
                     Push(optr,opr_in);* k% v0 ?7 v6 G1 }1 u! O; U  A% y/ W; S1 p
                     printf("optr入栈:[%c]\n",opr_in.ch);
1 X1 Q; Y0 y. V$ d! Z% w                     c=getchar();
: e% A) f/ W8 A6 c                     break;
3 {/ q: A  t9 U$ D                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/6 f$ c0 R  ?) L1 j3 y' f; q
                     Pop(optr,e);! W: C+ o; _, B3 _+ \3 I: m
                     printf("optr出栈:去掉括号\n");
' T$ R9 D  r7 ^  r- n6 }" Z4 c+ Z                     c=getchar();! p: H9 E) t9 v1 B
                     break;
! I6 s- r8 M6 ^! y                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8 y' X& O) A- J1 N
                     Pop(optr,opr_t);: F8 p) k8 k/ u3 H- D  K7 m
                     printf("optr出栈:[%c]\n",opr_t.ch);3 ^) U- @2 U! |8 w# T) Q
                     if(Pop(opnd,b)<0)
/ z8 ?5 K. a& H& j                     {; I; ?" M( j# C# e
                         printf("Bad Input!\n");1 D6 Z  V: y6 ?; J
                         fflush(stdin);
4 o% `$ I: ~. w- c. g) V                         return -1;" Y8 ?9 C9 ]' J4 I* P5 i3 q, v$ u
                     }! e7 c- |: R% ^2 r4 M9 ^
                     printf("opnd出栈:[%f]\n",b.data);4 j1 ?% _' B- o2 q) K4 s' G! s" @
                     if(Pop(opnd,a)<0)6 S( O4 A. k; h
                     {
8 {& F% c) H( ^9 u                         printf("Bad Input!\n");
# }# r2 H3 |4 F+ Z% p                         fflush(stdin);+ g  x* U" Q6 ]4 b. g
                         return -1;
: F9 ]5 a: @! i2 ?+ z                     }
; }" c* d6 r* t; w3 y- x' I3 V, @                     printf("opnd出栈:[%f]\n",a.data);) r" P9 ?8 W5 E& x3 P
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
* l% K; A% W/ `( K  [2 _                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/& Y) q: t" @1 A! E& [& F4 J# o( i2 L
                     printf("结果入栈:[%f]\n",opn_tmp.data);* H# U, x0 q$ M+ W4 y9 Y: |
                     break;2 _0 Z/ P  N  M
            }
& d8 v( S$ v: l0 D) B: ~        }. y" P! @* i# V. d! j9 w; i
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
2 c" u; c4 J" _    }0 a8 h( u; v& u$ p) z+ t
    GetTop(opnd,opn_tmp);
8 l0 s9 P- @( H, n    DestroyStack(optr);; g" d( d! V8 ?, O( _6 }+ p8 \. L! V
    DestroyStack(opnd);
$ D* [7 B: w: g6 O    return opn_tmp.data;
6 R% D/ E1 d2 y7 _9 k! A2 ~( K}
4 i6 T+ y2 }& J; C# p& w* T6 d: f. D
char *killzero(char *res,float result)4 T, u% s" e6 p: Q) R% Y" S1 u
{1 a) o7 [, m& J0 E% q. q
    int i;
( ?1 w5 Y& m7 o/ }7 N8 G" H2 `) T6 b0 h3 s
    sprintf(res,"%f",result);
3 S) }" j4 M, S/ {% }  v7 r, g0 ~    i=(int)strlen(res)-1;
) i9 Z( ^& x4 u7 d' _! v; p' X% w) j    while(i&&res=='0')
% K$ r# s% B$ ]% t6 V    {
& u. l* {0 o& }) Z        res='\0';3 @# r6 j, `+ J) Y6 G0 O7 |
        i--;
7 @. r3 i# b2 g% W0 K& H8 @4 ]    }
' r+ t( V% A; b9 E! v( [    if(res=='.')1 P4 Z5 K/ E! r. a6 P- n' q& ^
        res='\0';
1 b5 G# ^2 w& `, b    return res;6 s" w& Z' }7 m3 K
}
3 X: s8 e0 d# T
# x: |; w1 B1 I: E. z9 _# tint main()) z: T3 b( k- y3 S: f# t
{
. v; a! E  r9 J% J, D( z- z$ r9 x: P    char ch;* X: l, j' f) ^! W, k
    char res[64];3 l) q$ s! E9 G* K2 [4 O, K2 I
    float result;
7 k' I- J9 m; f/ o9 X. l    while(1)
$ Y& S8 T0 f% H. s, D: e) A  d    {
, }$ [, T8 J- n0 P  R5 A: B        result=compute();
0 Z) |8 y0 F+ M        printf("\nThe result is:%s\n",killzero(res,result));# N1 v: m# \* n* k7 X
        printf("Do you want to continue(y/n)?:") ;
: R- W# N+ o' V( U. C        ch=getch();' M8 P  F# V! i/ D6 T
        putchar(ch);5 P7 m, K5 L; F+ {
        if(ch=='n'||ch=='N')
0 X9 i; ^$ C! a% k            break;
( E0 M% [7 i8 c4 B7 r8 j        else7 N% c# }! k3 _7 Q9 ?# b
            system("cls");
$ g. V8 ]: ^+ `9 l. y% R    }
/ W8 w1 V; m+ m& u' J" k4 O6 N+ G    return 0;. P- w4 A- \: K. _
}
6 G* m! n9 I! m1 r% m8 F
$ F% Z$ D% E& ]& ]
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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