返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
/ _; \' ^' p) k) X+ I$ R程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
, ^+ w$ |# T. N- B" q, d1 J; r/**************表达式计算器************/; [' N7 d+ R& D* r
#include <stdio.h>" T. [5 S5 q  K- S
#include <stdlib.h>, d5 m: g2 C- S$ v. B! I" ^1 z
#include <string.h>
# W8 }( Q0 L% v$ v#include <conio.h>
! m( T5 m  M' B) M; {% |+ H#include <malloc.h>
: ~6 l% X/ f, _0 ?3 ^4 O8 b  r! y, v: B
#define STACK_SIZE 1007 |  E* e$ Y, l$ Z
#define APPEND_SIZE 10
' g$ k& W' C% n5 m2 s7 A# e+ F$ H' Z" Q
struct SNode{
$ X2 m5 U9 n* F: z0 `8 o* E+ w    float data; /*存放操作数或者计算结果*/4 `, c& g5 Z& n3 S
    char ch; /*存放运算符*/: B3 G1 a+ d$ H
};* e. {9 E. i8 a

8 g. m8 M( Y% [# a2 q2 v, Ustruct Stack{
& ?' Y: k  b' E: C1 G: ~. ~    SNode *top;
+ p$ a( I. ?1 l    SNode *base;
2 K/ n$ V* p4 `& A& M9 K. S, X# }) D    int size;
% E' k& H; s4 |& t7 |+ c+ M& P};
2 z& P  V/ t9 ^! U# K+ q4 `, w" R6 p" U) e
/*栈操作函数*/
0 b0 p! ?9 D1 J1 Z' w' R: X# ?( Dint InitStack(Stack &S); /*创建栈*/
$ N: Q1 h; |) }8 jint DestroyStack(Stack &S); /*销毁栈*/
9 y% L) j# Y$ O$ nint ClearStack(Stack &S); /*清空栈*/
! Z- }/ @5 M1 zint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/8 d) N0 u* j, B9 U" H
int Push(Stack &S,SNode e); /*将结点e压入栈*/
/ M8 x( m1 f9 G+ N( Q' zint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/# }8 l5 C& ]6 K  Q
: b) E/ a5 I' G* w
/*表达式计算器相关函数*/
! W* K/ `/ q9 M  O9 ~char get_precede(char s,char c); /*判断运算符s和c的优先级*/
9 S% T; ]/ D+ w$ n2 @3 Rint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
9 C* |- J3 X3 G- O* O% L% Mfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/, y$ O8 A; `( a) l6 ]
float compute(); /*表达式结算器主函数*/
& `" r7 t0 c" N5 ~# ]% q3 o1 qchar *killzero(float result); /*去掉结果后面的0*/ % c8 w! U; N* v8 p9 A2 X% w

+ S, c" o, n: D$ t# K0 n3 ?int InitStack(Stack &S)! {# j* [. Q4 S$ D. A
{
; i/ L# L9 x  y" k4 K- O- K4 u7 o1 r    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));5 B/ g8 p! p0 H! J6 P. H; x# g# l
    if(S.base==NULL)
% X0 R# e6 J! c( o8 @    {/ Q4 }( J7 |* Y* L1 T
        printf("动态分配内存失败!");
) l/ c6 X  C7 H        return -1;
! I5 O/ z, W6 }0 q8 M7 ^    }" I# N2 f. r8 s
    S.top=S.base;! T* }8 g: {3 `# r$ ?" o, T
    S.size=STACK_SIZE;+ ~! X5 W  e8 m  m+ d0 [7 c
    return 0;
: a; m9 c5 _+ z0 }2 d9 \1 F}
' e: Q" O. B- k- `* j* i" f  g1 h, C" A
int DestroyStack(Stack &S)
; A8 d( w% f: K4 b4 P  W& o. x; [{. |, }! b3 \0 ]
    free(S.base);8 v8 W/ X: B  h
    return 0;
# u7 H/ Y4 ~8 @- w/ s}
( x4 @( o4 `6 [) \3 l: M" y; f: _' D: E2 V
int ClearStack(Stack &S): R) l+ p3 A) @$ N6 q& X
{9 x+ b' F1 @& Q( B& h: W. d' x
    S.top=S.base;
9 `7 R& ?& B: o0 l" P* a  V    return 0;
$ P3 `+ |- A; Z7 N}+ ~- c( H: H% u" k# U

: X5 X9 P. K% ?+ a1 [4 j/ fint GetTop(Stack S,SNode &e)
5 |- T- X7 t1 A# K! h! f, t{1 U" X! \& x' G
    if(S.top==S.base)
7 s9 O1 [+ {( A2 X7 W( G6 V    {: q+ a7 P- v% \: z$ e( E  A
        printf("栈以为空!");
3 l5 I) O( f  X( u( p& l5 h        return -1;/ S' `5 U8 n; o8 h9 B. X$ p
    }
) R  @1 @* {( y# `% s    e=*(S.top-1);
( X. b' Y* d0 O6 W4 B6 ]    return 0;. W( y" r5 H3 c
}7 ]2 Z/ ~2 j( T3 q, C

) n4 C/ X" U" l# f* Hint Push(Stack &S,SNode e)
! K& i2 q9 y6 w1 `( [{
# _' }: X3 T* d& A, B) S4 p    if(S.top-S.base>=S.size); [' z. D. ~) [% a) J
    {' d- E# @) T9 i+ M) B% D2 D0 D
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
5 |' |4 M1 [; L' w  ~2 @1 ^        if(S.base==NULL)8 E  V- i1 p: y2 Z# K+ W8 o6 O' M7 c
        {& [# e' g5 o7 V) U1 i
            printf("动态分配内存失败!");
( t$ |* M/ Z, j4 Z" Q, ~( N            return -1;& H. B+ k0 ]+ _) u
        }
5 R& ~5 @, x4 T- V' {# l        S.top=S.base+S.size;
& W) F5 i; Z) Q9 h# f: K        S.size+=APPEND_SIZE;
# n4 U$ E3 Z5 b+ f    }
4 Z' L6 r: o& }& I0 M7 c' p9 F7 h1 e  {    *S.top=e;0 j' L8 R( v9 ]: z9 h
    S.top++;
) K$ F- S* S/ g& `    return 0;
2 J/ d/ ]6 X! {7 |8 K6 W}
( _: j. [3 D( g* p( w' K5 h( L
* E2 R$ P7 i7 E0 `int Pop(Stack &S,SNode &e)* s, V) R% g! D5 n3 r- ?
{) F# H( u  F& L! L9 y) U2 O
    if(S.top==S.base)& ]5 y5 ]( ~- Z$ V" Z
    {
$ t: f: a6 Z- o+ U. f+ Z/ p3 j        printf("栈为空!");4 A7 E* \. W6 D8 ]0 U( d8 y1 f: e
        return -1;
4 a; u# w) M" r/ G$ Z, W) c: s! Y8 {0 a    }
0 z3 M$ g: O4 }/ N, A0 z    e=*(S.top-1);
4 E; n0 H& Z# f) i: I( H- {    S.top--;
; |; J- ^7 o3 _" Z5 V$ w9 ]    return 0;: H% u1 t% Q/ A9 e
}! i! d' H/ a; r% b8 f) I

1 d0 C3 Y2 |1 A6 J# d8 Z$ tchar get_precede(char s,char c)
4 _" T. E( M8 {7 E0 n1 I4 b: R( N{# b4 H' ]. _* W8 g. V! s, t4 G* M
    switch(s)
  J% G# ]: ^7 V    {. d% `9 P$ _) c5 e
        case '+':                 / Z; s) G2 r& G* M( D' \
        case '-':
# {% [$ q  U) z8 P& q) I& w- H) M             if(c=='+'||c=='-')7 C. @( c( Z  u+ e4 [( U
                 return '>';
+ p5 ^: B$ J/ u6 Z             else if(c=='*'||c=='/')
1 N. w" u9 D, L6 L+ i( R9 P                 return '<';9 F4 z* i4 d6 D
             else if(c=='(')
) ]7 I8 C& ?8 A' y% _, z/ H                 return '<';% l. `7 m! Y8 @0 y5 d8 |8 ?
             else if(c==')')9 N6 t5 X' H: X; x
                 return '>';6 j9 g& w! O/ O( `# N
             else & C1 s7 ]# _! P: ?+ D; e9 B6 G
                 return '>';3 a- o+ l8 b& a6 K; f( P% ?
        case '*':" ?& X, p6 l( Q- O/ o0 G$ P
        case '/':: ^3 P+ Q! j( M
             if(c=='+'||c=='-')# R- I, I2 Y0 _
                 return '>';% H( q' f9 F. {; C5 U: _
             else if(c=='*'||c=='/')' [! u) a/ e0 ^( I: ~6 n
                 return '>';( F* F! |. p& e* F2 b( O
             else if(c=='(')
) R% s5 a9 i5 h  a+ P+ y; }) C                 return '<';
: f8 C1 M- L2 I5 Y9 B; W1 X3 }             else if(c==')')
6 Z- W- {% H( m5 p. ?                 return '>';% j0 H4 T3 O5 D+ B" y
             else- ]. U3 t1 o& Z( U1 X, z+ F, |
                 return '>';- M) H3 A# Y9 M- T- w
        case '(':
) N8 O9 A3 D& ~! @/ G' S8 E             if(c=='+'||c=='-')
  g  Q# L. ~* M' w6 o                 return '<';( y: o+ x& _+ V0 n& z, Z+ b( P+ A
             else if(c=='*'||c=='/')
" u8 E! v8 K! S3 L* ?                 return '<';
) a* O+ b2 k. @9 v" X( Y* p7 F& s             else if(c=='(')
# F; j) A1 Z! ?  x) S% A( @                 return '<';6 x$ y& U4 ?  U1 i8 B
             else if(c==')'), b) K" r% b" {
                 return '=';. V, W5 l8 n1 c$ G
             else6 U- ~- q9 }  F1 w2 U
                 return 'E';
% j1 m' v/ p8 y7 a* x* w0 v        case ')':
& M* F% _; @) [4 [6 G( @6 n             if(c=='+'||c=='-')
* Q3 @4 W* \; W# w: u$ Q: |/ U                 return '>';+ y2 }6 ?: h; Y, z5 n( _: }9 K- v
             else if(c=='*'||c=='/')
) A$ I% p$ h" g% e2 l                 return '>';  A0 h: j6 K" K8 J% O
             else if(c=='(')' I9 J: k- g$ `4 V+ y' z; Z$ m
                 return 'E';
* G; q3 V: i% b' i! b! T' x# S2 Z             else if(c==')')
! O1 ^1 ^7 [6 V  |  J) C                 return '>';1 j4 o. G1 d$ ^  A8 }) A9 a
             else
" Q$ N7 T( Q- ], q                 return '>';. \& v% e" M! Z3 P6 m- [& _9 F4 {5 a  o
        case '#':
3 f! Y+ i/ l. T+ I( R5 K, y8 A. L             if(c=='+'||c=='-')
. f# s9 t( e! r6 Q2 `) J8 Q2 N                 return '<';
3 W8 w( }6 ^7 D7 v             else if(c=='*'||c=='/')0 v/ x% B, z" x5 p- D
                 return '<';% i5 |4 `- l' X2 {& S) G, ]
             else if(c=='('). }* z$ q- r5 ^0 e- \
                 return '<';
4 i& H( y! p# x5 w6 U$ Q! u             else if(c==')')
  U7 \8 @1 M4 G" t                 return 'E';# Z" L8 ~% D; ]5 c/ ^0 x* D8 f$ p4 q
             else& Z- E0 o, c4 K& Z8 _) R
                 return '=';) O8 f' n" j6 h5 W' z
        default:
5 j+ H+ L* V8 D+ a; y, o             break;
  O! @( d: i' F5 q% x    }% \: \( N, ^4 y( |4 I: O
    return 0;    ! i; h2 I4 V6 B) M2 T! H
}
6 w$ R6 I  e) @) v% _7 m5 Z% V6 t- n2 p' U2 Z3 e  t' x
int isOpr(char c)& b# f6 `& O! {, i. r) `  T  m
{
& f  J; Z# `/ z) I7 k- z- H! p    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')" B) [2 n4 M! |* M' u
        return 0;9 N$ p7 R/ Q( o7 t! i; Q% I1 |
    else
0 M2 q) O8 u. X5 M* ?        return 1;8 G% P* ^8 K$ w. `
}
, r& y4 K' F6 q9 J8 a1 N6 j& M) {2 K& t! T1 z
float operate(float x, char opr, float y)
2 ~  i# f# n+ w{! Z$ P* v. \6 Z1 }( S/ l
    float result;' ?9 m) K6 |: G  W; \( H7 o: K
    switch (opr); T( K% Q0 O- i% t* s- {
    {
7 M2 w' H: J. Z        case '+': 0 J2 X' x: F/ F+ G  I
             result = x + y;( v& }+ ?' N1 s4 J
             break;$ @1 b: T4 I/ v& v+ C9 d
        case '-': 7 N% n' [1 d3 s3 M& b
             result = x - y;* z+ i$ B5 t7 ?$ M% A' W1 M
             break;5 g, L. d# |4 @  `0 @* W4 f. b8 r/ ]2 p
        case '*': 0 o" S# x' G, P% ^& N. \3 N! B3 J
             result = x * y;' n! X7 M# J* `% w
             break;
2 @: r" j% k3 ^  ^7 X* S. j0 ^1 S        case '/':
+ W  \3 t8 ~+ y& S" k1 M             if (y == 0)
2 q$ A: ]8 z  P3 F             {
6 f7 t) b7 ~0 Q, z3 M                printf("Divided by zero!\n");
# m; X' q% f4 \                return 0;
" r' N1 x3 A9 D             }( k5 k5 ^; t5 B/ }
             else2 ^1 a8 J, X/ M: R5 @* K. a8 w
             {8 A1 x: k1 ~- j1 M+ z/ i- t% p
                 result = x / y;4 x0 w2 e8 U0 Y5 p6 e+ Z
                 break;( p" Y1 I8 J2 G2 K/ V2 B" d+ ]  ~
             }3 `9 w1 ^0 @! S) K6 s! ~
       default:
) u8 d& K% N# g; _6 d' ^             printf("Bad Input.\n");
9 Q  ]; S. b( l3 z# D! y6 d             return 0;1 ?# P& w& }0 L( p& U' j
    }
/ M+ P+ A3 z& T" u0 l    return result;  o+ z8 ?" R, O
}    # f. B% U4 q6 ?- i
1 y! L: t: W0 }+ E8 ^  _
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/# ]. S- [' {: l6 Z! a
{7 U' t$ H, I6 m- E
    Stack optr,opnd;
. ?; w0 J7 {8 l8 X7 `) G    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
, v! s9 i6 D: l8 u, ?2 Z    char c;. P0 R$ {+ R& j9 Y6 [( E
    char buf[16];7 n6 H4 X+ G8 k
    int i=0;
6 A: o; n$ ^! Q    3 W, u! u9 k# W' ^* m
    InitStack(optr); /*用于寄存运算符*/& d( A( D& G, Y; H! b
    InitStack(opnd); /*用于寄存操作数和计算结果*/
* ?: J1 {% i" z    memset(buf,0,sizeof(buf));
1 `, X$ [$ k/ g% l$ k6 Q    ( E3 B3 @9 T1 }; Z1 Y8 L! t$ }& B
    printf("Enter your expression:");
7 `; C! c- B9 k& @/ y/ |        ( S+ D. t! \3 n
    opr_in.ch='#';9 a$ @3 J: d- N5 m$ U9 ]
    Push(optr,opr_in); /*'#'入栈*/
; I# p; R" R* ^3 D  k    GetTop(optr,opr_top);
( b) A9 L' q5 L, V    c=getchar();
0 o) Q- S% {* }* ]- `    while(c!='='||opr_top.ch!='#')
9 R2 X( S- k5 ~0 e    {
- z- |' T  V6 m5 l% R. Y- {        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
4 v/ b( I% A. v        {3 C3 p/ C7 W, L, @. Z' a/ N
            buf=c;, |) i. l: W( X8 N4 X1 ]
            i++;/ K/ c% Z& F7 o3 _- e: @0 P
            c=getchar();2 i) p5 L! D: U! n7 [% H
        }! r: _; V8 k% g+ A4 l! O+ k
        else /*是运算符*/
! ?7 B5 c% F$ g( Q# N        {
5 \& t+ A( |% q: p6 A" N5 }1 ~            buf='\0';
7 k3 @+ a: ~# k8 E, `% Z            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
- i; p5 d7 y- I3 t& Y- }            {$ c0 i, C# Y, q* j
                 opn_in.data=(float)atof(buf);
- J0 ~4 F9 O& q) M6 O! F( }                 Push(opnd,opn_in);
; r3 y* }# _, G2 V                 printf("opnd入栈:[%f]\n",opn_in.data);
1 {: L: v6 a  E4 Q0 r0 `6 S5 t                 i=0;
" I0 A! G& o, S' |9 s+ M                 memset(buf,0,sizeof(buf));: ?$ u% Q9 v) Z. o0 F+ Q% q) I
            }
" I9 x3 n/ w- q/ p; G! f' o9 k2 n            opr_in.ch=c;3 g5 y% w; v4 Y3 w% Z6 H
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/* z: W* J$ l& r0 y1 }, v" Q* q
            {
& s) P8 Q3 h0 U9 D7 y/ P3 Q) F, ]3 C                case '<': /*优先级小于栈顶结点,则运算符入栈*/7 d! e* _7 O1 ^( g/ Z- n
                     Push(optr,opr_in);
$ V1 T' M) g7 I( N1 t                     printf("optr入栈:[%c]\n",opr_in.ch);3 b9 m) \* g: |5 b0 }4 `5 v' b
                     c=getchar();/ v) B: q6 |8 ^" P6 x- a
                     break;! k+ I# C( {- a6 L4 g
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/5 X3 ?5 |3 z: q/ E% l; n
                     Pop(optr,e);
/ O% A5 o7 `# H. t; f3 G                     printf("optr出栈:去掉括号\n");
* X$ j& f: }, O% ?* D                     c=getchar();
9 u$ s. N3 U. c                     break;
$ d+ _9 k; t4 U9 ]: u1 x. y9 o6 ~- }                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/1 b2 h  O* c  ^- t8 S% \9 ^, w, Q
                     Pop(optr,opr_t);
0 ]% q7 z5 u8 J" d4 Q$ V                     printf("optr出栈:[%c]\n",opr_t.ch);; u- k' D  y; z( b/ Y' o
                     if(Pop(opnd,b)<0)3 K: ]) C7 G1 F
                     {8 @4 O; l6 A/ ~& j
                         printf("Bad Input!\n");
  _1 P% ^/ D- B( m6 i& ^                         fflush(stdin);
0 O. Y& L/ j( w# q' x: u                         return -1;" @& ^4 C9 w& J5 u2 c3 {
                     }' v$ t; k, E1 e- Z
                     printf("opnd出栈:[%f]\n",b.data);
" s6 O6 C: n4 i# p: C8 [                     if(Pop(opnd,a)<0)
  P7 X2 n* N6 p                     {8 c2 g% j+ w% A% m5 z
                         printf("Bad Input!\n");0 Q7 Z' u' P1 N- D  T9 D
                         fflush(stdin);
* x6 a$ Z8 _$ r; A& ?                         return -1;
/ w6 ^  h+ |- v                     }" j( N8 A, _5 f: ~
                     printf("opnd出栈:[%f]\n",a.data);- m3 W. m* b9 ^/ t- A& i3 ^4 r
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
) g9 u. d2 v% v5 g7 W* A; a% ^                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( q/ U2 Y7 j! ^# Y: p. u                     printf("结果入栈:[%f]\n",opn_tmp.data);6 a1 p- @+ Y: _. o6 V
                     break;" B+ j& I' }- Q3 N( y; A! @7 g
            }* O( v4 |# N% H
        }
3 U$ X- E# A2 I  M, N: W3 o        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
. a% O9 D& I7 w) {! G% N    }
% A$ z7 W# o" l2 J3 f9 @2 H    GetTop(opnd,opn_tmp);
) l0 |* N, N- P( }% z- J6 o    DestroyStack(optr);* i2 D3 {! [# K+ [
    DestroyStack(opnd);
* e* n" n+ O6 M' H: `. s    return opn_tmp.data;
8 l/ g0 m: {7 n$ K}: j: w  O& L9 t6 K7 u, n

1 a* y% z  A6 c( I7 y" _& e# Dchar *killzero(char *res,float result)
4 H) i1 Y3 m, y$ Y  l5 o0 N{1 ~# W2 Z, e4 K( z* A4 n* y/ r7 ~
    int i;
3 T0 P$ z! R: C
6 }5 a5 {& }7 i* C# a- H    sprintf(res,"%f",result);
9 E% o+ x9 f2 m% H3 C    i=(int)strlen(res)-1;( ^: w+ X7 \0 o: W
    while(i&&res=='0')
$ i: e( V0 O! e    {+ F! X) M5 E; ^! c% c! U# ?8 A: T5 e# t
        res='\0';5 H" [5 J* M9 N0 `  |8 Z
        i--;' C: O, N$ |$ ~1 y7 w
    }# `7 s$ B8 ]- @, g
    if(res=='.'); `& y+ Z. F/ [
        res='\0';
6 p* W- O3 u; D4 z    return res;1 w3 }. L* E4 O- C& W5 C( @
}
) [4 ~5 l% H( @+ s" @9 \" q. x+ D. G4 }! U* P
int main()
9 K- q3 J* C! b/ a: x8 a, V& w{
: [; W9 ]0 {0 j; Z    char ch;& {6 `: ]0 c* h  N
    char res[64];7 M' I  h& L# a8 V4 Q) H* c7 W
    float result;0 H4 f/ h0 B: M8 L/ E# P
    while(1)
; `( u% M0 g3 Z& A: t  _1 N    {! f; [  F/ L% i' {% E1 z
        result=compute();9 G0 r; i: S) ?- o
        printf("\nThe result is:%s\n",killzero(res,result));
$ T! X. L( Z& |: l% q- Q1 ^        printf("Do you want to continue(y/n)?:") ;! ^; s& H, \8 A/ W3 ?/ T
        ch=getch();1 ^4 t7 E" l! p. l# Q+ s
        putchar(ch);6 T' m( w7 H! t8 {
        if(ch=='n'||ch=='N')
& v- l. H  i! F' k# ^5 @            break;) P/ R1 J0 K! r
        else3 v9 L/ \0 N9 B/ K% l5 l
            system("cls");
  d( h( W! }9 C1 i    }9 r8 |% U6 V: ]5 O& @& N
    return 0;
9 o) `" C" Z( C4 l}

& A9 z" s3 ^3 r# G. s: A* M7 y/ i' U6 z
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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