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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.! y' V  h4 c1 N! z5 a
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=! {# [: p0 H+ K# L9 O: ]" }9 i* o
/**************表达式计算器************/
9 [0 w5 K& W0 W/ a#include <stdio.h>
3 t2 k: R# e/ b' P2 p7 h#include <stdlib.h>  ~  R& I$ h7 U* W; z
#include <string.h>+ I3 b: p2 Z# }/ t8 C- t$ W, Y) H
#include <conio.h>
) i& Y6 A6 @0 F8 E7 |7 D#include <malloc.h>( F9 \, y# y1 U

) W$ B* i+ G  M4 P0 Q. T#define STACK_SIZE 100
% C( e8 q' L4 q6 B% v#define APPEND_SIZE 10' O- S9 T( T( d/ L  {' I

- M7 g& t% E) D3 U3 @! Gstruct SNode{
; g" V/ V, k! c. n5 R4 C    float data; /*存放操作数或者计算结果*// ]# t, B  L$ M6 W, M+ P" I
    char ch; /*存放运算符*/; i6 Y0 R8 @+ p
};
% C3 z2 g* k: Q- p
* i- N: ?5 L. B5 wstruct Stack{
3 e0 N  a4 @) @/ V2 }) ]    SNode *top;
# T1 P1 _1 N2 {* c    SNode *base;
2 {1 I( G0 O, T" ]6 Z5 X( G    int size;
  s5 D+ U) I' {, S* F) s( b};/ A4 S" N, w# u% D4 N/ S# D
/ o5 [( U, K/ @) S$ e5 A; k
/*栈操作函数*/
2 o. c- t, e* tint InitStack(Stack &S); /*创建栈*/
% [6 m$ ^9 Y' P7 O" R4 Vint DestroyStack(Stack &S); /*销毁栈*/$ S- q2 L2 ~$ j3 P% T" o
int ClearStack(Stack &S); /*清空栈*/
  y7 v: U' p2 nint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 m: P% ^+ S+ }% w; }, u+ B& cint Push(Stack &S,SNode e); /*将结点e压入栈*/
4 a# d1 o; B) |& y" t1 }! gint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/% A1 O4 p' \' ?  V( S& h

' v, y( k# {7 ?/*表达式计算器相关函数*/
1 |$ e8 b9 Q2 q1 ]+ g2 ]char get_precede(char s,char c); /*判断运算符s和c的优先级*/$ B# y0 |  @' W6 ~
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) U, w' o! d2 E, N2 P
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/& }; \& V; z7 `/ h3 s0 l
float compute(); /*表达式结算器主函数*/7 k' P2 v8 i  P. y# g- ]% u! e
char *killzero(float result); /*去掉结果后面的0*/ ; y, v2 }1 e- q& Q' J3 f* T, O; c
1 q9 T+ h; K8 G! @( a) B
int InitStack(Stack &S)
7 O2 S& }3 o* W" t6 K/ y" P{
. h: l4 o6 Y* v- L/ B6 t2 t    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));! l& s1 R4 g" [# k7 Y. I
    if(S.base==NULL)
( w4 C; J5 U  e    {( B8 R& d3 A3 Z" w2 _/ e
        printf("动态分配内存失败!");
6 R  C( R, R5 ^1 S* A* D        return -1;5 V6 U! v# q: Q$ b) P: ~% o( A$ R
    }
4 v3 r# ~6 _& ^( ^0 h! ?    S.top=S.base;+ a) D& _& v) Q" R8 }6 n
    S.size=STACK_SIZE;
" [3 C- _( g. I4 v* g* a    return 0;
" V3 V  Q8 F8 U' ^' w# j4 w3 ]}4 @9 ~, O: X  N* W# }1 m& j  R6 p
: q. R0 n: ^" u' n# c4 u/ H2 O, c
int DestroyStack(Stack &S)
  [6 D! g, J- q% N. @( x$ P{9 S7 c/ o0 V  \% q' |; }1 `
    free(S.base);
2 R$ \/ D; V! N9 ]; O( ?8 _    return 0;
1 ?8 O7 q# S( @  G, N  o" h}$ |3 d! ^9 u  D; J

/ C8 R- ?0 ]  e. M- g" _9 ^1 Fint ClearStack(Stack &S)! @- h* `4 _1 Z0 j9 S- r
{
  S4 Q* U( L" H$ t$ |    S.top=S.base;4 k' N& F: }9 u& G* G0 s3 V
    return 0;$ [1 `* C: T8 A2 D  F! U5 m' C
}
- s6 p+ m3 t. U0 S8 y& g8 [* R$ D- q2 A! s: Z
int GetTop(Stack S,SNode &e)
7 I8 J, b8 u9 ^* N& Y( p3 F, G0 s' p5 X{7 ^/ x  i1 d" y% B$ \( {
    if(S.top==S.base)
* J# C; X# [# }5 m- m    {5 l! M' D- ^2 ^+ g* b/ o0 z' @" b' t
        printf("栈以为空!");) q1 v7 f! e" S7 _+ k! Z" [- a- |
        return -1;
" }3 F: V! l6 g    }6 o+ o* y3 g8 P: s- w
    e=*(S.top-1);" g: \% [, }8 ]
    return 0;3 u; m: I* _; L
}
3 F: y; V. l2 g& E9 ~8 k
2 M2 ?& A6 ?& s5 H9 vint Push(Stack &S,SNode e)5 ]2 K6 n1 x! ?3 l# d# I8 D
{
( }# b' g$ h9 W; u& s1 c    if(S.top-S.base>=S.size)2 a7 ?+ R# O2 d. ~* t
    {
; B6 ]0 w0 H3 {( }, M9 o        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));. h  A' z0 o1 P
        if(S.base==NULL)
4 s. i! C$ V5 R7 b        {
- b! L: Z: j' Y8 A/ c( l            printf("动态分配内存失败!");9 Q8 v/ x( _$ i6 Q' B. _
            return -1;4 K/ j: Z0 h6 d0 Z) u
        }5 ]9 c2 k6 Y7 i0 r( ]) ]8 k
        S.top=S.base+S.size;
9 l2 ?- e) d! A( W/ I        S.size+=APPEND_SIZE;
8 [3 E7 l' S, W% K( m0 I; H    }+ Y7 N$ {0 h6 i) `- g& d6 G
    *S.top=e;
0 w. V% p+ b+ J    S.top++;
0 I2 Z8 U1 p' y! P6 h0 w. s* w( t    return 0;
% \( f' |( Y- A6 C% j  W0 M6 R}; [& l( m% X) X+ Z; g0 `' {, \
: m" |) V! v# @
int Pop(Stack &S,SNode &e)
* g2 q* s. ?7 h' T1 t+ ]{
: b. o; ]# k8 d( m+ Z    if(S.top==S.base)# ?. [  a' ~: V: M" l9 d7 p% Q7 @
    {3 ~. x# e: A! n7 w* k
        printf("栈为空!");
4 x- c2 Z, V  G. _  H9 P- t: b        return -1;
, J( ^" _) P( r& A+ y    }
/ M" l1 X+ S. b3 v6 J    e=*(S.top-1);
' b' z& L& _1 m4 n: ?% Q3 R    S.top--;# f1 o5 H  b, i: l: w  {& G
    return 0;5 B9 N4 K, \) M) m7 P
}0 u! F7 I: I" e3 s4 k* j
) d$ Y, M* H& y$ `
char get_precede(char s,char c)
1 _: n, i1 \/ X; k{
  m+ t  q" F& Q' P0 I    switch(s)# y1 L4 h; k, c) l8 `8 a3 W: S5 m
    {
) o+ ~( @* ^- _+ l0 |        case '+':                 # g) Z5 ]) t1 F) U) c
        case '-':
6 z! l# k, `$ ~+ y$ n; y& t             if(c=='+'||c=='-')
- C+ `. a5 w( R: \" }4 |% P                 return '>';  e+ }3 t# i1 `. H
             else if(c=='*'||c=='/')
5 h; A, ?: P) s& r                 return '<';
% |; w) K0 M5 p4 n             else if(c=='(')4 u% _8 g! u8 H/ c9 z5 O6 `! ^6 t
                 return '<';' i( A4 t" k7 v0 e1 T
             else if(c==')')3 \/ a+ F) E5 E" N; t
                 return '>';9 a5 y" \4 y+ R( I
             else / Y" e4 d. W' D
                 return '>';
; e9 {. E; p2 s2 ?        case '*':: f) f( p( t: ^0 W
        case '/':+ t% y  y, _; H- i
             if(c=='+'||c=='-')2 }9 N$ n6 }. w
                 return '>';, s; W  m: r! \9 K/ h7 _; ?
             else if(c=='*'||c=='/')
- o9 r3 z5 G0 O; r" |# u                 return '>';0 [, m0 U) p$ `9 x
             else if(c=='(')$ C" x9 |$ ?  l& |# g
                 return '<';
2 {, K0 V5 \! f* P' M2 h1 x7 r! y             else if(c==')')
8 G$ Z; D: _: u# L  t                 return '>';4 F8 g7 O7 M# b  s' L( O4 B% g
             else  R0 ]$ n+ p: E
                 return '>';# [; a6 D2 }. w. @4 w; J
        case '(':+ D% H9 ?8 |+ a
             if(c=='+'||c=='-')
7 ]; P' E  W- f( h' k$ J                 return '<';) n% O$ V* h& [% |
             else if(c=='*'||c=='/')
( n5 g1 ^4 I2 Z8 I3 t& p5 V, i                 return '<';
; T8 d- H2 W0 N' y             else if(c=='(')
# x% x7 `5 [$ A8 h* a6 J) \                 return '<';
6 a2 p1 g/ W) j; A7 }0 L             else if(c==')')( ^; R) f8 r! L4 z! y7 s
                 return '=';6 e% [1 _, L9 i( K( K. L  ?
             else( {2 t7 C$ x9 V' y/ c, a
                 return 'E';
3 f9 r2 G+ ?% v# e/ W        case ')':% {8 z  Q8 P  l( c" q2 ]
             if(c=='+'||c=='-')
% K* g& R# ^8 ^  K$ K) j- t8 E! D                 return '>';
' H! g# u/ f/ R; B& V. Z             else if(c=='*'||c=='/')" a' H- v6 \' _( b
                 return '>';, J! Q' b$ |: U/ ~' {, c
             else if(c=='(')
6 I% S' C* k/ l$ t, ?                 return 'E';; x: A% z8 K' ?' x) T
             else if(c==')')% E1 r6 ]) f; s3 U  P# {
                 return '>';
# O9 S: c1 J2 Y2 m6 C. x             else
5 |  [- Q  l: ?- j# {) B- e" @                 return '>';
3 u& I  W" U2 U1 h        case '#':
% X; L% l0 B8 S. M4 I             if(c=='+'||c=='-')$ x8 P2 |2 U5 n6 s" r+ N
                 return '<';3 V9 W1 s% A) t1 W! o( y. e) T* b
             else if(c=='*'||c=='/')4 v# y; j; M4 _/ E# ^1 W
                 return '<';& A* B) X5 t* u- c# N3 B* p
             else if(c=='(')
8 ?/ [4 S; ?8 p; c4 C                 return '<';0 ^- [# I( r# j# E% Q" X9 c7 [
             else if(c==')')$ m! \3 o: d; C5 q5 @" _  ~
                 return 'E';+ r( C1 Z. z. H3 T* J! S
             else- i- H+ I; O. S& \% m5 i6 ~) J& P
                 return '=';
0 u" Q8 T# T! [9 I0 G: |: ]: t7 F        default:
; g8 u! ^, m& S             break;
  c$ T, ]  r. Q; C  n) Q$ f9 X    }; Z# ~4 C. n# _( r+ J2 E, D
    return 0;    7 M- {9 n& l9 h  c) g
}
' V7 C& C/ V. b+ W5 ?9 {8 s5 @* I* T. b  m& \) h* n
int isOpr(char c)
, ~6 A- u4 \* Q! p2 H{
; d$ K' l6 O( \# ~' }8 j    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
  n9 A& s$ m/ Z2 u9 G        return 0;. W4 N5 n' y/ V" e" H. K
    else   Q# k( d# W6 Y$ |
        return 1;
* ~7 w2 x3 S. z: w# `}. v* o9 w4 F* b% s8 o
+ @7 r4 {& \5 h" g
float operate(float x, char opr, float y)
1 F% h6 ~8 J: T% O  r. E1 p/ o3 _{" H2 G, z- t0 q# g( H
    float result;
, p" \2 P% U% Z: L$ d$ t  `& K8 ?    switch (opr)# x* T0 d* B  h- c' `2 m+ g- m1 y' V
    {
# [6 B' C" w% ^3 e        case '+': 7 G" [& z) f% m2 `! `5 w
             result = x + y;
$ w& h& q4 m# C9 `# p2 Q. v- m% Z             break;
. d" a3 i3 _3 Q" ~. o        case '-':
! Q, {, ^" F# i2 N- x# f             result = x - y;  ~& D$ e# }# t% D
             break;
3 ?1 Y; I5 V+ |9 k* ~. r$ U/ Y5 G  L        case '*':
* I# Y! i+ R# q             result = x * y;
- r9 K$ Z" o, s, q8 j6 O/ D             break;: U2 r% E: H, o+ m! k: Q- r2 o
        case '/': & v- ?! w- h! R5 N) k
             if (y == 0)5 f6 V0 ?4 o% d9 ^3 a: x
             {# Q( `5 X; U% x
                printf("Divided by zero!\n");
0 m, Z2 Y7 g) Q/ E2 }4 ~( Q                return 0;8 R# t$ k$ m' X8 U& O* O' i
             }: i9 I  l: z8 N+ ~5 V4 p! r
             else
8 f! ]0 t7 S2 ~; P7 b' T             {
. \. I  V$ B, y; x& t' O: h                 result = x / y;
% t2 z9 ]: W# W                 break;
  Y& M/ v# T+ k; Z+ b- `4 R# \             }
% S; ^/ T* [7 m( Z       default:
1 R  c, e. B# _  H             printf("Bad Input.\n");
: k. l5 O. x0 l8 w  t3 V+ K             return 0;" b1 I5 W! U- ]6 S  B% h; @
    }# H3 C& c# s8 Z6 [! F  u* z+ N" X
    return result;
  N6 B$ Q7 c' M}    ' s+ n; p" E. Z

5 h6 P- o6 l6 M, R* K0 f+ C9 lfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/2 W" _4 @3 I1 c
{
0 O  U: e7 i0 b    Stack optr,opnd;
: u& Z, a; ~4 q5 l* X9 M4 @  E    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;& w6 o0 o9 _5 ]
    char c;- k! u" R$ V4 ?- C) }' T3 w1 ^
    char buf[16];
7 f1 S& {8 X* V+ B# B    int i=0;7 H/ H# q2 p5 c/ C' H
    1 {8 \2 O9 }' a% ?) G
    InitStack(optr); /*用于寄存运算符*/
% G. H0 x3 i9 S! E) }    InitStack(opnd); /*用于寄存操作数和计算结果*/( ]; ~" b- _: r) m
    memset(buf,0,sizeof(buf));
9 }, L) [+ X3 x, S    4 ]5 z& I0 Q. @: J/ O
    printf("Enter your expression:");4 K. n; W& E$ ]" o8 {/ F  ]
        
9 w& J* C! k5 p1 u. Q" N  y    opr_in.ch='#';
8 T. B! s- @* V) z6 d    Push(optr,opr_in); /*'#'入栈*/3 ~! F  o$ S7 t8 t0 Z- J  ]( Z
    GetTop(optr,opr_top);
% _; B) T6 x+ g5 \% R, F2 q0 k5 y    c=getchar();
. Q) \4 c0 E9 a    while(c!='='||opr_top.ch!='#')
/ c! G2 R/ m0 T! C* c    {
! e% u3 k' m% O; u        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/7 R, @# S7 x4 K+ {9 D$ X% P, C9 {
        {
7 b; |' L, j6 A2 F; n            buf=c;
& C% B- o, i# T5 w            i++;
8 \1 O2 A# a  @& e" |" x7 \            c=getchar();
- @$ O* i" U8 o6 P( o        }. u/ P  C5 S) C% I
        else /*是运算符*/5 V% }' F2 _5 ?! b0 H' U- _
        {
' K. u# n$ R8 h; g6 t' i            buf='\0';
  q/ n! t' y$ d  @: U! E            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/5 E9 I) t% b2 r1 R- O
            {
. K( N1 ]' f- E" N  I                 opn_in.data=(float)atof(buf);
4 {' w1 T7 d3 k0 A8 v  e                 Push(opnd,opn_in);  n& A5 u! g$ j; _# g) H/ J2 L
                 printf("opnd入栈:[%f]\n",opn_in.data);
& U- l# \) I2 n4 f) W9 M7 K  X                 i=0;! s# w# K: ^! e! G$ j9 X- R
                 memset(buf,0,sizeof(buf));' F$ a4 g' {) E- |  H" \5 W$ b
            }
5 n$ X$ Y5 Z8 f5 _1 q3 v            opr_in.ch=c;
4 s2 K# Q8 m7 F            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5 U( |0 ~" @: R' ]1 b            {# V$ t# H3 O9 }
                case '<': /*优先级小于栈顶结点,则运算符入栈*/# M* O; |; w/ T. W3 s1 [6 K1 z
                     Push(optr,opr_in);
! s; ]$ i% \8 q4 E                     printf("optr入栈:[%c]\n",opr_in.ch);
. w4 Q* F; R- c+ g5 D$ u4 m                     c=getchar();  M3 M* X& R5 [; u* |( C6 |
                     break;
# f. h0 M2 G1 Y( d                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/% f4 b6 |' t6 w/ ]" }( k
                     Pop(optr,e);" \9 V$ }3 F$ G8 y2 \
                     printf("optr出栈:去掉括号\n");0 P. M" K. e3 O4 r& t7 k- v. i: }
                     c=getchar();
  c' U0 D5 {8 Q) Y. L                     break;" E7 n5 R3 R% |% z: B6 R
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
% E! I4 t( A; {, ?6 f& J* Z6 ^                     Pop(optr,opr_t);  |9 A6 ~/ t3 y: p* f9 i0 j; r
                     printf("optr出栈:[%c]\n",opr_t.ch);, F6 i0 L- d4 z7 S' ^
                     if(Pop(opnd,b)<0)
% x; o. Y" A) R( h* |( g                     {9 z9 Z$ J9 W& Z& T4 R$ u* {
                         printf("Bad Input!\n");
' s: b2 y. o9 v, U# ?                         fflush(stdin);
: M; F, |' b3 T                         return -1;/ E7 L, m! n4 i0 M% U  E
                     }
: C, D% V9 R  p8 t7 g                     printf("opnd出栈:[%f]\n",b.data);1 G, p# N' `8 G6 U6 Q8 m" }# i( d% v
                     if(Pop(opnd,a)<0)& ~0 P* W' F. U5 W/ A! w% `
                     {* |& S; l7 U* t, [( Q
                         printf("Bad Input!\n");
, h" z# u; v7 H$ Y8 l1 T                         fflush(stdin);4 o: o: @3 d7 l6 [. H
                         return -1;
" I8 k# `$ X* O! k. |2 p                     }
: a5 p" O5 B8 W1 g                     printf("opnd出栈:[%f]\n",a.data);
! ~- C1 F  K% X                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
% c! C, i% ]0 U                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
/ }$ t) j& _, R) y/ H                     printf("结果入栈:[%f]\n",opn_tmp.data);
* n( q: A; @5 h4 o& j3 ^) |8 X3 ?3 ?  _5 x                     break;
" C- M8 V0 I0 L7 q4 Y2 I2 s  i: ?            }
$ U8 B! p0 z: `8 `: L# a. \        }
# D( B5 y  x( X* `; ]0 B" X5 p        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
6 b" Q$ E* M. N1 w" F6 q. X    }8 ^5 ?. r4 {9 p2 Q! Y/ `
    GetTop(opnd,opn_tmp);+ i0 P6 a1 i0 l0 Q
    DestroyStack(optr);
# |! |/ Y: ?: e1 q6 d4 c; N6 H    DestroyStack(opnd);2 |. r. L$ J5 j2 f( c
    return opn_tmp.data;
% d$ ]! _, R8 M" a& h}
& {: ]0 T8 a7 F- ^0 g9 @  \
, B* `- J7 N% N& e4 p6 J& mchar *killzero(char *res,float result)7 |, k- W9 `; e" I( d0 F# h
{
* i# p7 X: z% S: v, n    int i;: p; I6 {" h) W/ T" ]" [

7 h- R$ A( n+ \$ l/ J: b- K4 z    sprintf(res,"%f",result);
0 ]: k6 j: G3 I+ X* v' c2 ]    i=(int)strlen(res)-1;( u; ~& J2 K. J2 P7 b  w7 i
    while(i&&res=='0')* v' B- Q& Q# n# l9 w2 r- ^; N
    {
* t6 c+ `% g6 a; \5 t5 t! I/ a4 r        res='\0';3 n4 N  h& V: f2 k& s/ Z& Q
        i--;) z, M) n3 x/ b) b: j7 e* S2 Q
    }
( W) h& b) u. c9 X% [8 T0 k    if(res=='.')
6 g3 y& u# H* a        res='\0';
. p" l0 l1 @: s4 e7 t    return res;
. Y, D2 v, O, M2 [6 E: A% o# K}: D/ E, @$ M( {1 X4 z
* U8 M) p, c+ B) \0 o; [4 B, ~
int main(): J) W* N+ J* s1 `5 P
{9 x; _! _# _" n( R
    char ch;" m# ]% f5 R3 [7 z: }( j
    char res[64];0 |  z1 S! ]8 [7 H% [
    float result;
# k+ g4 C6 Q% p* G  w    while(1)
) r1 k0 g; y9 r1 C4 |    {9 l* n& x* _* Y+ d8 `" x; S4 q
        result=compute();  V" ^) G; Q+ o( o; z* z
        printf("\nThe result is:%s\n",killzero(res,result));* U! ]2 E, k' m7 r* y, I
        printf("Do you want to continue(y/n)?:") ;5 Z1 N0 U/ B: m4 z1 Y
        ch=getch();
1 V7 s% Q8 t, q$ s% i        putchar(ch);; d+ q: R$ j' u( I# i/ H0 {, {: o
        if(ch=='n'||ch=='N')
4 Y9 L0 E% D, d            break;
2 U; W' V$ T, ^+ \( G* m' N        else
+ }9 M; v8 |* L  U            system("cls");9 B! E2 N9 o5 K; u9 Z3 n* j
    }
5 `7 a$ p  I0 Z+ o    return 0;
' t6 q* d- W2 W' @' ]0 l}
4 x  _" x& `8 ~7 a: L
- o9 `. V# p; g) e: Q4 s, c
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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