返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.) b, t1 {  }. e. v
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
3 |9 i+ n$ d' U/**************表达式计算器************/
6 `9 }3 Y' M: s9 K% \* @* D7 g#include <stdio.h>
+ r5 F$ ?# C' u& l0 a  u' q#include <stdlib.h>
7 {! j1 I) m4 ?, v5 \#include <string.h>4 W- B' {$ l8 |( B4 n0 {% A/ {. {
#include <conio.h>' }- C. t3 p# X+ N1 Y6 o
#include <malloc.h>
! k4 k. P1 ]5 u/ r" _2 z; U3 t' ?* i5 R! s& c9 w! N* W8 M0 U& [
#define STACK_SIZE 100: W  C7 m5 x! Y" X
#define APPEND_SIZE 10, J# q  s' B# b' x( `4 T% G0 g
5 [( X+ W# H: ]/ b2 N1 Y
struct SNode{5 m6 H4 w4 T  |- B$ a# m- C+ u
    float data; /*存放操作数或者计算结果*/1 R/ O+ C( s3 i  T
    char ch; /*存放运算符*/
* K5 v* d& |, l. f( y3 e9 Q) ?# j};
% a1 Q& M. V7 {* A% ^
# G$ {) a" I$ Q) L7 k# {8 }struct Stack{
: p* `- |- ^, z    SNode *top;& m9 ?" e. f: k' x
    SNode *base;* z% ~: L$ ^; d' U' [/ e- U8 m5 p
    int size;6 P, `. ?# }% `3 N
};
' @. `( G; [# l% E
; _  p& H% D& C$ I% o/*栈操作函数*/; g% v& r- K2 S& r- j
int InitStack(Stack &S); /*创建栈*/( i) `+ s. R! l0 H
int DestroyStack(Stack &S); /*销毁栈*/
) w0 T" ~# j1 w( J  n/ }int ClearStack(Stack &S); /*清空栈*/
8 T7 f. D: S! Iint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
% [% j, \. \& Y' Y: I- X+ I& Rint Push(Stack &S,SNode e); /*将结点e压入栈*/7 [% c' T0 N, F6 y! m
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/0 i# h- ]- S9 ^; `/ J

+ ~4 b1 l4 m( E1 f; [+ }) i, Z' N' z* E/*表达式计算器相关函数*/8 K5 s8 D; n5 f
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
! g5 U0 ?0 t8 [: B) t. Eint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
( A& U4 k# O! x& u& ~* Ufloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/. \+ W" z) K( e) G6 v
float compute(); /*表达式结算器主函数*/' M+ K* L  @/ f" }2 f- h7 r% u
char *killzero(float result); /*去掉结果后面的0*/ 1 o, d  M5 Y7 |: ^1 o2 G% o

2 X. d5 O$ R$ g! m; f" Sint InitStack(Stack &S)
. P0 u5 `- C* a+ ?{
) z0 c( u3 W, _5 _* M& Y    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
" _9 I& H; _. {7 a) t  D$ _( E    if(S.base==NULL)
1 X4 M0 f8 P; T, h0 G    {
8 X( {6 _6 T. ^# f" p: U7 X2 v        printf("动态分配内存失败!");% l5 `! U  u' [' |( V
        return -1;/ C3 T9 U9 \7 Z  A& }* b  z; D
    }
* X8 E2 Y( L- p- Y/ K    S.top=S.base;) x- M" G1 f$ Z) E) w  J2 |0 o
    S.size=STACK_SIZE;
! V" L3 a0 r  [9 _( e) `; h1 n$ [% }    return 0;; F& j5 i1 j' D* s% A8 @
}
' j1 x' r! d. v9 L0 Q6 G( p) o2 w
int DestroyStack(Stack &S)
) I( I" Q( r: m! `4 p0 M{" w/ e6 u, u8 q  p& _! Z
    free(S.base);
) M* ~$ U) \$ P    return 0;; k2 x7 K1 D4 y2 E8 h# w6 {
}
4 I3 m, K  f8 ^
7 g* ?: z9 b- r3 {" y2 Dint ClearStack(Stack &S)  z/ c# f) ~6 R. o3 a6 f  v
{) D) v$ y1 f' [  h+ o. s# R! E" n
    S.top=S.base;
% a( B2 j; O/ K# }2 N6 L  |; l    return 0;, H- F( z% ~  m+ r4 E
}
# }. e! K6 g$ C
6 ^+ p% }8 d! Cint GetTop(Stack S,SNode &e)
0 {4 C" q3 s# k{' g* \) B3 Q  ?
    if(S.top==S.base)
* G8 @% [# s7 ^+ l" M( j    {; o" g! m- s$ @4 w9 Z) T) Z5 K
        printf("栈以为空!");* J  R0 V6 D0 }5 T9 ^
        return -1;
7 X1 G' L5 S8 y8 W& f    }* p- L$ F5 {: M( _- y7 f* l
    e=*(S.top-1);
1 b7 y/ \& W. Z6 h* B3 s1 O" x    return 0;+ C" D- Y6 w/ q0 Y2 }
}
7 c9 ]1 W  Y+ }1 I- n/ j5 g" ^2 e, f8 }+ ]1 {! s- e: r1 o. C. W- Z- [
int Push(Stack &S,SNode e)0 B& P  Z2 o0 q
{4 O* L( D$ I# ~& f5 z: w  S
    if(S.top-S.base>=S.size)
5 S- g, ~8 t! Z: \/ a- w' v- V    {  r8 l. y5 \0 X; o
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));$ h' P% Y: j* \% Y0 d- G
        if(S.base==NULL)
: ^9 W3 L+ b4 [4 i$ P- m        {
" }1 c6 u: O5 Y0 Z0 B/ _$ x            printf("动态分配内存失败!");
: j4 w$ x: W  |! y# ?            return -1;$ G1 u9 p2 i% H3 x5 o
        }% V7 ~* X$ E4 ?6 A3 h  N
        S.top=S.base+S.size;3 @: F, t' H% W. E) z# L2 B1 D
        S.size+=APPEND_SIZE;
; I! b& u3 h5 P5 ^, b    }. @5 I& Z- g% j9 d; ]4 h
    *S.top=e;
6 j1 [- C( O. K! H) W) T5 {5 [" u5 `1 }    S.top++;( I# S* k! e/ O7 }
    return 0;
9 P1 U: K. v* G; ^4 c* \}% y5 z' \9 a" S6 m+ ?
  y0 @6 I3 I1 S/ b: {' j9 a6 R
int Pop(Stack &S,SNode &e)
. _6 s1 X" w: y4 y) y6 w{
# g8 K9 H( E3 y) |1 c: a. g    if(S.top==S.base)
! d6 `9 i5 n/ ]3 M$ F) a; \6 F( V, M; z    {
3 D; J2 W& I4 W& g        printf("栈为空!");5 ?% d0 S, O* Z
        return -1;6 I& \& G' A9 a/ `5 M. h
    }
# O2 ^, N  j8 n. L2 M' L  x) U! F    e=*(S.top-1);
, P7 O! `* x6 E, S, f    S.top--;& P( E# y# A, a1 g* n8 B# m
    return 0;
1 z+ s9 D9 ^; e. g% s}7 [2 s0 D$ q  q; p+ j# c4 u& x  }

9 ?3 |3 }/ h6 \5 M; \, b1 ochar get_precede(char s,char c)* t+ J2 t! G: t$ T6 g9 I
{/ F9 C3 p' U; ^: M6 E
    switch(s)
  E! O$ M, @9 v9 o    {
! b' a  U  x4 y  @- P) Q4 ~        case '+':                 + y6 F! w: r/ H# d5 J. n$ d
        case '-':
& J' B* \/ [6 T( u, |1 J% e             if(c=='+'||c=='-')
9 L, i( f& ]4 K                 return '>';
7 {7 e% Y" _: R+ `             else if(c=='*'||c=='/')
* W, t8 y+ j& Y8 m6 y* M* r                 return '<';$ [! Z! J, Z4 C/ f& ]2 m
             else if(c=='(')
, V- J; V: k. ~, L5 O                 return '<';
. ^( [5 p) J  j4 W2 {7 y7 I- r- _% p             else if(c==')')  m' n( k- w$ Z9 A. o
                 return '>';& m6 f% I5 r& Z, b* l- W, V0 c5 I- [. |
             else
* u* h+ `$ A) u" Q: F  B                 return '>';$ w/ D4 y- ~4 y* g. `
        case '*':+ d0 s+ U! q$ W- K# n! U
        case '/':
+ _; R* d, R: f9 \             if(c=='+'||c=='-')# m7 e" ]+ s8 _& Q3 {$ b) W8 y! x
                 return '>';% w) V) f# A- B" n" ~! \1 e* l
             else if(c=='*'||c=='/')' f- p2 v+ V8 ^: h4 d
                 return '>';0 M9 x- }# r4 y% N3 C8 D
             else if(c=='('): `* q+ _% V* T1 L
                 return '<';
  g6 @, W) W/ v2 C             else if(c==')')
6 U4 |+ M. W8 ~! W3 j                 return '>';
' a! K  K5 C4 C+ ^$ I) X             else
% V2 q( I5 r2 R9 K                 return '>';
- H* k# N, e" h! r, t% ?        case '(':, R: {. ], E/ E: o) [3 p# s
             if(c=='+'||c=='-')2 l/ ]. v2 H+ }0 v
                 return '<';6 C3 R8 M7 [) l+ U) _
             else if(c=='*'||c=='/'). q4 b' g4 d. N" E& W& l  f9 Q
                 return '<';' M& l7 t+ z8 V
             else if(c=='(')/ @; d7 {( y) [; q4 `  L3 e2 X" ?
                 return '<';
( I7 f$ U, }# k( F$ w             else if(c==')')
+ W8 T- \6 j8 r! Y) i* n6 a; e                 return '=';
& _$ Y7 I' t) s9 U% p+ f             else
" @9 |( }5 @' o9 @                 return 'E';! t! H$ d& @3 i1 X6 T. E
        case ')':
3 x  R; b' I2 c9 ?( D4 s5 ~- q             if(c=='+'||c=='-')' l8 ~  a" c' k4 |3 k/ a' A) M) ]
                 return '>';% }$ K" q* ]$ ~- k5 J7 `' {# W; T
             else if(c=='*'||c=='/'): h! T+ B2 E; Q' Z
                 return '>';% t* P) q, o0 i6 u+ U0 B' H
             else if(c=='(')
' ^$ K! L! r2 u7 R9 c% \; D                 return 'E';
1 r5 b" ^7 |% k- p6 j             else if(c==')')
) s, D, R; y5 y4 X# O- u                 return '>';: p1 \4 @) @* s9 {: K) q
             else
; d- D% ?" R# b8 ^) [- y4 L  Q                 return '>';
1 l- P3 E- Y9 E% i7 O        case '#':% M* n& e- b+ l; ]8 C' C
             if(c=='+'||c=='-')( S5 ]/ z/ E6 C8 ^" p
                 return '<';$ E8 U* `5 U/ V# P
             else if(c=='*'||c=='/')
) z# g0 F" p. C                 return '<';3 |8 i: o6 o2 A7 P! X
             else if(c=='(')
) D4 D4 u  m* N* ^                 return '<';
% B. d8 u6 @$ C& }; b3 S' A             else if(c==')')6 I: m6 ]: j! _5 V( l5 [
                 return 'E';
5 H0 b" C& d# V             else$ w/ S1 u  `: g1 @
                 return '=';0 t+ |/ I7 j6 m9 c+ U" d( L5 t+ b1 {
        default:
) @# K% n. R# q. D             break;# u: ?! }! |' v. t; `- d
    }
- a6 ?% E% p  N: Y  F& `9 \/ y    return 0;    * d- ^% P* B& \+ A$ o  d! P/ r. u
}
* N, `! C6 V0 a- X; `) D
4 }5 B$ S( R7 W) y, w) f) r! m  |int isOpr(char c)1 l" U) ?( C* z, _$ `0 |3 T* U8 I5 b& ]
{
+ [7 \% L9 s  f0 {$ i% [    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
9 A) v% `: U' p% V) f: L: u# R8 h1 K        return 0;( N" R6 T* m; B& F* n3 r
    else
9 B. ]% C8 J6 y( l& c: y        return 1;7 y7 L* Z, B5 t- a
}# u$ f% H- c2 i' }6 x5 u% s" [8 a: U

' N& K3 e8 G  g: f# Yfloat operate(float x, char opr, float y)! E# f5 f3 s# _
{
5 t+ i- V. m# }; M4 y    float result;1 _6 d" {5 G- Q, l, T& o  [
    switch (opr)
/ S7 X- {/ L7 H3 E    {
+ e, @* }" a9 |        case '+':
# \& q3 X) ?  q* y* G% D             result = x + y;2 x+ Q, L& E, x1 A0 c, z
             break;' L' {$ \8 Z' \" R- w
        case '-':
# |3 p& Q# }6 w2 p: z% Y9 ~/ ^( x5 M             result = x - y;
" k, T( ]( r' n( t4 z: m% {: h             break;
' D5 W5 M) |. x  X! o; N) d        case '*':
& @4 O3 w2 O; l' r. Y5 O( J& l/ b+ p2 [% {             result = x * y;# e( [& O; D, ~' C: R5 h
             break;1 W5 J1 n0 j6 d
        case '/':
; p; b! y1 P5 t             if (y == 0)
. h6 g- ?/ A* p* K             {% M5 c; _6 R( n9 X  _
                printf("Divided by zero!\n");5 w5 a/ w9 z2 H
                return 0;
' g( N1 K2 {7 I; A             }
' g! ^4 I" S' J3 O9 i6 X& Y6 d: P             else
* |1 `0 @* J+ V) S) V$ V             {
4 I2 ~: m& Z7 T* S4 a- g                 result = x / y;$ f# V$ k9 E  h8 r! {# q4 W
                 break;% U( d8 W# p( {; S/ c2 V
             }# M- s. _+ w  x
       default:
, F) l  z( h- I+ w             printf("Bad Input.\n"); 0 m  _) W- {/ R3 n; c! N, ~( O
             return 0;
# B/ m# _0 `+ h& x4 ~% B    }3 P# J* E( Y/ q" z/ @
    return result;2 B8 H( |" @& n" V
}   
3 O$ f; o' E1 U; D/ ~2 J
. p* w, ~. s: X+ a+ Afloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
! L* e4 F  k+ P8 n" `{" n  j; P7 N' w( l& g. d5 Y0 M; V
    Stack optr,opnd;
* |7 `0 M' V) k4 E+ k& \    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;+ G# w2 M  \" m5 f! W
    char c;
, n) r; K1 I' y' J; f    char buf[16];
2 C# ]0 h) t3 `    int i=0;
) l, w! x- a4 X* c$ a) V4 Y. ~6 B   
, B) t, I8 Y  t3 E9 ~2 y$ N    InitStack(optr); /*用于寄存运算符*/( W( g. a7 f; I3 h
    InitStack(opnd); /*用于寄存操作数和计算结果*/: \: N, v% e" H
    memset(buf,0,sizeof(buf));* }/ O9 W8 U4 C7 J
   
+ ?+ [) L# D( c) \( D& t    printf("Enter your expression:");
. S9 [5 M' [! R        
. K8 y8 s. V4 ?0 B2 N. G4 {5 L* P    opr_in.ch='#';% X- S$ Q& D1 V( }3 t
    Push(optr,opr_in); /*'#'入栈*/
8 ^$ F9 y" K$ {    GetTop(optr,opr_top);( `0 t; X% v& U9 W7 H
    c=getchar();% U3 V( v2 h/ U0 V/ c
    while(c!='='||opr_top.ch!='#')$ s; y! u+ Q# ^) f, A" u
    {
/ r0 j: c5 l( _& w6 A1 V        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
1 P1 d, V; f& L8 k5 m1 c( N0 |$ Z# N& B, m        {
' H+ |; U% v7 @; j" A7 ^            buf=c;
/ N" s0 ]+ \" M3 X$ D            i++;& t" \3 X& ?9 Q) |! l% Y' U
            c=getchar();
% f; u$ l6 x1 O3 H) o# }        }( o! F% l6 o6 f% ?5 o
        else /*是运算符*/
( `9 Z1 y) L  Q% C1 N! n        {( w3 E4 Y7 o1 N/ V
            buf='\0';
* s! f% i3 R9 n  r; u$ o4 G+ w7 F            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/! ]3 A. _( g4 X' {
            {
' j3 C6 j3 Q( _+ a6 U# w1 M                 opn_in.data=(float)atof(buf);* g) Z/ r8 l4 l* J* y, ^1 u
                 Push(opnd,opn_in);
* k& j& n7 f" y                 printf("opnd入栈:[%f]\n",opn_in.data);5 W' R" I+ C6 N- |) _3 T
                 i=0;0 w! a& q0 o- w* _* `
                 memset(buf,0,sizeof(buf));
6 Y6 w0 `. a  h; x. v# u            }
3 \* u) }* a; h5 z1 v$ [7 E& Q; D, u            opr_in.ch=c;; Z4 K8 e6 c6 {' @/ Q! ^) z' B2 r
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
/ N( n1 C, m8 E: x" Y6 t5 g% m            {5 b; m  x' Y+ m# z9 W
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
- i" \4 b! U4 H* u' P                     Push(optr,opr_in);& d5 t% Z9 ]7 q
                     printf("optr入栈:[%c]\n",opr_in.ch);1 T+ F4 J' T. Z9 \' Z$ S& e3 Q
                     c=getchar();, `9 _7 S% `2 w: r6 [6 S
                     break;
% {( W) K( F* B' x  Q8 E$ g+ r                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/# R8 q- d4 B; }2 V
                     Pop(optr,e);
( a0 |. ^( a7 K                     printf("optr出栈:去掉括号\n");8 i: w" f/ g# q- ]4 I# d
                     c=getchar();
' m- i. t- g' w4 l                     break;
6 v; p- D( t: G% G) N                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/6 S/ _& \  W* _$ J* [, C7 O
                     Pop(optr,opr_t);
5 q* X3 ]4 w8 ~0 G                     printf("optr出栈:[%c]\n",opr_t.ch);3 k6 n8 R0 x# l
                     if(Pop(opnd,b)<0)
" }+ K: {4 {+ n3 M! [( B6 w                     {" S1 |( y8 J, P' X( |
                         printf("Bad Input!\n");0 [3 Z- q& o+ ^
                         fflush(stdin);
2 \4 y# \" ]1 i- A$ k' d2 z6 _1 u                         return -1;
; [" P* o; U) }# T, H                     }0 `) _, k3 B# a5 v
                     printf("opnd出栈:[%f]\n",b.data);1 _3 @+ y' l, I
                     if(Pop(opnd,a)<0)8 S! z6 l3 J$ K
                     {
% j/ U1 B& p2 `" O                         printf("Bad Input!\n");
! y0 k+ ^9 T/ c( c# v  j) x8 s                         fflush(stdin);
6 ?+ P/ \# X0 ?                         return -1;
. s4 h& `: C+ y6 u6 e7 c                     }
9 h: P2 c, Q& S% `, {                     printf("opnd出栈:[%f]\n",a.data);
. i5 @6 R2 z' Z$ ^1 E& r+ E/ Y                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 Z8 u5 ^6 L0 n% _0 n- j                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
. A0 p! O9 b5 p                     printf("结果入栈:[%f]\n",opn_tmp.data);
$ b* u. r5 _3 S! Z, z6 g3 P9 @                     break;
, `% f8 R( o4 C3 w5 @0 x/ \            }- e- S$ ]6 U; g/ `  d9 ~
        }+ V9 T2 ?. B% V5 O3 m
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
: A0 H8 F8 b" n$ H% @( ?2 G( Q    }0 J, z9 X2 \2 G5 G& u& P* F
    GetTop(opnd,opn_tmp);2 d, l# @! v0 q0 J& Z
    DestroyStack(optr);
* p. \* U  i" [; r0 L2 E    DestroyStack(opnd);$ }- \( M+ F# M3 B' k
    return opn_tmp.data;$ V  y! {0 n% K4 k; F$ I+ J/ k
}+ O" _( g% J9 e8 s6 k4 ~: P

/ A. y% J7 _0 r) D6 {7 x0 n+ tchar *killzero(char *res,float result)& C/ i+ G  r! k5 J; T8 p" u3 p
{
3 R3 K/ a" {0 X' z8 l  p) l    int i;* t2 e0 f4 x) y% y

. A% N$ F/ u* c6 j9 @    sprintf(res,"%f",result);
# ~9 x" k, \9 `- Z! `    i=(int)strlen(res)-1;
+ t! Z9 y; L  s& [; @: M+ v( y    while(i&&res=='0')
. v: s' C3 c2 }4 y/ U$ W/ v9 `    {
% H9 V$ L' T, x2 `- D! B% b        res='\0';
+ g& W# _* X- Z! _        i--;  J! C5 l, ?5 W) ~
    }
+ r8 S1 v5 r# }3 t    if(res=='.')
' G7 X; k( m* \5 {6 x* c        res='\0';* q6 R2 u* G' }& p# A; ~  n7 r
    return res;
# o0 |2 f. N, Z* x' k  r; x}
0 s5 R5 H" `& B$ _- G  s; J
5 V; Z5 c, P/ ]int main()
$ o5 j7 F0 f- X% p{! g* ^4 y: T9 J8 s) T9 U( A
    char ch;
4 P" k5 u: x7 ]. e$ D4 @    char res[64];
( Y. u) f% y* W; M' x+ t    float result;
' p( l3 J9 R& y5 i    while(1)& v  l/ i' |+ ]
    {/ a7 C, i' ^% ]" {5 c
        result=compute();# Q) |5 a9 k1 F! q9 [, z- o
        printf("\nThe result is:%s\n",killzero(res,result));
1 N$ K9 y4 f+ T, q" ^0 M* M        printf("Do you want to continue(y/n)?:") ;( G! z" }& z) {
        ch=getch();) \, B# [2 b: Q; b! Y5 `8 q
        putchar(ch);, y4 q# a$ s7 K' o- l0 I+ ~
        if(ch=='n'||ch=='N')( @1 J4 S' H6 t0 U2 q. t
            break;+ f. J2 M7 D# v9 e; \! u4 z# ]
        else7 N9 D" S# y: H! f- j  P% e" I$ ~
            system("cls");, X1 O3 [. L. S! A6 ^/ H7 D9 f, z3 u
    }
) I8 [& }) }# G2 G5 c: w; V    return 0;% I% i$ D. q+ [8 O- G8 e4 R% w
}

7 o; O0 v1 {1 V$ n
' e# [$ l) I) n& b' y! K, |: I[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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