返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.1 x  l) I& B; l$ Y- n3 u
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! |. T6 g: l# S$ n1 @/**************表达式计算器************/
' g, A2 A/ H& {& @2 P/ w, F#include <stdio.h>
% f* Z! w5 @) |' o#include <stdlib.h>
, P7 m, ]) c% a# W5 h#include <string.h>
6 A! `5 W6 [  @0 h" r& |#include <conio.h>
' c+ r, ]" F9 B8 D$ N. {#include <malloc.h>4 O5 \+ w' B) K
' q0 G5 `+ W  f% k! l8 t
#define STACK_SIZE 100
: t$ {9 ?3 Y- r: U#define APPEND_SIZE 10: A& T, M" d+ g. R; b4 @
$ T+ ]: ^4 t. K  p! n& o3 R& z
struct SNode{
0 ~, b% s9 D" \& Y    float data; /*存放操作数或者计算结果*/
& u- h' C3 R# c0 d    char ch; /*存放运算符*// \9 \+ E5 L7 K
};
! U$ z5 J, G# N6 `# p3 Q8 b( ^7 I- B5 Y5 i- c3 T
struct Stack{( g$ O: Y& {+ J4 f& }8 m
    SNode *top;
8 _* L$ G8 F6 O" b( z0 \    SNode *base;
4 Y- B/ S0 e% v6 Q    int size;
# b9 c$ M. M1 N% y};0 E5 l) h* f# ^+ \. i( D
( W  {* A: j: C9 Y; ]
/*栈操作函数*/
; D( [; V6 C. |9 ]2 V7 ^' gint InitStack(Stack &S); /*创建栈*/7 f" k9 G+ n; G: D$ k+ z
int DestroyStack(Stack &S); /*销毁栈*/
! P, r3 e+ ~0 @  ^, M% X4 ~6 fint ClearStack(Stack &S); /*清空栈*/
: L. C$ n. J- D% L0 U' g7 I8 v2 F( `int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
, q6 Q+ t8 d3 Gint Push(Stack &S,SNode e); /*将结点e压入栈*/% I4 @$ T: h; M/ D5 p9 d0 F
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/9 i: x6 q/ S6 J
2 b. E# a0 h% r0 a. L2 z
/*表达式计算器相关函数*/
5 K! y0 g* Y* [* O* schar get_precede(char s,char c); /*判断运算符s和c的优先级*/) |1 g6 [% H& ^8 d4 ?* `. M' j8 L/ P, g
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/9 }, R8 _+ M5 j  k3 r4 Z/ H/ V+ l
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
4 ]( O2 _% ~/ g8 |float compute(); /*表达式结算器主函数*/
! i" Q: p: j  Nchar *killzero(float result); /*去掉结果后面的0*/ ; R# h2 f  L) ]) w' ?

- c0 w$ f( o: b  Iint InitStack(Stack &S)4 p' Z3 t4 g! G& K
{. N2 K7 J4 @, J
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));! j2 ~5 ]3 G4 i. Y7 }
    if(S.base==NULL)
: h- T( l9 r9 t0 p" t6 K8 B    {* O3 |% t/ O- X0 j3 p" Z6 }
        printf("动态分配内存失败!");' c' h" n3 ?" z; z
        return -1;
, N/ z5 L/ J) H# q. h4 ^    }# v# a, H5 }. X) r3 \1 g6 x4 ^
    S.top=S.base;% B: V2 A& o$ r, @  R0 t/ C9 h/ h
    S.size=STACK_SIZE;
' }1 k; C& w7 w7 d    return 0;: k2 L% _! W# ^. d9 C5 T; m8 V, E" F0 E
}
5 j8 h8 s3 V' F, l6 l: B4 C$ X+ {, Z5 R
int DestroyStack(Stack &S)4 C( d1 `  q, X
{# j9 w( x% w1 a6 l4 i8 d0 C4 V
    free(S.base);; P! ^# l5 `- ]  W0 ^% ~3 x
    return 0;% R& Q3 p% z8 s& a: k: `. w
}
  x0 k3 _3 ]2 S. D) D
5 J! l5 K; j* g2 O+ rint ClearStack(Stack &S)
0 d* n0 D3 T1 s. e{% t8 [; }9 K: M- h
    S.top=S.base;+ n; C* T- Z4 Q+ v. u0 v) N$ P: T
    return 0;. H1 E% X% S; [& X1 B
}, A6 s% E2 t9 J

: l/ i9 D4 {: a- _9 f8 ~7 dint GetTop(Stack S,SNode &e)# v7 B0 G1 O3 ?+ C" a! Q9 x. `
{
/ t! V1 A+ U3 F    if(S.top==S.base)2 x# O; L% o1 Y; s5 ~
    {/ k  U( z4 U9 e. s3 t" h. w
        printf("栈以为空!");
3 _' q8 W2 N3 f  s" k* D        return -1;' {" [" G; G5 u3 D/ |
    }
% X4 O4 G4 @# a9 `    e=*(S.top-1);
7 U0 r0 ^" _) }    return 0;
; l$ G8 d/ z& B7 M  U  x( X; f/ x}6 H3 _* j& q. i' j. N. `% W  s9 q
  v& A0 x% _1 W! [1 B. V
int Push(Stack &S,SNode e). A5 v. \( e- M, ?4 a
{
/ h6 l! U9 w3 _8 C7 Z" [& h% I* o    if(S.top-S.base>=S.size)' c/ ~5 b, o! G. @
    {5 F, ~/ f# r% D& p) I
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
  Q& S8 W9 ?4 w; L0 f6 V) P. b        if(S.base==NULL)
4 H5 ~4 y$ F3 }4 s        {
; J0 s! m* ?" _0 p2 U- ^            printf("动态分配内存失败!");1 W9 F# B% Z; m/ s0 e  \
            return -1;) d1 W  u0 ], `4 c% k3 K
        }
( T. D5 w0 X, S4 Q, W9 ]        S.top=S.base+S.size;/ h0 R. M2 B& j7 N, o" \2 T
        S.size+=APPEND_SIZE;% v0 b3 V& b# _* L) V
    }8 R3 T1 u* e, \2 b9 H7 Y! [
    *S.top=e;
# c# |9 T3 ?9 D% E8 b    S.top++;
9 ]. e+ J. u  Z) P. v- h& y    return 0;8 b$ K0 g4 _; ]. o" l0 n( A# t
}! j0 D* p$ J  \
- S. I: S- `7 v9 u% U3 _3 k; U
int Pop(Stack &S,SNode &e)
# i- W- u6 `* J. Y5 G* S{! G  F/ u  B# _8 d
    if(S.top==S.base)
# r- {  i. h) ]& ]& M$ r    {2 |' F: K3 B7 `8 T$ u7 l
        printf("栈为空!");
! c1 ~! [4 m. N1 m0 Z5 L6 F        return -1;" Q7 F" p8 ~4 x2 J
    }
# Y, t5 g/ B1 K' k1 `" d& x/ p    e=*(S.top-1);
  o! ^1 p! a* J) O) |    S.top--;
8 [2 J( k- V! o) I/ U3 m    return 0;+ `2 |4 h1 k0 C2 E: @
}
! ~5 x  M: f' R% N
6 b) h( Y3 {- I& lchar get_precede(char s,char c)
3 {% R; p1 ]3 J3 ~5 J+ i{7 a( m( G/ |9 u# j- ?9 o8 x
    switch(s)0 ?$ X( @4 m( r, w! w4 z
    {
5 D6 |9 j+ N# B& B, U0 S5 Q+ r        case '+':                 & f3 s* y, o8 @6 A! _  ~4 `
        case '-':
& {$ _" L* F6 v' C6 O. ^7 K' \( }             if(c=='+'||c=='-')6 P% t1 D( D( J; d2 B
                 return '>';* U3 h' N' s. w8 q. v  w
             else if(c=='*'||c=='/')
% h* p$ [4 [# {( ?' p( O& ^                 return '<';; K( X; t& D2 z+ O: Q
             else if(c=='(')6 r6 i. n9 Y+ b) l8 _
                 return '<';
6 x* c; \' \5 N$ b             else if(c==')')" s* {2 b) q% g
                 return '>';
: e- U- O1 J4 [# }  `             else ) O7 Z! b3 z/ L  x$ q& C: j
                 return '>';
# F  p( T. R" a- n& ]        case '*':1 u. Y# }0 {$ B: I# `7 k
        case '/':
3 |- K; u  y4 s; O1 ]             if(c=='+'||c=='-')) W, c2 D. d* }' b
                 return '>';
5 ]; Q* k7 D6 a6 I; h8 S8 W             else if(c=='*'||c=='/')$ [! i; Z& J: h; v! v
                 return '>';2 Q+ E& L% F$ f
             else if(c=='(')9 ^  O1 z4 Z4 U1 l  l) C" N1 J4 h
                 return '<';
' ]' d5 n7 [0 w+ V; E' U" \! n             else if(c==')'), ^+ i2 }& w& j% A, J
                 return '>';9 V7 N+ t6 v! A7 I" \. H3 x7 @* m
             else
: z! r: S. F! C% w                 return '>';( P( x5 N8 {4 \* E9 J
        case '(':
) `) N, V5 U( L             if(c=='+'||c=='-')4 T9 F4 R& H* }9 W8 n, G
                 return '<';
4 v  q; ~, m+ C7 m# s2 q             else if(c=='*'||c=='/')
; g& H# s3 k" P                 return '<';
- J/ t4 ]0 ?+ W             else if(c=='(')
9 _7 ~/ _& _# w( J3 R7 A                 return '<';
" w7 \) t" H7 [1 @             else if(c==')')8 e! _7 {5 ?2 D- {/ {! D/ ?) n
                 return '=';
; D3 Y8 X* E# I% G             else; Q: A% _0 M5 l
                 return 'E';- K% k$ Y$ `- k6 w2 R
        case ')':7 M5 K) z8 S; |7 T- V  g) I
             if(c=='+'||c=='-')$ S, o; m1 F6 g/ @! J2 g" x! l
                 return '>';5 c2 T8 H6 N0 m" f
             else if(c=='*'||c=='/')
; R! {' R3 l" e8 ~/ e0 m( `                 return '>';
: r1 X' A+ y" f0 C  k/ K             else if(c=='(')
5 c  b) @# r9 O* D9 N3 U                 return 'E';
1 b7 I' N! i3 R. k. F             else if(c==')')6 y" X! X0 }' r* a# k8 [
                 return '>';! |2 w7 E6 J1 u
             else
% e% N# b% O7 @                 return '>';
1 {9 n! J5 T9 ?! U" ?        case '#':- y+ @: k! y8 l- d1 |1 I) s! |
             if(c=='+'||c=='-')  h) |* x# X7 m- R, ]1 [+ a% q
                 return '<';
+ z2 k4 t+ Y/ D3 U. e7 H             else if(c=='*'||c=='/')1 S" Z  J; K. ^) D
                 return '<';
3 G" G9 S  F) C; `5 D             else if(c=='(')
' G6 J. w7 u+ w% E                 return '<';
% ], w9 {1 c0 z1 V7 u' |6 ]# ]             else if(c==')')
! g9 `  o  u+ N  u6 k                 return 'E';
$ P+ l" c% g$ [0 |5 p" B+ ]             else
$ s1 a6 T. `; U                 return '=';
/ f! c" s4 x7 D0 V% g( F        default:
6 j% Z9 j$ \. x             break;
( z# e, i/ J7 k+ [    }
: w' w4 t$ J6 ~# p: b# Y  m, f    return 0;    ; F# h4 V/ r, e
}
9 X: r: Z' l0 w" X' l( U1 W4 J# r* F7 I& v! S0 W7 l2 u
int isOpr(char c)
# g- _+ `1 U  J: x{
& x5 o. U" P6 h3 s1 x( R5 _    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')" C% {5 \' b  N+ t
        return 0;6 Z: q! z: M9 w
    else 2 [/ h3 z: K2 T2 r
        return 1;
; \$ x: B; o0 C, ~- O: s/ A; O) T}
$ |# b+ }- L# G5 Y2 q* T, S7 n& H5 q  I8 }
float operate(float x, char opr, float y)
& \+ l1 H3 Q8 O8 @# z; h{
7 p$ I7 O/ N* {( K; P; T    float result;
7 B2 J4 J/ R/ I/ V  u    switch (opr)
: W$ X' K2 y8 D# u: y* Z2 t    {
% I" @. Y$ d' v        case '+': 0 Q# W- [* S, ]' S& L  d
             result = x + y;- _4 M- [; m0 T$ W: l
             break;
3 ]9 S" M& s' m- t        case '-':
% l$ y: Q/ ]4 d) h: M# i& F             result = x - y;
/ H5 r$ K( e/ K* F- W" q" z% e0 o             break;
& o+ C/ E9 a( X4 ~+ p7 O, m        case '*':
, D% Y2 i" Q% L% r9 O: V9 F  p3 r             result = x * y;
" o; l! d' A9 t5 x5 l             break;8 w: x4 J) @# O7 N. a2 w  Z
        case '/': 4 `7 ]4 Y: N6 [/ I. J7 g5 Z, [4 w
             if (y == 0)3 y6 ~$ `# K1 u1 n2 v# `4 v( c
             {
9 T6 l3 ], x: O. Z0 w  e; j                printf("Divided by zero!\n");& A/ x6 K* b& D3 ?- c
                return 0;$ ]5 k% o3 L) v+ \3 N/ [" a' T' a
             }
. A! k& _7 k6 s3 O; }             else! j4 D6 q1 ]& b. Q
             {0 o2 b8 u$ {: k& K* m# t+ B
                 result = x / y;
7 Q" P+ K. n9 Y/ q$ t4 h5 e                 break;7 V% O" q* m1 a
             }
& E* M2 c4 ]0 x5 M. N6 ^       default:
2 @8 F, k$ P" ]. c, ]             printf("Bad Input.\n");
4 f9 e& N6 u' ^. y- t             return 0;$ P/ O+ G& C# P% r, r/ E
    }" U; `# \0 P5 e# [0 `
    return result;+ @; F1 b0 U$ i& O" ?
}   
" O3 l* |7 i; K0 k! \/ V
4 t* D0 Y& z1 Ffloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
. A8 f" x0 D" s* t5 I4 Y{
5 G: L% w3 w$ d7 m7 V9 B( n1 q    Stack optr,opnd;6 z9 _0 d" J) o$ m( F+ h
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
$ I  |4 Z; j3 I- Y5 E% Z; M) h    char c;
6 S8 ~( H' L0 e* g- A    char buf[16];5 l3 F0 r6 ^2 D* l
    int i=0;
( ]8 k6 k+ Y& v    8 v8 @+ E+ A- E9 s
    InitStack(optr); /*用于寄存运算符*/% I6 `' V% i0 e% I. X" ?0 D6 j
    InitStack(opnd); /*用于寄存操作数和计算结果*/
2 |" X3 w) v8 f% ]    memset(buf,0,sizeof(buf));  c! Y) v* @& Q
   
0 U1 u8 M9 P# d2 x( |    printf("Enter your expression:");1 S5 A5 u) [' u! e' O
        
  ?. W# O9 |: e# G5 i    opr_in.ch='#';
" _, y$ v7 m4 B8 V! S    Push(optr,opr_in); /*'#'入栈*/9 W- z# I0 `3 D8 i/ _  u
    GetTop(optr,opr_top);- I  p2 k- I0 E
    c=getchar();
& t/ s( m8 n. T* E    while(c!='='||opr_top.ch!='#')
# T) A7 @# B' s5 q# B: c    {" e) Y/ m- A1 S# w
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
& a- A9 A( ?- x9 K* Q        {
' ?% c' u2 X$ B' Y" k9 v            buf=c;0 ]" f0 V9 y5 N. Z- \8 t
            i++;
9 @' k; M$ g- u8 e3 W% u; _            c=getchar();: y7 R" i+ Y; V; U1 E; E
        }3 n- W  e9 P, N6 o2 o) v
        else /*是运算符*/
; _" g' h" F* C& v# S        {6 [% p+ a; X- u0 {
            buf='\0';
/ Y8 u8 O5 e1 K* W. J0 b            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
+ B7 F. j( K3 @0 R9 X9 L6 ^# }            {
7 `3 q7 L; j& ]) i2 X                 opn_in.data=(float)atof(buf);
8 K8 o: L/ x- [* F# v( a# K                 Push(opnd,opn_in);# _8 ?( ?4 e" o
                 printf("opnd入栈:[%f]\n",opn_in.data);* w- _% a6 t3 j& l
                 i=0;1 u7 Z7 i2 k6 C& ?* m* w1 |! N
                 memset(buf,0,sizeof(buf));! [, g- r6 |3 J: q2 V
            }; f! P" R3 c' Q' m, l. h4 o) }; Z
            opr_in.ch=c;
- {& ^; p+ C' d+ H( ~            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/: P0 k. R  I6 k" u
            {
3 k1 {% g5 z3 _! j                case '<': /*优先级小于栈顶结点,则运算符入栈*/2 ~8 ^4 y7 q. u6 S8 V( t. X# a
                     Push(optr,opr_in);1 W1 y- y6 o: k! A# H
                     printf("optr入栈:[%c]\n",opr_in.ch);' E) B1 g' H! T+ D4 _& F
                     c=getchar();
0 \& d2 ~- [2 f8 C                     break;
1 H- Y8 S, u* p$ y6 R) S# l                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
$ a# M# P+ I; g% H, ?% O4 F                     Pop(optr,e);4 \( G& f, X2 `0 A2 T  o9 Y
                     printf("optr出栈:去掉括号\n");$ d2 n) f$ t4 m2 y5 d
                     c=getchar();' I9 `6 E8 ^! D) ]
                     break;
6 W* C; ~' P4 A' ?' K# n3 i& M* D                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/. C4 b$ t3 X5 I3 ^2 u+ z- u, |
                     Pop(optr,opr_t);& u! W% p7 J7 ?" D" A
                     printf("optr出栈:[%c]\n",opr_t.ch);
( \* X& b0 n! Y( H* M                     if(Pop(opnd,b)<0)7 P/ ^$ C/ M; O( y2 |
                     {
" \2 B: j/ k5 _                         printf("Bad Input!\n");5 f7 |# ^) n/ d: v3 ^! v: A
                         fflush(stdin);8 f7 W; m  A8 E  d! W
                         return -1;( m* ?: e* m4 i
                     }
% W+ d+ w  {3 f$ z                     printf("opnd出栈:[%f]\n",b.data);
+ _0 W* V! l1 i/ ?& v+ |1 ?                     if(Pop(opnd,a)<0)
1 {8 ~( U! W  i5 d                     {% I) u) A1 v/ ]9 Q7 G; t
                         printf("Bad Input!\n");- h$ d- h) O  }+ E  i4 R4 A0 I
                         fflush(stdin);
# s' @& q2 X: ^# D) r7 D8 e                         return -1;
2 H7 ~: T# y, }5 Z: |- j5 [2 n                     }
2 ?' ~4 Z9 Z/ y6 k# d: [                     printf("opnd出栈:[%f]\n",a.data);
7 B, r4 A9 A! X: X& E5 \) s                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 D  e1 e' `, C                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; S( f  T. s# l; R& x% v                     printf("结果入栈:[%f]\n",opn_tmp.data);
8 q8 U1 H  Y! z6 I' A6 S                     break;
8 {! p5 A/ m' d& E6 K* ~% M            }
8 X# {$ H8 N( h6 z        }
$ M/ p+ a3 |0 s1 ?, i1 U/ J* w. I        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                5 H8 F  a" @  [# i5 b4 d
    }
- w7 S  y1 q$ d% I! v3 D3 P    GetTop(opnd,opn_tmp);" y) q) y" @9 p0 b. U5 }' c) \' ?
    DestroyStack(optr);  A7 x/ U+ k4 V* d" U. _
    DestroyStack(opnd);
) g* d" ~# c  @! Y9 \, Q: m    return opn_tmp.data;3 p4 W& o8 t* _0 A
}
: @7 K. y. ]% J1 a0 n0 N4 c( A4 e  t7 u. D
char *killzero(char *res,float result)
$ X# D% x  R% o: M4 X  _0 d8 t{
# }, e, B: `/ n+ o+ h: ]    int i;6 ~( z! R4 v- g% V, Q

: T' i8 s, z3 F9 Z6 E$ O% k    sprintf(res,"%f",result);4 Y7 j+ I' i# J1 M- o8 c
    i=(int)strlen(res)-1;
$ B1 l8 ?, ?7 k    while(i&&res=='0')
* c' x, ]7 V4 o6 ]" T; N    {( v6 S* F4 ?; ?1 k3 y" q% e/ g  g! {
        res='\0';  o- a9 j; i9 D) E- M' M
        i--;# F% O) ]/ Q5 k9 b" s, @
    }
+ m3 X7 b. y/ Z; U2 u    if(res=='.')
1 Y  O3 ]3 M) X' _' B; N0 Z/ h        res='\0';3 q* f0 @- I' ]- i4 P$ N5 M" F4 Q
    return res;
3 _8 n; i6 w/ d) K0 I) `}7 [9 T* m5 q! O
4 U. T! k. M$ S% A  U
int main()- P6 k1 W. J2 f/ E( f: a
{+ c3 Y4 Z, o, @3 q# u
    char ch;
& z2 Y* u# t9 b0 E$ y" V    char res[64];
: Y1 Y( o% w1 {' X: E4 ?    float result;* h1 N0 X& [$ k% l1 e+ j4 F
    while(1)
) J: y8 u2 X" ?3 ?$ f% n    {# q# B: ?8 `4 w( B: A$ ?" T
        result=compute();" u. W! g+ {+ A) q' ?0 o/ M
        printf("\nThe result is:%s\n",killzero(res,result));
8 ?8 v. L$ h. `+ e5 @. J        printf("Do you want to continue(y/n)?:") ;
1 S2 N* R+ |/ R2 A: {4 x        ch=getch();+ ?4 R% [3 B' r- b( N: t+ G% ^
        putchar(ch);
8 @, w8 B: K5 D, _! R6 f2 Q        if(ch=='n'||ch=='N')
8 A( P; ^+ }: H0 s' R6 }            break;# `  |5 d' N4 |; R% P- Q
        else
+ Z5 Y+ ]2 _1 x6 f$ c            system("cls");
# c5 p  J6 k8 w# P* h    }
  y% Z9 y5 z5 i    return 0;6 u6 Y1 s% K+ H: O& e8 G) }
}
8 n1 @4 L0 J7 ]; `* O) Q

! {4 x: T5 n% E[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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