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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
+ y- o+ i' Y) B/ e3 X程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
# _/ o. x8 D$ |4 i; V/**************表达式计算器************/+ q7 E# `0 @6 M: q: i
#include <stdio.h>
4 ?5 Z! ^! }: f#include <stdlib.h>7 |5 ^* |% |: o0 ]
#include <string.h>: h: t3 o* }1 M0 U# Q: Q3 P
#include <conio.h>, k/ h/ ~+ E# k
#include <malloc.h>
! C( G' f$ j; g2 G
+ ~  ]' I* ]- b#define STACK_SIZE 1007 G# b! c2 p) l6 R
#define APPEND_SIZE 105 j7 F/ z9 U$ G: I9 L1 @! F) A

5 I3 @! d, a6 @9 N7 z4 {; ]struct SNode{
' a' v1 D8 _8 z+ p% O* E% _  H    float data; /*存放操作数或者计算结果*/3 G$ n! L. d  [1 p) c$ z. T) n
    char ch; /*存放运算符*// l7 b1 n5 e* t) J  _& n5 D
};: J0 ]* [' ?& [
. [$ U# Q4 U2 N- y
struct Stack{
) @1 @! l/ Q! U5 Z3 V    SNode *top;" m" k. A& A7 q" R) J  ]
    SNode *base;
- S6 F9 \5 L# t+ k4 ~0 k    int size;/ Q/ T1 @1 V$ v$ E6 I4 I1 j2 K
};
, v1 S/ d; r- z& N9 P
: D$ E/ k& t- V/*栈操作函数*/
7 H2 b" S$ P: A, y5 Eint InitStack(Stack &S); /*创建栈*/
1 B# _/ s. G1 u+ v# Eint DestroyStack(Stack &S); /*销毁栈*/4 e6 J: z9 Y* @! A# ]
int ClearStack(Stack &S); /*清空栈*/3 m& I4 U9 X7 M( ]; g+ U
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
% t( h3 {8 ?: W' mint Push(Stack &S,SNode e); /*将结点e压入栈*/9 f9 ~: t  S8 j! P+ E4 Q
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
0 o0 y. A7 e( \1 z7 S, q
) j5 y5 J5 }' g( P( w/*表达式计算器相关函数*/
$ A7 l: I4 Z5 _$ A9 @0 cchar get_precede(char s,char c); /*判断运算符s和c的优先级*/; r5 I' T# c8 P! K
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/7 K  ?2 c5 t, a$ Z% @8 ^
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/8 }) z, u; E& ~4 _9 g  }+ U! y" M6 Q
float compute(); /*表达式结算器主函数*/9 P6 d9 m4 ]5 v& u
char *killzero(float result); /*去掉结果后面的0*/ / @/ p' V) P2 n2 J5 W& f5 J: O7 i
0 l* C# j6 B1 Q! D
int InitStack(Stack &S)
% q2 }' @2 i1 Q. m' m{
( Z% y' ^3 n5 \& t" T1 T& A) E    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));) _: [1 q6 z7 w
    if(S.base==NULL)
/ w* Y$ X2 [  {) ?    {4 U3 @, }, i* J' R
        printf("动态分配内存失败!");  c' k* y& @; ^" D4 o8 z
        return -1;* `& ^# `9 N3 D: K# r/ G( _6 ^5 ~
    }
$ t4 p6 K+ |5 f) H. C6 q- p8 C  x    S.top=S.base;) `* i5 H; f7 ?
    S.size=STACK_SIZE;
2 ~( l- ~# f: N4 b    return 0;
9 u5 I; z# R+ I}! o! M8 y. a3 ?; L0 w

# U* ?6 R  B% _- A, bint DestroyStack(Stack &S)
! F) A" S6 |: N7 W- n{
5 T% F# \1 J/ }, o    free(S.base);2 |# P! g& f* k1 Z% S4 Q
    return 0;4 N8 V  ?9 D: G5 c4 ]  E/ \
}
( @" @. b& V5 j7 V- M1 `
+ s) ]* M2 j6 `  D. }int ClearStack(Stack &S); b) I/ {! t8 g! S
{0 v& N4 h2 j* u- T
    S.top=S.base;
2 n2 O  c/ {8 n' q) f7 q    return 0;
9 Z& M) |1 H: L0 W8 i/ V# j}
/ L+ k1 F$ \* Q" L' U2 |' ~7 `
9 D. l! _9 ~4 Hint GetTop(Stack S,SNode &e)# Z% ~4 _2 }( V! |- e2 E+ z
{
6 M7 R0 H! n2 A0 r9 g    if(S.top==S.base)6 e7 ^4 J8 S# S
    {
2 Z5 e. y5 {9 r; D, A& ~$ L        printf("栈以为空!");
0 q  A! S& h2 j1 A) D) `* z        return -1;
( V2 C4 G, l! T) n+ d8 C% g    }
6 O. {- `4 ?. y0 k' v    e=*(S.top-1);0 |8 A; a5 n3 A
    return 0;/ G( @9 p) |. M$ n
}
9 @- A9 @+ ?+ d) ^+ W  E5 C4 C  z- Y/ @) _2 _+ S
int Push(Stack &S,SNode e)0 k) c2 }, C, A# q3 ]& r1 }0 x4 o
{
7 u1 C+ q/ ?3 A% A1 R( s! t    if(S.top-S.base>=S.size)
; p, \$ C+ _- o    {
( M. z6 a- V0 G1 K. ^        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
1 z3 i/ l% O7 x/ d3 V$ L        if(S.base==NULL)
( Q' R; B8 D+ B/ e' \$ S        {
) A  i# L: g& v  h. y            printf("动态分配内存失败!");1 F( ^. A5 X1 p9 c( t: T
            return -1;
+ b' \4 O# A- u) J1 S        }8 s. \; h  N( p+ E  V/ a! T3 n
        S.top=S.base+S.size;
6 ?) L7 L# m6 \/ d  J        S.size+=APPEND_SIZE;
! m- Z0 p' Z  G) r    }) s) Z2 q+ c& C6 y/ O
    *S.top=e;
+ [* `  A- V! S; B4 [- }, H    S.top++;
+ `  B( H2 g: Z: I" T: q    return 0;
5 l  H* Z/ e# {}% v8 y- }" }. \! |8 n

7 p% O! @, V# Z2 ^int Pop(Stack &S,SNode &e)
7 q2 f6 f2 p) z' }" C, w$ S{
6 S9 U+ Y# k% y: f* I4 [% S8 b    if(S.top==S.base)
  j) Y2 [7 v# g5 `5 e* [- B+ I    {5 m# \. A% V4 J- {0 v. ~) l
        printf("栈为空!");
, `% Q5 p! o, M5 z0 Q# _        return -1;2 |$ ]' }5 p/ A
    }- m: L" i0 {! i" z4 W/ Q" f, F
    e=*(S.top-1);
7 f% g4 G* {4 t* e, F2 i4 Y* Z3 \    S.top--;
0 s% Y6 j3 i' _  q7 ]" e6 x    return 0;( Y8 J3 u& |5 S
}: Q* J7 g3 W: O3 q
; ]( B* x- G" [# K
char get_precede(char s,char c)6 G4 z+ n* o8 a) u% X- Z
{
7 [% l" J: |, b* v" r    switch(s)
: j6 a6 t: b, P: M3 ]0 `( R) m    {
! S# y: S- Q) k1 ^        case '+':                 
7 u& b9 x; z1 x9 k% S        case '-':4 r2 x1 ]' ?# V4 \3 Q9 c6 U
             if(c=='+'||c=='-')
' |) W3 i' q5 x: M, L  f                 return '>';
2 f  S. d* ]$ G0 {3 _- M5 A             else if(c=='*'||c=='/')% q' x" @* T* v5 ^; _, Q# P
                 return '<';
9 h7 A7 G2 O2 b# e3 h9 T             else if(c=='(')5 H) H0 K% L* Q( L( F7 o
                 return '<';
5 w; q# t# B+ n! T             else if(c==')')
& @  M  ?, ^6 Z/ A& D) M1 q                 return '>';
% g' P8 p! K  a7 v# O( S! l+ t             else * u( J" U$ t( L. ?9 u* P" B
                 return '>';8 B. \4 T# R+ k. n7 b/ i, b  _
        case '*':2 _1 R' n5 q5 w: e* c+ o; }
        case '/':
9 M. R$ T9 B; J# c$ }- c             if(c=='+'||c=='-')3 Z- j, f" \+ ?- Z. \
                 return '>';
" p& U- r" X  H) c+ M             else if(c=='*'||c=='/')
: F; j! h  i. i' y% _                 return '>';
2 l& ~/ J% }# R             else if(c=='(')* c, t' U9 @1 k: a
                 return '<';
/ n5 q9 z6 E. M7 N             else if(c==')')4 I$ I$ t8 V/ X- b4 E
                 return '>';  A' O4 g4 M1 z  c( @
             else
0 C9 A9 r+ O% J# m- o& E                 return '>';
0 q* `+ @6 o% S        case '(':
1 N* H9 \1 \3 N3 c* N+ N             if(c=='+'||c=='-')
) Z8 A; K0 m7 P2 }. t: U: ^                 return '<';3 v* m0 ?3 N- q
             else if(c=='*'||c=='/')+ {3 n, f+ Y$ Y/ x( y
                 return '<';
8 z" ]2 J& Q. q  g" @! E. j             else if(c=='(')7 K; u1 c6 V1 X9 G8 |0 H
                 return '<';
: s, G, Z" i$ Y/ s% Q) @5 v" ]             else if(c==')')4 w; |9 o& F5 E. P, h" C
                 return '=';
3 k8 c' s+ t# L- P) _2 `  _             else
% s" Z# O- L2 I) z4 G3 X                 return 'E';' G/ }3 V: k* Z  |) K& h) k
        case ')':0 Q, I3 v: _/ q, S+ B' G" `9 G! z
             if(c=='+'||c=='-')
) H+ t) F- J' }( h: e* ?% `+ Q9 B                 return '>';( D3 |+ _; Z& P4 d6 j3 |+ q
             else if(c=='*'||c=='/'). ?& o" ^2 F9 \0 B7 w# L( G4 }
                 return '>';/ ?/ j. u: x' m6 f' A0 I
             else if(c=='('), R+ a" N2 m& E; w7 I
                 return 'E';. ]% I2 l8 t% [4 u# `, a6 i
             else if(c==')')# H6 |" p0 K' _' e. {% O/ z) \
                 return '>';5 `9 e  U" z* j! N# Y
             else: ^5 H, S/ _# z% ^/ }% v
                 return '>';% M5 N1 f( c9 X8 ]# Q, Z
        case '#':' Z% W% r' l( Y# c8 d3 w% t
             if(c=='+'||c=='-')
6 |( M1 |+ I, |9 M, I; k                 return '<';
7 ~5 z1 a: _  ^- l# j# i$ _             else if(c=='*'||c=='/')
) y4 ]* k6 H3 F0 G* o' j                 return '<';
6 G9 F8 V* G0 _: z% h7 V             else if(c=='(')% x6 l& u2 Z) i  n$ X1 d8 h
                 return '<';
, C, s" Z4 b( \             else if(c==')')
0 G8 ~( Z$ A6 c6 B4 Q' G                 return 'E';9 g0 r" r  u" h4 K9 O+ k/ {* s
             else' Z9 ~" Z) R  v  y8 E
                 return '=';- D: I& a! `& b, d! |* h) s1 y
        default:2 v: G5 w) `, ?6 X& L
             break;0 ~1 b, ]# o' g, }, v7 I) M
    }6 v: j3 S4 Z7 G% [$ C
    return 0;    0 S5 V9 [8 b8 M
}0 G/ c+ G5 \3 r- J* P  z

9 d$ `) B  e; C+ F1 ?$ O) oint isOpr(char c)
  g& E+ E+ z0 O{
! R0 d% s" P- ]    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')0 q4 [- @% k3 q  e/ |, M
        return 0;8 v% H+ m! u. ~* F
    else ( p5 x: {. `. W1 o* T  I" t
        return 1;
' X+ C" U4 m/ W. a& s( ^) y}: {  T. W# ^$ l" ]/ B7 @  M

$ P$ ~  P1 R6 ~0 u0 P9 jfloat operate(float x, char opr, float y): q0 }: Q+ d* m( a
{- j; H1 T: M% s' v9 f/ e. i7 s3 p
    float result;# T9 w; N7 ^: A; ^1 H! ]4 I" l
    switch (opr)
+ I8 Q7 g2 L! R    {  G. [# [4 K6 g' d* c1 J$ j' i
        case '+':
1 p. L) Z  X; R; F; B5 C1 d             result = x + y;0 q( r1 D4 [. }# @6 |  |- S
             break;
( h. C. B. y' X! p2 P/ B        case '-':
( g4 D: e0 Z6 W8 R/ D' t8 V             result = x - y;$ D6 B/ i, N  [) e  s' G( o9 s* m
             break;
: }& K. b' t( W" n6 N0 R" a) A        case '*':   q5 ^7 R; d. {' U3 }( O: z
             result = x * y;
& L( b! t( N' Y7 w             break;
# N* u7 ^* ~5 R8 ^. F4 B        case '/': 6 x/ `: i8 }  M+ ^# |1 B
             if (y == 0)4 Z/ V$ T( n5 ^+ U. }
             {
2 @( d, E% S0 m5 f                printf("Divided by zero!\n");
4 ?1 U* j" `9 a3 O  d$ \                return 0;3 S9 M2 T0 |8 H
             }
0 X: k: G( b+ W) s. @             else  w/ I# D& p: x$ d/ }1 Z
             {3 u6 {  B& X9 M- {# t8 H' o. K
                 result = x / y;
0 x+ L" l9 D& r0 O8 a# ?0 t2 r                 break;7 J% e7 o+ v5 `7 c( I3 r& t
             }
$ h6 g; u3 w" W7 ?! N4 B       default: 1 C$ K, y. T* S) z9 p. f- ?
             printf("Bad Input.\n");
& G# l% p- |5 D+ O4 ^7 H             return 0;$ Z( l2 e- d; x; @7 I% t/ A4 |) b4 N
    }& B) a* J2 q  X
    return result;
9 y. h2 y& }( ~}    8 t' x! D& f) n4 m( t
: k. b6 K6 P) T2 p2 r" m$ F
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
0 l) e- T' ?5 F: @* w( w) a& x0 ^{$ D8 t: W. P6 ^- O( d/ F* @/ t
    Stack optr,opnd;' i1 J6 g5 n1 a& x
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
! |- k0 I* J+ Z# I    char c;% ~- P- n/ P" O& X
    char buf[16];4 |4 y6 }. t( r; ~. N. y: s2 Z! {: m4 _
    int i=0;
: G# y( q7 d% k$ D4 L$ @) m. _& Y& M    / z: S# z2 A! R# E$ e
    InitStack(optr); /*用于寄存运算符*/
' P: R& K' X% p1 X3 _# f. x    InitStack(opnd); /*用于寄存操作数和计算结果*/
  J. r5 x5 i. V& O1 C8 u/ U6 l# g    memset(buf,0,sizeof(buf));1 U. ?9 `1 Y' i0 Q1 Y8 S! k
    ( w9 \- Q. S3 O
    printf("Enter your expression:");
% ?4 C" @8 N" f3 f' m        $ d* e8 ]/ U9 Q
    opr_in.ch='#';
1 ~9 i: q2 {8 y/ m. x) S- ~; I    Push(optr,opr_in); /*'#'入栈*/
! G& W/ [7 y+ s4 e1 o# ?    GetTop(optr,opr_top);; |7 P  C8 |7 n2 e8 {
    c=getchar();6 D, d4 d9 n$ }4 [% g
    while(c!='='||opr_top.ch!='#')! s# C) F+ A  V9 c
    {
$ F, k! k  `1 Q7 L  B* l& p        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/: a8 `0 @# ^5 d6 B: A- U
        {
5 f, f, x' |* d- u; {/ M5 |            buf=c;; l; k& u. r2 Y7 x6 D2 A
            i++;* z) ^4 W5 y& M" _7 G# O
            c=getchar();
) C1 I' W# H5 ?; T6 k0 N& G        }
8 X! [0 ^) v/ C; V- j        else /*是运算符*/
; c* _- J/ a+ b        {% z5 r7 p+ `" T! Q$ B' i' G
            buf='\0';
, U  W, o' W: `            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
+ @' z, ?; _4 R8 s) H            {
& V, M5 U" H6 a- M: G2 S( S( i                 opn_in.data=(float)atof(buf);
; u* C' m( E( U$ W                 Push(opnd,opn_in);
# W+ z6 q! g0 T4 c  v                 printf("opnd入栈:[%f]\n",opn_in.data);# E; A  n5 g" y; M! ~
                 i=0;
# t7 {8 C+ m0 t' w, q                 memset(buf,0,sizeof(buf));
# U4 g4 `4 [$ Z: x; l! I            }: B/ y" O$ d7 }5 B% `
            opr_in.ch=c;' M7 ^' N5 e' e2 _# d
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/: P# u$ f& R1 o5 d' M* v7 R; g" Q
            {
& L* p9 w7 n* j                case '<': /*优先级小于栈顶结点,则运算符入栈*/: u8 s- S1 R& j+ Y) x
                     Push(optr,opr_in);, K" j3 t0 a/ ?9 R% [! m; D. c
                     printf("optr入栈:[%c]\n",opr_in.ch);& U4 C, z3 \) U  K3 {; y
                     c=getchar();. I/ O; `, R6 e5 R7 f! T  Y" k+ d
                     break;
6 S! U! m# o: ], d9 W/ T0 [                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
6 L- I) c6 V7 V2 V                     Pop(optr,e);
* [% u( T. P+ z+ u$ t                     printf("optr出栈:去掉括号\n");
3 O/ H4 |6 W2 R& I  T- ?                     c=getchar();) R& q/ f/ A  u4 A  P
                     break;/ I$ `0 l3 K! _2 h( V' f( N
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6 F4 X2 A! W/ ]( s" o                     Pop(optr,opr_t);
4 D% \/ y! Q! M0 s* m                     printf("optr出栈:[%c]\n",opr_t.ch);
( |1 I, u$ ?- Z0 }* f. Q3 T1 Z                     if(Pop(opnd,b)<0)
! W* d8 D7 |' g/ I3 \0 Q! U! L                     {" g0 I! r6 P- o1 f" K5 a& [! x( N( l4 }
                         printf("Bad Input!\n");7 w" Q: ]2 o7 z& o; {
                         fflush(stdin);
6 V: b$ ~% x6 o" U& @( q                         return -1;- Q9 q- ~* a! u( E& v' p
                     }1 R; g" A! J* K' R! e
                     printf("opnd出栈:[%f]\n",b.data);" w# u, H; r2 P( p4 t( J: q+ n2 J
                     if(Pop(opnd,a)<0)
- u/ B+ l7 \. z( ^2 b, r' W/ A9 ?                     {- d+ y6 |% _( Z; S
                         printf("Bad Input!\n");
; Q# T1 h: X0 _  Q                         fflush(stdin);
; q2 b5 @  f8 I) l' Z9 c: m                         return -1;
! d+ i  B4 a- F( U1 o3 f                     }
3 o1 N. G" p) V( P                     printf("opnd出栈:[%f]\n",a.data);2 p$ z2 G( E4 Q; _# `/ G+ k/ @
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9 ?9 i$ Y3 G) t# u                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
0 W& @+ \6 F5 o; A; n                     printf("结果入栈:[%f]\n",opn_tmp.data);
4 s2 Q- ~8 N; P$ ]# f9 K                     break;9 ]8 {/ m6 U) [, f. r$ b7 ?
            }
! Y, A. [7 `) Z) Y0 C        }
  d& N' s+ u4 u  X- ]' ?3 p        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                + q9 L; F/ _3 h! [! j* @! ~
    }
8 y2 J6 }. E  Y: B& P    GetTop(opnd,opn_tmp);
, x& \3 q# m) L7 v9 [    DestroyStack(optr);
  x6 T  f: V/ P    DestroyStack(opnd);
! x0 l; B: V& Y# O    return opn_tmp.data;
' Y" h- M9 a: V% G}- k+ j+ ?( m& \

+ j# W- a( S- p' dchar *killzero(char *res,float result)
2 m3 b8 _0 ?6 i6 K{/ u% w! M) n6 ^0 Z% t; k( }
    int i;9 i( E0 I/ c2 x0 o  e- C- c

% ]/ z) `0 t& {4 N# U% X$ Q2 p    sprintf(res,"%f",result);; W/ m- U4 G$ V7 T9 C. B
    i=(int)strlen(res)-1;
: x7 _! R: U* b6 o    while(i&&res=='0')
! M5 Q2 W1 o! X( H, }1 N/ j    {
/ J; t% V, _. \) ]0 z' J        res='\0';
" ?' w% w9 c; v  u9 c        i--;7 n" h  u; s. N) L. O
    }
6 O7 P) z0 `/ y4 R; ~) o0 p% z1 g& E    if(res=='.')
  Z$ i0 b2 I' f9 ~7 |- ^8 P        res='\0';1 y& i9 P; F# E5 T- c
    return res;
9 P" S+ `7 i- }; C) N- L8 B7 b* s4 w}& P3 f9 f& y  v6 e

5 l% @( g7 T7 ~4 C1 A- C1 G& \int main()3 J1 \: u8 ?5 @' ]& F1 i' ^' v
{
& n- J0 P+ f- s( S8 P, @+ V' }- x    char ch;. }  L  y- n% z! Y8 s7 {% K
    char res[64];
: S+ Y( C+ F! O1 Y& w: E# N& g    float result;
/ e+ L" l& J7 L$ m' z    while(1)! V) j& @6 p6 y) o( w2 Y  e' R
    {" B1 s# E: x# v( I# M( R
        result=compute();' }9 y: w) e1 I7 i7 E3 K1 @4 A
        printf("\nThe result is:%s\n",killzero(res,result));
! ~$ |  [! C7 X0 J        printf("Do you want to continue(y/n)?:") ;
- U% g' u# o. @, G! m        ch=getch();
- q; M/ z4 F5 C2 h/ m; G  t        putchar(ch);# D* x# x) `4 _, H$ ?/ L
        if(ch=='n'||ch=='N')
6 N! {1 l0 u; \5 [            break;
' W8 ^$ ~* a  O+ i        else
! Z$ S' [  p/ ?5 [/ k+ g  s8 y1 {' Q            system("cls");/ w- n: _# @: ]- A
    }0 u! b- Y/ m2 O; e: E6 Q
    return 0;
4 O6 n! x8 Y5 T5 I$ ?4 K}

4 w* j2 \9 `6 V- `6 p( G- B* E, F  [# l
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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