返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.- I3 [6 X6 l0 c
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
: d) ~( y( h( M) P" K$ Q/**************表达式计算器************/8 \# a1 D9 G4 ~! v& S
#include <stdio.h>9 V$ C5 `( H3 n. Z) F% s& Y' _
#include <stdlib.h>8 [* g, a2 G9 K  Z4 o" z# O. G
#include <string.h>/ L$ g' h; l' ~% Q: {: _# j
#include <conio.h>
  d& k# y0 D( t# O* `7 Q#include <malloc.h>
  x1 |. ?6 J4 g' y" B+ N! C% Q, q: j3 w  ?# N7 j
#define STACK_SIZE 100
" p& ^0 P2 O, p) C#define APPEND_SIZE 10
8 i4 _7 v2 c0 c8 F7 S5 h; j5 Z0 h8 L
0 @% Q) F/ }# S( C3 |struct SNode{
+ q/ I- W. k" T: X, R! X    float data; /*存放操作数或者计算结果*/$ ?3 Z3 e8 \9 K+ J5 ^3 d+ y
    char ch; /*存放运算符*/! y: g9 m1 B1 A2 ?; V8 ~
};
! p: ~4 o4 H: U& Q- {8 C; r5 V( y# `$ x( S: N; u; m! C
struct Stack{9 S: a; m+ Q* J
    SNode *top;
" z- |' e. P8 G9 j    SNode *base;
$ B' K- `6 {+ L- R1 G3 N5 T    int size;
' ~: ^3 q4 Y8 p2 {: \6 k/ F};* g7 T, b- m1 F4 H
% a6 l0 U% d3 V9 P" E
/*栈操作函数*/9 k. P: u& w: |
int InitStack(Stack &S); /*创建栈*/+ p2 {  ]1 ^1 n& M9 c; j8 r2 i
int DestroyStack(Stack &S); /*销毁栈*/* B4 n" ~- M; N/ m. y' G
int ClearStack(Stack &S); /*清空栈*/1 ]2 S1 y) I; A
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 H, L% E' r6 f0 X8 Kint Push(Stack &S,SNode e); /*将结点e压入栈*/" X$ t, k8 R7 H/ ]
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
8 A5 v/ h; W: X0 t7 u" t# l6 @
, I# o* h2 \' J; m. Q/*表达式计算器相关函数*/
/ N3 \" g: h. y1 a0 Y4 t6 I/ u5 achar get_precede(char s,char c); /*判断运算符s和c的优先级*/2 R9 |" b/ g! S# b4 e) U
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
% C% [0 }% [5 X! ~) a% qfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
, f8 i, w- w2 w0 J2 Z: y+ y! Xfloat compute(); /*表达式结算器主函数*/
: ?' o- w5 c6 a- U' Z5 h8 Gchar *killzero(float result); /*去掉结果后面的0*/ ( |9 \' y6 P1 _6 K* n$ W" }& N

+ X4 s) ~) J$ q: Y. bint InitStack(Stack &S)
# |7 S: L. |+ x7 H/ c4 @  x{& V' s* y# w/ D/ I9 A
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));/ z, O' ~1 Z9 ~/ ]3 |' W
    if(S.base==NULL)" L. b3 L/ A* _( q7 t
    {
. a1 i; H" A3 @  S# I. H        printf("动态分配内存失败!");$ Q% I) h5 m. Z1 E
        return -1;
6 r( n4 ~* V% ]# {( M    }) J3 T: o& X8 [
    S.top=S.base;
! E  o* C+ v8 ~0 c7 B    S.size=STACK_SIZE;3 C8 s, p3 o( L$ W
    return 0;
9 e1 q9 e# c; u! D}" w0 s$ S5 k' i  V% }$ w6 q) w
' X+ }5 J; H) ~0 Y  `6 O' ~9 ~# Q
int DestroyStack(Stack &S)
; p( ^* P, z% h$ G" _7 S6 ?* \& G{
# V/ I& f6 r: S    free(S.base);
; U8 |, z' _0 e4 m- K/ |    return 0;
; k& y4 u& C! K% S0 S* C}8 N6 q+ g( i7 n& R6 ^/ i

1 I3 j7 l$ Y; H, Z# o9 Kint ClearStack(Stack &S)
6 G) Q0 N) T0 t- G* B% ~{9 i: \3 g8 j  _0 D+ [; I
    S.top=S.base;
! K* R8 U. f2 d( S( ~$ J4 h% D    return 0;* X! e! R/ L# d/ h
}2 a' n# o/ @) ], K5 t* q

& l6 s6 @) `7 H  l4 k% Gint GetTop(Stack S,SNode &e)
  C) H1 n) D% d( H+ r2 M  k{1 }8 a) [/ R! }) F# C! [, Y
    if(S.top==S.base)# W8 u. h/ M, s0 g0 b4 N, S) N
    {9 ^) h; p% C) i, i& d9 {
        printf("栈以为空!");
* F' n4 }# S5 e/ M; Q  j        return -1;
9 K4 G4 k# k; a) B5 D6 L" m    }
) f; @( o, d1 I& U  g8 j# E    e=*(S.top-1);
( O+ `8 [* T% w- I3 s! @    return 0;! J9 a$ T7 A' m& V: z# w  t6 q+ s
}" I* I5 B# j. h! @4 w
, D0 [1 C% `" _- d( |6 n
int Push(Stack &S,SNode e)5 T; U6 O. ~0 Z' P
{
- y7 M/ Z% v* B2 n    if(S.top-S.base>=S.size)7 z& B( T0 f8 G( ]# z
    {4 A0 L  _) u* m+ p6 s  y3 T. J
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
! d7 r; a- R4 `7 c3 z# L        if(S.base==NULL)
6 o1 E6 ^# L, L  Y" [& W        {! ^+ V0 v1 m3 n  V9 u( a- P& e
            printf("动态分配内存失败!");
( \  I' Y2 d2 C1 `$ ]! E            return -1;
0 Y1 w0 y3 n. u9 u- X1 ~. d        }+ c3 g" R, n' L
        S.top=S.base+S.size;1 C+ c0 V7 M) s
        S.size+=APPEND_SIZE;0 R. B3 J* L- K2 c3 P4 A9 o4 s& W5 ]! P
    }
) [0 f9 E- Q, u. m( l! Z9 C    *S.top=e;# a+ ]+ P& u3 b8 B
    S.top++;: y1 l$ G! H/ y( d, h! q0 z- S$ ?
    return 0;: G, Z1 [0 X2 B6 x
}
7 m, Y" ?- E3 S+ W) M8 W. ]' `
* o5 y" x  r- D1 e; k/ t1 Kint Pop(Stack &S,SNode &e)/ \7 i$ V1 k/ b6 G
{
3 @* y& w% ?1 J, Q) ^    if(S.top==S.base)
7 d0 J- C+ y) C% ]4 W    {
+ X8 @4 w" ^$ n. e, L/ k/ [        printf("栈为空!");1 _" B3 L) M+ I& V; |0 M+ B+ D/ o  ~( `
        return -1;
$ J7 W+ e/ M3 \  x    }
! [5 g% j" O3 y' ]2 H    e=*(S.top-1);! W7 y. N- p: q! n( w' q3 W2 J
    S.top--;, [, k" O2 k# k6 V
    return 0;3 N5 h; E: [  g/ D
}
- z3 a; m9 r" p) @& N% A( Z8 Y" f4 m& G$ s2 p
char get_precede(char s,char c)9 u8 G1 m- g  |4 m5 `$ p7 ?
{
6 n! }( U% C! s! o/ w4 w    switch(s)
3 ~; @4 f/ Y6 c& @: V    {' ?5 w$ Z: ~4 R7 y( S  _
        case '+':                 : i4 x5 U. D2 C9 W
        case '-':
/ p+ y  M/ ]4 s* u% V0 P4 ~             if(c=='+'||c=='-')' Q. S4 V. n: v  W0 m
                 return '>';# `- t* r% @9 t% p: @
             else if(c=='*'||c=='/')
: U1 x9 @! G* W2 q+ y" f                 return '<';
2 P! p' t  V3 ~* L             else if(c=='(')
4 K5 v$ D# H: d! F& [& }: F! I# d, p                 return '<';  ~3 D7 ^( c3 i
             else if(c==')')
% C% i+ t9 V9 @4 Z4 G  d                 return '>';
% ~- j) ^, j, Q/ ^             else
% D1 {+ k7 ^# z. K; i1 c8 v                 return '>';; q, |2 R: |& ^
        case '*':5 v; t, ?+ I* b5 B' o# E* {6 q
        case '/':
  {1 K( {# Y2 F             if(c=='+'||c=='-')2 G: l* v* H& ^6 \7 T) S! q
                 return '>';1 p5 W6 ]% j4 S. V) Q3 b6 X
             else if(c=='*'||c=='/')8 d/ j2 N) u1 G7 A
                 return '>';1 q, v: |1 ?" ?$ i
             else if(c=='(')+ z9 C' c0 b% x2 f  o: [4 r8 C
                 return '<';* |$ h$ s' T. u# A7 h+ m  Z
             else if(c==')')1 ^5 o9 c  C- k6 T; q- Z
                 return '>';0 C: s6 `; Y% `+ y4 X! n
             else, D8 y4 b. {1 n/ v$ C8 c
                 return '>';
. ^. n+ j4 f6 E9 |6 m2 T- d        case '(':  R+ {( R) G4 y; D
             if(c=='+'||c=='-')( N6 c7 `) J& {5 D; I9 J
                 return '<';
8 F+ F5 {2 g$ P8 _9 q9 ?. F             else if(c=='*'||c=='/'); z/ ]- d8 w& `1 M
                 return '<';, D% B1 V) g9 T2 z
             else if(c=='(')& }6 [0 B* C, G# n
                 return '<';
" y) W8 y1 X* F1 U( I8 e             else if(c==')')
4 v5 x; \# d' [                 return '=';
% U1 v5 h1 {7 u3 S7 n& q5 m             else
: a! \( c! L* K$ y8 }8 |: P- n5 }                 return 'E';
, R7 h+ v5 O1 S4 M        case ')':# W/ k8 E# L, m; x& }1 o% ~' I
             if(c=='+'||c=='-')7 r6 z! Q" i0 ?7 N" c/ @* N5 `
                 return '>';
2 U. W; D6 e, H" s' S             else if(c=='*'||c=='/')
) L* Y! B0 ^5 @9 @0 k  m/ m2 X- ?                 return '>';
/ A8 J& P" D$ G$ |- F             else if(c=='(')
( N; E  h. U) A' X$ K5 ~                 return 'E';0 h4 ~; j* [' m
             else if(c==')')
8 N6 `) J; ?4 i                 return '>';9 Q9 E$ Q' e1 |
             else# q3 v* V5 @; g
                 return '>';
1 @. c* }6 P. H: I        case '#':" M5 W& _3 l3 _  r% j# |  J: E
             if(c=='+'||c=='-')
  ?' a& M, S' e  Q  t! y8 G                 return '<';) _5 V' M4 a. z! I' S8 x
             else if(c=='*'||c=='/')# g, L$ `1 X; v  h
                 return '<';* q+ z2 o" }' _) d
             else if(c=='(')4 u  S, _2 w' h1 `% H$ {: B& x
                 return '<';
2 Q' W* j4 i' R+ \             else if(c==')')
( d1 K; b6 ^& h9 ^% ^, Q* Q                 return 'E';; L) N. m. d; E. Y' J
             else- e. C: M6 Y/ H$ Y; A
                 return '=';
' ^1 O- B: I* X        default:0 @9 C, }$ l' Z
             break;
4 ^- i* g. E8 K8 ~0 u    }7 a  h  r4 n: W4 w. s% U2 e/ A, h
    return 0;   
* g3 B9 U9 N+ i, F7 J( z1 ]# D# o3 x}
# ]% Z/ C3 l2 Q$ G7 `! _, s, i, R
  S0 O7 n9 p7 R* pint isOpr(char c)6 A! {1 e" ^- [1 w3 A+ }
{; H4 r9 e2 V2 @" k& I* c: P
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
6 b( B/ G. t/ E' S# f  s3 A        return 0;
. n$ J: X9 n: i- p7 |2 b4 _    else : w0 c  d9 s4 A9 ?8 O4 t* }/ y
        return 1;
3 j5 p7 v8 ]' ~}
4 C# T8 Q  b; c$ s8 ]! e* @- q+ l9 K! w
float operate(float x, char opr, float y)9 b/ |' r/ h( w4 ~( Y% D
{
8 {8 q9 N+ A0 q& i; M    float result;6 N( i) U- m- S( N$ }7 [
    switch (opr)6 B( u" v( o, x% O; B! A/ {( G
    {* X8 Y3 R2 U- O5 y% h& o6 e2 t
        case '+':
2 [; N. j6 F0 ^% `% c# S- r7 |& j" H5 g             result = x + y;! ~8 F. d, d! O/ j, W7 g
             break;
3 P, e& a% ?% T3 B" X: p        case '-':
/ }5 L' M( R& L! R- S* g" ]             result = x - y;1 z- S( l' L1 n; x+ `
             break;
' x+ ?# @4 {. b        case '*': / V, y% E' ^: k; ~* B9 v: c. m
             result = x * y;
3 ?0 j; [; s; t9 F8 D8 F7 j. b             break;1 j, @2 k1 P- b0 l: y4 ?
        case '/':
. Q  l( c3 ^) Y( n% R             if (y == 0)* g% _  P4 g  I' R6 ~" U+ l# [0 W% M
             {, W0 _6 e+ u& ^
                printf("Divided by zero!\n");
3 g* c: p. G# I& b& i                return 0;& R- R# U9 }/ U! @: x$ E1 g, T
             }
5 P+ Q/ v& @+ z6 s             else, ]* Y: j1 \! [% K7 ~* o
             {0 U" F0 u8 m! Z. {' t# P2 ~3 h- X
                 result = x / y;( @- V: n- A1 F7 d* m6 w$ K
                 break;: [/ S: @) N. d# |8 k) H3 N2 p
             }
" r0 v* x  _4 @* c6 y. Q: ^       default: . h, f; P% u3 G4 E5 ], m
             printf("Bad Input.\n");
$ j: W. |9 L0 q/ S             return 0;( ]% M" u* t" V" ]
    }
. c6 u  r- |" |/ t  X- a    return result;7 V; L7 y7 P: m/ W. n$ B! _
}    * P+ O% O/ c6 B8 r

  L- P8 X0 J, M- Rfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/! y, c- z) i- W" |# g8 {) {5 m
{0 g& Z. [4 n7 f) H" Q
    Stack optr,opnd;% `# A5 [9 j$ [  b) {. m
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;% g$ R9 G+ x2 z
    char c;& M9 }3 i. j2 b
    char buf[16];+ ?8 `: M4 A3 |, \* s
    int i=0;
4 b0 N0 u+ o% A" v   
4 [! M2 |. V4 S    InitStack(optr); /*用于寄存运算符*/2 H! `: [; _' b
    InitStack(opnd); /*用于寄存操作数和计算结果*/0 E8 b  S; f* O  o# e
    memset(buf,0,sizeof(buf));# l) q/ z+ o1 o/ q! }& k) u) I2 E
    , M/ p* A9 @/ R" y5 L
    printf("Enter your expression:");
6 C0 d* K3 g! d3 X* V" ?4 ?        . q. T, N; n1 J+ a5 Y9 @
    opr_in.ch='#';
- K) l; d  t: A$ t% P6 |    Push(optr,opr_in); /*'#'入栈*/! z  A. U" V; w  v9 @) _, X
    GetTop(optr,opr_top);% k/ I# O; m7 r8 g
    c=getchar();
% |4 b- s7 b: E/ B    while(c!='='||opr_top.ch!='#')
7 [2 H% }+ y- P    {
  F9 f" k! i# V! c: Y3 q1 k* \" v        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/6 {- x4 @: h9 n
        {
" ^" l" p7 P+ I# R            buf=c;6 J& [: n; S! W+ u# k
            i++;
2 _+ ?( K" U6 i6 ^* K; b: x            c=getchar();; v! R  W- K2 _. ]2 \2 Q
        }
2 `; c' S* D& T) o: g* m! \        else /*是运算符*/
9 @# I9 R3 G3 U3 L3 G  J0 W        {
) K9 b2 a: F$ ?4 F( K8 i  x& c            buf='\0';
% H/ I: K9 ~; d            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
# j! F7 D: D9 _) L            {
: f% Z5 P* u+ ]' N$ ?& h% P4 u                 opn_in.data=(float)atof(buf);
, O+ i" @; a% W. e$ X- p1 j& Q                 Push(opnd,opn_in);
/ m1 d; {6 L+ p4 M- r                 printf("opnd入栈:[%f]\n",opn_in.data);
- Y: ?. w# R4 L3 _                 i=0;, O6 x  I* J* i8 {% |# t
                 memset(buf,0,sizeof(buf));$ w. }. K7 A7 s) F8 F7 v2 y
            }
/ T$ A, Q/ m4 J; U% M6 m# P            opr_in.ch=c;
1 V" F7 r4 Y+ [7 T7 r            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1 m' O% j9 B, z/ n* D/ N6 \' f            {
& Q, j6 _# T# y3 a                case '<': /*优先级小于栈顶结点,则运算符入栈*/
2 L' D/ l$ Y2 A2 m9 c                     Push(optr,opr_in);
2 d+ t: s* T- J6 Q7 W, ?                     printf("optr入栈:[%c]\n",opr_in.ch);6 Y" s3 W: w1 Q9 }; A
                     c=getchar();% T; P. Y$ \  @( a; b5 m3 G6 r
                     break;
9 z- {6 {5 d7 H& K+ V                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/, O4 O8 V6 O. y$ ?- k, @
                     Pop(optr,e);
) V  x& W7 w. d0 m- o, W                     printf("optr出栈:去掉括号\n");. L2 R; C0 ], q; @/ U
                     c=getchar();
; @* S& ?! J6 F# ^8 V( H' r6 m                     break;
+ |. [2 X9 _/ j6 w; u% Y2 G, |1 f                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6 I, f+ j5 `  N  |) n$ Y                     Pop(optr,opr_t);
4 A2 P* Q% M3 `1 X4 L$ z                     printf("optr出栈:[%c]\n",opr_t.ch);1 d* q* {  J0 J; o: a+ c
                     if(Pop(opnd,b)<0)
1 P, j8 n& Z, `7 J0 i. _                     {2 Q5 Z' D- Y+ J  c, z  \) S
                         printf("Bad Input!\n");% p5 Y) T- Z( A3 ?
                         fflush(stdin);
$ m' y, h; W2 S* z6 D8 \8 C0 C                         return -1;9 B+ [' _7 Y/ ^8 p8 v3 V
                     }
' V% r# q" i( w; \                     printf("opnd出栈:[%f]\n",b.data);
. D1 R# d: p5 s  [                     if(Pop(opnd,a)<0)
4 V8 D) J3 w( t( r/ C- Y                     {1 H3 P5 ]+ L6 s0 `: B
                         printf("Bad Input!\n");$ s; w% O# Q* \& e+ P2 P
                         fflush(stdin);
& K- x1 _! i" F7 B7 a  h4 Q                         return -1;
, Z, E& w/ h4 [. X. L# T                     }" w( R2 ?5 X/ }* v0 f) s
                     printf("opnd出栈:[%f]\n",a.data);
+ x4 J# J6 G, a. w- A                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 T6 O. R" |1 ^                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
$ g: H# @" B! G) M; v5 b" r                     printf("结果入栈:[%f]\n",opn_tmp.data);
2 u& |5 f3 i! G5 v- g5 ~                     break;
  _% D1 ^9 ]4 M  A# r            }. G( C- Q1 w$ T. O) k/ S9 @; m
        }
9 A! K1 K- ~. k/ r0 U        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ; z0 {3 w! B2 \; o
    }; M( D0 m+ E9 f( l
    GetTop(opnd,opn_tmp);& ^3 q/ d1 |+ C
    DestroyStack(optr);# b( `+ P0 P/ T5 ~* S7 O* g7 I( J
    DestroyStack(opnd);4 I4 V  m5 Q2 q8 Q. `* G' e) T" f% W
    return opn_tmp.data;
& z+ r' d. A* Y5 ^! b5 \  M6 p}( v. i3 N5 M( O4 M* E( b- _

0 k  i; f$ i8 U! O' }& P" v9 J- `char *killzero(char *res,float result)6 W7 E4 |  K' H; p, [; U
{
3 T( {0 d" t7 ~+ U; i" c! e    int i;
& O, h7 r4 u  \# m7 q7 n% g) Z, [5 W# A
    sprintf(res,"%f",result);
( X# e1 p8 r) }; C2 l  E, L    i=(int)strlen(res)-1;. H6 ?; E9 y0 w
    while(i&&res=='0')0 w( q9 w5 T" f- X
    {  {& J5 k: q0 U. e2 q
        res='\0';. a, u$ ^) V! g) k: z# R
        i--;5 v( v3 }: C5 S8 \+ z
    }( _  B3 F" Z2 C7 w$ W$ a. ?
    if(res=='.')% m8 r" Z+ b; A8 @  z2 I
        res='\0';
- l9 R5 T. {. I9 N& O0 n! X  N    return res;
+ ~; ^, w% R+ [}# P. R, W- `- Q9 g2 t3 k

7 u/ x4 X; @& r, v; G( iint main()
  b* e  [9 G1 e3 ]; t0 @+ Z6 j{/ l9 r* q4 k* F, z
    char ch;
9 E& T9 V2 J8 F. A3 i+ |    char res[64];
. }5 U& _$ n  m4 g0 a# I/ C6 ]    float result;; i! l1 [4 g! v, H
    while(1)7 r& }3 x& _7 _6 r  `
    {
; u) X2 ~" `+ D( l1 i2 }' b        result=compute();
2 |$ p- J) g% g6 i9 x$ _+ m        printf("\nThe result is:%s\n",killzero(res,result));
3 k6 G! x( k" v. h' D- |        printf("Do you want to continue(y/n)?:") ;6 K4 V% r' d: E: r+ J' F9 _
        ch=getch();
) W& O, @& j5 a; |4 |: ^# M        putchar(ch);
1 J6 S4 F3 y! i6 j- f# `9 x        if(ch=='n'||ch=='N')' r  K9 @4 q6 b
            break;5 t7 J' A% F/ R
        else6 H3 S8 E# g) x
            system("cls");
, o8 l  l3 D7 X" R' O% g    }& a3 I6 \( c4 k! f
    return 0;
0 Z& v/ S, d( I8 ~+ ^: s  A2 V}

% T/ O4 L: T0 c, n% V2 J. a# T9 _, U8 p! \* V* x' S7 p" k( Z
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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