返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6 Z! G, H* Y6 p* D% W
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
- O, [: H+ k  c- ~/**************表达式计算器************/% w7 P8 v/ S1 q" n
#include <stdio.h>
& ]% t, R3 }& x  N$ w" d#include <stdlib.h>
4 y) I/ e$ H% |7 }#include <string.h>
6 w9 B9 d& H; ~: I& w1 n#include <conio.h>1 K- t' s' ]7 d: ]" w
#include <malloc.h>$ A& N* Y& J; \6 }" r( v
& q- e! [% Q5 G7 a, c% b
#define STACK_SIZE 100" |" `( U& e6 e
#define APPEND_SIZE 107 c2 {  V9 i+ y- L4 o5 d

' y2 e1 Y- u  W2 T' t( E  a% R, xstruct SNode{/ }' Z" S# {8 ]7 {2 F; a
    float data; /*存放操作数或者计算结果*/
! T5 W9 x! v1 U) v  D) y3 V    char ch; /*存放运算符*/. [8 L" u$ _9 P  u
};+ \. N7 F5 N9 h) M& U: w; H

1 b2 x$ |! @" S9 C. G+ S% c9 _" ?struct Stack{
6 ^1 I- O  G# k/ v$ e    SNode *top;
- b2 z, l/ G! J! X1 F7 _  B) w, P# W    SNode *base;) v$ N/ p% S! U! v) H6 R  m, N
    int size;* v) X( G7 {9 O# o9 x
};
5 X9 s. m  k* ^9 x# e/ j/ w! L
5 Q) I. y* X) @/*栈操作函数*/: c! V' S; ]7 S. @; |2 b
int InitStack(Stack &S); /*创建栈*/
0 N# A: |' J5 Z5 g8 i# xint DestroyStack(Stack &S); /*销毁栈*/0 x9 @: n( c$ i4 U
int ClearStack(Stack &S); /*清空栈*/
7 e9 }# G# X4 r& i8 x. _4 \) C. dint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*// @4 V& `( [$ N1 C; J; L2 G
int Push(Stack &S,SNode e); /*将结点e压入栈*/% l4 b& X, p  z' X
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
* U0 }' B7 r( Z" u9 R3 h5 E8 h" g* g
/*表达式计算器相关函数*/
8 e, {4 w# s* }8 o# F$ \char get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ E- r8 j  v  t5 @8 n' aint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/* R6 \+ c, m1 S$ j7 M8 c
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
' L2 @+ v2 C8 Q/ s9 i8 ?float compute(); /*表达式结算器主函数*/
* k' L) z% D) W- D8 J% Schar *killzero(float result); /*去掉结果后面的0*/
1 @. m' G9 A" e6 k  W' @$ O: Q) p1 Q0 l$ p2 N
int InitStack(Stack &S)9 `$ Y4 I& b5 r. E5 s! f, O
{2 E4 O  I8 H* O
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
: k/ L: s0 {4 _. ^( F. A4 T/ s    if(S.base==NULL)
6 d0 s; h! |9 {    {$ _0 W, g( x0 P% Z
        printf("动态分配内存失败!");
6 d" ?& n! I& l        return -1;
7 x) z5 @+ ]( l& T8 D$ ~  R; {    }
7 t- x5 y  z  ?/ T    S.top=S.base;
1 ~4 ^0 p3 g' r; w( {( n1 X    S.size=STACK_SIZE;6 d( K3 S7 V4 o/ i0 o
    return 0;
9 @' r* E4 Y9 v, N}) \: G) `( k) q+ _  `: s
+ c8 ^9 ^" ^  @+ p$ h9 \- e9 |+ F5 S1 S
int DestroyStack(Stack &S)0 g) M- ]. R1 D
{
/ U/ T  F9 w4 P7 y5 Q    free(S.base);
' v$ w( j  p# Y$ I" I    return 0;% Q* N; O! Q, {5 W3 V0 O
}
& M. c( T( T  R' N1 ~+ v" d- j' n7 \
int ClearStack(Stack &S)+ a% C( I: i4 _' [
{, Q  H. h  M  M9 W- W
    S.top=S.base;
) K1 `# i: \. B: X* u    return 0;
% [' a/ o6 j" L4 U  e}4 G) Q. [  {# M' n; J2 a; b2 Y

5 M. M4 `6 i3 uint GetTop(Stack S,SNode &e)
0 K/ }* q" @1 o% i. I# W9 `; b  x{
1 P, f+ _/ [0 `: I" A, W    if(S.top==S.base)
3 U$ K% d, z) @( k$ \% J    {
) e1 [1 \! H5 x- e9 E7 F: y        printf("栈以为空!");
8 i  ?% u, F) R) F0 c7 \+ `        return -1;7 C, A1 m! o: I+ }5 K& @  r
    }
8 Q; J7 X$ j! U) X, j: L7 X: d    e=*(S.top-1);
8 P; f; \! ~: A3 h# V5 ?    return 0;
3 `, w6 o1 d9 a3 F}
% x1 G! [7 M5 k) y% [, A4 ?
  e+ d- M4 w9 B9 w9 ^7 j) U8 ^int Push(Stack &S,SNode e)2 s7 [# }4 a; i5 V. b
{! n/ B' X1 K1 c1 O. e
    if(S.top-S.base>=S.size)
, f6 D# Y7 T$ i& _  B: f- s    {
! A. z) Q! [) {( H- z. x0 K        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
4 Z, S7 H! N; H6 J, r3 z4 r  I+ B+ D        if(S.base==NULL)
7 Q+ y) Z6 Y) Z  h+ e$ O1 _        {
0 I1 S& i& A: c. x* \. |, H            printf("动态分配内存失败!");. O% s* m- f7 I. c! r$ o
            return -1;
! S3 \: ]- w1 `3 @        }
2 d6 y/ [! @" g5 ?, A) w1 G! N  \        S.top=S.base+S.size;) |) H( o3 \/ k
        S.size+=APPEND_SIZE;/ e$ c. D* b; x/ V9 i3 f
    }5 Q5 r" {& y% A3 m, g! n
    *S.top=e;
4 m/ p0 D1 B0 o! `  F+ @3 ~    S.top++;
9 b9 A. w+ o& p3 @4 t8 i; b: O1 I. e    return 0;
3 \2 h' J! J; l( r}
+ v2 u1 P' i. L
- G$ X' m: S" X2 @$ f8 ]/ tint Pop(Stack &S,SNode &e)* D1 i. k' T  V+ \! A2 P& C; I
{
( q" x7 {: A, l4 L; G    if(S.top==S.base)
2 L7 ?. |# z* G4 p8 Y6 e# B    {
3 p$ K, I1 F5 M* ]" a        printf("栈为空!");
3 u$ A# i6 A- Y" S, k6 |        return -1;
  x2 f# @5 |4 G3 P, ?    }
! G0 R9 x% m; d: `. Z6 a4 }    e=*(S.top-1);
/ r; B) I3 Z# z8 f6 @) S    S.top--;
6 B" f+ H5 o* |0 ^    return 0;
5 n9 m7 ]5 f5 y0 C}0 Z) c/ o& z9 U; j; G) h1 K
0 u% @: Q: D' t6 Z2 a
char get_precede(char s,char c); k6 `  s. J6 |
{
$ G. I# o$ j) X3 \$ L2 m    switch(s): h: a) G2 W3 j  S$ G, z
    {
3 R( }3 q5 R! d8 z( C        case '+':                 ) B6 S- m' A4 e3 y; }- g6 D
        case '-':
# [- O1 x, e% {0 O+ k" ^8 z% [             if(c=='+'||c=='-')
+ ?# c6 g  T, Y/ v3 ?3 F  m                 return '>';% ]; A5 |5 f1 y3 U: T9 k6 Q
             else if(c=='*'||c=='/')7 B' Z1 h  o5 C7 Z8 {' u
                 return '<';3 U) w' x* e1 O& D
             else if(c=='(')9 ~9 w% M0 X5 h9 b8 s5 k
                 return '<';
  y- p7 I. ]2 M2 _3 q' C             else if(c==')')7 M2 p+ w0 m, Q0 o
                 return '>';! R0 W. c$ m( P5 N1 ^
             else & H* T, Z' M% F1 h4 @
                 return '>';$ l9 L0 t8 ?5 J/ x% u
        case '*':
* r4 I0 m1 T8 ^) q" k        case '/':/ I: f, N+ P' S; u7 e
             if(c=='+'||c=='-')6 Z9 D& n( ~( {
                 return '>';& k! G7 m/ r7 ]0 a: s+ F
             else if(c=='*'||c=='/')9 Y* L: N5 c2 R
                 return '>';* E# i! }+ H2 I9 c% m
             else if(c=='(')
9 i; {! }% y( C! T( U* r                 return '<';/ \, q1 V- l7 _9 q/ n
             else if(c==')')
# c* A* o% A0 r( N                 return '>';* ^( [$ G; c7 J' E  E4 K& V. S
             else, r/ B: |/ n! Z' B% g
                 return '>';" z. w: k5 w, K5 n5 N: J( F6 ~
        case '(':
5 l/ C; o2 _% U( ^  X             if(c=='+'||c=='-')( |. u6 u% {, }# C  V% V
                 return '<';
: e$ a+ t. w! [# ]( s             else if(c=='*'||c=='/')! X! l7 f! g" U; r
                 return '<';8 g+ Z" T  Q6 ]" x1 k4 o
             else if(c=='(')" b5 y0 g& I  d2 n2 i  n# ~( W$ P
                 return '<';
6 S3 A8 l1 }$ g  c3 o# W             else if(c==')')
1 T9 N2 z9 y0 C$ J# v                 return '=';  s1 o: ^* G! x- Q# }
             else  j. o+ F# b# H4 W5 e
                 return 'E';+ c& n3 K! j" p( h
        case ')':) h0 O% j7 n( N
             if(c=='+'||c=='-')
5 j. W, m4 m' g2 q6 L# F                 return '>';* V5 v; d/ Q2 P7 B- ~
             else if(c=='*'||c=='/')' M- @" @" j. p1 H9 G  d
                 return '>';
9 Y7 a) o. h) o             else if(c=='(')' k; j5 r7 N4 V8 L+ \4 T  E% b
                 return 'E';
: S2 y8 s1 k8 ~             else if(c==')')8 N9 T  ]# k' d# F  |' ^2 t& g8 R
                 return '>';0 [) u! t$ i; R6 \- r/ E  }
             else
- ?/ A2 f7 T8 y1 C                 return '>';
  Q5 x3 S6 m: g        case '#':' s6 V0 c2 Q: j7 \0 X
             if(c=='+'||c=='-')
4 o; y, q3 O% P/ G4 L9 w                 return '<';) G7 j5 l3 `2 B; K1 |, f; p' A
             else if(c=='*'||c=='/')6 I' i, r7 F( Y, m1 l7 c+ w/ g/ D
                 return '<';1 T! K7 U  D$ g& z* ~+ w
             else if(c=='(')7 P, i+ {* m7 e- U6 M2 f
                 return '<';
! }4 |4 {0 J1 F             else if(c==')')
. ^. p" }6 ~0 r3 O                 return 'E';1 \8 G5 {7 j  ^; Q
             else2 C  ?  z0 q5 z6 C5 X! h  V9 d+ g5 X+ S
                 return '=';# O! u. @, H4 M
        default:0 S) C) ]5 ], T+ }" {
             break;+ _# \* I. |0 W
    }, A5 q2 T, i9 v& p
    return 0;   
. l3 }- E5 V. s3 @}# N( ^  e2 u7 M% U8 O3 n
- d9 w& t' V; Q/ ]" q
int isOpr(char c)
2 u4 A6 a) L% a7 M/ a{
1 l3 _5 X; \4 s  R( q    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 r; F9 x9 Z7 L        return 0;
2 G5 F% {$ k. n1 L' c9 x    else
- q. t9 w- S: X' s& R4 n        return 1;- D2 ?$ [( G* n: v2 r8 A! C
}
2 r. z$ @! W0 X) ?
6 {4 f4 S$ d4 V  w5 X6 q$ }float operate(float x, char opr, float y)1 M7 c2 Y" E) B$ A# `& n
{) z0 p6 R% p& W) z" Q2 i
    float result;2 _( R8 |$ e6 ?0 d. _' H
    switch (opr)
9 c6 Z* {1 R. Z. C, u8 o4 c: {    {4 H$ T/ X) s$ N* h. p2 t* q
        case '+': 5 |9 `/ P5 A- c3 N$ N! \$ S6 k* F
             result = x + y;5 R6 e" s# V6 c- d& B2 c6 O% T9 g
             break;
; @! F: S, ~4 M& _$ O        case '-': 3 v( i" Y  ^1 }  m  ^+ N
             result = x - y;5 C& A) w2 X6 W3 S7 i: m! Z
             break;" g2 x8 ]+ N1 m1 F8 h
        case '*':
% p5 q$ Q0 O; e# C& U             result = x * y;
8 q2 [( F+ A) A" S+ z& A$ w             break;6 B  i# M- Z2 n* C  [
        case '/':
: ~. s4 K2 f  \- @8 o3 o7 F- r             if (y == 0)
) X' l5 q" ]7 q) s             {
* S$ y5 C- r4 P# h0 i& w7 k                printf("Divided by zero!\n");
& U+ \0 a8 a! M! Z) G2 Y                return 0;( ]; h' Y9 L# X; g
             }
$ i3 U2 e9 h# @" t# J             else
0 M2 h  p. r+ c6 p: v             {+ K  @3 I: l! S% m
                 result = x / y;
' q! x1 K% _( Q5 q- A1 Q. J                 break;
: }) V+ I) L4 |. p             }
: P4 R# P, w: T' s       default: 0 J; L1 [/ T  b
             printf("Bad Input.\n"); ' T- s5 s* z; v( B
             return 0;2 p; f& d/ [$ |/ T
    }
. \1 }$ H' Z4 a- r' q& b    return result;
2 z' g( ^* a- n8 k}   
# v1 \- F& H  g! |4 C/ a( ^! |0 ~: Z
  J& P( d1 b* d( G8 [) Hfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
& V+ p. P7 y6 Z# a- Y9 O+ P0 P) D{$ R3 Y" O. O& q0 V9 y
    Stack optr,opnd;1 P; \! v! ]4 ~+ D. x1 a4 i$ y
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;6 ?3 A- Q2 u( R; D2 g1 _
    char c;
4 |* k! R0 I& g+ N. Z& f    char buf[16];1 d4 V$ P. v! s. ~9 @2 ^. W# n7 M; ]
    int i=0;# y, B! |9 ]5 J" i+ P) }5 q
   
7 b" f6 @0 U$ m& k* p( r( a8 H4 D5 N    InitStack(optr); /*用于寄存运算符*/
% Q7 e; y* C  a% o4 Q( `$ |    InitStack(opnd); /*用于寄存操作数和计算结果*/4 _) J7 @# J8 F& P3 B1 j' u
    memset(buf,0,sizeof(buf));
9 S8 |6 f' k' Q: \+ z! q   
6 z/ z; h7 C) ~& h( y' c5 G+ j    printf("Enter your expression:");
7 {$ {1 |; w: k! B+ z- M* B          m4 G4 A2 J6 S; ~. c
    opr_in.ch='#';& U' m( ~4 ~2 [/ u
    Push(optr,opr_in); /*'#'入栈*/
4 V4 ~  I3 `6 P7 x, O    GetTop(optr,opr_top);
7 w5 [/ S5 p; Q# Z    c=getchar();
8 W9 P5 S6 `4 H5 ~( K- U) K    while(c!='='||opr_top.ch!='#')
. R3 w; h% K2 ^& x+ I! c    {
8 ^8 F4 v! v( i+ L' [        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/( p$ z; z, z" s8 F4 ~8 Y3 A: c
        {; u, q6 l3 d$ c6 h" v2 N! t, ]
            buf=c;: I9 H! Q4 P$ [( k: C
            i++;, v7 W( x1 K4 u  H/ {" `
            c=getchar();+ I/ `- B7 a2 [2 k0 g% Q; c) V) n
        }8 W, m9 V- j) o# `, _
        else /*是运算符*/0 m% x( j* t# J0 _) [0 V
        {
8 D. |6 j& }  m4 k% C            buf='\0';
) ~# f3 \, w( [; ^! {9 ?            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 Y) |3 e9 `+ d
            {) T/ o; t2 F" v0 s$ j: v1 m
                 opn_in.data=(float)atof(buf);
! x% o2 m- R# h. g: j                 Push(opnd,opn_in);& x9 [) q. K  J( D' Z& K
                 printf("opnd入栈:[%f]\n",opn_in.data);
6 O9 n* a! z6 j+ r6 H, O                 i=0;
! |, J  u6 q0 H/ l$ Q5 P                 memset(buf,0,sizeof(buf));
+ R/ t9 h+ |; S            }( Q8 N! L- ~+ I7 \0 [6 S2 P* v
            opr_in.ch=c;
/ @/ z5 i! k, N( E$ r; j, t            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
! `  H3 c1 n1 g+ k2 ?' j. X            {
# n) @* G* j6 |2 ^. @0 J                case '<': /*优先级小于栈顶结点,则运算符入栈*/! [7 B  K1 P" r5 R8 s2 [
                     Push(optr,opr_in);0 T. x# Z+ [/ i, `1 s
                     printf("optr入栈:[%c]\n",opr_in.ch);
$ a, ~& u* a- N                     c=getchar();! k9 I  Z& i. v
                     break;
  S7 b8 A  J/ E                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*// J+ s7 S$ e& i/ c3 M
                     Pop(optr,e);
- ~  C; Z  D0 p                     printf("optr出栈:去掉括号\n");1 V( T3 D9 }0 F$ J8 z; ^
                     c=getchar();; W; o9 x( ~/ ]* _9 J4 K
                     break;
% i' g( @3 S- ~2 T2 g* E9 j                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/4 B7 S3 m) x3 O8 B0 c- X- H
                     Pop(optr,opr_t);
4 [# c2 B# o/ I  Q& o                     printf("optr出栈:[%c]\n",opr_t.ch);
9 b+ X& X3 _& O                     if(Pop(opnd,b)<0)
0 m  t* z. k1 Y$ j- h8 N                     {
; U1 O7 ]5 @; i0 j3 E                         printf("Bad Input!\n");
5 f. ~9 U% h- ^) X" f                         fflush(stdin);
' m- O3 T* f; V0 w- ~                         return -1;: I, h3 M2 ?6 U" F/ z8 w; F
                     }4 m& i; E% `3 ^3 W
                     printf("opnd出栈:[%f]\n",b.data);4 F& X0 z# C! h4 h
                     if(Pop(opnd,a)<0)
7 E7 r+ t, z, H5 L                     {
! n' q- n% ]: ~% y8 V3 j                         printf("Bad Input!\n");3 L" Q& \3 k' n( I7 F
                         fflush(stdin);
4 v. l/ G/ T7 ]2 T" Z, ^7 _                         return -1;* D/ |" {5 M; l  Z
                     }
5 }8 W% D: x* {+ n, {                     printf("opnd出栈:[%f]\n",a.data);) G" o3 @9 Z3 b# r/ R9 R; K
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 i. p# F# c) y  ], y& s* v                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/# W2 v; }% `: x
                     printf("结果入栈:[%f]\n",opn_tmp.data);
( _5 ~- T1 {7 ~                     break;
" m9 o! Z8 c; R& O$ l. C3 X            }+ x7 A6 l$ h( e# r  w- f
        }
" `2 t+ l; O+ x        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
( G& E7 L" e6 X7 k" L: Q, T    }* r* r! w( U9 ^6 v2 j/ y, y
    GetTop(opnd,opn_tmp);
' x- w3 A* `* k% Z. V; Z3 C) k; z4 Z    DestroyStack(optr);
$ x" W' ^" S+ Y3 [: {    DestroyStack(opnd);
" k# q9 a# F4 `. z    return opn_tmp.data;
9 K/ r: X) P  X+ y2 ]! Q$ K}
, l% y+ F- D: ?3 v* X. C' U
2 @. d- |& U; @6 Kchar *killzero(char *res,float result)9 Q8 _7 N4 b8 m3 U
{# S/ R" Y3 K+ C9 e2 J, N
    int i;0 B% W% B, f& i! I) n/ J  ]
: T. O% X6 R- {8 u; ~0 P
    sprintf(res,"%f",result);0 W% O) j. }1 w5 k+ r( _
    i=(int)strlen(res)-1;# \/ S& u  `0 q; ]' E
    while(i&&res=='0')4 S: l4 _# w- j8 h; g* w- n  R
    {9 C" |& J% R( F; Z. Y
        res='\0';; L8 R2 s' ?4 S/ |9 k
        i--;
0 K! K$ ~$ e. e* L5 ]* P; w    }
* T. H' G# {2 ^    if(res=='.')0 C4 X) f; U& y9 }3 l
        res='\0';
" j8 q5 _3 Z. s; q+ R4 K2 X    return res;
9 T- U: ?( ]6 D& b+ ~9 g}
! H, l/ F7 h: j: X( D" _0 X9 G
; J8 ]4 U7 o# T: B. d6 b: X' ^4 uint main()+ s- C. r) ^; G
{
& P1 h8 s% C. k. Q8 t    char ch;
. a6 V6 V% A8 |9 z$ k5 ~% t    char res[64];7 O! h+ \. f5 K  Q
    float result;
8 l+ M9 P* f# I9 l, R, t    while(1)0 S* ^% g8 m5 Y) N
    {
1 f6 H) y- Q! K* O( l        result=compute();
  u6 x! ?, H& Q* [9 ~- |% k! g# `        printf("\nThe result is:%s\n",killzero(res,result));
( P  X" K$ C5 _/ ]. T& o: _2 Z/ N6 s        printf("Do you want to continue(y/n)?:") ;
- A/ Q: ?: P- k3 q% q        ch=getch();) x9 E- U& E/ d
        putchar(ch);
9 f7 {# t' g# b) l; p        if(ch=='n'||ch=='N')
: w- M% g+ H6 H! Z: K, s            break;
$ d- f8 U7 u, Y# X  t        else
: W: Z6 y; ~+ V& s, C. G# W0 ~$ {# W4 w            system("cls");. b& C/ R/ }$ R9 `! L9 F- X
    }0 \# n5 S- t0 [: k) k
    return 0;
# }+ W- ^0 I0 ~! G}
/ k! j: G8 f/ c7 T/ b- |2 d- }
) V; K4 C. V/ l' h* u. w4 e8 P, }* W
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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