返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
8 {& P0 @/ |) P4 e* w! W% [/ Z程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
; l/ }( T0 N4 h! b: j0 c+ A/**************表达式计算器************/
2 Y' t, R& Z, p  j+ y, e* @/ A: k% ^#include <stdio.h>
( H$ \: X6 I8 d9 [* ^% z7 M, d#include <stdlib.h>8 F. t8 P; k& Z' C
#include <string.h>
0 I+ q; C2 ]! ?#include <conio.h>  f) a. C) i1 R: i
#include <malloc.h>
0 Z4 R! B- @" O5 h$ @5 w: e. M. @
#define STACK_SIZE 100
* h) k, `: Z4 _3 ~' r$ B#define APPEND_SIZE 10
; y' G% w8 Z) p9 \) J6 P
6 ^' p, _: W1 z' fstruct SNode{9 Z" v: |/ s+ P
    float data; /*存放操作数或者计算结果*/7 p, M9 p9 o* K  |6 W
    char ch; /*存放运算符*/
3 [+ ]" A4 }0 d- g1 \};
0 r% ?0 ]3 i# g: |8 h7 X5 n7 N' h" o- @* n0 ]3 S! r" }0 r) O0 h1 ]4 F
struct Stack{5 y" c" C; U! K
    SNode *top;! |6 j. r8 c6 }
    SNode *base;; u6 x( g+ R, T! p
    int size;$ W4 w" w2 f9 X' w9 \
};6 p" C1 l0 p1 V# N

1 T$ ~# z' x1 z. p  M4 L% h+ ]/*栈操作函数*/) n- d9 L/ X2 t- {0 }# E  W7 Q5 Q  q
int InitStack(Stack &S); /*创建栈*/, \0 n) `2 D1 o, J/ {
int DestroyStack(Stack &S); /*销毁栈*/
2 s# I" [+ Z" Q0 _& |int ClearStack(Stack &S); /*清空栈*/
3 f8 {  V$ f' O8 [6 Z7 iint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
6 C0 v" ^# q3 L# C+ D" r5 y( |. `int Push(Stack &S,SNode e); /*将结点e压入栈*/" \" a% J/ `( l% I# L
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/5 R7 g' E% L, B* C  l5 E
& O" E2 v/ a  P0 T
/*表达式计算器相关函数*/  E2 ^0 y9 ]7 w% r% d, z1 G+ ]
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 J0 X# w8 _% v# T& _: w+ |( jint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
0 }8 z# _* x3 q. i7 u. ]% U/ cfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
  j+ t9 B. q& k. _, Qfloat compute(); /*表达式结算器主函数*/
1 f  W8 n. C7 a, k0 ]char *killzero(float result); /*去掉结果后面的0*/
; I. i6 W$ E# M- h; @4 ?: x& Y% Y6 O9 N' }
int InitStack(Stack &S), U- R# J4 R1 J5 d/ @# E0 J9 g/ q
{! B0 e6 f+ _7 k5 e1 E3 b& W4 Q
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));& R5 c: }6 V! [- }
    if(S.base==NULL)$ _& K: ^+ E, C- J
    {! I0 Y0 w, t, A9 Y3 ^2 h/ b4 x* l2 X
        printf("动态分配内存失败!");
, L- |1 F& @9 L        return -1;
  z4 M$ V1 B7 ~8 j0 K6 {    }
! G/ ?. [3 D4 f! ?3 Y    S.top=S.base;. M& \. k  M6 t( `
    S.size=STACK_SIZE;
3 T/ G0 W# j( }- r/ E- m3 t4 }    return 0;
" ^) G0 O/ w$ l2 [* c, r  s4 M6 I}
. {6 K+ O) i; v- n1 d5 v+ c/ |: `0 m4 `6 z9 D) Y
int DestroyStack(Stack &S)
3 T8 q9 F  l3 G  d$ W{. z: _& N0 ^$ c2 F" j7 M
    free(S.base);2 z1 U5 N+ V( s$ i8 N* e
    return 0;
' j9 m4 W( ^% C0 A& o( n}
0 M6 t4 w! _8 a4 i6 m  R
6 H, j- M2 _  nint ClearStack(Stack &S)$ x  ^9 P8 j& q, U1 ?) G- s- G4 G
{
9 ?, `1 Z6 T+ W0 e& P& ?0 F    S.top=S.base;
. j7 m1 ~2 k- _: K6 f! l    return 0;
& e- ~. J) R1 ~- x  B/ |4 }, Z}  T/ B  @$ M. z) x8 d; T& g: h

2 W5 `" |; S8 ]  N/ q' yint GetTop(Stack S,SNode &e)
: e# Q8 D1 g3 E0 n{# C/ V0 B# W8 h! w; ]
    if(S.top==S.base)
, L; z* I  O6 l( l2 ^2 C    {& ?2 E5 P  w& d2 E* y
        printf("栈以为空!");, U. x9 N$ ^+ l" W+ b: r
        return -1;
4 X# y+ s: {* a: q1 J- F/ F& [    }
7 i6 x5 x. L7 Y+ @4 z0 u3 I    e=*(S.top-1);
7 A$ m  g% I7 o5 `    return 0;% u( }. ^5 z+ v8 B$ S
}
! x& k: F9 E7 Q: r- I5 q* Z
$ h$ }# K: C* c0 Vint Push(Stack &S,SNode e)
4 L2 p! _  h5 ~/ D/ U{
0 ?5 p% p, a. D, x3 z) z8 i    if(S.top-S.base>=S.size)
) `5 f1 S0 b8 g$ J8 J( n    {
6 v5 B+ Z( \& N) Q  v        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
  E6 w0 s$ u; [9 H' D8 M        if(S.base==NULL)9 G' Z/ z5 W& r* `" e/ ^1 Z
        {3 r0 _# y: O# E9 V5 o
            printf("动态分配内存失败!");+ [* P" P# Q. t9 F% l) j$ v
            return -1;
" \! \/ Z5 J3 v        }
$ f5 }7 G5 D- W1 k        S.top=S.base+S.size;# y" R0 A! T  Z) ]  |) d
        S.size+=APPEND_SIZE;9 j4 E9 h/ y6 ~5 M
    }
+ a2 Y( ?+ P, ?$ R; {    *S.top=e;" h) o. S4 y4 l$ |1 S1 Z* \
    S.top++;# W  e& j4 T+ \+ W
    return 0;5 H; s3 V: j8 G. r+ L( A* F$ s
}* l* \0 J+ c1 r4 K
9 p" b+ X* N2 y4 t' [$ G
int Pop(Stack &S,SNode &e)$ m! }$ x% w6 _
{4 L% M# j! d0 a+ q0 X- z5 g/ r. c
    if(S.top==S.base)
% C( `- N: h# ~" a) D# G    {% r+ O. c3 m9 G8 o# \
        printf("栈为空!");
) ?3 C4 q, P$ c" W% I- R, `        return -1;
( K. |& F1 I/ S: d1 q; U, K5 M    }
: l/ y( ~1 l+ |! U    e=*(S.top-1);
( Y, t/ H9 n0 v3 A/ R    S.top--;
9 j( n, t4 s! l3 T2 B' q+ @    return 0;
$ m2 [4 }2 s1 c) Q+ e+ H}0 a' G! ]3 g+ C
2 d+ @+ L$ R- N) H2 d) _: [& k
char get_precede(char s,char c)
. w7 y) o, l' I2 h9 V, j) X{
( |9 I5 z' _* |$ Z) E# h    switch(s)% `  i" F7 h. Z% A1 N  }
    {
0 I, a. W* \: i1 E3 K6 r. \: }        case '+':                 # o2 D, T/ h2 \- p) F# T
        case '-':& c  R+ S5 u' i6 n) C
             if(c=='+'||c=='-')9 J& s: i! m! z4 B
                 return '>';# a9 E# F: }; J. b$ x
             else if(c=='*'||c=='/')+ A, S7 k5 k( H3 s- M, `
                 return '<';: m- T$ S* {0 k
             else if(c=='(')  ?4 d+ L3 r- C0 K" R5 U4 b
                 return '<';
( z0 [3 N! f+ @4 `( U7 s2 @+ z+ q             else if(c==')')
, z( ?$ v" K' B7 s  c1 u1 ^                 return '>';
/ c+ b; U2 T. V: G; {             else ! @/ X7 I( }: a% k8 w/ R
                 return '>';9 g' \0 Y, K* L9 O
        case '*':7 N- R8 G$ T8 O$ b" ]
        case '/':+ D. F1 ~6 }/ R7 u8 Q7 t; N8 c- W
             if(c=='+'||c=='-')/ |9 f$ ~* L" A$ V! K
                 return '>';
) h1 o; S# ?- u9 Y% j* y             else if(c=='*'||c=='/')6 @* B  T: X& |" t2 e) z6 {
                 return '>';5 A* @; V/ e8 V6 ~& A: ~" t
             else if(c=='(')
& H1 F1 R& u+ L; u                 return '<';/ K9 C' z$ G' D5 t
             else if(c==')')7 X) ~7 K4 S' k) }) Z; [
                 return '>';# n) E$ \8 m$ x- W4 s2 }
             else
4 m7 i6 b& d* ^3 _                 return '>';" i' Y+ F( O- y1 e
        case '(':8 D. N% A& Y, z: e. F9 Z
             if(c=='+'||c=='-')0 Q: k. i; q8 o' d  x5 h/ n
                 return '<';% B; p; q1 V$ E0 V3 n+ O8 p
             else if(c=='*'||c=='/')
2 b5 f0 |: q9 b- Z                 return '<';
% F8 g) b8 k' B, R% U             else if(c=='('); N: G$ ~, N5 a! T
                 return '<';
9 b( t/ V4 _$ s( Y/ p             else if(c==')')
* i  ^5 U8 \  P3 y1 X1 t                 return '=';
/ C* y# V# U' n0 Q/ l( a             else
1 L( k9 b; {: S1 w: f0 L                 return 'E';
8 L+ c) K" E$ ]2 K3 X9 i        case ')':$ s' P$ @7 p+ B! H7 I! u
             if(c=='+'||c=='-')
% e. Y  Y" f& R( _. Z; ?5 ?  k& ]- W                 return '>';- u, l  ~! ~1 Q& P
             else if(c=='*'||c=='/')
% k, F+ }1 @4 D- z8 a  E                 return '>';4 n3 V% u6 L6 Q: L- N+ A
             else if(c=='(')
3 D, Q3 k  k  A3 g                 return 'E';
8 N6 J+ A6 F4 Z7 e0 M             else if(c==')')) y/ R, n! y, v! f0 L
                 return '>';3 b' h  C: h' }" Y
             else- t' g1 F  e% E2 b/ Y% ~
                 return '>';
4 `! p% D; {8 I" J) u" V        case '#':
8 I  H# q4 j0 k2 a, _0 p/ `7 N5 Q             if(c=='+'||c=='-')4 j$ t$ a3 F1 i/ C# ]) Z9 O
                 return '<';( N# `4 U6 Q5 K: {% F* F) _
             else if(c=='*'||c=='/')
2 ]- Z" ]* z, [7 v; K- ^+ g  |                 return '<';
& C+ p; a- N: p2 @" P" G             else if(c=='(')' P- H% B. V* ^/ k6 Z
                 return '<';
( V1 g, @8 F& m7 D% v             else if(c==')')$ P. f6 u7 E0 _. O, n& R
                 return 'E';; R( a0 R2 N8 J4 i5 a
             else# i; s& }- O* T4 a8 e/ O, S
                 return '=';  b: |, R2 |% i; j- j3 k! h
        default:9 y) w) \" u- N! d9 `
             break;
+ [6 e2 ~) ]3 f( P. b" x; u    }+ A7 H0 x+ _( X% h, L9 G5 X( F
    return 0;    & Z9 s6 [  s! T& ?! A7 \
}5 R9 L2 [( [8 z- L$ [

8 l: J. I. `% O1 f9 ~; Lint isOpr(char c)9 F( X8 \9 h4 }$ X- H: L3 Z% u
{
) ]( C$ M6 c6 D! Z    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 v' {6 X' p3 U, P. u8 h, q( h
        return 0;
/ n% f+ B# G3 r/ D: F7 }  O, C. ~  M    else
% s) w7 J/ v/ e& S* _! u        return 1;
# X9 L) B- L' _/ e' O  i}
4 L8 a0 u+ d  K; n) k: R
- v( ?" z+ r# U! e7 ofloat operate(float x, char opr, float y)
. I  D7 K) z: N8 `4 I+ d{8 {# d+ Y$ S6 ?& Y
    float result;
+ D& C; u+ r/ I2 O7 V  B# I    switch (opr)  B0 T  \" k& B
    {$ @( K- w; u7 f, q" o) S4 U1 K
        case '+':
+ w2 [1 K5 I# {$ x             result = x + y;2 a; z5 g4 S8 \/ J, u: }" N6 A; w
             break;
3 o/ d5 W; X! ~! d* C        case '-':
/ d  w8 b: s( z# P' ]. Q             result = x - y;
" g8 F4 g3 J: v& T+ T             break;
& y& O5 a4 U4 x, q9 Q        case '*':
% M% f7 Q4 \7 `             result = x * y;
4 L$ O4 e( }! p; y0 g             break;
7 @% @( [& B4 t# r+ p. E        case '/': " B6 x3 q! l. d1 N
             if (y == 0)6 @* R4 [9 l5 O( t
             {
/ h, ]& I6 N; |# \                printf("Divided by zero!\n");
4 _! A5 W7 A- E2 Q1 V                return 0;; M) J& u  ]9 s
             }
3 b" |' H) ]( ~  p2 n3 z3 w7 \: w9 @+ J             else
! J* n& O3 f$ H! \* d             {- [/ ~5 P- c0 u+ c
                 result = x / y;7 ~- }+ L  ^5 Y7 C
                 break;
) R3 z  e6 c' Q9 m; D             }
1 S6 g( O$ J% H# R& R       default: - _# K& w7 s, w" ?2 ^+ E
             printf("Bad Input.\n"); & ]0 Y0 M3 ?; f. p; D
             return 0;
$ ?0 Y. Y) F$ f9 d    }
1 _- X) N! L& z( N1 b3 `    return result;, P& C6 p& e/ M  {* |0 |9 @6 n
}    8 [/ r' k! c1 u  `$ |+ l0 |

* M- Z8 x0 H1 g- s9 U  ?float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/2 {* _: p: X: s* B
{
) ]: H- J1 c! _5 [& D* U* Z: K    Stack optr,opnd;
# U% Q8 v1 B3 ], B# `    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;: Q2 w% Y& B4 t% J
    char c;0 k; \) z* A) H* u( m- U& T
    char buf[16];
- i0 k+ v& z3 x    int i=0;# \! K' z* \& d6 v' E# [2 ]* I
   
& z  B5 y) d/ M& s6 R! y    InitStack(optr); /*用于寄存运算符*/
( p$ z6 q3 [' l; T" p& l    InitStack(opnd); /*用于寄存操作数和计算结果*/  B$ Q5 C% I4 T" }) e: U2 j5 B! L; n
    memset(buf,0,sizeof(buf));+ _( b; ^4 L9 j! Q
    6 Z- S' e: O" u6 W3 ^
    printf("Enter your expression:");! J( ], m, v+ Y
        
1 _% ~: O3 z  Y2 D0 s% L& }' }# \1 O    opr_in.ch='#';
# @& g* j  [, |8 W8 a3 [6 C    Push(optr,opr_in); /*'#'入栈*/8 y) W$ D! R" H; H
    GetTop(optr,opr_top);' H& G2 Q: n- L
    c=getchar();, h$ i# ^4 l0 b( U
    while(c!='='||opr_top.ch!='#')4 [$ ?+ {& H" C4 T! B
    {$ B0 b( x  P3 R  j2 E" `
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/" m0 |2 D3 j$ d" R4 w) T
        {+ o2 E( V. l5 ]4 c, U9 j2 c
            buf=c;$ |! G- s- q8 a! ?7 B" {& e- j
            i++;! F& Q8 f. O. E$ F' ~/ i
            c=getchar();( f- V) N  t6 X7 L
        }
4 U0 e$ Q" C2 F! w3 C9 Y6 n        else /*是运算符*/
; ]0 S" f! E$ v- U' `        {& @! Y, h/ H/ J, Q
            buf='\0';
5 J3 x7 N- w6 l. t7 W            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
. r# v% \8 I8 T2 x9 ]            {
/ \. [: k3 B2 x$ ^. Y8 R. R                 opn_in.data=(float)atof(buf);
( M7 \) I: G1 e                 Push(opnd,opn_in);
& U3 R) q. a: i( A4 X/ W                 printf("opnd入栈:[%f]\n",opn_in.data);, M" Y3 Z  U5 |# {
                 i=0;
# w+ k1 |" I, M5 y! G% ?                 memset(buf,0,sizeof(buf));
2 B4 }; ^- F+ y) r$ C% X            }
9 ^& ~5 k5 L) L" N            opr_in.ch=c;" r  ~( u  h1 l0 I. @
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
2 Q: l4 f3 W: L& f            {+ c% T/ J  K7 m* `" e) Q
                case '<': /*优先级小于栈顶结点,则运算符入栈*/) e4 R7 |: l; V6 b9 ^  v
                     Push(optr,opr_in);  d% D% f0 I' r
                     printf("optr入栈:[%c]\n",opr_in.ch);% W$ D5 j/ Q$ t
                     c=getchar();
5 s( C; X$ g( A* A                     break;- U/ _7 j. f& s5 x
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
; A9 M- L% `+ U, Y! I  U7 V                     Pop(optr,e);
) {5 y  |0 j8 j2 g                     printf("optr出栈:去掉括号\n");# p4 n' D$ s- `6 t
                     c=getchar();- t' @1 [( n1 U( k3 n) w( W8 ^
                     break;
) G3 i% J, [( i2 v7 W                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
: ~( e, c6 R# ~* z/ T2 z5 f                     Pop(optr,opr_t);
8 Y6 P) a9 R; K( Y: C                     printf("optr出栈:[%c]\n",opr_t.ch);3 U: p  r3 X7 ?% o3 X0 ^+ }
                     if(Pop(opnd,b)<0)  y9 q5 j& f0 M7 q
                     {6 j; I5 J- i- _5 S, l2 L! G8 q
                         printf("Bad Input!\n");! R+ ~$ r+ ^4 E8 i0 d6 r( u
                         fflush(stdin);; B  w7 c! t5 C% V$ `
                         return -1;* R7 [; t! v4 e9 H* L
                     }2 O& Z! U. b+ K% n: _4 q/ n
                     printf("opnd出栈:[%f]\n",b.data);; N9 ?$ c2 j; F% p
                     if(Pop(opnd,a)<0)
8 s9 a6 m2 f6 ~                     {2 Q' c3 H) M3 `( }$ T! T6 K
                         printf("Bad Input!\n");
/ Z% Y: O! d4 @, x                         fflush(stdin);
( F% o" r% F" F& K9 u- A                         return -1;
# N. z% A/ S" l                     }6 v4 ?6 w# a: d3 B
                     printf("opnd出栈:[%f]\n",a.data);
( _. V! C+ c1 l3 H8 Y9 r                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/7 X- L* V8 e/ k8 z" o
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/( o  J7 I& [  B
                     printf("结果入栈:[%f]\n",opn_tmp.data);
+ S( E& r9 `1 |6 n/ Z* H0 Y( z                     break;
; X( ?& L$ U& I) v1 o            }
' s, V" h8 j. L        }
) H& {1 z) n2 ]4 ~% l* l* D7 z        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                + \8 A: Z- V4 Y& a7 I4 O$ f
    }: t9 s+ M! H( J9 c
    GetTop(opnd,opn_tmp);3 r3 e" v& U+ Z
    DestroyStack(optr);0 ~/ x2 E0 G8 O3 v0 O
    DestroyStack(opnd);
- o/ \0 V2 a$ P+ I' T    return opn_tmp.data;
( k" l$ z' a% e% L" E) `% n* @}8 T& O& J; ]4 }" b( P
$ [7 t& Q; C- Z6 w
char *killzero(char *res,float result)
4 ^# M2 p! R& Y( f{
$ ~# v- ?' }$ _) T% l    int i;
; R. I" L" M  f8 i) h8 [. o5 C8 L, O
    sprintf(res,"%f",result);. a; m* X' i2 Z! g, I# O
    i=(int)strlen(res)-1;
+ D7 ^* ~0 ~$ f" c" q* B! O0 F1 t    while(i&&res=='0')8 }0 V- o8 i. e
    {- I9 m0 G. V& X$ b2 x
        res='\0';
9 Y! p) k' I& m        i--;
6 Y3 ?+ k5 S  p& g8 `    }! u; F+ l; `/ l+ u
    if(res=='.')
3 T' K$ L& q  i* U. f4 K8 V# F        res='\0';$ N5 z# _7 c1 u" H" E
    return res;$ G# Q  c/ a0 E: E$ O6 b2 p) ~; j
}
& c7 [8 V# A+ Z5 h( E1 j  ?1 @7 r' q! ], M! k. ^% `+ ?. Y
int main()# \8 N- N% I) `, O
{
! f7 f4 b8 e4 }) K    char ch;
# W0 G  M: Y( ~. c  n7 J    char res[64];
2 X0 y8 C" f3 a0 B    float result;
8 A) \7 }8 y' V5 R: i& s$ ~    while(1)3 X2 A2 K; O7 a5 E5 f; \0 n
    {+ @& P8 R/ y" E5 a0 j8 V" f
        result=compute();0 W9 ^8 p, O( i
        printf("\nThe result is:%s\n",killzero(res,result));
# l! Z9 h/ j% _9 I1 T. y1 B+ j( K        printf("Do you want to continue(y/n)?:") ;# l+ y2 e+ [* H$ s" W
        ch=getch();
. C; ^* V) k; @+ m1 i        putchar(ch);
0 y% E/ _! F9 B* Z& f) O( @1 u        if(ch=='n'||ch=='N')
4 w% e# [6 t& ]. M# ?( Z            break;
1 Z8 i1 G; p8 J) ^5 J) [        else
. Q' I2 e4 ~: c            system("cls");: g/ z: @: C& r, |* |8 V
    }. q3 R! h; p7 n/ D- T" H1 Q, f  ?
    return 0;0 q/ u* U1 b$ k: z+ u
}
& ~: o) x; `3 s) a& X) V! A5 J
7 p. o% b$ J7 a, [$ [* k
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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