返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
- j' N, x7 V' }/ ?$ P8 K程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=4 ?7 s( ?; n% R6 e
/**************表达式计算器************/# g0 D; ~0 c3 W, _
#include <stdio.h>
/ u) V7 p/ t2 Y( F. q#include <stdlib.h>
5 E2 Q9 e9 k/ x) Y' T( A* C#include <string.h>
0 N- o0 ]: u8 J- p( @* m( R9 q#include <conio.h>. b. x9 Z; K* w! V! B
#include <malloc.h>
9 F' W3 s6 C8 G
0 ?9 `6 N) ^0 N( @' \5 D#define STACK_SIZE 100
3 D- Q: t7 \3 R9 p5 z#define APPEND_SIZE 10, m! A7 P0 X6 D4 p4 Z

0 t7 D: \# j: I. y. Nstruct SNode{
  p( u  o, ]; C9 i& ~/ f( \    float data; /*存放操作数或者计算结果*/( k% }$ ]+ x  g
    char ch; /*存放运算符*/+ `2 e- K$ W! h& c0 o+ v% g
};8 ?' C: o' Z; w+ _3 G+ E- O

* k9 w3 P% g' I) t4 a& Zstruct Stack{
/ `( n& e. q. d# S, x9 |, p0 H    SNode *top;
; |& B6 V* o& V/ J" [, a    SNode *base;
7 H0 J% E" s/ m9 r; p1 J3 ^    int size;
' M; \! j% M& }) @2 H};, o2 l; [5 m  o9 C' U
" ^1 L$ w7 a5 Q9 f2 f* v
/*栈操作函数*/
, j! C  G+ w0 d& Bint InitStack(Stack &S); /*创建栈*/
3 g" ^5 n7 m% I- ]" o6 g. \int DestroyStack(Stack &S); /*销毁栈*/
1 {0 Q) b! L  s( h/ [5 {int ClearStack(Stack &S); /*清空栈*/4 ?7 e# `( D/ X0 A* ?$ j' u& G4 _
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/; t; @* Y! B7 [2 I
int Push(Stack &S,SNode e); /*将结点e压入栈*/* @- u6 F+ s; k1 Y! S' J
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
; e. v" @. V! F) s  W* `  S. N9 k9 J3 [' X! z; L# `; ^
/*表达式计算器相关函数*/
( q% ]0 S1 ~" R1 m$ b/ l) g" Pchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
. n. E) i( Q3 q3 p; Y2 ^int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/0 Y, d; w8 k: z) Y& m9 |$ r9 I
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
4 V" T* e( J8 s( H# T$ ^4 G8 Cfloat compute(); /*表达式结算器主函数*/
1 z9 w& I7 \* T+ \% I" z  M$ y* Ochar *killzero(float result); /*去掉结果后面的0*/
) r3 F2 d4 L' c* G) b; X; x) G2 B2 g$ o1 c' _
int InitStack(Stack &S)5 @) Q7 M* l6 i+ q
{3 E3 e+ A. Z, Z
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
; m0 J) {5 o3 W- |/ T' w; W+ W1 s3 Q    if(S.base==NULL)
% d4 X" {1 x& `+ Z, p    {
2 ?6 X: J: l+ M* e3 U/ k$ p7 P        printf("动态分配内存失败!");
9 q+ i( ~% @1 E. V$ K        return -1;
% L( v% A* U: w9 @; p. w! Z6 a    }
- K0 D# {. f, Q+ a1 T    S.top=S.base;
" W5 L/ [4 u  H9 W( U/ q' G    S.size=STACK_SIZE;$ o# y4 v% G# I, d
    return 0;
: z. q% P- V, s5 q6 C* ]' \}
1 k3 u; Q$ p" ^7 G/ k1 z; o$ q6 d: `1 Z9 A# ?( `1 {3 K. V7 [) x
int DestroyStack(Stack &S)3 B) {; w! p; B+ g
{1 u* U9 N- g/ ~7 W) x! V
    free(S.base);
8 T5 a0 V3 v* |  p4 {; s    return 0;# _/ J* R. Z$ o. ]) y( w- k
}
% t/ H. z0 p  d1 _5 F) Z, d1 B* d$ [5 ?2 A5 Y' p0 y
int ClearStack(Stack &S)
. ?3 K! O' {4 C6 u8 K8 ~( m5 P/ ^% G{/ u1 ?) f: p4 l0 J9 Y8 u
    S.top=S.base;
2 z7 @* P$ V" {1 q9 A, g% i& y    return 0;
0 N0 K, U& `- d& w+ s. ?# N}
6 M" w1 r) R7 R! `: c0 c
* k( X) B& Y2 @' q3 A( N) Gint GetTop(Stack S,SNode &e)
* ~+ L% h# z- y6 L7 U* c1 H{0 k7 C: ?+ \2 t4 _' g5 y0 ]. _
    if(S.top==S.base)
% f. C$ G9 n, j( \" I6 B! V    {' B, S8 v" t  f4 j% H/ s! w0 o  `
        printf("栈以为空!");
* [2 J# F8 `/ S7 _& K; T        return -1;- f! n, k" M) c3 I0 W
    }4 e6 t2 q; b# Y- x
    e=*(S.top-1);! T! e9 h" [( F8 X
    return 0;7 }5 w% ~9 B. I5 X6 M5 y) {' {: U9 C
}
8 p$ w; Z! e6 ]5 |6 e. @+ G% A- \3 R
int Push(Stack &S,SNode e)
. N  E, I* D% y5 l, x{
( i& ?# i3 ?# F8 S' f' ?  n, J    if(S.top-S.base>=S.size)
3 [; j) K4 {8 o6 ~    {: z+ p6 v7 b! ^: G0 a
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));) S3 o5 w% k6 ?2 l
        if(S.base==NULL)! |* ]0 E2 A; G2 E9 F+ h
        {
6 F2 s9 ~/ U$ n, j: h" }            printf("动态分配内存失败!");5 M6 g, r8 v9 w2 f1 ?6 O  b! {
            return -1;
$ e/ F. k, U+ W1 N: W7 A        }
6 R% ?: i8 Z$ g. N' }5 H        S.top=S.base+S.size;- ~- X) E3 Z+ w% W
        S.size+=APPEND_SIZE;% K! o" N+ s: M  g) P  Q
    }0 h# k) t) S; J; K( z' A6 t
    *S.top=e;. w& O- z5 C# P- X/ z
    S.top++;
& f) G# l. h( J+ ~3 r    return 0;
, P$ w' _5 f, m; l- @}! v1 W2 ?+ P; `- a8 i4 `

" }' B6 g* ~/ L4 @; Jint Pop(Stack &S,SNode &e)4 q% M6 |7 r8 X* x
{
8 L2 V. P6 F* u. f. _- `    if(S.top==S.base)
4 k* t* [5 H4 s. {% b% @    {
" B) \. N; l1 N3 u0 C        printf("栈为空!");8 K4 @# o. S% n4 b8 ^( I' f$ W
        return -1;
+ t: E2 m4 W) m. k    }- n, N! P% A. E
    e=*(S.top-1);. x6 N; _3 |: @+ {6 _: ?$ t9 z
    S.top--;
  C. g3 s! z4 }9 G- L. f  m    return 0;
; E- Q1 L: B# M! Y- {; a& K; H3 i) v}
9 @8 U7 f$ S8 a7 F+ a' P
1 L9 p2 ]+ U  {$ g( C, `" Tchar get_precede(char s,char c)
4 m( S* G% f8 K$ O{
# L( o4 A$ m; ^' j    switch(s)" T7 Q" j7 w3 n. A9 L+ u
    {. ~5 u6 Y- W# p* k% e
        case '+':                 
2 X% ^! o# Q- b' O        case '-':' K* B  m% M4 E  ]! m
             if(c=='+'||c=='-')
# t! Q# v; X0 V' K7 G: K                 return '>';
: m; P5 f1 K! e; {             else if(c=='*'||c=='/')" O; N) G6 b4 B. i( e" r
                 return '<';' \6 Z$ A& u+ D% F& U% Z4 c& s- f
             else if(c=='(')9 s) i$ B0 u9 r
                 return '<';
# k0 @; z6 l8 Z5 N             else if(c==')'): l% G+ T6 s; w& j$ d1 _
                 return '>';6 Q& p: t. i8 H, r% `. b
             else $ y- y: s" x4 O/ n, M9 B
                 return '>';
3 p  C) ~# b2 z% P! ]. x        case '*':0 x: o% p: O7 I( ~4 U5 B$ [! W  U! s
        case '/':
4 ]; R9 p0 g3 d( W: W3 W% T             if(c=='+'||c=='-')
3 \  M+ e0 G5 f6 ?1 P  E7 t                 return '>';$ u& _5 Z/ `$ I* Z8 l% m1 _* [
             else if(c=='*'||c=='/')
- u/ v( P6 s! k' C: E                 return '>';
; C9 U; ]/ I5 Q- ^             else if(c=='(')
' E! _/ r* ]) j7 L3 `                 return '<';
4 m) M9 P' b( d  i; G) U. F( l$ q             else if(c==')')$ z4 K4 W: S. b) p7 q4 L
                 return '>';4 e5 w/ U- S( S6 W
             else$ Y: T* k' x7 u3 o3 Q8 ^
                 return '>';
/ m1 `1 d" K# |7 g2 a% q        case '(':* k. q/ z( J: y$ C( }
             if(c=='+'||c=='-')
$ c) b2 P7 J. r  R                 return '<';( m5 h$ l& a% w- O' m7 U, m
             else if(c=='*'||c=='/'); T7 ^) e. [, P
                 return '<';7 P% d) f( R$ U( e
             else if(c=='(')
$ |) p! [# W! o5 v; |+ C3 L                 return '<';
% `' q3 `! D2 a% x% m) V' A             else if(c==')')# F5 V1 y& J7 L1 G0 L
                 return '=';
) K  c8 `# B7 r( T2 k0 S             else1 E+ [  I$ y* i& T0 H: o: a/ c
                 return 'E';
5 \; |( ^, U* I* _& N& U9 U        case ')':
0 T- \- O7 @) k  C; @* [  X! T/ f             if(c=='+'||c=='-')
+ ?  X; T8 f3 N! j2 B+ P% m                 return '>';
* {( ~: f( I7 p# \             else if(c=='*'||c=='/')
. e  X+ ?1 C, V8 X                 return '>';7 o- v( o( Y- A) x5 t! [
             else if(c=='(')# {( t; [& Z$ f, j
                 return 'E';
3 @, e0 G* a, I! I             else if(c==')'): J' O; m; C) j! C% {/ X
                 return '>';! D$ R) ~# b& W* r  [- x. a
             else' y9 l( s& s- L/ A* p! ^
                 return '>';
7 `( m# X8 p7 p% L* y7 |4 |# l        case '#':
. q1 h* S7 h5 r" C             if(c=='+'||c=='-')6 _  M9 K' h4 d& p5 ^: B
                 return '<';' p+ S$ z- t! l7 g
             else if(c=='*'||c=='/')9 C4 t6 i9 P% ?" i$ |( X6 r* D2 I
                 return '<';
4 x/ P0 d% l. t% ^6 k! q7 R             else if(c=='(')
3 X5 q* I. r+ G+ V( e                 return '<';+ r9 w8 ^) u5 e2 v! f
             else if(c==')')1 h- r2 H0 `: e, `/ b+ Z- Z$ V* ?6 F
                 return 'E';
$ Y) _6 T7 n1 w# N# H+ s. c' f             else
+ \3 }+ A$ g: h, q5 k                 return '=';0 v5 ~4 u; V' F3 E% ?( f5 F: h
        default:, y4 e9 t/ ~- P! x" T- s
             break;4 c% h' t+ Y" l
    }
, F. A" R) O' r5 j4 _    return 0;    + Y; X/ C. B  J2 ]9 u9 f- s
}" e2 i  X# ]5 i' [$ v
' A2 [. O) ]# ^  M7 O% E
int isOpr(char c)  V7 P; w' g4 e" j
{  E7 J2 q3 V! f. m+ ?! ?  `+ s
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 O% ]! ^; v1 Y% u( T5 Y
        return 0;
. x. B! ^! }' w- N) ~3 ~  ]    else : C: q* f% w/ y
        return 1;4 z4 s$ t6 I6 Q1 j  b
}+ c  ^' W3 P1 |/ a# [% m" t

4 ~" c2 b" U+ k; u4 ofloat operate(float x, char opr, float y)" b  o4 |6 w. M: @! }& }
{
% t7 b3 k! n4 B4 }/ W. H    float result;
8 m  ^9 P9 b( _; r/ F& G: f/ O    switch (opr)
9 t- \5 d4 G7 O    {+ ?- b( [8 O5 ~, \
        case '+':
5 ~2 }- r, z3 k  G9 U) T0 g( f- X  r             result = x + y;
+ V" ~, s+ ?# \: _& r; b" B2 ]  m             break;7 n& C* M8 O& X/ r
        case '-': 6 Y2 J+ T& y4 m
             result = x - y;5 A+ Q) H4 H* E  i' M( L
             break;. U- j. W) d. Q! r5 h' O
        case '*': 1 u* V5 n2 n# g0 C: l; {/ ]
             result = x * y;
6 d( k9 O7 V$ x. F- \* H             break;
& k: V# w/ N% Q        case '/':
1 L( I: a, k5 j- r  i  D* p2 ~' r& |- V             if (y == 0)
1 m5 U& v4 c" `6 S: J2 p             {
  k+ y! |  d8 M* {' c* J* F6 S+ s4 [                printf("Divided by zero!\n");
" t9 b4 j2 S2 t2 p! g9 L                return 0;
* z' t0 `) I. u/ h             }2 L$ b9 [# y$ z! }
             else
. o* P' ~, }' g7 V3 p. H7 [             {
& q% q( \# E" [% h' m                 result = x / y;) i0 Q7 S( F6 o5 n, U/ c  l( g
                 break;
8 G+ p# d0 o, l& D3 u5 Y1 g/ H' y( u             }9 t" {. O* j% a3 M! D- q
       default: & r/ W' h/ `! P& s/ g$ g* _! v
             printf("Bad Input.\n");   e. u) Z# M+ _9 e. e6 V. M
             return 0;
5 E7 h: V3 J3 {. c8 L9 a- J: h. f    }
' c& L# S, `5 R+ n: R/ _* w    return result;
+ o; U/ H0 S# s) ?}   
6 |1 R! m  m  T* E8 k8 w6 e" c; B5 q1 W
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8 Y( t9 Q2 s" j! Z& N3 }. X5 R5 J# U{
, A; J2 p  u  T4 y* d2 I    Stack optr,opnd;% c5 w8 E7 ~4 [7 X
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;! ?9 ?  C* v" N/ M7 b& C# S
    char c;6 L$ G" Z4 p. P7 }# r( m/ W
    char buf[16];
* m" o' U6 s% \    int i=0;
! }9 N- D; U9 S& Z: o   
4 z8 A: `- E- q# L  q1 X    InitStack(optr); /*用于寄存运算符*/' _/ a/ J7 e. _0 J
    InitStack(opnd); /*用于寄存操作数和计算结果*/3 i4 Y5 x8 j( H# b
    memset(buf,0,sizeof(buf));
; W- Y; z9 f  `. @, x+ w  f* C/ d   
: H/ ~, B& B" [: |% b    printf("Enter your expression:");' h* R0 j7 V) M  ~: l
        
  g2 {7 K, K; N, u# C    opr_in.ch='#';
# [4 ?, Q/ y: w5 w9 N5 g6 `( g, k& e    Push(optr,opr_in); /*'#'入栈*/( L0 s- \5 E. z) j% g8 Q3 `
    GetTop(optr,opr_top);  F" g! T: P6 G* q
    c=getchar();6 X+ h* p7 P  j! `9 ~* I, p. f* J
    while(c!='='||opr_top.ch!='#')
$ y1 E* ?8 l  Q& D- |. r8 U    {6 \, s% C4 O; i" u
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
( |/ l+ f: W. b( ^  i7 m6 |        {3 V; y. S. T# R( U2 J
            buf=c;" r* t) _  Z' ~' q  H# q
            i++;
0 ^/ i5 {$ m, _+ M            c=getchar();
4 \% }3 x% R; u4 ?2 |2 R        }
% Y/ t, u( @& U( J# c% u        else /*是运算符*/
: y% R% x8 I; i7 _9 g, m        {/ H6 u  j+ M7 g  e9 ]
            buf='\0';* ?5 `+ G4 F% g0 I' p( [
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3 Z8 C4 E) j3 \1 W/ Z5 O
            {7 z! w; T/ Z( N- v5 F* e
                 opn_in.data=(float)atof(buf);
6 J7 m. ]5 E* D0 O+ I/ w  ~" Z7 Q& T                 Push(opnd,opn_in);" L# o; t- ~2 H. P' R
                 printf("opnd入栈:[%f]\n",opn_in.data);
& ~4 S2 a4 w5 o6 F$ U                 i=0;; D  W. s2 _% E
                 memset(buf,0,sizeof(buf));6 Z- T5 d' K/ a
            }$ F$ r6 k$ T, i; l7 y( L9 _
            opr_in.ch=c;
5 U: |) o: _+ Q# A5 U2 l6 u# |            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/8 i" v7 b. E; `
            {
$ m7 J; w+ @3 J$ I* I) G                case '<': /*优先级小于栈顶结点,则运算符入栈*/
# w! Y, o* I3 \8 S$ q                     Push(optr,opr_in);. q( P+ N8 l8 h: T# i1 U% j& V
                     printf("optr入栈:[%c]\n",opr_in.ch);. A7 W" ~  X  w/ x2 x: V+ R! {
                     c=getchar();) j& F& F/ t4 e8 i- t/ G7 S1 o
                     break;) ^! Q; k4 q0 e! B1 v8 [: {
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/( Z) B+ t8 ?% ?  q, L
                     Pop(optr,e);3 t; G0 w3 t7 @  a8 q, I
                     printf("optr出栈:去掉括号\n");
. ^& z0 k8 p! o# s' f                     c=getchar();& ]$ h7 p& ?, z
                     break;. u! o' C1 ?$ s+ F6 e
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
- ?; B- I5 z' q+ H7 p2 ~                     Pop(optr,opr_t);% U0 f6 M  D: a+ }) A7 [
                     printf("optr出栈:[%c]\n",opr_t.ch);
+ Q. a, U, j) Y* {                     if(Pop(opnd,b)<0)  o. P' G; j% b+ T- D
                     {8 g# s6 J& }. V" Z+ H# k
                         printf("Bad Input!\n");; j; l8 n& N& p
                         fflush(stdin);# t: O- l& _* ~! H8 O. Y
                         return -1;! f6 t! q* @) B6 y
                     }6 @) r6 }  Q7 D/ C. `
                     printf("opnd出栈:[%f]\n",b.data);
& S0 ^! s' L5 D- h! n* t: y                     if(Pop(opnd,a)<0)/ A) ]. B2 ?& a8 u6 S" K
                     {: i* r+ Q2 H4 E* e' E& j; W
                         printf("Bad Input!\n");
: q' p/ P& @3 x- b. B, J                         fflush(stdin);# A! H2 `6 e! D' o; N+ X
                         return -1;
! Z8 }# T& q) _* o                     }% e, H9 x. N' ?! x( x: n+ x( n; I' g
                     printf("opnd出栈:[%f]\n",a.data);& o0 C2 \- a5 c( T$ o- R* t
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/2 \' q2 W. S7 X
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*// f% g* j5 m" C# @  `& Q
                     printf("结果入栈:[%f]\n",opn_tmp.data);
  ]0 w  o% y* r2 `                     break;, ~2 X' b  s; f
            }
! W/ p! m# t+ y* d        }
7 Q2 \" s- f6 n7 L/ j; A        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                7 B: z2 w; y( g+ i) l
    }
1 a- g5 ^* {+ p. L6 }  g; m    GetTop(opnd,opn_tmp);
% e0 h' y$ N& W) _6 t3 o, H! `    DestroyStack(optr);
8 e& b; z+ [! h& |- `    DestroyStack(opnd);
; |. m  s7 `* M- T- o$ g    return opn_tmp.data;
' r. d1 j; U- z0 E4 a) O0 u5 V}
% C7 @. c% z8 T3 z" Q
2 ~. x( d0 @9 ?char *killzero(char *res,float result)+ h0 R9 ?; |$ b- z! o1 j
{
; f1 \3 I- c9 a& `+ c    int i;- c, n3 @+ I) n4 v3 l9 u
+ W& P# X; k' a: j
    sprintf(res,"%f",result);
! V" n0 ^. M" @! z# {8 L    i=(int)strlen(res)-1;7 a( H2 F+ z* W& C) E
    while(i&&res=='0')
7 E3 g3 J' g; ^" @    {
, X  |/ R7 r4 ?, m7 x        res='\0';
: |; D+ v' K1 |# P0 ^        i--;
( |, @3 w  f: _9 \. ?    }" M  i6 n0 Z  I. b, M! U" {
    if(res=='.'). v& J' ?  m, b, {* Y! @# N& @
        res='\0';- O$ O& e2 [- P! {" g# k
    return res;
& `5 m' x+ _  H: T3 m}" x' B& U7 U8 R: r4 i+ d! V

$ N8 y6 a% I8 ]9 y9 Vint main()- [4 g3 W5 M0 [& }* W) D: M
{* ?5 p+ R" h' P. C0 W
    char ch;* B- W# E8 n8 }
    char res[64];9 q5 U% [# D9 |* u
    float result;2 v7 u8 u- s/ K) u' m
    while(1)
- f! }0 L" q& Y5 C6 F    {: }/ W" F( N2 V4 i
        result=compute();; f7 d# i4 X- p" \4 L
        printf("\nThe result is:%s\n",killzero(res,result));
' M# l/ y3 H. ]7 _$ s  g: \        printf("Do you want to continue(y/n)?:") ;
5 N: x8 d: a: r4 E        ch=getch();
8 a5 _0 @# d' D/ g        putchar(ch);
$ _! C1 |, k+ n6 z. g/ l        if(ch=='n'||ch=='N'). ?1 l1 S4 Q1 [1 \" I7 ^) D  Y
            break;7 h3 d: n; Q$ u9 w
        else
, @+ l0 B( _) G            system("cls");
, b! h' Y* Z2 X0 Y* s    }2 N/ X* z8 O$ b/ P
    return 0;# V$ i: r- `2 d0 i" A" A+ y
}

$ x" H* r1 U. o. N" T
9 k' |' p4 y: `' h, ?" l[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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