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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
+ j# M! w$ L3 p9 E7 P% A程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=9 ?' {3 z+ o) N
/**************表达式计算器************/
4 E0 z7 z" x  A#include <stdio.h>
% }* r: k" \6 v$ L; G8 }6 M#include <stdlib.h>
( W" q  y4 h. ?5 D#include <string.h>' }0 ^) z+ V% L, N* P
#include <conio.h>
& f% b! v6 \0 q! O8 B0 [. q#include <malloc.h>
6 r  u7 u; [5 Y* a* g
8 A  [- A3 m. u6 N/ b* `#define STACK_SIZE 100
9 t& h2 g/ q8 K0 @7 P#define APPEND_SIZE 10
0 y( x+ L# U1 Q# B5 N" H6 C* u' g5 m5 l9 c. E: F" z( P2 t
struct SNode{# r1 C/ p) y+ f4 n0 z
    float data; /*存放操作数或者计算结果*/# R$ |" }$ l. E' ^3 j5 `, T
    char ch; /*存放运算符*/7 B$ }$ j5 {: _* F* i1 l- G4 M
};1 O8 I( l5 h& a! U

8 _7 A3 q9 D3 z* Q: ~: U) @5 Sstruct Stack{3 e3 }. Y9 M# S4 W$ R  F# m
    SNode *top;' L1 j6 |7 z- v5 V7 y
    SNode *base;0 x/ `" _" p( d
    int size;
2 Z# {& V# S4 A# e};
, d" Q6 m1 |5 z
( r4 l, n% E; [( i/*栈操作函数*/9 Z5 p2 _( o. {
int InitStack(Stack &S); /*创建栈*/% V( F8 G" L* F/ _  @* B5 H' T/ `
int DestroyStack(Stack &S); /*销毁栈*/
" Q6 V# \2 @  ~8 e3 U7 w% k7 t, gint ClearStack(Stack &S); /*清空栈*/; h3 C  d) F6 j& a, M
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/! w8 i% D& U5 {$ E& {/ B( v; a
int Push(Stack &S,SNode e); /*将结点e压入栈*/# C% ~" J+ ?; X5 k( H
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/- e8 q* \# a- _3 [, p
8 J7 z  \  y) |& Q
/*表达式计算器相关函数*/
5 b  {5 U+ q, Y- N3 G" uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
" ^/ h+ p' @! g/ Cint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/+ X5 g& l0 _1 V6 F& H! B& k2 X
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*// ?5 I( i. Q5 h0 B- {$ X6 X# g
float compute(); /*表达式结算器主函数*/& i5 m* F: ^1 B5 p: {$ c- T
char *killzero(float result); /*去掉结果后面的0*/
2 R+ \! l4 i& i" D  U3 s
- V( b% W% h/ u9 J  Qint InitStack(Stack &S)
$ z! G9 x( B  Z; Y8 ?{6 }' m( z/ ~3 ]) g! X+ M. `
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
/ ?: w7 @$ p3 @# Z$ ?    if(S.base==NULL)
0 {5 l2 g$ B: V+ o- u    {; `% ^( r& b* A$ p+ H' ^7 E- g0 a
        printf("动态分配内存失败!");+ |6 [$ X* o+ R" Y8 g" j8 {
        return -1;( L" N3 n! I( K. X/ e& \
    }
* L: T) l& S- n2 U! A+ |    S.top=S.base;8 m2 @& D. t+ {
    S.size=STACK_SIZE;
2 z3 h. Z% c4 t; C& v    return 0;' b' f3 D# x) W
}( {$ p' e7 R* t% X/ n% P
8 |2 g' g5 h  e. e
int DestroyStack(Stack &S)
. B# R2 P. A0 k/ q+ i; Z$ p% o{
" v- n5 r+ x* i: w. Y    free(S.base);0 b( X! z" x9 X- I  r/ @
    return 0;+ o4 W0 b, s: O8 T  @. {
}
/ [' \' O* s- x/ {; |0 ~9 P- R0 y  S0 M; W. t) G9 V
int ClearStack(Stack &S)
( `3 q  b: u' g! h{! v! W- `/ [1 _# a* u
    S.top=S.base;
9 a. b5 b8 Y* q$ m% @  Q- L: r, v, @    return 0;
$ z9 s+ m# ]. w}
! Z0 t& Q  ^: t& J) v
& k1 a& d4 Y: @* J+ A1 m6 S1 m1 hint GetTop(Stack S,SNode &e)
" i  _: |/ H0 O* h{. S: V) R9 Q' s4 l7 n, }
    if(S.top==S.base)0 P9 ^3 j; G3 h* f6 Z, b
    {) E$ _- Z3 K; \- c3 M( g/ B
        printf("栈以为空!");
/ L4 g6 j4 P% k0 U        return -1;
4 F4 e3 x  O0 n) U6 t6 Q    }9 g; p, O6 n/ W. V% c, P
    e=*(S.top-1);
# p; U8 S: l3 I% Q( R    return 0;0 n3 `7 c3 r' y8 G6 ^8 {2 @
}' p! b" A% i+ \2 v

/ V7 |/ P1 o; p2 L: wint Push(Stack &S,SNode e)
" Q' ^* E, I' u- Y& V{: i$ S2 o+ ]; i9 ?. G9 T6 g* ?4 x' K% F
    if(S.top-S.base>=S.size); V! a) K0 o& @
    {5 ]& V) L8 D* ^( @
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));8 M0 T+ K8 _& w& x
        if(S.base==NULL)3 T1 m3 {3 p, o5 k
        {. c7 }3 p5 E# n. \/ Y
            printf("动态分配内存失败!");
: Y! J! ~) F6 ?" J  s% {  P$ e2 q            return -1;+ L* G& Q' C& M. H8 t
        }
6 b3 {5 B3 F2 b, A4 b) U        S.top=S.base+S.size;
8 {( S9 s6 i# R9 B- P+ |        S.size+=APPEND_SIZE;$ z! t* i; K/ h/ D( J
    }
5 G1 b; a& G+ e0 P" E; D+ F& h    *S.top=e;
$ Q- w, `2 a; k/ v# z    S.top++;
( J6 ^3 g  Y1 m/ C; s    return 0;2 o; ^6 L* o$ b- c6 E) q
}
2 I% r6 M1 K% h) q: |8 Q  n! ], U* w. l4 q
int Pop(Stack &S,SNode &e)" t( V8 T3 D: b) r% o. u
{
, b" z, o3 R* A) `0 e    if(S.top==S.base)$ ~* J' a7 p7 x
    {* v; ^, o) u! R
        printf("栈为空!");
8 C* W9 Q( _: {& Z$ Z, T        return -1;
  P9 o; J, }8 S! T6 _# l0 `    }$ B& P7 t* M! T  T) f  D* J
    e=*(S.top-1);# B5 T5 [9 i% w6 Y7 \% l
    S.top--;
. R, `* ~5 j  x" L  c" ~- A    return 0;4 [2 t6 G/ Z* l, |, g. N
}5 h, w# k, s. I1 f+ w

$ Y. L4 I, T: J( ]1 q6 h% Ychar get_precede(char s,char c)
& b1 I; R/ x0 r) n+ @{6 u9 J" j' f* B8 N1 Z
    switch(s)
+ R6 D2 o1 B: w/ E/ v    {
1 y5 N% n. F  X! ~        case '+':                 
$ I5 e. j! D2 I& Q7 ~% e        case '-':
* e# ]% {$ E( h  O. F# J             if(c=='+'||c=='-')
  _- ?+ u5 e2 G* K2 ]                 return '>';
6 J" Y" ?2 T2 D  U" r             else if(c=='*'||c=='/')
5 n; d7 R, |( k' ?. w; T                 return '<';
( f" a9 r. f4 s* [( v             else if(c=='(')" m/ C" S8 B/ s7 S4 O2 |2 ~/ ^0 s* {
                 return '<';
/ m9 r8 T  G7 Q& H- [/ @3 g4 ]             else if(c==')')
2 {% N; U6 I; _# I9 D3 |0 D                 return '>';
8 q/ y" L+ u9 d) N; [$ c             else
6 y! H5 N! U$ E$ u4 Z                 return '>';2 Y7 Y4 g9 T, ?
        case '*':
$ y: x  x# I  f% ^7 K( P+ B9 f3 p        case '/':1 l' r4 ^* d/ P+ @" V0 e
             if(c=='+'||c=='-')/ {- [4 v2 U& A& _* [4 \
                 return '>';
/ W0 y/ @$ {! a3 R' c0 H6 @             else if(c=='*'||c=='/')
) p7 I- s1 \: _9 C3 V                 return '>';8 m3 B4 \0 u. `& `& v: ?
             else if(c=='(')
5 C* h/ t/ @$ F$ v                 return '<';
) r; l" o0 x& `$ F6 i4 q  g             else if(c==')')2 L9 Z  s& R, C
                 return '>';
. E' U4 n1 M& h1 ]3 ?* l  R& m             else
# O% o* K9 O! t1 P" W                 return '>';
* v" e& y) J$ s  q) G- m        case '(':& l' _. F# \" Y% m1 \- z
             if(c=='+'||c=='-')& ^9 Y2 A1 w+ R
                 return '<';4 V5 T" T6 h4 d# N. l* A
             else if(c=='*'||c=='/')
2 F7 Y. _5 ]) J1 d# l: S, r                 return '<';
; V) A$ I- s3 Z) j: Y             else if(c=='(')
) B3 l0 J: M7 `6 G( e                 return '<';
% ~. o/ R7 l' H0 P: j/ |  x             else if(c==')')( T; ]7 R$ {! |8 t# n
                 return '=';! C0 f/ ~: P$ V" Q0 L
             else8 N3 N7 s& p+ v* d
                 return 'E';
5 k% s# a( N7 _: c" j( p2 d1 u  g        case ')':
, O& p& G9 u; u# @( e7 M             if(c=='+'||c=='-')2 w, [2 H  z: _* h9 d3 S6 b* Y
                 return '>';
. f( |$ {0 |' r( Q+ F1 e% }: R             else if(c=='*'||c=='/')
' W$ Y, v: I: {5 M                 return '>';, ?* w5 i) r; o: M1 x) t, V  m7 B
             else if(c=='(')8 o8 X8 [( a, e; h% _7 T
                 return 'E';- i% R& }" m3 t  N
             else if(c==')')
! `) v* s' y0 ]                 return '>';
% R; B& Z+ x6 `$ r2 C             else
+ _+ T- @) {: w( r) V                 return '>';
* J( ?. l9 S. K: t        case '#':+ S5 P! \6 g6 g3 t' o
             if(c=='+'||c=='-')
/ o( ~: [- M! H+ y# u' }7 \1 ^+ v                 return '<';
6 K4 h5 t" L, b% r             else if(c=='*'||c=='/')
* ~* o6 s  N* N! m6 e( e3 D: Y                 return '<';
/ K9 a8 a" ~5 u             else if(c=='(')( B' @5 u' Y! F1 O6 ]. z) {
                 return '<';3 @$ H+ a+ J' s2 V( g; }
             else if(c==')')
  B, d0 V& E4 f1 l. S                 return 'E';
9 X/ ~4 F8 ~: r  M             else: P* b; k3 _9 |/ w1 [
                 return '=';/ h: ^; d9 n" z
        default:+ n% L6 b, _+ a$ t8 |
             break;
0 I+ l+ Q( o6 J, P1 R8 N    }' C# s0 }6 n' R  Z6 g- {
    return 0;    & Y) X9 z* w# h9 v3 D# E* S7 z
}
9 ~1 u/ `- k/ a" {3 N8 ]3 |4 L& d$ O6 [' G( a5 X
int isOpr(char c)1 L! s: I9 ]$ Y+ Q' j
{
9 Q1 z0 l5 Z$ o) Z, Q7 f    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='): D. W# u) o  m! s! q0 r: U6 O1 S9 u
        return 0;
+ ~) _7 J: s, W$ k2 J    else 5 J0 \7 J+ o* q) S
        return 1;
  B, I' D& P) D+ F' v3 Q9 U}( F0 n6 n/ _. Y# B. G

3 W6 Y% c; Y+ z1 c: ~8 k3 Ofloat operate(float x, char opr, float y)/ Y1 I1 n  l4 ]4 `
{( r# b/ a+ P( v9 Q) [$ X6 t, Q
    float result;: q( M& u0 G9 ~4 B! A
    switch (opr)5 j8 L* Y- F4 K' [; d$ h
    {
8 z4 ^2 m/ g/ H! Y; d        case '+':
3 C% X1 q. S6 s* {; _2 t, ^0 F# k             result = x + y;
; |) |; H' \  E             break;6 u9 x2 o8 i# V9 x# c, ^
        case '-':
7 J# J! \& e# {! i, X  ~& y             result = x - y;: \+ x0 D! x5 w* z8 Y# D& B
             break;: ^+ K" u! e! ]' I: e% l4 v* X
        case '*':
: W9 u2 U$ K* M) H             result = x * y;$ h1 f- i& ^2 M% L
             break;
- d" |" v) g; e2 O9 h# J) P4 e        case '/':
+ G3 \0 m# b5 M             if (y == 0)
$ U) Z! V- i( [: J$ m0 k             {
# O6 r% C7 p; \3 T  N0 B                printf("Divided by zero!\n");* z+ }! n  a' F  k; C' S' q
                return 0;9 }9 v6 I7 _* \' v9 A
             }: d. M& v% N: N% c4 V3 W: ^
             else! F! C0 u1 x6 ]& X! _: X
             {' f; c! x) z+ d
                 result = x / y;
; Z  K; v; e7 D+ l, k& g                 break;
4 `2 G3 D( z) c             }
3 }( H3 o/ w9 L       default:
! j6 Y$ d$ F5 n9 U1 M  X             printf("Bad Input.\n"); - |* Z" A; Q# W9 {; s
             return 0;
5 y$ v) \$ G& c    }3 w0 h- c/ U: E! u$ T4 T0 K
    return result;
3 ^+ O/ N, ]& r}    9 M/ f' N7 j5 k7 p

* e* o+ s3 L1 u8 ifloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 P$ _9 @) E' @3 ~" b{
& a3 w9 m4 I7 L# X    Stack optr,opnd;
6 ^0 k; k; b" |9 d. W* |    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;/ L5 U& h9 k  x+ E' t
    char c;$ b: d) [, z6 a7 q
    char buf[16];8 t6 u) X# q4 n9 ~2 V
    int i=0;; ^- E! q( z( v$ O, P* I5 g6 ~
   
- t. t' z+ v0 P    InitStack(optr); /*用于寄存运算符*/( ?8 s5 W* k+ |1 X; d% N4 C, m' E
    InitStack(opnd); /*用于寄存操作数和计算结果*/
9 D1 x$ M. S5 j& @    memset(buf,0,sizeof(buf));- q. C' t) g: r
    . J' _* w  O/ D( K( |  P5 p9 z
    printf("Enter your expression:");
. y5 I% U" n+ P& Y* I+ i: }        , B5 @  J& e8 ^* X& `" W* h+ }
    opr_in.ch='#';
0 f8 N& T1 t& |6 L    Push(optr,opr_in); /*'#'入栈*/( O8 h( E7 Q, h+ K) ]+ H" ~, J
    GetTop(optr,opr_top);3 \& D6 B* C3 J
    c=getchar();9 R6 l$ F6 d: u4 B& N) ]6 a
    while(c!='='||opr_top.ch!='#')
6 d1 A! R! ~' }# t' I    {
1 y! _8 Y" {2 L        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/! o4 L$ O/ [& e3 T
        {
* Z+ _6 z) M: U4 L            buf=c;
( Q+ Q* F/ k: x& G2 _+ c            i++;
$ S5 y! b/ y- v            c=getchar();
& x: K. d1 ]: z/ s4 Y) S        }" _9 p% ~% R! k% @( @% l9 [8 h
        else /*是运算符*/
/ }) Y4 v+ P' y# u2 \$ ^2 E        {
/ p4 ]2 X- E/ z            buf='\0';
9 Q+ @! w& g3 j. y0 U# G2 w' d            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
* N- z$ B, ?0 p. U. v* i            {) [/ e0 D5 C9 }% q1 n* c
                 opn_in.data=(float)atof(buf);
4 A. {* z/ P: N" `                 Push(opnd,opn_in);5 W# i; J- f6 ]  r9 m; T
                 printf("opnd入栈:[%f]\n",opn_in.data);
" D  |0 ?: c" V$ V% i, y( G                 i=0;
2 p5 w0 C5 v- e3 v9 J                 memset(buf,0,sizeof(buf));3 Q! j3 q/ t: }7 Y
            }
0 P9 H2 a4 `  s5 w            opr_in.ch=c;
2 h8 l6 b1 w) U. Y* q5 D8 d            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/! b7 h* @# ~+ b- e7 ]9 W% M: j
            {
, {7 a' C, E9 k* ?% P                case '<': /*优先级小于栈顶结点,则运算符入栈*/7 m% p) @, J" I# i4 `$ S
                     Push(optr,opr_in);- s8 k/ H. h  N' V8 O+ m/ r" H
                     printf("optr入栈:[%c]\n",opr_in.ch);
6 m3 N8 S+ k; |$ W                     c=getchar();
4 T* E% G3 W: Q  `3 _                     break;4 e. n: f$ q5 N3 [! b. m( }! p
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/# K' Q; P5 O- y4 @( U: U
                     Pop(optr,e);
( ?6 |# c# K5 A- [$ R5 y                     printf("optr出栈:去掉括号\n");% d$ l. x4 j9 `# O, \8 L
                     c=getchar();1 K0 M/ b  q4 G5 H
                     break;
  p4 b7 {# ~% F* ^+ ^                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5 `& I- E" b2 p: n/ ]
                     Pop(optr,opr_t);$ M* _% n' y6 U! x; \# Z7 P
                     printf("optr出栈:[%c]\n",opr_t.ch);
' B1 p3 R4 m$ M' f                     if(Pop(opnd,b)<0)
5 a( ]/ U7 M/ l8 y7 r: z0 \                     {& `& o2 ]  J4 I% V/ G8 G
                         printf("Bad Input!\n");
0 s. n; c9 E) A) T% `, a8 q                         fflush(stdin);; ]- d, q% `) R3 e: [
                         return -1;
0 E! i3 B: A1 H' \! n0 }- x. v                     }
8 `$ q- i% E7 ^- ]! r+ ^6 q                     printf("opnd出栈:[%f]\n",b.data);
# Q# a5 X6 M9 A4 D/ L: k                     if(Pop(opnd,a)<0)+ Q! v" [& v0 s/ J& O
                     {
! x; E3 E: }4 V' v* q                         printf("Bad Input!\n");5 l, W+ d' I, e+ ^4 j  N; V
                         fflush(stdin);( b5 `( U; k' y: y1 k
                         return -1;
1 s7 \7 `6 ]5 Z* e6 r2 u                     }
  d; m1 ~2 O# s3 y) ]                     printf("opnd出栈:[%f]\n",a.data);
7 ^; f( u: B7 X" S9 z( |                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
# F4 f# N4 M4 M, I                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/, j) h9 R% o: ?7 T
                     printf("结果入栈:[%f]\n",opn_tmp.data);
; @1 @: U. X' B& A( }& b/ f8 B                     break;
( N7 e7 _, L' |% |+ K: X, A3 a/ Z            }' l4 k- R3 U8 S+ A4 f2 D0 M6 q- b
        }" j! b: B1 ~$ l5 [- a( i8 A
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
, C. J' o8 ]9 y8 \( R4 ?" G    }
; j8 K- a8 p1 r6 C/ _( d" `$ l' }0 {    GetTop(opnd,opn_tmp);
/ G: e% y6 I5 E4 Y% x. m    DestroyStack(optr);
9 P8 A, n9 F$ T# U    DestroyStack(opnd);
( J, b+ _) D' ]( y6 ~    return opn_tmp.data;( |6 Y, I, m$ ?4 v
}. l3 c- X9 @- R
/ s4 Z1 h; x7 R! @
char *killzero(char *res,float result)
9 p: c/ F% O9 m3 F) `{- _8 P0 X; b; L/ w
    int i;
. R; E* R) J' d3 K4 I. N: {2 a$ j: a  I4 h; l
    sprintf(res,"%f",result);
, ]; R9 B8 {. q' r    i=(int)strlen(res)-1;
9 x: M1 C: p( ]) L" u9 V9 M* b* `5 s    while(i&&res=='0')
8 e$ {: N3 W" H, ]8 K9 D! @    {7 |6 y1 M1 Q: k2 L9 {' S
        res='\0';+ V. f% G. C  k3 z$ c- [4 f; G% k
        i--;
1 Y: j3 @( G6 `5 M    }& g/ m- o$ k! Y" ~
    if(res=='.')
8 |( N) ~) f8 E  J: d" O: \        res='\0';
5 N. ^" C& j; ]    return res;
- t" K- v2 o9 u9 C6 u" x  Q' B}3 B  `6 S# J2 }6 y4 M5 n: I; M

! E3 N! m4 A9 F" U7 `int main()
: F8 i$ V7 l" h: t, z{
/ \( O+ i3 Q( ?! U5 v0 L0 n' k    char ch;! \0 Y, [! Y/ M: l
    char res[64];
8 O6 k; F; L1 |+ J( S    float result;
( e& a% Z7 ~9 [. O9 _5 F4 v    while(1)
; F* M4 m, I  F2 l- P    {" D% @- A) ^! j
        result=compute();
! A: B3 V- O- L  r7 _7 f. G        printf("\nThe result is:%s\n",killzero(res,result));' Q% `  @% G  O7 Y
        printf("Do you want to continue(y/n)?:") ;
" }; \, `% z; p$ h" `% x: A, @        ch=getch();
+ D% w7 w* Q3 G; H        putchar(ch);
' l4 p" s- C, G2 Q4 f% c# Q6 Z        if(ch=='n'||ch=='N')/ a, V: F6 o4 X3 L
            break;
( H- N: k0 o/ q2 t5 p: ]9 \        else
5 T( V: z1 Z. m; R0 j: H( }% h5 G$ V% m            system("cls");/ f: T* E% u  }7 u* F& d% a
    }
9 H5 b) m9 m$ p; Y1 O7 E, e    return 0;. ^! h' n% n( |: K
}
7 e$ M0 k" Z: b* B; P

  M. b8 O) s! p1 ^$ j' w[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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