返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
/ F9 C5 `' u; v7 U- D4 }程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
. y' B/ t( t3 k4 e1 J% {& W( h/**************表达式计算器************/
5 U$ ]$ ^6 a( H$ z#include <stdio.h>
" L& ^+ v6 O4 r' y3 g& k; k#include <stdlib.h>
! H  `1 K+ A. W3 r' F8 `! [( K#include <string.h>
- }2 O, c2 f0 a4 y8 e4 C9 J) F; z#include <conio.h>
* F$ a, Y$ v+ Y+ m#include <malloc.h>
2 y1 ?! i8 D* U5 K+ J* Q
( |$ A; }# g2 s! H1 ?#define STACK_SIZE 100
. R. X4 r2 p1 X+ |) f#define APPEND_SIZE 10/ |' ]3 Z( I0 `' H9 a

# j5 ^* W7 @3 \3 D& @/ Cstruct SNode{
# F+ a$ x( R. T6 z7 X- j    float data; /*存放操作数或者计算结果*/
4 r) Z) `3 w1 P) S" S  C$ z( y    char ch; /*存放运算符*/
3 Q6 \) h2 e. X$ [9 t: S4 |# D};
' i# T  c2 v" [4 v3 |: ^( c3 n. ?  Y/ |4 n6 e# e7 j* _8 U
struct Stack{& ^, c8 I6 e* ]+ Y- T
    SNode *top;
$ J1 b$ E; K/ x; T" q% ?: h    SNode *base;; q! u; O3 d0 d0 q. j' q
    int size;
: U+ ~6 t, O% s2 G* u/ B! U};7 A5 e' Q$ a1 V6 C
8 x5 g8 n" v9 b, f. g5 m
/*栈操作函数*/; P7 Y) {" p, N' G3 y$ M7 @
int InitStack(Stack &S); /*创建栈*/8 u9 S9 \; a$ ~
int DestroyStack(Stack &S); /*销毁栈*/
4 I# ^* G) c( n. }int ClearStack(Stack &S); /*清空栈*/0 x' @# `3 v$ D  ]4 i/ v* W1 [
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/( S' x7 ~3 f  ?
int Push(Stack &S,SNode e); /*将结点e压入栈*/
" b6 A" v4 i+ m0 q) R6 U+ F! m  ~0 Uint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/  P6 E1 E6 X7 V7 ^* p+ K$ m% A
; t# H" b% ^# N
/*表达式计算器相关函数*/
1 r, Q4 b* G+ G: T, B2 t6 a7 Nchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
$ C: E+ l6 Y* n/ ~- _int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/' ^; `. U! A# F3 t
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/, v$ L3 X4 [; J7 m
float compute(); /*表达式结算器主函数*/
, j8 f- T" j9 m2 ^2 s0 T. s3 ~& R. Achar *killzero(float result); /*去掉结果后面的0*/
, z2 G) l2 k& j1 t( j6 Y
. K- R4 C, g0 l3 k0 Gint InitStack(Stack &S)
# N( c  E& ]! Z2 r) e{
! `: [" Z8 y1 @& |' P1 s1 ^    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
$ Y$ P9 d  y) g) z" ]/ E6 K    if(S.base==NULL)! z+ C2 x* U) Q3 `) G2 M# k# t. k4 N
    {6 k9 C1 M3 ]2 X6 A7 J1 h# S/ E+ h+ U
        printf("动态分配内存失败!");+ W3 b) J, f: ]9 g9 x9 i& u5 r
        return -1;( L. x2 I% D: D1 L6 S
    }
/ G* c: l. ]( O) S# ~    S.top=S.base;; A; r4 K* F7 l8 ~# H" K
    S.size=STACK_SIZE;
4 {' U4 k: Z! @2 t    return 0;
% o2 q( O+ K1 c, ?6 x# {2 a5 q, }5 p}( k  ?; e. X8 P4 H

! X: [7 S$ m. J! dint DestroyStack(Stack &S). r0 N7 l8 a- n  x" x
{# c& L) j0 R& q6 J. o
    free(S.base);
. o$ r" _7 [# L5 v    return 0;
1 B& A* S& i) f, z7 w3 Z}8 B% z9 w  S2 e5 T! m6 M
* p( s1 d# d8 k" d
int ClearStack(Stack &S)
& W+ ?$ P+ M) S" R+ O' w{
4 Z. [8 {/ i3 c5 E    S.top=S.base;
: B# ~% ]/ B3 N) k7 s. A    return 0;0 ~9 l9 K* L7 c$ Y6 w& d7 a
}
0 q& m( Q# u% f9 {% T( |4 a1 [! G/ _1 }
int GetTop(Stack S,SNode &e)
' K5 I5 t: p6 }: R* |! V{* E; S" O: G7 Q# F$ T+ t8 j
    if(S.top==S.base)" ^1 I3 F2 _' A- H
    {
6 E) V# Y( `7 g        printf("栈以为空!");
+ F8 ~  d/ `0 q8 b        return -1;1 d" A- c# V; R# j# p( l
    }
6 X- W+ @& K7 P7 z- d8 y1 W    e=*(S.top-1);
+ g. A! J9 x) t0 C, ~    return 0;
- i% d  m( _; A, H/ T$ x" X}6 G+ a2 j8 I% g6 R/ s6 Y5 F3 g8 N

# I' A# N, ?! ]9 Pint Push(Stack &S,SNode e)
1 p" b- X) X# d" X7 u{8 {8 {  U9 t2 \% M" v+ {
    if(S.top-S.base>=S.size)
/ n1 G6 |4 k' S! U6 _6 a    {
/ n/ t/ D# n5 N        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
, B- E' c7 x) m        if(S.base==NULL)
, M, V+ y& `8 V' p* h        {3 m/ S+ `, e% ?1 i2 i: n5 d& w- j
            printf("动态分配内存失败!");$ c- K4 b9 i/ B! P" t; i1 z" z. P
            return -1;% K" s- a( u5 a' k. s/ ~# s
        }
3 v: z. e7 `7 a+ E        S.top=S.base+S.size;
+ A. B4 H6 p1 S' v/ p- p1 C        S.size+=APPEND_SIZE;* o1 ~/ \6 G. L( @
    }* S: M- D* O- A+ a  T- p
    *S.top=e;5 H) k6 E, L1 K" x3 r0 r
    S.top++;0 q% R  V/ z& P4 Q6 H- {9 c7 _- q
    return 0;
2 T' K* n3 j; l, o4 |( R( l}2 V' c5 r' k% ^1 }

4 ]( d  z4 D" i2 a% ~$ `int Pop(Stack &S,SNode &e)
6 d& A, M2 A* f& g{
" s- d0 w) J# v    if(S.top==S.base)
+ T6 X% q: \6 z    {9 b8 w1 x; {8 b7 J6 V
        printf("栈为空!");
2 O' _' y$ F! v4 D        return -1;+ I/ L& m/ y8 Q0 H9 W$ y
    }
  L9 d8 R  E. O    e=*(S.top-1);
6 x! g& j' {5 J/ d. N    S.top--;3 t' `/ l$ N* G- p- C' b
    return 0;$ K* S/ B5 S  P# m+ P, X; l# [
}
* x" E$ R* Q( a: q3 F
. q# n9 z% u6 ?. n- Kchar get_precede(char s,char c)9 X& v, G) }9 M% V" l' K: I! }
{. o0 s& Y7 N" T
    switch(s)0 H  F; n6 a5 h0 |, n, A! v* g0 @' U
    {
8 d3 B0 @& Y: E/ O8 f/ k& y        case '+':                 3 K; g2 \* d% @/ o7 \4 [  U* ]
        case '-':
. `0 S; ]: s! m8 e1 j7 s; ?             if(c=='+'||c=='-')
* i, e* x) }) Y- f6 x7 i2 m% @: Y                 return '>';& U6 X/ ?) P% }, w4 f* k
             else if(c=='*'||c=='/')- D! O! D, C! i: ?  j
                 return '<';
7 }! r& \) P5 \$ s& N3 m! C9 y             else if(c=='(')+ i; [6 a! c& F+ h0 d6 R
                 return '<';
- `/ Q0 y$ W) w  |             else if(c==')')5 U, ?/ _3 d$ ^
                 return '>';
+ z9 C7 b! o# ^) y5 Y+ G4 Z2 ]- m, d             else " [$ @$ K# V  v$ ?3 M
                 return '>';
4 X9 X/ h+ T+ E+ Z3 J! K( r4 J        case '*':
5 u; X( |6 C- Q! r, P+ u, L        case '/':, K: X$ u* B* X3 l* E
             if(c=='+'||c=='-')
* I; Z2 J/ L2 N- c1 y                 return '>';: p. b/ A8 V& t  m) }& t
             else if(c=='*'||c=='/')8 |# r3 l6 v) t6 ?6 b
                 return '>';
5 Y8 b) F& S/ N9 d! y: G             else if(c=='('): R5 G! F$ w% _9 h5 x- X
                 return '<';
1 ]0 H# G% V# z# `* U% v# n             else if(c==')')
- J! d% ]9 k/ w+ v2 J( P                 return '>';. `( U* r; h) M+ L: R+ }4 l! t
             else
, w# e' q3 ?& [/ T& _! B                 return '>';5 X4 b! p; K" S% v
        case '(':! p- C' m8 E2 H2 x! {" {
             if(c=='+'||c=='-')
0 u" D/ c& I5 a2 B: J                 return '<';/ b6 c: \7 V4 I5 I# P- ~) m% H
             else if(c=='*'||c=='/')
6 X; M" o7 d3 [/ l4 _0 o3 k                 return '<';+ t/ U. m* t0 J% V( S( U$ _
             else if(c=='(')8 o$ B6 w- \& K1 \* Z2 ]
                 return '<';- B+ x9 D  @* _* x
             else if(c==')')
) j0 B/ T9 Y  I5 Z                 return '=';, X: l5 s( B9 }% v# f
             else- V2 O6 F# g* }1 p' Y1 B
                 return 'E';
  T: W+ I" a  @, [7 O+ `# j1 w        case ')':
% P; B$ Y( T: o0 Z$ u, _+ Y             if(c=='+'||c=='-')9 I, m1 l; s( m- B( O$ X) o
                 return '>';+ u) c7 {% K" ^6 k6 y" W4 ]9 D& H
             else if(c=='*'||c=='/')
0 x) L2 o. f; F( L7 S  C) r2 X7 U                 return '>';; g& c$ |, h: |6 W$ @
             else if(c=='(')5 f# G5 e. M5 ]+ }+ ]1 L* x& V
                 return 'E';: `( `+ e) G4 ^4 G! y
             else if(c==')')+ i+ u8 k5 [4 w0 [
                 return '>';! Z. @, x% b0 S6 u
             else
# A- @: A+ j/ a0 Q) E                 return '>';
0 a' [; c$ d1 R: z" u* k7 Q        case '#':; t2 V# I1 D: l" z$ Z8 `
             if(c=='+'||c=='-'); K7 Y7 G# l- Z: d6 }/ f
                 return '<';
0 A, w$ ]5 ~* ^- K- ^+ q% c( J             else if(c=='*'||c=='/')
: t* g: p4 z6 ~                 return '<';
: Q: v: _* H2 c. w             else if(c=='(')& Q% G, |/ r9 m- L9 \  G% t" F; @" D0 @
                 return '<';: P& m# y" a0 U6 X5 d& F; b
             else if(c==')')" t2 ?% C0 b* h% y2 I
                 return 'E';
! H3 e( |( ^" s" n             else
& {7 W8 S6 a' }. b                 return '=';
$ j. B/ h5 k7 T; S  x, {3 B  O        default:
* |+ G# b" x1 ^  H! }, P             break;" ~6 w3 G* W- |2 z4 @, j
    }- U- n3 V. D; i# x/ E6 B* m9 b
    return 0;    ( c9 H- h# O5 y+ t& m2 v4 s
}
9 j: V) z" c6 @3 ^" W4 r! G7 x( k9 X" `) G" H/ w7 n- n
int isOpr(char c)2 ~' u9 E' C. \% O$ M8 D" c
{7 q' B1 o# J9 r9 |
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
  B' ^! }1 R2 P0 I        return 0;
* c. Y, `( N/ I) M9 o, A    else
# I3 M" U9 E6 S/ ?3 i0 I2 P' z        return 1;
" t3 D8 I: Q$ q& n}
4 S6 K$ T* O, t7 O( }# A. e
. j% ~" Z+ F( Z' b  \2 Qfloat operate(float x, char opr, float y)
4 `9 x. o& b* s$ A8 y{* O, _  \3 R( Y2 G
    float result;
# t3 u+ N+ J7 f  c+ o    switch (opr)3 E2 ~+ ^, j" I. D1 \
    {# v7 q3 }% ?- y8 [: A! V
        case '+':
  E0 b' R: }( K4 ]5 a             result = x + y;! ?: n; }- D6 e- U0 x4 |
             break;  `! k$ G" w; S0 W$ v( r& J
        case '-':
& e$ c3 p1 [& _- a- N             result = x - y;
8 R6 o) ^  S& B2 u& k! \+ e0 c1 P             break;
& q! h0 c; i* r5 _% t/ E% l        case '*':
- x% ^  U8 y, B             result = x * y;, h. K3 x* I: [& z4 n( v
             break;
7 s9 [" o" D$ {* N        case '/':   x" Z6 v$ e5 Q
             if (y == 0)+ {+ r. f' |, Y, G/ W& \
             {" A1 i( A2 [- F
                printf("Divided by zero!\n");
( t' O0 D/ }4 a: I% ~+ r                return 0;' C: I. L. o! O; W5 H) d
             }- {4 O( f  j9 d+ u; o3 j  J
             else7 P% O% b+ O3 w* ]9 Q0 I
             {
* ]7 O4 F/ v; v- s                 result = x / y;
2 A( J& j+ c6 ~$ ]. o, N& V                 break;
, L/ S4 N* a4 D             }8 q% h9 _. n1 Q
       default:
6 v( B( I+ \% @1 i1 }9 D             printf("Bad Input.\n"); 3 R% M8 D  N( M! U. r
             return 0;
$ K7 M8 |# _$ n4 d$ Z9 y    }: \: K: |' {' x- b3 w' i% u
    return result;
; X2 P/ H/ |' q( J( x}    " Z' e* [# Q0 ^; ]$ g- w/ M

2 L7 s* A8 z% K! N9 W8 I' Afloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/# u# l! F( A& e2 H
{! O+ Y* {3 [" f
    Stack optr,opnd;( \9 F& ^' `# y& r& H6 c5 k
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;% ]  B5 g9 P1 q
    char c;  ?: C. t& j- F$ g, O! L2 c
    char buf[16];
7 B3 g9 _  t# U- B2 |6 y- b    int i=0;" z$ ?$ a- u2 J- }, R9 c1 ~9 x
    ; `# u- P% k% K- Z5 o
    InitStack(optr); /*用于寄存运算符*/
  e0 p: j9 Y% S& _    InitStack(opnd); /*用于寄存操作数和计算结果*/
% R# q, }0 ?" Q3 J5 t( ^* J    memset(buf,0,sizeof(buf));( k* q) G5 M( P
    8 u+ x# o/ W2 B- C) \% M" B
    printf("Enter your expression:");8 v( k! A; Z* [7 `4 Y! j
          N  e% |2 X  s( U. i: ~  R: d1 M" }
    opr_in.ch='#';
0 T- I: c0 x2 J9 G& G2 |+ u5 U    Push(optr,opr_in); /*'#'入栈*/
, N8 m: }0 g% Y6 X  h# H    GetTop(optr,opr_top);
/ {+ `' b6 Z& D9 n+ x    c=getchar();( l- @) `; _& W- V
    while(c!='='||opr_top.ch!='#')! ?7 _, f2 T, k* V: g9 r) x- C5 J
    {
2 a6 v/ u6 z6 q3 K        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
; o$ _- q5 e& t) `        {# V: {- s; I0 d( h2 a7 O8 Q
            buf=c;" h  X( R' ^* B/ k
            i++;
; _" f6 z$ M6 B9 S( J            c=getchar();$ f3 p: R7 {' }4 f7 a: \% u" ~: }
        }8 O6 u* ~/ H) ^7 z/ B
        else /*是运算符*/
/ P$ j7 Q; Y9 o, D7 i4 {( T( q        {
$ ~) |- v* v0 U            buf='\0';
4 _6 T* G% u- E. a9 Y            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3 z- B1 B4 F. q5 C5 e- n; ]$ X
            {( _* E- j0 T- w9 n8 Z% c
                 opn_in.data=(float)atof(buf);
4 q2 v5 _- v( V5 x) Q2 j8 U! o' G                 Push(opnd,opn_in);
5 Q2 i9 F$ I6 F6 [, K& O' @; B0 \1 I                 printf("opnd入栈:[%f]\n",opn_in.data);! O; d; j- q7 V6 P1 l  V
                 i=0;
5 K4 b5 b  u9 N9 u                 memset(buf,0,sizeof(buf));: @2 D+ u: d. W- O) w0 j/ q
            }
  ~& |5 O  C! n            opr_in.ch=c;
" n+ j' A# f$ D2 ]8 ^            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/6 T% L% _+ S3 ~3 e" I0 Z
            {
% x$ Y$ u. `0 d) i1 s. O8 H+ d                case '<': /*优先级小于栈顶结点,则运算符入栈*/3 l3 w$ w7 G5 s3 \' K  J
                     Push(optr,opr_in);
  R# s0 Q, R% O' X4 ^$ w                     printf("optr入栈:[%c]\n",opr_in.ch);
/ H* x/ x! L% p, G  f                     c=getchar();
0 ~9 ~& b1 q& d! C6 m                     break;
3 M+ U" F0 ]+ l3 y7 I) m8 W6 h  P1 h                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
3 l5 E8 t% Z4 l/ f                     Pop(optr,e);3 E+ v  W# l3 r! f, C
                     printf("optr出栈:去掉括号\n");7 }2 K! Y* @2 l7 W
                     c=getchar();4 L5 M; u: [" u0 s6 G, K7 N2 P  O
                     break;; s2 F( V- @& l. c! B
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
2 F/ {: h# V' E( R9 T% G                     Pop(optr,opr_t);, M8 a+ W! @3 l' e9 v
                     printf("optr出栈:[%c]\n",opr_t.ch);4 {3 u8 n' b; p9 |5 z
                     if(Pop(opnd,b)<0)
5 O7 ~1 @, u8 x5 L  Q  G9 A                     {: s7 q2 l& E0 [
                         printf("Bad Input!\n");
- B% a0 {5 B3 S4 s7 k                         fflush(stdin);/ V  s; K. |& M; i: |6 i
                         return -1;
/ Q! t, X0 \% v- V& \+ X& G                     }; b) D, X" M& i/ X. L' }* S
                     printf("opnd出栈:[%f]\n",b.data);, D/ L, s6 y+ N1 ]
                     if(Pop(opnd,a)<0)& P6 e* C+ i, n: g2 J1 _
                     {- V* r( f8 U% L) R4 o9 y. F' d. R
                         printf("Bad Input!\n");; P3 Z4 Z% t# }; j; h
                         fflush(stdin);
* v9 z3 J. Q% c. k                         return -1;' C+ _" _/ [2 _( N! b
                     }
2 d# J; X" [( z/ p                     printf("opnd出栈:[%f]\n",a.data);
; Q' t# v% O  Q) ~. M; j# h- ~                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
. R/ Z/ ?1 ^8 M                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
" I& v( W" a4 J; R                     printf("结果入栈:[%f]\n",opn_tmp.data);
5 }$ n- ~& q3 Q5 H5 ~9 i- {% I                     break;
' I: ?3 E. M2 m  j            }
+ K: j; y9 S" M6 [        }( u: ~: ]" B$ d9 Z
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
9 u8 H3 c6 N$ p, |. v$ t    }  e1 m: [9 a7 o4 ^
    GetTop(opnd,opn_tmp);% }8 B! l$ \$ P$ r2 i0 I
    DestroyStack(optr);( P" l( ^# a% `5 D, R
    DestroyStack(opnd);* u2 f) ]( p$ C/ b3 x: r& ^
    return opn_tmp.data;4 c: I7 x* o% x* T8 v8 V2 k  [
}
9 {0 X9 F! n; |2 `: C% Y" c- C/ N7 a' V- ?
char *killzero(char *res,float result)
. N9 [% b9 z/ s+ i( E- C{
6 D4 O! w& w& ]& W5 ]9 C' o; ^* D    int i;8 _9 c0 n2 I" R& {4 M- m8 e

- V) T& K# Q1 {' A3 c9 n! ?! `# G; J    sprintf(res,"%f",result);
: b$ G1 c, T  y& y4 I    i=(int)strlen(res)-1;
" R9 U* H4 i3 z% T    while(i&&res=='0')
7 \1 `( `, O6 b5 P/ P$ Z    {& E' J8 q8 s9 X" i3 |
        res='\0';. c" F. Z" A% L9 L! w
        i--;
8 J3 L% Q9 L3 h* Q' T6 T7 l6 j    }
# N- G# p( ~0 G! i# p' p    if(res=='.')
' ]: \$ S+ q! Z0 [* p        res='\0';
. T. C; F+ f) x, ^    return res;
* M  ?7 u# ~3 k" n}
8 Q$ N5 b+ k6 \' k( U: N, v
4 g0 E+ W/ H; a; o( S4 Q5 gint main()8 A' E% h4 z/ p7 e1 \
{, Z' D4 \7 i* R/ f8 F) W8 i; u. f
    char ch;
) H# x) x  Z  [5 V2 l, A; r9 J6 O    char res[64];
4 h$ ]6 k2 N+ a  c5 U4 J5 g6 g    float result;
* f3 _8 S" q( T$ V5 I$ O    while(1)
& S* V+ |8 H/ ?2 d    {
! G4 b" }) ^$ ^( O        result=compute();
( B9 v7 ^5 H% x0 p) \" U* L        printf("\nThe result is:%s\n",killzero(res,result));
7 Y6 m- r6 r, w/ ^3 ?% `0 R3 W7 k! q        printf("Do you want to continue(y/n)?:") ;
7 N7 H$ c* g3 l$ W+ D        ch=getch();! ]# l' t3 p) Q7 Q& Y
        putchar(ch);" X* v* x( N) `. _  ]6 Y  ?
        if(ch=='n'||ch=='N')0 ~0 S0 O: u" f6 \3 [  y8 a' g' @  B
            break;" I5 J- s! N& I- G8 t! o2 h- }
        else
+ d$ B% J3 r* v! o& s" U            system("cls");1 j" X( `' K6 j) ]6 w# T
    }6 s0 h. n2 b( q1 ]! j5 ^
    return 0;2 ~: @: l4 U7 f- \
}

9 j' V. b& N/ r' l8 i5 [
; {0 @0 t6 |% m( Q[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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