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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.& M* A% s8 _' e. ^& j
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
' V* y  X* Z2 Q/**************表达式计算器************/' T# i/ q7 {1 r, t
#include <stdio.h>
  @" I! e% Y( G5 _9 `- F2 v#include <stdlib.h>
: I. k& E1 t. o+ G# G; b5 w#include <string.h>- C! L. H# S$ T3 |8 g
#include <conio.h>6 i1 g2 {8 k- p3 v
#include <malloc.h>3 Y/ V1 b# F; s& {" |$ M5 Y
- l* J* A: a  q( @5 c
#define STACK_SIZE 100" u% k% c# l5 s
#define APPEND_SIZE 10
  O7 }9 t, |' Z' y# H$ @% c3 S" ]& b
struct SNode{
" N  _( v# e+ u  c, n2 B4 t) ^    float data; /*存放操作数或者计算结果*/
* A2 f  z" o7 d) y; G    char ch; /*存放运算符*// I$ v" C3 Z4 y% j/ I7 T. x
};
, V2 {! d: V9 b. }' v% _
/ Z" P  l; u2 K) Q% g( f2 Istruct Stack{& @& t/ `, ^+ ^9 j: f
    SNode *top;
; P& x( @' G+ n& e! d' G# c+ T5 Z% j    SNode *base;) P' I; y* W- r
    int size;
8 [9 D! ?/ U' r  \+ F3 W1 B6 w, z3 E};
' p8 P1 @0 n; Z  f
4 a+ ?/ S+ b  T; `: k, Q/*栈操作函数*/
* t2 L; ?  \8 l" K' n) jint InitStack(Stack &S); /*创建栈*/$ D6 |6 T, t& P
int DestroyStack(Stack &S); /*销毁栈*/3 `( `0 \/ S* i! d" X
int ClearStack(Stack &S); /*清空栈*/
) S2 k+ u: o: W2 I3 s5 \) fint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 R- _; C' R7 @' m' T: |int Push(Stack &S,SNode e); /*将结点e压入栈*/
" h" O" o/ K* }) rint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/$ @; o. T1 c# G+ b; h

% @' q0 k1 O& y& W+ w7 ^6 v/*表达式计算器相关函数*/
; {, P2 _5 o8 ^' b4 L) L# p$ uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
% N$ Y+ I& p' U) ~# \int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
7 |0 d7 b7 H7 T; r3 e; x5 efloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
# N- P' e" J" G6 J3 hfloat compute(); /*表达式结算器主函数*/
' @( w: f& s0 U9 G/ a. bchar *killzero(float result); /*去掉结果后面的0*/ . P* u- G* Z% N2 z& G' V
. N/ A3 _+ z  p8 u
int InitStack(Stack &S)9 O7 @$ f2 T( `
{
" q2 W. O% u  a# i/ J    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
9 }5 g; f4 O# z, ?  @5 o) J* \    if(S.base==NULL)
# ~) T! ]/ \' _% z1 t* \9 r    {8 f" I3 W4 z4 r
        printf("动态分配内存失败!");
6 o5 k9 R- t$ z  T3 K* P        return -1;5 m3 a; W- a6 v7 c
    }
+ @6 L/ u4 u  C  t/ B2 D8 m' W    S.top=S.base;& }" T) [! y2 s# D
    S.size=STACK_SIZE;
( _' m, z& f6 s# t3 R# Z- I* ^0 W, Q    return 0;; R* \% M- z4 E2 i% X
}/ {" o5 u& Z3 ^2 G4 B7 @" g
' W3 D4 X2 n7 l' [6 t
int DestroyStack(Stack &S)% s" t, {5 F2 p' D- h. T
{' w) ?. \; w7 P5 F
    free(S.base);" o4 N/ k) ?7 Z  R' l* r! \
    return 0;
; E# `: ~9 j, l* ?}
3 f5 K8 ^' j' N0 {3 K, N5 m2 j" H) C
; B' s/ g7 N% K5 [) Uint ClearStack(Stack &S)- U; r, V1 m4 |* w. q# v7 u
{# k) x% b  s  M* G- Q% c- ^
    S.top=S.base;
$ C# w9 R9 c  K( E2 h    return 0;
7 I7 C# C& K) o7 c. L* I}
8 W* g- u& n! i
( e3 ]( ^% X4 C& o- kint GetTop(Stack S,SNode &e)
! t! k5 j. a: S0 `) U8 z  i{" a& m1 W9 A8 M) @0 `
    if(S.top==S.base)% o! b6 t& \1 r, k
    {2 q  {/ O* B9 n7 m( v+ q
        printf("栈以为空!");0 {8 p- b! U  i, N2 n1 }
        return -1;
9 J' S! t  K) U+ n* V; p    }
: {% I8 R& }3 f5 ^# F2 e    e=*(S.top-1);4 G: G9 T. y* h5 I  R
    return 0;# a; L! r% m, B* k; ]
}  H% Y$ `. ~9 R. O% G

4 X- s' }9 {8 H0 s. N) tint Push(Stack &S,SNode e)' I' ^& D% l2 e% m
{
' U3 \6 G( X( {7 q: l. a$ T    if(S.top-S.base>=S.size)
9 f+ {0 O# w- y$ P5 x0 c    {
7 \4 _3 e3 n5 `        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
7 n* I6 s4 v* e! A1 m6 {        if(S.base==NULL)$ u" {' r* I, o# g
        {
( a8 K" `; B- H5 I& G            printf("动态分配内存失败!");
+ F7 _* z  V0 O2 h. Q            return -1;5 F& _- b2 F1 b9 |% F* P% J
        }* S3 X+ x) u5 r. [! B. ~; o
        S.top=S.base+S.size;
" d! B9 v4 y  e        S.size+=APPEND_SIZE;* D: j6 }3 @# c3 b, v9 u+ h' ]6 f
    }
9 g6 X/ l  Y* E( D    *S.top=e;5 [9 r$ W; [6 J9 U( B& V
    S.top++;
6 C+ E* V! l, X. S% W    return 0;7 ~6 E4 `2 ?  {/ T- {
}+ b2 ?& }% m4 ~

, t  Z+ Z3 K  c2 V" r- Fint Pop(Stack &S,SNode &e)( C( G$ c+ L, U5 z. ]! H2 r7 @
{
3 x* V8 s, L9 R- \+ G: k    if(S.top==S.base)# p( N- d4 q. z
    {6 v; _" ?6 S  ]2 U8 Q5 Q2 h
        printf("栈为空!");" y  L/ E: V2 f1 r
        return -1;
4 t' l' d) O& V    }. s; C  r, |! f% J' N
    e=*(S.top-1);$ i- g7 W2 V5 {5 s/ b; q; o
    S.top--;7 U& W2 ?; n9 }- t
    return 0;" Y- d, [$ k6 i
}+ N) l; r! S$ @& D
- G" ]& E! v# k
char get_precede(char s,char c)
/ X1 {0 U1 f& `{( p! h- O9 ]6 T- @, E
    switch(s)+ `' N: D. J( R4 ~- _% e
    {: [4 g+ w; H9 P7 h0 c/ W+ l
        case '+':                 3 X0 u' k+ _( G9 T& v, P
        case '-':
# p/ p4 r/ }. h( z             if(c=='+'||c=='-')% {! @1 [) I0 q$ ]) ~
                 return '>';
$ E" J2 K1 Y! B. g+ ~             else if(c=='*'||c=='/')3 N( Z! x( ]6 Y4 v
                 return '<';. J/ R" M9 `. {* P% @6 V
             else if(c=='(')+ l9 J/ \; ?3 P
                 return '<';
2 c2 f- Z" p, T             else if(c==')')) O' m. \+ C7 A
                 return '>';
; J- o& R; D8 T, |2 v) g             else
! C7 R7 V) y, i3 Y                 return '>';
5 D& x) S2 s7 U6 B        case '*':5 X& A+ N- m8 ]5 I/ w
        case '/':
; T0 K9 h1 c1 ^& u! z, w) c             if(c=='+'||c=='-')
8 e0 ?1 j0 D' H, F# a, `                 return '>';3 a1 W7 V- M, l- Z8 Z. F9 c% ]' @
             else if(c=='*'||c=='/')
- B/ `: q; v$ @1 m" |+ |1 |6 V- I                 return '>';4 |3 S: \5 e: z
             else if(c=='(')
8 C$ u  c" M/ I# v                 return '<';
3 D% J& v) H/ e8 B& |; T* R4 n6 n             else if(c==')')- \1 m; ?' B1 ^3 Q
                 return '>';: _- q6 y. T# Y/ r9 i0 J; B: I
             else" y, ~$ p& T! v. @( u; |
                 return '>';0 V- b! C. d: D8 S( L
        case '(':; X, @8 `) P( m" t
             if(c=='+'||c=='-')9 j& R# w. c* L. d
                 return '<';6 G% Z/ W! K6 t2 h; G8 X& |7 ^
             else if(c=='*'||c=='/')
' C' f: ]' y, t- d) Z) g! }                 return '<';
* k; s- `* ^: a& ^  D* S" c! l/ ^             else if(c=='(')
& u- o5 ?  M3 v0 e' ~                 return '<';
; p# r5 E7 k" U# r* C2 Z             else if(c==')')
4 d6 J6 B7 a! i/ g9 [) d2 b: J                 return '=';
2 i# x) F# o% b0 z9 i9 V8 [             else
" m1 b! x1 Y: N- R3 G                 return 'E';
& `0 d  ~5 r' c9 d% x( A& n        case ')':
2 L5 \1 n+ z. I; x             if(c=='+'||c=='-')+ m4 j6 f; K* h( _6 X
                 return '>';1 Z: N2 @3 i3 c1 u+ _, K! ]+ c2 K
             else if(c=='*'||c=='/')
0 {0 y8 L& t& W/ V6 U, S                 return '>';
. b, E. N1 P" w* Q7 H9 k             else if(c=='(')
8 I# V9 M3 O) @% r/ p4 ~                 return 'E';
: g6 x7 X5 `$ {6 O% o1 `9 _, f             else if(c==')')
0 E7 C) D8 P: T: `' H                 return '>';
$ ~& B# R& _, k- d             else* M# i+ u! I& J7 W$ y
                 return '>';
' L" }2 j& t" Q        case '#':: {$ B: N$ L7 d! i% g
             if(c=='+'||c=='-')% |( ?  L7 B8 P1 l' l  j+ z
                 return '<';2 t% J# b. ]0 W+ T, J7 ]
             else if(c=='*'||c=='/')+ X+ N( B& R+ D
                 return '<';
5 Q4 D2 w3 M5 q- L+ s0 V+ f3 Q' o             else if(c=='(')
+ g+ y0 N/ e* y! _                 return '<';, N1 Z4 t. A) M3 s. ?0 q
             else if(c==')')  ~# r" s' X" r+ @- i
                 return 'E';
9 w8 m4 O, _2 w- F$ w+ `             else# e. f% h& h, c6 i, ], R
                 return '=';
- T) G% _( r  w9 O- R; E! e9 E4 _        default:
. ~+ B. H* s- ^  W( z' d             break;
! M* j2 h. K" c. @7 x    }' a/ H# o. N9 p8 A$ X
    return 0;   
6 `0 C% F1 {. F/ L+ }}7 |% b7 l/ t, c8 a, s

6 S& E1 c' u1 Q2 {int isOpr(char c)
; @: N( Z  ?& {6 ]1 U( D" A{
& X7 Y; A9 x' {0 L    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
9 H, y* z6 Y7 O. X5 x) e        return 0;: ^- q' t! d8 i5 |' J8 [1 x
    else 2 k, M0 O" z. z+ x
        return 1;- {9 K# w0 J  u2 x, X% P
}4 q7 J8 |+ @/ i% P5 p' q
4 I- q9 }+ s4 T( @  Y
float operate(float x, char opr, float y)+ h2 S$ g5 d$ D$ p2 m( ~
{0 W" E& m0 H2 `& T
    float result;
! q* I' ^% i8 R8 W$ B8 ?6 n    switch (opr)4 U, ^$ {1 J! u: ^
    {
# c7 b" X1 |9 S/ W5 A        case '+':
8 ~8 w' `2 z: F: \( L             result = x + y;7 v# K$ y0 P6 T( }0 x+ ^; H
             break;% L* H$ K. Q( c1 O: Q
        case '-':
. \' ~+ ]1 ^8 R; L/ w! D             result = x - y;
/ C+ M9 z( N' e             break;
4 Y" y* W3 q3 v! J; H* A2 [- @        case '*':
6 N7 d" g  a9 B2 m8 w6 P             result = x * y;
* z6 y  ~% S0 ~; m) ^- y             break;/ o& s% H! A. G7 u/ v, }& o
        case '/': 4 s$ G9 q1 h3 _. z: J& ]* ~
             if (y == 0)( q% `7 D" `  l( ^. a
             {' h& h5 D) ^# L. R* a! ^
                printf("Divided by zero!\n");  D. u" z) y8 H# E% \' _# }0 G
                return 0;
# H" i# D  e/ U7 [- ~- E7 x1 a             }
! V7 v$ ^) F# y4 _) q             else: N( \5 z5 E' w& r
             {) E+ [  J( G4 Y# m
                 result = x / y;
6 Z- i) G  u% U' I% c0 M, k                 break;
4 B  j8 x5 l. s* k             }7 j. T  E2 \. r3 ~! n
       default:
8 f# u! q% L1 ~0 b             printf("Bad Input.\n"); - E. U, h6 ^, o# ^$ `
             return 0;
+ c6 c5 Y" ~, }' F7 Z% z    }
  ]# b* x+ q& w    return result;0 b4 b# g) e4 U% t2 o
}   
1 \, p4 i5 U  L  k0 k! c& n( @! H# ^/ x9 g, }& K! I
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
* ~  @% y) Z' K9 R' t  N{" J6 T& R, e! Z& c% ]$ l( A
    Stack optr,opnd;2 n5 M9 A. ^" m% o6 R/ C
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
- Y) Y- p4 p% p    char c;% G3 e& ]/ F- ?+ u8 b8 i
    char buf[16];
" |- K; s( t9 \    int i=0;
. D. A% {3 h7 i   
3 n# ?0 g9 z+ q$ ?; H    InitStack(optr); /*用于寄存运算符*/
" q1 p2 q, F4 I    InitStack(opnd); /*用于寄存操作数和计算结果*/; }# a' e' a# R7 p* G$ _" g  S8 O
    memset(buf,0,sizeof(buf));# j( r) k+ q: F* ]3 v
    & a8 X3 j# H" \2 V5 y+ b
    printf("Enter your expression:");
1 ^$ R& p" j1 V        
! D7 {+ N: {$ J2 C* L; V3 i    opr_in.ch='#';! i3 T6 v. k+ D! H  L
    Push(optr,opr_in); /*'#'入栈*/
! @2 q) @. Q1 P4 ~5 l, i    GetTop(optr,opr_top);4 R, Z- n* O3 e( ]0 M" Z3 x
    c=getchar();
6 D& m. G6 P1 x& q) C7 c( x    while(c!='='||opr_top.ch!='#')
1 @2 T: Y4 R% _    {! O- h/ A* r& W8 K2 ]- f/ t; r1 m4 f
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/# O2 q3 X% M# G; Z; {: ]
        {
1 ?7 ^2 t6 ?# F: m5 ^9 A: i            buf=c;
8 t$ A6 ]  o- f! \, F4 E            i++;5 z! ?$ v+ C; l& m; q' I7 O
            c=getchar();
# V; s2 C/ g2 w7 h. X5 o        }
/ |* I0 U' {2 y. A2 P6 T# B4 I        else /*是运算符*/
, R5 R" ?3 r' W, W5 k        {7 U2 B7 n2 H9 R+ G, b  n
            buf='\0';
1 x2 A- q2 J- o$ G3 Q' y# X            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+ Q' a# r+ H: @0 W% u3 c
            {
! z/ W6 E7 U/ R                 opn_in.data=(float)atof(buf);
' c; J2 B+ y  K; y0 D% P; r; L% A; B                 Push(opnd,opn_in);
) a, s1 s7 }2 O                 printf("opnd入栈:[%f]\n",opn_in.data);) L& Z5 _0 |  q: ?/ W
                 i=0;
/ F( ]" U. ^# I, T                 memset(buf,0,sizeof(buf));
' M  q! u2 J& x3 h            }, P2 B6 n& `) e  o
            opr_in.ch=c;/ h8 i0 z- q- f9 T" [$ [1 `1 `5 q
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/) J' g6 s% @0 l1 t! i
            {9 U5 l0 o# S/ ]/ T; }4 [4 ?& O; o! u
                case '<': /*优先级小于栈顶结点,则运算符入栈*/) H) w4 Z, n) U; G% x. w; r( ^
                     Push(optr,opr_in);/ e7 o3 X! x' Y
                     printf("optr入栈:[%c]\n",opr_in.ch);0 N# F. X1 s8 N6 ^  \+ C" o
                     c=getchar();
$ S/ p7 d3 G! k: B6 H                     break;$ b, P! ~' Y  r% o8 n% h
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1 Q$ y9 ?8 J$ o+ O4 N! p4 A                     Pop(optr,e);
- m* z1 E6 u9 ^( W! y                     printf("optr出栈:去掉括号\n");
5 @* X2 w' U" T                     c=getchar();4 o0 N+ P  m; F* y) [6 Z
                     break;
; K" H, ~0 s6 u6 n+ ]. n8 O* I                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
: h2 n3 J8 M* }! c                     Pop(optr,opr_t);" `* R# n/ M( R& [- N) Z4 t
                     printf("optr出栈:[%c]\n",opr_t.ch);% m, a( o6 N5 n6 A
                     if(Pop(opnd,b)<0): S, y( i, S  p& B
                     {
# ^4 M* J- c+ r& C# p) v8 X                         printf("Bad Input!\n");% e. m* H/ h6 c5 x3 m7 d+ N
                         fflush(stdin);- A' [# ?( S& Z6 ~! _: ^
                         return -1;
( Q6 K; n5 u, t/ m: D  I+ e7 D( N                     }3 A+ a! C( t$ o# ^; `
                     printf("opnd出栈:[%f]\n",b.data);
& m# O8 C7 k/ y4 L- H, [8 D                     if(Pop(opnd,a)<0)
9 H5 o& D' P: V' g7 X! C                     {
; T- g7 S( X: z: J* E                         printf("Bad Input!\n");4 d8 M% W) r- e( X4 J2 U" J0 m
                         fflush(stdin);3 N2 B0 t$ ~1 N2 m1 l
                         return -1;% [0 X/ b2 T2 j, z. ]. b; r
                     }
: D% \8 z0 _7 U# a                     printf("opnd出栈:[%f]\n",a.data);6 ~; Q5 y; [  J3 w/ [2 F
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/: u1 D' v& B2 v& }2 b. Z
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/$ w( {% O$ l: [+ [9 ]/ z
                     printf("结果入栈:[%f]\n",opn_tmp.data);
0 x: t0 B  f* N3 ?, O                     break;
% H2 s' X0 F8 E+ W# v% |/ _            }7 Y9 b! I( S1 s* j6 o
        }: f) Y- w9 ]( m6 A% t( t
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                % q- `3 X) g; L  ?; k& D
    }
- J" f* ~/ Q) d/ C1 N% _    GetTop(opnd,opn_tmp);
. e; P2 C" d: b2 {% Q* l5 {/ g) B9 i    DestroyStack(optr);4 G' I8 F+ L; F$ d* P7 G
    DestroyStack(opnd);
- T7 [; ]: |3 e5 s    return opn_tmp.data;% N9 K' q; B" c
}
5 B5 P! c/ s; `/ l7 \' }1 T& [& u( w8 r. @
char *killzero(char *res,float result)
1 T7 i9 A7 O+ b/ {, j6 C( m{
6 R8 T3 L; S& K( j/ Q3 f2 v: G    int i;+ @  b) N) ~- m  y& Y, `

0 J5 ?9 y$ c  C% s, M7 u    sprintf(res,"%f",result);1 M5 z. d1 U+ ]: z% q+ [) Q
    i=(int)strlen(res)-1;1 `0 d! D$ K, K2 N4 Z4 U
    while(i&&res=='0')
4 p/ G1 h2 R7 y3 ]* H8 }    {% @  R, v) N& {- h# a
        res='\0';
5 M) h, [4 F1 \  J& C4 |) A        i--;* E+ k; j; z- Q; g0 @5 S
    }
0 R5 ?9 }0 [4 }7 B% X    if(res=='.')
3 l) e' `) Y/ H( y( ]8 y% I5 v+ ?        res='\0';
. v& C9 i8 \4 |( t% F1 W4 R    return res;
5 n+ z) Q1 V  A# a}+ b/ q6 |6 z4 N; B5 H/ L' ~7 L
# W0 C4 D& Q% Q
int main()
0 n3 o0 j$ Q  b* i- A, f# Q. {{; j% o" l7 Z4 U! f
    char ch;/ ?  w" l: N5 m: S6 O1 p
    char res[64];
7 t( F6 L3 r) H1 X    float result;
4 R" \# a& Q* M; F! |    while(1)% b' C$ q# _0 p
    {
/ q9 F4 F0 D4 {        result=compute();0 r# U! \& w, L
        printf("\nThe result is:%s\n",killzero(res,result));) Q, D" `% Z4 j8 |
        printf("Do you want to continue(y/n)?:") ;* Y/ o' d) ^4 i9 c5 i1 |
        ch=getch();
/ _- w! [6 v0 [( F        putchar(ch);$ V: L- l2 L: |. V* T% F
        if(ch=='n'||ch=='N')5 H9 x/ H5 a4 K  h
            break;
( v1 g. @- ^' Y8 T$ H        else
) w! r, d/ P2 _            system("cls");5 O; j0 R) S$ A/ Q0 H" Q
    }
9 @. ^: O* y! i1 O4 W    return 0;1 e" `  g6 S  S6 t" i
}
. m$ p% y  }" O. d3 k2 z" G4 D- K
, ^. j3 w2 t& l5 ^6 i9 ^
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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