返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
3 Q" ^& r) d# w程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=+ L9 x4 r+ x4 K: L' x
/**************表达式计算器************/
4 F6 f; q. C. S7 {+ B: ]0 J5 U2 @#include <stdio.h>
% g" x; t$ H( m/ C#include <stdlib.h>
$ [! _5 R& H( U1 G! j( S0 J5 e  [#include <string.h>
4 b7 t5 E6 b- e, A5 L' z( V#include <conio.h>
4 F7 G8 A, F- a7 O9 Z( Q+ C#include <malloc.h>* V' y, o3 `$ g- m% [6 P+ |5 _9 u1 G

& g+ [. M" ]: z+ ^$ w# G#define STACK_SIZE 100; I- Q+ ^. {# f# U" A& D- T5 Y
#define APPEND_SIZE 10  D7 [3 Q) D6 x" K
& H2 x* @' ^6 C( ]% m( j9 r( r, H% c
struct SNode{3 v/ \/ {8 J& x3 u5 ^- {
    float data; /*存放操作数或者计算结果*/
$ s/ Y. y+ b+ K8 d  P( f9 _2 m2 E1 `    char ch; /*存放运算符*/
2 i3 }# J1 B1 G. y' }};
6 ?5 S5 S* m# I5 N
* t! t+ f* P  g# C% F0 h  D  Wstruct Stack{
) i9 N: ~6 P! ]$ O  q% T5 T    SNode *top;  |6 y% S# |/ c' E8 Y4 p" |  E* |
    SNode *base;
: p/ _/ g& V! ]3 I) U- t/ ^    int size;
  f+ F4 I3 r: @5 _};. J+ O. J3 F; m5 a/ S4 k/ D* K+ G
. Y$ z! V- o* w5 F3 L* O
/*栈操作函数*// g4 M; b1 T3 L& C$ H
int InitStack(Stack &S); /*创建栈*/: b! t4 G3 {/ z2 T7 V7 o
int DestroyStack(Stack &S); /*销毁栈*/
& L- ?4 F8 ~$ b* `3 s' Nint ClearStack(Stack &S); /*清空栈*/
" e1 H1 E, e, s9 b' m9 Q" V7 X. Eint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
: A4 I0 }2 q* x; Eint Push(Stack &S,SNode e); /*将结点e压入栈*/
. F3 o6 C6 c# ^, j& X1 Gint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/) {" p. \5 f* O4 J1 _
6 _/ m! }9 I* L: K
/*表达式计算器相关函数*/5 ^$ b9 V& U2 p
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
3 O+ n1 E, o; C1 }5 Sint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/4 c3 U  O  G; }+ G
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/" X1 |0 K$ q6 D7 k: ^0 J6 n
float compute(); /*表达式结算器主函数*/
; I* z/ b/ @" o7 Zchar *killzero(float result); /*去掉结果后面的0*/
1 d9 G( o1 O& M  q* v2 g8 T3 J5 H  `' @+ z! @
int InitStack(Stack &S)
# D9 o9 L0 N: l" R{5 ]- k( p8 }! P4 g( U! ?  e( u
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));. r0 a, u' W* g" r: P6 I( x
    if(S.base==NULL)$ g+ B& s# e, A2 P) h" X
    {
" B  x4 c& F1 n; K6 W0 x        printf("动态分配内存失败!");
* A% L3 B; ^! @, [7 j7 S0 v: D        return -1;0 u' Q. I" o/ c1 g- D
    }
2 v* Q6 ~. W/ c2 z' d9 f7 T- i    S.top=S.base;
1 O& L- C  W7 i1 e: {" L* @    S.size=STACK_SIZE;
2 G7 x/ i* \; @2 _" y; @    return 0;6 L8 t6 r' N( C9 b9 R9 o
}$ w& Y" I2 o" g  V( @
% Z7 w" f- t( l. y$ Z9 X! [4 o1 y& O
int DestroyStack(Stack &S)
" m* ?" x6 |, I, g  @{
3 z/ u  k1 `; p8 [: G    free(S.base);
5 n- |& [3 w* U' ]+ o  z    return 0;
3 \- A" Z; x6 _4 @% ]}
, M4 L& U( e7 K" U
6 S9 n3 o) _' n. `( r+ a8 dint ClearStack(Stack &S)/ E' K9 V% Y: q/ K
{. s3 Y/ v* e' Q" w$ @7 Q
    S.top=S.base;
' ]: B* ]/ |' A( Y9 H4 ?* @7 {3 i    return 0;4 A4 @# P0 ~  k6 i! s' W- ?  {: `
}
* O! e3 Y! X* D  D0 @; s
, b6 Z, _8 R1 W. i8 {' q$ eint GetTop(Stack S,SNode &e)
8 A+ _3 F3 R. D  y7 f{$ T# r2 A1 ^& w. U* x7 {& I
    if(S.top==S.base)6 G5 T4 M+ H4 k4 h5 [! x9 S* H/ Q3 a
    {% L7 ^4 t3 Y, B9 }) Y( l
        printf("栈以为空!");) p/ v2 w! G7 R! u9 C; r
        return -1;
6 C; r, y( g  G8 u    }
9 T& ]3 C8 M5 z5 J: i    e=*(S.top-1);' }( D$ I; x/ L1 a! s2 K
    return 0;
3 I' }8 U; R; s. S& U8 U}  `3 C4 @) w2 m( O- O  ?

$ h- A4 [9 ]- p$ j5 F( B, @int Push(Stack &S,SNode e)4 K4 x; t& N6 S# H$ V8 \
{
! O! j/ x+ p5 z+ n" g    if(S.top-S.base>=S.size)
4 j; W4 q. |9 M    {+ n" G; J5 r' G
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));1 u. A# j; d4 W3 H4 f
        if(S.base==NULL)
% h' C' D2 t2 \! x4 G        {
2 Z& W7 ^5 f7 N            printf("动态分配内存失败!");/ @9 W- A% ]% u# p! h
            return -1;8 J8 Q4 h( }5 E6 |0 }
        }8 q$ w% s# U$ e5 M
        S.top=S.base+S.size;, q5 t: i) W: F3 ~/ Z
        S.size+=APPEND_SIZE;" D! J0 f3 w' O# J1 z8 D$ c
    }+ a# U8 T# x1 {* M5 M. u! h5 P0 R
    *S.top=e;! H3 j6 ]# c) e2 F
    S.top++;
( ~2 ?) U. y+ _" c5 t; Q) \8 i    return 0;1 z- S5 L: _) x& X/ M
}
7 J# L0 w. F( _% C! y; x
* w2 ^7 P' k2 w& u, uint Pop(Stack &S,SNode &e)* Q( v6 A9 x( S' z! X
{1 H. J/ j  F1 ~
    if(S.top==S.base)
# _6 G2 n: h6 V6 j" _3 _    {/ {6 q$ }. r$ ^) c' I8 q/ d- N$ U( o
        printf("栈为空!");8 U/ Y* H7 V  H/ O, m$ F! g
        return -1;
1 i  b- {2 w' |    }
5 I9 n. Q/ U. s  |2 A& s( @    e=*(S.top-1);' q/ [- t, b8 Q; O
    S.top--;
5 X5 f2 O( m) m' y    return 0;% H) d/ F4 t6 |2 S3 G% E
}
) L/ S/ H0 I  s) ]3 O8 l' d1 [9 V0 X9 S/ M8 u% e
char get_precede(char s,char c)4 i6 p* B* z9 ~  S
{
3 D9 P- l8 ?3 o0 S2 _1 i* E" B    switch(s)' o- l% z2 z; M3 ?
    {+ Y( c7 P$ ?6 y8 Z
        case '+':                 % O6 h' U6 o9 l: U# c) g/ g2 P1 y
        case '-':9 z; c9 F1 F7 @5 u# j5 a. o! b) I7 R
             if(c=='+'||c=='-')
7 z0 u" B2 I/ T1 n6 n                 return '>';" ]) H, r# g1 b6 r
             else if(c=='*'||c=='/'), Y- ]8 o: _; X2 F
                 return '<';* ~$ X, K+ e; i4 w( ?, K' C
             else if(c=='(')% l) E, A/ X% C( x+ U! X
                 return '<';$ @9 x2 A# t; _8 T) r  m
             else if(c==')')
% C/ N/ t8 K# H                 return '>';. Z8 |  ^: _/ v* L$ ]
             else
( n, ~! ?, ^- S1 D8 F: u* E' f                 return '>';
% B  z9 j7 y9 x' t, L( }  @        case '*':& O; o, w3 W2 h) l3 O
        case '/':
. b1 g& ?( ~  i' J4 y/ W, S3 \             if(c=='+'||c=='-')
/ E6 Q" C6 }+ i                 return '>';
7 ]" F# R5 p( W: q& j             else if(c=='*'||c=='/')
! ], R' ^8 s# T" k- _+ P5 b                 return '>';
9 t1 l0 e" W1 g, s) _             else if(c=='('); R5 ^' K* U3 ^
                 return '<';
! V$ I; N! |- U( J             else if(c==')')# W) @: g! N7 Q* v* ^$ R" a2 y! L
                 return '>';
# M; f7 p/ f1 E& h5 Y             else! v1 [- z( v) V* e4 |5 o! R$ h
                 return '>';1 w8 W& U3 z' L  l. t  L) k
        case '(':) C3 U7 U* J0 C  b9 F  G
             if(c=='+'||c=='-')4 ], x% ~4 F+ f
                 return '<';
( h5 ~( E7 M% u2 G: j             else if(c=='*'||c=='/')3 o# @; b3 \% s* p
                 return '<';; [; y! t+ c+ c
             else if(c=='(')
9 _1 }, ^8 }- h( y/ }- T' p                 return '<';
5 D& A+ ~0 M' }( z# t& _% M             else if(c==')')% a+ c8 V5 q0 a) f9 r( Q9 X
                 return '=';5 T! J/ ?. B5 O
             else
/ u7 Y/ ]) u) i0 z$ ^                 return 'E';
3 T4 \+ t& h* a        case ')':
, f' D( s& l2 E9 z3 `  |             if(c=='+'||c=='-')
* j4 D$ O1 j% t                 return '>';& H' B8 H9 P2 V6 s$ m2 |0 C
             else if(c=='*'||c=='/'): W8 U& j& B; {* |) M) p
                 return '>';6 A- [/ i5 N$ H! v* E6 B3 m. e1 a  U
             else if(c=='(')# f+ P/ F8 Z. h
                 return 'E';  f' j' Y: P; |/ W; j
             else if(c==')')
, T1 x& }* V: d, F                 return '>';8 }0 t$ e" g9 H
             else
" Y+ \! }9 D0 L* q+ W                 return '>';6 D/ M( I* U# k7 o) [
        case '#':, J9 p( G. w# X, U, A/ ]2 S; E
             if(c=='+'||c=='-')
) X: S5 A" e: l5 U                 return '<';* \' z' v& D1 f8 a% ~
             else if(c=='*'||c=='/')
- p5 P% F2 \, p. Q                 return '<';
5 k. \  U! b" Q( c' R# m# S1 X  X5 F  M             else if(c=='(')
( J$ Q; b0 a+ [1 i                 return '<';& z  N3 k3 n& ^4 \5 q% a
             else if(c==')')
; r: [3 ~; T# q% {- k                 return 'E';9 j: S* s" }9 H. N' ^0 K9 J5 I% r
             else1 h; S) g3 y! Y6 V- u
                 return '=';6 j* ?+ k( k! [: H5 Z
        default:
; b4 i  H) A, v             break;( ?6 K: |4 f( h8 X
    }- {/ Q3 g' d: R; w
    return 0;   
0 k7 U& l$ s5 }% ?: T! x+ e}" e. ], k* j  l6 i2 u
3 g) J2 ?- n6 z# J* N0 ?' f9 l) I
int isOpr(char c)
* f8 K" {/ F; d$ |" K& `1 \2 p6 i{
$ s4 b3 T, K4 o5 l( Q    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='). x9 Q7 Y- L# w/ |4 u. q
        return 0;
( d! \1 e# @5 ]0 w: O    else
7 o1 V/ U( M5 K! U2 E        return 1;" H( k6 b  O8 M
}) ~# ]1 \7 p# e7 G% A. G

2 p* v2 `0 ?: m! V  Kfloat operate(float x, char opr, float y)
. a6 _6 a/ J/ d* c2 W; Y$ m{
# h8 o# C; l2 {+ D% }( `- s, q+ @+ N    float result;
% q* x6 S! H! \% m    switch (opr)! x( d# e: M2 ]8 }6 G) D! ^1 I6 _
    {; x7 i( N" N+ e; l5 }$ c) I2 Q
        case '+': 2 ~: o) B, t+ \
             result = x + y;
' z# O9 ^# P' y/ T/ A             break;, S3 C1 w* {) b3 m5 F
        case '-': ' C4 W$ I# I: p- i. V" J$ I! n
             result = x - y;
" {% ], m) M; E% n: s- S2 D- v             break;/ x' W3 f# k  a; W' ]1 Q
        case '*':
$ [, G# F5 Q% t             result = x * y;
8 t  E/ F: X5 l- J* p$ Y" L$ ?6 j             break;
: z& B5 ]  z; A2 f7 V$ n        case '/': 6 ]8 i( K) I" @
             if (y == 0)
: z% c  t! W2 S8 W2 P             {
. h$ y) E0 N# p$ \; n                printf("Divided by zero!\n");! M3 @( c- m5 b1 J
                return 0;
2 N( F5 m, R+ L             }( X# d& o! r( H; |
             else
# p. H) H3 J8 G6 h: o             {
) A1 `+ a) U: O$ ^3 \/ n1 K                 result = x / y;/ I1 Z! [# K$ |' V; a
                 break;
5 t, h) }  v; [8 w( U2 r- j             }2 H/ X1 c$ B8 f8 s8 U+ f  B; z
       default:
& X8 k5 c( q9 d             printf("Bad Input.\n"); % J, M1 M* t2 {- W+ W
             return 0;' C9 q# C/ S/ S1 ^7 C/ b2 n
    }) \% G) x6 S; m
    return result;- d; Y- l9 u* U
}   
* L" E3 ^& }9 y) b3 Z- I3 V; `; q- \$ ~
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 o# z1 g/ s9 q; }{
/ \- a$ y  v  w6 R" c    Stack optr,opnd;5 Y  P6 Y+ {- Y9 L* A
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
7 M; Z2 n  o1 h$ g& L. K% ^    char c;
6 S% V1 F( _; V& m5 w6 V    char buf[16];
( [* @" Y" e1 i- B    int i=0;9 H+ R$ H+ x" r
    3 n+ q% O" B  R' A
    InitStack(optr); /*用于寄存运算符*/
( h" M' v/ b4 V: s: t3 b3 i# D    InitStack(opnd); /*用于寄存操作数和计算结果*/. Y' |+ l, z- L; b! t/ R! p
    memset(buf,0,sizeof(buf));
9 f5 q& {% G) u5 M    ( B- L: G& _8 S+ y9 {$ T
    printf("Enter your expression:");8 m8 x$ C$ E; {; [, k
        
3 b8 v; W' n; c: O6 K& M2 e+ U    opr_in.ch='#';. A& f" I. C  M. i# x* v
    Push(optr,opr_in); /*'#'入栈*/% a# w* H7 P7 D6 p0 f
    GetTop(optr,opr_top);1 n1 W4 D, @: x' L
    c=getchar();# y+ m: s! @% L
    while(c!='='||opr_top.ch!='#')
5 M  Y, C1 c- i    {
% s8 Y) H2 X% e& a7 W        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
- ~' f, [4 q  G' s+ N6 K7 m        {
  I& D2 l$ Y, \3 j7 R  q/ Y# i: I+ @3 O: E            buf=c;
: Q+ r& F7 Z* H3 A+ J/ T            i++;
2 ~/ ~3 w; N( p: H, ~            c=getchar();
7 O! s5 U; q9 Z4 ~        }1 ^, C. ~5 H% l
        else /*是运算符*/- `1 j' w. b3 B% x) K; {7 U
        {- L2 |) J9 R! v* ~, L
            buf='\0';
$ ?7 k) M0 l- N- }/ o            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
. M9 r$ c% a" P, Z! c+ g            {) }# T+ O( S" q! D
                 opn_in.data=(float)atof(buf);, ^( {1 V3 N5 B" k3 n* ^" \
                 Push(opnd,opn_in);
# m/ m6 {9 |. u                 printf("opnd入栈:[%f]\n",opn_in.data);/ }- v  J' o$ X2 h% C9 U. S& Y
                 i=0;' J0 B2 f  c2 `' n
                 memset(buf,0,sizeof(buf));
+ U" J! P4 N8 I* b6 w            }
( ]+ O/ X; n, n- k            opr_in.ch=c;) M8 B' O  `% j2 o7 Y& g
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
/ f2 _. g- Q6 e0 J1 A, B: d            {+ k$ z1 D! q9 N* A3 F  I2 h
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
; J$ o9 r4 X- `, D                     Push(optr,opr_in);7 l# L' L$ X2 Z& S
                     printf("optr入栈:[%c]\n",opr_in.ch);
( L/ S. A2 Z" E9 @& u6 j                     c=getchar();
$ ^$ M1 V6 R: `8 W- M. H                     break;; |, ?, C( [+ i# m: Y9 G
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/( `5 X1 Q& Y1 @9 Q
                     Pop(optr,e);
1 ^" n+ t' g# w% b! C                     printf("optr出栈:去掉括号\n");+ f9 H: C2 w4 C, a" z
                     c=getchar();
4 K( J  j* {; |+ T$ t* ^                     break;
. R5 b& E, C* d+ h+ w( ?                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/" t9 k! q0 c- e- B
                     Pop(optr,opr_t);; E3 H* `  H8 w: G6 {
                     printf("optr出栈:[%c]\n",opr_t.ch);
1 N: o5 X. ]& G0 _- y! L                     if(Pop(opnd,b)<0)' J% N+ F. }& d' t8 g
                     {
/ W. n5 c, w1 x! U                         printf("Bad Input!\n");
( l3 q. U# E% o& T/ P5 l7 N7 O                         fflush(stdin);: S6 I0 N( r! _
                         return -1;4 r- P9 G( [# `
                     }7 K# i/ A9 S( ^' D
                     printf("opnd出栈:[%f]\n",b.data);
3 t1 Y' q* s, x% s' D$ u                     if(Pop(opnd,a)<0)
6 b" B- u9 y! R7 ~# `; R                     {
$ _9 ^1 q$ P8 x                         printf("Bad Input!\n");
: [6 `! J2 j- X4 O! K                         fflush(stdin);
* K, `  W4 X& g) _( m# u' L/ [                         return -1;
0 X! `2 D4 C+ M) l6 X: @                     }
$ G1 c+ ?. O  ^8 G5 F& W                     printf("opnd出栈:[%f]\n",a.data);
) r( ?& n/ m: }2 f8 P! z0 u                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
) T% R; @! c/ \                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
% S+ X6 S/ S7 [' g( C6 u                     printf("结果入栈:[%f]\n",opn_tmp.data);& S$ c9 ?# w  s' d: ?
                     break;
2 r& N! x- B! M6 b2 S            }
: H6 W+ b6 U) `9 k6 r2 n        }. }0 r/ V/ F% E: z9 J5 \+ ^. v1 V
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                0 {  \2 m3 a9 L. D
    }
0 S! [! S# s2 v* x- G    GetTop(opnd,opn_tmp);
3 j3 o( ^% R& y/ a+ L    DestroyStack(optr);( |2 t2 N  e) m, \$ k
    DestroyStack(opnd);8 u1 L3 H0 C& X' Z
    return opn_tmp.data;
2 ?' m# Q' t/ E2 J}: G. D+ t/ m+ r) D1 y5 v

+ {2 Q$ k0 C' m# [4 gchar *killzero(char *res,float result)
+ z* [, j3 s) d- M{
1 v, }% b5 s9 `8 \3 ^* |; s1 n    int i;& f8 o* e+ q  g0 [. i" H2 c
! j9 p9 W. @; s0 g) Z% b
    sprintf(res,"%f",result);
+ @  d3 ~* T3 G6 J) r    i=(int)strlen(res)-1;
  S5 F/ k3 z# @3 P/ S: G3 W* n; x7 R    while(i&&res=='0')
2 C- ?* h( t6 Q! d    {" P1 k' x  R+ g# @7 D" j
        res='\0';9 F  n1 \  m0 Q) {3 Y( ]
        i--;, y- j/ {$ Q/ s! U7 q! W% M+ y# t
    }
8 D% q+ n8 u0 P& e* N0 F7 Y) M+ h    if(res=='.')/ |# I' [$ k1 ]  M$ K+ P8 z
        res='\0';
2 f$ A& ^8 k. v. O! r5 G    return res;
2 g; C5 p+ W; a3 r: \! q$ f' x! p}
  y! X8 k! B% I4 V  L3 m& _+ M+ ^0 u0 j" `* F' U' Q
int main()/ Y& G( |6 W5 G6 ]% I; i: j
{
5 J' ^; t' t- |! j+ [1 V* t    char ch;
# F) \( S( x* b  ?- ?6 e    char res[64];2 \' w; _, l( y* _+ f6 z
    float result;
+ m# v/ j! `" I; \    while(1)
' S" S* [8 p* I; K) u: G    {
. m) v; N9 H4 M! \" B: h8 o        result=compute();% D* ?9 {4 X7 a# {6 p6 @( `
        printf("\nThe result is:%s\n",killzero(res,result));
1 P6 p$ \/ H/ ^3 l( R; G. a        printf("Do you want to continue(y/n)?:") ;
8 y. H' i+ E  w        ch=getch();/ J% t  I# b4 z; \' J
        putchar(ch);
  M4 m" y, A/ |5 B: v        if(ch=='n'||ch=='N')
2 P+ U, i; Q, \1 y7 i5 _" J0 l            break;
" n7 p/ z$ c, f5 O        else) X: P" d& n7 H  _
            system("cls");
% E! u* Z7 g$ E8 o1 i    }% f$ G/ i, U2 z7 x
    return 0;6 a+ C5 H4 A3 N3 x
}
0 n  N9 a1 K' C
: \3 \% d  E; z3 _- K! U; I
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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