返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
8 V5 R) n" @9 J3 L0 |程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
' o: }- M% d% K4 B4 }, ~/**************表达式计算器************/
# n( d$ b  x+ d% G$ l8 K" ]8 a#include <stdio.h>9 K5 y; K# z, t2 q2 K& |" l
#include <stdlib.h>
# z/ I; N8 o  S0 F# S#include <string.h>* _9 q$ l& R6 U! W( ], d
#include <conio.h>  @2 y9 u$ c) r2 Q" `5 @
#include <malloc.h>! A4 z$ R$ S" _9 ~! A2 T

( K$ ?7 e! }6 V- J2 c# j; F4 M; j& p5 O#define STACK_SIZE 100
% e0 u( o2 f% c7 l+ _& X( u#define APPEND_SIZE 10
7 C5 Q/ Y& m/ i3 C
9 ?! J3 p: J& Y2 Sstruct SNode{
$ v  V9 |( A# F7 V    float data; /*存放操作数或者计算结果*/; R' A$ q  l7 Y0 z, f; ~
    char ch; /*存放运算符*/
4 B  M3 N8 C4 e* t};/ l: A# i/ Q( @4 Z$ V; L9 N& F- |

& C" l" O6 r6 f  n) }! H6 I0 m! Fstruct Stack{6 ]' P1 B7 a! l- W9 J" |. B, q1 F
    SNode *top;/ l: t& Q6 j6 ], r
    SNode *base;
% q: G, s: j0 O) p6 \9 J8 K9 Z+ }    int size;0 m- p# {' n0 Y$ ?% V( L" A% n
};0 l+ J% k& Y" T- X8 N7 K) N
% j$ ]" u; u0 N/ @% u! N9 ~
/*栈操作函数*/* W5 C1 }% w7 ~$ R
int InitStack(Stack &S); /*创建栈*/: g3 b& ]5 i  x* \# ]
int DestroyStack(Stack &S); /*销毁栈*/+ s2 O1 o; D% m/ H1 Q
int ClearStack(Stack &S); /*清空栈*/
& p8 E) f7 p4 {2 D: L6 E3 Qint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
. q5 N4 x) M9 L) C: {5 \int Push(Stack &S,SNode e); /*将结点e压入栈*/$ q2 q1 N9 c' j( \/ t* ]" d
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
) {' |5 n9 l2 ~" t7 e5 b& G7 p' b4 U9 c" }( y; x! q) f2 l
/*表达式计算器相关函数*/1 F5 X/ X. W  O
char get_precede(char s,char c); /*判断运算符s和c的优先级*/; U/ N% z" Z: W. p6 w" n3 P1 ^& R
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
2 H1 ~% U7 z1 X9 I+ xfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1 N  B) M+ _0 r. Rfloat compute(); /*表达式结算器主函数*/) f' N# U7 a2 C" I$ v# J/ q2 ?
char *killzero(float result); /*去掉结果后面的0*/
9 X% ?; l! A9 s, a6 s- v7 t4 G5 ]5 p! R) Z# p5 w
int InitStack(Stack &S)" Y( K' V3 z2 U% |) u
{
8 E0 @6 {( e. B2 M    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));) `( U% i3 h6 R1 V+ m& D# h
    if(S.base==NULL)3 w$ _( X) r5 c; @5 s' ^
    {
$ L  j: Y+ n( H1 I3 h5 E) ?- `        printf("动态分配内存失败!");" R1 {" }8 i$ V- F' A8 G: U
        return -1;
+ R4 d9 b& a: U    }
/ k6 Y$ K- ^! T6 ?  M    S.top=S.base;
& M' t$ y4 ^; X) F    S.size=STACK_SIZE;, Q& Z8 S, @# l. }* K% q
    return 0;
& q- S5 I0 C) t  F# y/ {: K}$ G' {* }/ x9 w, U/ p" u% U* Z; @; C' s
7 ~0 T3 S, e3 ]9 ?  D0 q7 F) ]
int DestroyStack(Stack &S)6 u# u( ?: {$ e" J% b
{
5 z) C5 ^2 M% b    free(S.base);+ J1 n% G1 ^7 H) o7 T
    return 0;
/ n" C. K$ Q5 H0 S  m* h}
2 Q' O! M! E  w$ S# \
6 B- w' z% N/ c5 Xint ClearStack(Stack &S)
  I0 |. O) }  p- D{2 }7 V( n( e  i# u7 l5 ^/ _
    S.top=S.base;, f9 E# ^7 Y. G0 _3 h6 s
    return 0;0 ?" A7 D% g, t4 V" U
}
- ^! H- Z7 O+ x/ s. m2 ~( m6 J9 V. j
int GetTop(Stack S,SNode &e)
* u( |7 D! F3 u7 _* Q) U{
6 z  H; u; B% G9 n/ G; Z' C$ {! ?* v9 [    if(S.top==S.base)
& K7 U( x+ J; E" s  ]- |% Y    {
& c! v, s/ x( ^$ ?9 L9 d/ Y        printf("栈以为空!");
8 M, p+ z6 N6 r, s        return -1;. A& ^) w! X# y$ T
    }7 k' M9 R* K) o* {' U0 I
    e=*(S.top-1);! U2 B2 j) }0 J* _1 J
    return 0;
" I- P9 J; X% ^2 D+ N: A}
: f4 s5 S( ^' f" Z! a2 z
9 u2 v/ W/ m8 n2 [4 w: c# zint Push(Stack &S,SNode e)6 T7 b" M( {: `$ E: V9 ?1 Q
{
( r2 ~' G( J0 ^# Q    if(S.top-S.base>=S.size)$ N4 D. C* K. }5 q
    {4 ]* A: X( b) U8 E! A- W
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
- I& S' I+ C  i. T        if(S.base==NULL)
; I: x; f$ L; v& n7 ?3 V        {
3 p2 Q# @& [0 l% [( i7 i            printf("动态分配内存失败!");
: F1 P4 |" V' T. p, I9 F# ]4 d- q6 r9 o            return -1;  \' W5 h, ?0 n+ E8 Y& |$ o5 P; N
        }& C# z+ C- R$ {: o% ?, C
        S.top=S.base+S.size;1 n3 w2 M$ \( [# V! T/ Y: S# R6 R
        S.size+=APPEND_SIZE;6 U7 |' A5 H! X* J  R- G% \
    }
3 `9 o$ K8 F' K6 G    *S.top=e;, }( e  B: h3 R0 G  m+ a, H
    S.top++;7 {+ c- {- [1 _1 |, t! w5 A
    return 0;
2 `+ B3 j: G4 q7 D  Y}" W( y0 q" f4 Y& D% @6 d& E$ I

. h3 S) m3 A0 q5 U$ ?int Pop(Stack &S,SNode &e)
6 m3 [4 p9 c# O, F5 J) s- W{
, {+ {$ I! Q# E4 O7 o- h    if(S.top==S.base)0 ?8 |. I4 k" p  w
    {
" n7 K9 s8 F: ?% X3 l! R8 u$ x) @$ F        printf("栈为空!");
# [1 A: U1 P0 g6 o        return -1;0 E* _. O. ?+ _5 c, `7 L
    }; I1 x5 R, j# @$ a
    e=*(S.top-1);
8 i' J4 y" W: s# P- ~  _    S.top--;" a4 e& O# f$ |* w# L; ~
    return 0;
, D: Y' M2 l) [0 }$ x0 ~}
! K8 i) t  F+ `5 f, e! e2 Q- A& p# d9 ]- z: Y/ E% ]
char get_precede(char s,char c); b& T6 D- ?# e( f
{
) `; L4 F- e1 A$ Y5 \    switch(s)
% w/ t1 T8 N& p' z0 Q- p5 o3 R    {
' p2 w5 ?4 N% y3 R- d; L        case '+':                 
+ N, \( v/ M; u; E        case '-':
3 ^' k4 X% i- a8 s5 B$ P             if(c=='+'||c=='-'); h2 t! B0 Y2 a  }, W
                 return '>';
0 c7 J/ n8 p5 t! Q; V3 O             else if(c=='*'||c=='/')
9 f3 i) k9 ~' z8 z6 J' {                 return '<';
9 H$ C! G6 Q$ ?( F             else if(c=='(')) w# M8 ^3 m# a, X7 M5 F/ P
                 return '<';% B  y! T) C& n, e  F+ V" c
             else if(c==')')
" {; ]. o' ]- }2 G  N                 return '>';
, x# U2 `- f5 ]- x; D3 J1 J1 v             else
( P5 D6 k. V- J                 return '>';' a' K: O3 l- h7 d( n$ ~
        case '*':
- Q# G3 {$ y+ n5 J/ X8 ]9 x* X" t6 Z9 D$ |        case '/':
/ I5 ]" B0 G* W+ ]8 U             if(c=='+'||c=='-')$ o, G4 ^' B; P; r' X7 I+ K6 O* n
                 return '>';
5 }% ~% r9 f) {3 V; j5 m$ d1 r             else if(c=='*'||c=='/')
6 r6 `6 b$ r3 T7 e: P                 return '>';
6 X. x5 @6 B0 R$ Y             else if(c=='(')% z* X! D5 g6 O% D3 M: @" f
                 return '<';* E. U. j& r, i# V2 b
             else if(c==')')
7 i1 X- V5 D0 x: y' K                 return '>';" D( G, L$ w3 Y3 W0 O
             else
: V' E+ d* Y4 y! q: w                 return '>';
# v- j2 c3 h4 n1 [! n) E4 z        case '(':5 z* k# e% t8 s# _* [9 P
             if(c=='+'||c=='-')
9 W& A5 y: y9 i6 l& O% j8 m1 _/ h/ i                 return '<';: D- Z3 @' u3 o  j/ w# M
             else if(c=='*'||c=='/')
, L! y. G1 d0 R! T1 @                 return '<';# j7 l4 l, O/ P7 b2 j! k+ ]
             else if(c=='(')$ ^( A" Y6 F) o& d. l
                 return '<';
- j. L7 b# ~6 D* x- _! t9 s0 \             else if(c==')')! D1 H( ]/ U5 f* v1 k
                 return '=';
8 H/ D0 c. P# ?: L1 @             else
* L( {4 \4 N3 v! U9 I" s                 return 'E';' e  ~/ ^# v# x; Z) D6 k
        case ')':
) L7 J: S2 n3 Z$ R             if(c=='+'||c=='-')& m6 G2 l7 _3 |0 |" Q1 w
                 return '>';1 a( {; V0 W$ ?; o7 ?4 L/ e. H" o
             else if(c=='*'||c=='/')  Q4 A( G% z6 d) I3 `* l( c
                 return '>';
, m2 h$ g0 B2 a             else if(c=='(')+ R2 O1 C$ g8 x
                 return 'E';
& a5 m/ O3 ~6 e" K             else if(c==')')
1 _2 Y* I/ o, z0 n4 }                 return '>';
) G7 ?+ `6 I7 i) n8 W# x             else
  k5 q9 t* d: c5 r$ t                 return '>';; q9 o2 q8 P: J) q. o% u7 K
        case '#':' g: i- j: ]5 `7 M
             if(c=='+'||c=='-')
$ w  L5 n6 c% l9 }7 w                 return '<';
7 V) \6 L+ f( O' [7 O% R! T             else if(c=='*'||c=='/')6 X3 Q  {. J2 W: {4 j/ I) L
                 return '<';
/ X6 W( S5 D- F" p" B1 F& C$ `             else if(c=='(')
2 U$ O/ i" t2 O# ]4 N                 return '<';
+ U% D8 v5 A* i$ B             else if(c==')')
$ X: r4 `% _2 R                 return 'E';
( C2 n& |3 l2 i1 w9 e( i; G. X             else1 e. a) O$ L0 j4 o+ M3 q
                 return '=';
* |' K$ L; B% d! L. d: X        default:
$ x* L' p5 p& F! b1 T- l: q! U             break;
& d' j: ]$ T# t    }
  y& a9 b& E+ @$ p- Y    return 0;    * ~# w" z6 P' ]
}
/ G0 a% |/ G+ y( m% c! N# C
: F& W1 Y4 v  J5 M- qint isOpr(char c)
% c' F0 R) A" B: c3 W{! w9 A( Z' d8 O  J* s8 \
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')3 T9 Z2 |/ d1 p, X/ e" a0 s0 d1 ~
        return 0;
+ Y$ H: m0 W! ~    else
& p, p$ G& N+ d9 Z" q- k2 M5 w9 d        return 1;$ J! B# t7 |0 u
}  P7 w5 X8 h( C! s. i
* ~/ H5 T5 m3 ?& E
float operate(float x, char opr, float y)! C+ [% R7 q0 I& [
{
" T: _" R+ H0 C8 p2 t" b( ~' o/ d    float result;
  g* ]' l2 {) g    switch (opr)
# ^' {+ k- U' H# D: v6 I    {
& M8 S# D) I6 s/ s' K. U( {$ i7 S        case '+':
& @: q. m. B3 q0 A7 l             result = x + y;5 [& c$ D2 F9 M+ N2 [
             break;  c& T1 B  x* e; Q" c) Q
        case '-':
* I" o$ [1 J: D4 W  S: d5 N             result = x - y;
  M$ L  G% c! i* v: w; L             break;
* u5 W1 f& e* a  V& z        case '*':
3 L% _* O! C) `/ w/ [; l0 i             result = x * y;( A" w8 \% K. k7 `4 b9 T
             break;# @" V0 S/ c* B0 Q( y
        case '/': , D, N2 R; K& b
             if (y == 0)2 I. }1 t/ x8 @' d8 ~6 h4 l1 r
             {
) g6 p2 I6 u% y                printf("Divided by zero!\n");1 Q8 n" R9 G  w( R, F, _3 v
                return 0;& A8 y" o- Q0 [& @7 {/ }4 u7 i4 O
             }9 Q) W- S# P1 |0 {6 F+ F- Q
             else
) p4 [8 J' D/ A/ w             {# ?' Y- y4 H2 \4 t6 e, k  D9 e1 T
                 result = x / y;' C+ E+ D% j8 e9 a2 ~% u
                 break;# Y5 [  [2 u; p( x
             }- b7 S2 ]* l" t4 Y
       default:
0 K& T6 M8 ?% _1 V0 F5 U4 b( R" k             printf("Bad Input.\n"); ' Z4 N/ k4 D' N0 w. @, X: K, L
             return 0;8 X% @/ i9 n( K9 m
    }
7 m) p# }( `/ }. p    return result;& S: [" L8 v" n
}   
% f9 Y! i% [0 `+ E1 p- `
/ y+ ]6 F1 Z! G# zfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
2 R5 K' V# W$ `# W{4 d- S0 q3 B% [9 y/ q
    Stack optr,opnd;2 B% x$ J) I, ^# b' u2 ~
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
0 I0 ~* c2 p( S" C; P" K    char c;7 J& G& ~! O, f2 N
    char buf[16];
+ q' b  S0 W! v7 B. K# ?- N: q& Y    int i=0;) C' W$ e! n. G  V! _
      c- G! u- o: A7 O7 M. T8 A
    InitStack(optr); /*用于寄存运算符*/0 L2 W% ~  Y5 h9 R  Z  T; i6 ~7 M
    InitStack(opnd); /*用于寄存操作数和计算结果*/
4 B9 B+ y# h  _$ R9 h+ W1 e    memset(buf,0,sizeof(buf));1 E6 f2 K6 g# m/ f7 ?0 R: D! I$ W6 Q
   
2 e4 h! u* R  w4 e6 e    printf("Enter your expression:");; G9 X- h$ Q7 P3 }7 Z7 K
          i# r+ o; w) a/ e" ]- N8 u
    opr_in.ch='#';5 O% j4 ]* ~) L. d* T; J4 ?4 p
    Push(optr,opr_in); /*'#'入栈*/5 ~# Z4 T: Y) F- x/ I- B4 I; ^6 p
    GetTop(optr,opr_top);
) d5 k! {9 V3 W# `) H9 X    c=getchar();2 A& S: w/ n/ O) t3 ^
    while(c!='='||opr_top.ch!='#')3 w0 f( F7 n  I" n9 l% u
    {
) M1 z* [, V  O- P" }* J5 c# a        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/& I1 d1 u0 T& ]6 d# a5 H8 x( d, V
        {
* ]6 m# M- J! I1 e3 }3 u            buf=c;
- ?$ y1 E+ B/ D3 v% B; p            i++;( V- r& P9 z, X$ S% x5 V! ]/ [
            c=getchar();6 ~8 ^: a+ z8 F0 x. ^3 F  M
        }
/ K5 T: X) \0 P        else /*是运算符*/$ o, X1 r/ `* M& R4 T  N% x
        {, k4 y1 X+ A& X3 W: ^. n
            buf='\0';2 t+ j; j2 \& ^9 G2 g5 a
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
* L0 c" G* u) N3 C( @            {8 A. Q; h4 s* ]! X) @! |
                 opn_in.data=(float)atof(buf);
& u% T% U/ N  a5 a+ ?                 Push(opnd,opn_in);* }5 w$ f  j0 a- [/ x6 ?' ^
                 printf("opnd入栈:[%f]\n",opn_in.data);
3 M7 {0 l% [$ L2 G9 m3 T, M                 i=0;6 l1 }. |4 {) a2 ]% n8 q
                 memset(buf,0,sizeof(buf));- c* z2 j& v$ g
            }
9 U5 ]6 }& p: V6 p            opr_in.ch=c;
3 |/ u9 u" t3 z; m            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
# M( N% D& j3 j2 t            {" [9 f! n$ e7 I4 P; L7 h
                case '<': /*优先级小于栈顶结点,则运算符入栈*/; t7 Q( p7 `* q8 E$ A
                     Push(optr,opr_in);5 W% C5 W# ~$ H) s* _
                     printf("optr入栈:[%c]\n",opr_in.ch);8 L. ^1 `  C8 x5 k7 t9 S
                     c=getchar();% [+ _0 P. ]* H2 h8 \" w/ l  h
                     break;
4 A# \6 J- H+ Z' Y, [) A                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
- [* w0 s2 i6 q5 O, Q                     Pop(optr,e);% {/ l& p" @3 F
                     printf("optr出栈:去掉括号\n");
6 B  [! i5 M' w8 S) `% x9 _                     c=getchar();
4 d& K4 Y- L  K) N                     break;8 @4 Q' [4 I& v1 _
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
' L- w* _# h% P0 K                     Pop(optr,opr_t);; y: b: \: M2 w" n
                     printf("optr出栈:[%c]\n",opr_t.ch);
/ F3 ^# E. Q( T& v; c: h$ [                     if(Pop(opnd,b)<0)8 \. g  Q: N4 Z, W. \5 J* R
                     {
. X. m0 w" C' h& @# `) F                         printf("Bad Input!\n");6 O9 e# ?% K, o& V
                         fflush(stdin);
; N* F+ a( y4 ~) z& j                         return -1;
) ~9 r$ X: h' ?                     }
$ b. v  U' w; J* T5 w, H) d                     printf("opnd出栈:[%f]\n",b.data);" }3 X* A* y) C7 q, i* }- L
                     if(Pop(opnd,a)<0)
' b. b5 I+ L7 X2 w  \9 U                     {
5 t$ j) {: _5 Q1 t7 d9 e, t                         printf("Bad Input!\n");* i8 X5 b$ x0 [
                         fflush(stdin);# ]" B" D7 T0 f: q2 K
                         return -1;
3 p. V. p6 L, i7 h0 `                     }6 Y5 }% F8 Q0 g! x* G! h% j$ J6 b6 a
                     printf("opnd出栈:[%f]\n",a.data);+ p3 H& x' d7 N# \, A* e
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/. T% x( J! U% E. w" `) }
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/1 e- Y/ Z. [9 S: D$ s$ c
                     printf("结果入栈:[%f]\n",opn_tmp.data);
' j8 M* D9 L' ]( F: G9 M& o1 h                     break;
$ k- c: K+ v/ v! k) A( s2 _5 ]            }8 ]) i4 C5 H6 x! f$ M- Y  _
        }; L5 p$ z- p. t7 X9 k
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
) c) v2 B% C) c' X5 b9 [( x% k1 r    }
+ _9 C, U3 D8 E" J& U8 ^( O+ _9 c    GetTop(opnd,opn_tmp);
% ^7 f) y( \" O8 @    DestroyStack(optr);1 n- e! ?$ g4 b( j
    DestroyStack(opnd);! ?# Q0 ]& U1 {4 U
    return opn_tmp.data;& G% Z* f, H, M, D* N. T; y
}
$ s! Y: u# f' q7 Z+ m5 [
% c8 O/ ?6 Y4 ?* Q9 ]char *killzero(char *res,float result)
) }) y/ @# Q& ^8 F  Q  m# d{; j. J* [' @  P' t/ v% o2 D
    int i;
& k( u; U; C% O
/ T" W2 h- g1 J7 q7 ~0 l    sprintf(res,"%f",result);6 X5 ~2 W$ G. b$ M; R9 y
    i=(int)strlen(res)-1;4 t+ r$ ~$ f3 E. F0 s! Q- r
    while(i&&res=='0')
" l" \. ]% X' ^7 Z* \) |) W+ B    {$ z) a/ N; @3 P
        res='\0';/ N! C- J& W" s" W* P
        i--;  B. y/ q. y9 R' q- F! u# P
    }
3 ?3 I! x. m& u    if(res=='.')' K! G7 }0 ~; n* z+ Z! {
        res='\0';6 _! X/ e: f! \, G
    return res;' g3 r; F8 t" ?' v3 F0 t
}
: B; r$ x8 u1 T' d/ u
1 P5 T, }4 @$ S/ {6 |int main()
; L9 x( \2 g6 z) l( v# F{3 w( q9 o, ^. Y5 K5 X9 k1 q
    char ch;
! E3 h' Y( X6 r( C8 r8 W" y    char res[64];
( {2 C" V* L' u! Z( S    float result;: Z' d& T& I$ d3 k' n3 F
    while(1)
# I9 ~$ k1 ]3 a& x    {
. Z8 w: G1 d2 ]6 O: x0 W        result=compute();
+ J8 U& a$ ]* e/ Q4 ?        printf("\nThe result is:%s\n",killzero(res,result));  z2 F9 v! b0 ]7 E: g+ s1 ?7 [
        printf("Do you want to continue(y/n)?:") ;1 R4 T2 {: A# ~7 z: b- `" D! U9 m
        ch=getch();
6 Z2 o4 P3 {0 }7 k. g        putchar(ch);
! p$ c! n% q  l) u/ c, j  @: ^# e8 I- J        if(ch=='n'||ch=='N')
3 T4 i6 U- \! U' W: I            break;/ N5 K) @( v. N! L5 U: V2 _
        else
# x; H4 ~, K. [, w            system("cls");
  H/ T$ h3 S4 h  Y& j4 E6 N    }* ^) q: C  a( Z+ f) M3 _1 b; L/ l% r
    return 0;- b* s& l' j! v' Z1 ]
}

+ x9 I: @+ u) q$ a: d% A1 u" Z0 O2 ?. H3 W- D8 O/ i; l1 w% w" r9 p
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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