返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
. H1 o. L+ F8 c; `: T- u程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/ O3 c4 e5 y# y, M! R) x+ `& f) K1 E( f/**************表达式计算器************/; ^6 Y8 l, D3 j1 x
#include <stdio.h>+ O: S% s  M- ?" H( W+ k
#include <stdlib.h>
  B- W3 ]. L, t4 z) z6 D4 m#include <string.h>
& g! p. x( b$ g1 A3 X#include <conio.h>
$ l- Z3 F& o/ C. V& _4 R#include <malloc.h>
- w- A  f# I. E- ?0 l9 n5 P) O
1 F2 M" g9 G1 N, ~: A* h; C#define STACK_SIZE 100
1 m, s9 H( `. @/ @#define APPEND_SIZE 10
( i2 p" W* U, w  Z6 d* \6 x+ _' b. @
; s* y  I# N0 d1 pstruct SNode{
) L* ~* |. l: w0 ~" u    float data; /*存放操作数或者计算结果*/
7 B3 P. J1 ]5 C; t    char ch; /*存放运算符*/
; O, `2 R: a. q% `$ s: v};
" [8 o! z/ B8 [3 Q5 T+ Q  W5 Z# y  p8 Y: i( F
struct Stack{% I9 Q$ {+ H5 d3 {, n( {! o5 _
    SNode *top;
& w; s/ O3 ^; N1 h2 g- a- ?) i0 a    SNode *base;+ e+ L. N$ \6 z( h; e' w8 p1 ?  v. M
    int size;
" }* F0 H$ F" u4 G5 U2 r0 X  e};
2 u0 d& h/ f9 a, x
5 x6 @4 ~( A8 e1 p7 m/*栈操作函数*/
9 B* l& a* ]3 k! _int InitStack(Stack &S); /*创建栈*/( g' @& h/ b0 f1 c7 M
int DestroyStack(Stack &S); /*销毁栈*/0 i1 i3 i% q, S# O. v! @1 b& f( t
int ClearStack(Stack &S); /*清空栈*/
+ t- b0 y# t, R% e1 U$ ]1 H# cint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
$ f0 S8 k# e3 m4 P* U* h1 Kint Push(Stack &S,SNode e); /*将结点e压入栈*/4 `2 A" K7 `' U+ F* y  P9 P
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
/ q  w$ l/ D: u' M, u5 x( i, c5 X& Z) N) o
/*表达式计算器相关函数*/
0 w( t3 B% R4 Uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
) s: O; c+ K: H" G% Iint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/2 d# B! y6 A! Y1 B! A- d
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 ^; E- u+ |7 i. v* M8 c& Ffloat compute(); /*表达式结算器主函数*/+ P0 z# R1 H4 D. ]7 @' _1 p
char *killzero(float result); /*去掉结果后面的0*/ 3 \" }. w3 \0 E9 A! T5 m1 O# X& l( n

& T  A1 y  k' `' eint InitStack(Stack &S): W: R. v8 U* A/ _( B
{
, U6 t/ B  Z; P' d! L    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
6 z7 [" c$ ?$ ^# E    if(S.base==NULL)! p* \+ i/ T- W: I% R+ c9 J
    {
( ?# J4 O$ j: W! G  c- Q        printf("动态分配内存失败!");
! m5 @) {1 i$ U! q4 c3 i& M; G5 c        return -1;3 L* E/ v& i, k5 H' w
    }# c0 f; @  K4 z- k, \5 G- ]
    S.top=S.base;
6 p. `; B6 ]; s1 D    S.size=STACK_SIZE;0 b- n' {- J1 n" j2 {
    return 0;
$ q/ N% \3 H3 K6 S' K$ R1 H}
6 e( o! y) Z) w6 v* u, X; k+ l
' a) p3 ?8 j' }0 cint DestroyStack(Stack &S)
/ S; L/ R% y5 g' K! N1 r% {0 q{
) j8 W. {* Z  E. r# i: i    free(S.base);
- r$ k7 o% X; J0 c; V; O    return 0;( T0 L1 l% S9 G2 O# J" w- w. U
}
# _/ n5 a$ Z" ?7 ^# E: e6 o3 C$ u& z4 G, g/ ~+ V5 }
int ClearStack(Stack &S); T" W  O! u& A/ k- h* h! @
{- k9 K0 g: e" A' ^- ?, G, v
    S.top=S.base;$ v5 Z: V1 m" Y) E7 c7 R
    return 0;
5 O) p; B+ E* V}% ~5 M9 [: i; r, x6 w

- H) W  }" b7 L7 L4 m% t' Y( zint GetTop(Stack S,SNode &e)
" f9 v6 _9 A+ r6 D{
5 r: v& f# y' U& E% s) L' _    if(S.top==S.base)' t" m# x' g6 E7 _0 w
    {
. K  ^3 {) r; Z& F$ i. l; v        printf("栈以为空!");
3 u( b% Y& ^# w* I+ O- m% w        return -1;  z! a6 c4 ?4 w0 Z1 e) t/ G7 u' k
    }
8 K/ d2 a, G7 Z    e=*(S.top-1);
! y, |. x3 W( a2 G0 Z( ~' j! K    return 0;
2 A. G2 ^# r* }& }3 _+ ]1 ^}- ~% F! `) w* v/ o' [" r  i

4 b) P5 B0 z" Z3 @! [* lint Push(Stack &S,SNode e)0 h# [) v: @! u& E. {& c; K, |, M
{  q* g2 v: v  u0 q! ?
    if(S.top-S.base>=S.size)
* m' ?7 L. b2 Z! C- v" ]/ E    {
# [. }% B& t+ i+ I        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
; Y5 r3 s/ e: U" e$ d# H/ l        if(S.base==NULL)
$ ]* p6 j) W! T6 ~" Q9 [0 M/ j        {# }# l# j8 _/ W( W: m9 y# a+ ]: c
            printf("动态分配内存失败!");/ V/ C( P6 Y5 N6 ~
            return -1;
  ~% z% }- d2 O  ?% s. V! n. ?3 k        }
3 i( A5 ]0 W; K! ]        S.top=S.base+S.size;/ P! A& d1 e' Y8 c& N4 [
        S.size+=APPEND_SIZE;
2 \$ T+ t, w' r$ y2 I: p    }5 K9 k3 N0 ?3 E1 b. T2 w9 _
    *S.top=e;& O7 `: I9 a; _/ M
    S.top++;
, Q4 F6 W. n$ B    return 0;+ G) ^" d% z, f8 {
}
' S- Y- @3 y1 {* W# J6 Z6 U% C( n6 J( [- Q4 f; j4 {0 x
int Pop(Stack &S,SNode &e): R: i9 z+ l8 d% c
{3 h# T% Y: R1 B/ ^) x4 K( U
    if(S.top==S.base); J. ^  _6 D1 k0 B! y' l
    {: [( A5 o7 C' T, |/ R& f- ]+ j
        printf("栈为空!");
- c9 P( O9 z8 I9 G+ y* q        return -1;0 v+ L! M- r  A5 d3 M; H# C5 j
    }
9 _' x$ @5 q) S  j: W    e=*(S.top-1);
( d& _! T% o& e3 u& B0 E1 N    S.top--;" Q2 W  s$ E2 @) j1 s5 g
    return 0;
2 r9 t3 ?0 Z  t# `3 P3 G}
& ~2 y% ^6 ~& H" U' `- O# |+ D# [  ?
char get_precede(char s,char c)
1 e* B: \  r5 c2 s{
; q- }. G$ E+ Q9 e' a    switch(s)
8 Q/ G0 Y# C; C$ b: ^- ?2 L  @: H; q    {, H  f' T/ T' a7 {" u4 k+ c* l# B2 S
        case '+':                 ' Z; H- v& w% W  e1 e
        case '-':
) Q$ I/ g& e* m. T7 D             if(c=='+'||c=='-')8 ]3 l- \5 C" Y5 }
                 return '>';
5 R, a0 i- [5 c2 f; K             else if(c=='*'||c=='/')
6 u2 n4 k8 R7 o/ L                 return '<';
3 }: i* z. a+ j# I% w$ E             else if(c=='('), p) e5 V- L. w, X
                 return '<';
. T" S* o& i0 n' `6 }6 ?0 l0 k             else if(c==')')+ Q. H5 b) f0 c" B8 o! r
                 return '>';
2 N% X6 D5 B7 |             else
' H3 q! b/ S' X# Q( ^, j' j4 P- M6 U                 return '>';- h: W0 Z+ e/ M
        case '*':
0 Z7 H  n3 m3 W: }" D        case '/':
" J7 O- L, g9 T$ o8 `$ i             if(c=='+'||c=='-')4 w' r! a! W  ^+ {5 o% A* g
                 return '>';9 J. S. _  s9 [0 E; t
             else if(c=='*'||c=='/'), y* S) S2 ^9 Y
                 return '>';
6 ]8 z8 r* T! |+ q! g             else if(c=='(')3 }) J3 e: ?/ f( ]( ~5 H
                 return '<';
+ n. Y( y' I0 o6 p             else if(c==')')
" g* Q2 `" k( B( Q                 return '>';: ]/ S8 E4 _# c. j6 k# J( s2 G* m2 S
             else0 v) F) x% M4 V, Y1 y/ g# D5 x, R
                 return '>';% I+ `' Q$ ]4 _0 P# m4 H+ t9 L
        case '(':
6 X; D8 _% V: O6 D             if(c=='+'||c=='-')
2 h4 g: Z4 _7 \/ K( }  T! v                 return '<';+ W$ t# p1 c$ G4 c$ L. t) a5 L' |
             else if(c=='*'||c=='/')
& O- x5 D3 e$ f0 c  Z( N  J" y. C                 return '<';: F) L) C4 y9 ]* r4 I; |1 x
             else if(c=='('): ?! V0 w& W6 J  }9 I! m+ S
                 return '<';! C* q5 \$ ~8 f9 d( W5 @/ C8 \
             else if(c==')')
9 j3 ~! [1 w% W- _6 t) t6 w& u0 v; q                 return '=';8 \* H. x: w- q9 l& I+ f2 i- O
             else* g- ?: Q2 G8 K3 X, F% Y
                 return 'E';. `1 u3 X" R# ~1 h/ U. E
        case ')':! D4 s) W7 R+ \/ s9 n% A. [9 }: d
             if(c=='+'||c=='-')
' J0 X) i* f6 ^% R7 x3 f; Y6 K                 return '>';5 b2 n9 L( Z, i: a2 d
             else if(c=='*'||c=='/')0 t9 m( e) i( E
                 return '>';; N' t, s6 a) N: ~# ^. i
             else if(c=='(')# o* ?% ~7 S  O9 g3 Z
                 return 'E';2 _: F; u* I9 o6 |' m
             else if(c==')')
- }, H" Y  w9 w( x3 r" q: G% [$ o6 I                 return '>';
8 B  V( i; ^# g; e" j             else. L1 P" e+ B4 F2 T
                 return '>';: ^9 c8 i. x2 T) B7 J0 Y
        case '#':
# |; ?" I6 j7 X  \0 P! f             if(c=='+'||c=='-')
! D7 k9 f+ A. I                 return '<';
" F: w: ^! `) h             else if(c=='*'||c=='/')
, }0 @9 @' R$ ^4 q7 i+ X                 return '<';7 w: n! g2 Z, P
             else if(c=='('); }5 _& ]. M3 Q% {
                 return '<';
+ H( Z) T: B  V* ~' T+ x7 D             else if(c==')')
  D0 n4 C) @/ c# I                 return 'E';
8 P0 R, ^9 ]$ N, e! [             else7 T3 \$ f6 n' m4 Z! p
                 return '=';
! s- f- e/ ~" l        default:
/ v! g3 E6 P, l# Z             break;
% M2 k* W( P7 ^8 F    }& ^/ ^& f7 r2 e" ~2 z
    return 0;    % ]$ O" g$ X% w" f( B, E# ~9 d0 L
}! ]/ G" @: e$ B$ [2 c* O

# ]7 g& k* M% q/ z( fint isOpr(char c)
5 @5 Z8 j, q( y, M1 {& {{
( f" }: D7 v2 d1 U7 k    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')" Y* Y2 J# S" Z+ {) m: G
        return 0;5 V3 C& d0 X+ N& f
    else
# y8 u: h0 w8 }        return 1;
1 l5 l  w# r2 X. Z4 B# C}
* F1 _* E* O/ T& w! ~
$ ~1 s+ N3 |: w+ q0 E- L4 Kfloat operate(float x, char opr, float y)9 m5 l, Z4 p# l/ }+ ]# F( H
{
9 z5 K7 W  b8 O+ z  L    float result;
; F3 c  C, |2 `9 F6 }# J% N    switch (opr)4 n- x5 V  B5 B, J! x
    {$ S  z: v/ i% \. m/ L  P
        case '+':
. h& @9 x* e" J- j& n5 d4 J             result = x + y;
9 Z6 e% [2 K2 u) ~$ P             break;& V8 P+ R2 z/ Z1 D6 ]: N4 j9 N
        case '-': ' l6 w! C' z: ~1 x
             result = x - y;5 q& W; a/ j4 p2 N3 O
             break;
9 }5 Q" A  [/ _& ]2 T2 r        case '*': * V: ^8 C+ u4 x/ U; p
             result = x * y;( d. S# U2 O- e9 r* W$ [
             break;
3 s& A) ]$ X' J# B6 `4 h( s        case '/': ! r: u8 x4 o5 T1 _# ^# [2 v
             if (y == 0)' z  V/ r! M- i: w- J5 U
             {  P! L4 C9 X  C2 ~: D( K
                printf("Divided by zero!\n");- \; M# p8 W' K! A* H) u
                return 0;
* y3 x2 N5 r# c* L6 A             }7 y% L/ K+ \/ s: T0 u0 H. D% U
             else
6 e1 j8 P# ^3 G! C! K' z' }             {+ v0 l+ j* v; V2 t
                 result = x / y;
3 v+ @- z3 F; \                 break;
+ L: V: I7 k, A  p6 S             }
( H- c% |% I4 ~7 F1 `6 X       default: + F: `. @( k( h8 m+ A+ S
             printf("Bad Input.\n"); ! M6 d# D! J5 k6 ]
             return 0;
8 [+ p8 A: i. d- E' M. J    }  }3 \3 r) g0 P; K
    return result;
6 R) e  Y2 ^6 y5 s& |}    6 u7 `% b. @6 s' k2 g5 t! E0 f# @" _
2 U3 M. e* f$ x2 s( U3 x
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/+ m; f! k6 a. T8 Y0 ]
{
0 |" Y+ b% B" k6 c6 C    Stack optr,opnd;% \; ~) t% u! v" ^/ n1 C2 p
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
5 Z7 T# E% O' V% `" M6 W! t( i    char c;
- k, J4 x5 G' z% s/ {, r    char buf[16];
4 z, {8 i: q! ~+ _' f$ y: L/ f    int i=0;9 _2 \! B1 [/ D' A# w) ?0 [
    ) b9 u# T" O4 [9 a; z6 @, U7 m
    InitStack(optr); /*用于寄存运算符*/
( D2 ?: u/ _. `1 c+ x. r" A2 n2 L' ?  F    InitStack(opnd); /*用于寄存操作数和计算结果*/
  f+ v6 v8 f  K. {) C1 _    memset(buf,0,sizeof(buf));
2 p2 ], g1 {& O7 H. [   
5 w( |8 s5 u$ ~2 U$ R2 X6 H6 p; B& u+ n    printf("Enter your expression:");# w: l; ~  t2 W5 Q
        
/ ^+ _" X" j+ w  g/ u    opr_in.ch='#';
+ m" y, F3 F8 h0 x# \    Push(optr,opr_in); /*'#'入栈*/
9 I6 s: F. `! Q1 I/ ?& I6 G    GetTop(optr,opr_top);) F! q4 \& W- C0 k# j
    c=getchar();
! t6 k/ B' n3 f( g+ w    while(c!='='||opr_top.ch!='#')$ U3 y# ^- G* L  Z
    {
( G% T) S9 v, k) n  Z        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/. {, u* l# i7 V6 z
        {0 m  \! H/ d( j; @. ^! b7 }0 K
            buf=c;/ q  o6 s3 z& e# I
            i++;8 F* w/ i% w$ I. d
            c=getchar();
$ K( }0 L, h5 _& R& x9 G5 ~" c        }
& q( Y$ ^9 B' B, T/ w        else /*是运算符*/$ o. S& }1 u- F2 R8 z
        {1 y$ ?4 l- I  q4 F/ I4 y0 n. T
            buf='\0';
/ W; [4 g/ d! _5 n9 e            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/' Q( H5 j& D) r2 G* T+ N% ^
            {
1 C% G- u: g4 S- t$ n                 opn_in.data=(float)atof(buf);: O; h$ e% N' ^' c( j0 E$ \
                 Push(opnd,opn_in);
, j, u3 P) c& c* ]4 l2 q                 printf("opnd入栈:[%f]\n",opn_in.data);
' C6 \9 ]+ S- q* L$ A4 H& Q3 g                 i=0;
/ O# _- u7 g" p: G2 U% N                 memset(buf,0,sizeof(buf));
' c# I6 ?4 M" ]            }
% t' |- q, O0 S& z/ R            opr_in.ch=c;( c7 |3 a. {4 P) L5 A% I
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
. ~# [  s: B- ]- v: h0 B5 S            {
9 B3 r5 g" i! q1 g- `9 b3 z                case '<': /*优先级小于栈顶结点,则运算符入栈*/! \& l7 t0 b0 r9 G! I# \6 c
                     Push(optr,opr_in);
6 l0 a' B, T$ u% X& w0 W+ d                     printf("optr入栈:[%c]\n",opr_in.ch);
/ w/ Y% f  m" u5 B4 q: A. h                     c=getchar();
8 c3 p1 V# P4 `( s0 B/ A2 K                     break;
( K& K9 i' ]; b# f4 |+ V* T                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
0 v4 A' Y* y: U; s+ P                     Pop(optr,e);7 T  Y4 G# [) a; P8 k) L7 p
                     printf("optr出栈:去掉括号\n");9 n5 c9 [% S6 c0 A  O9 j# i; \
                     c=getchar();
- i& B8 d) N2 p  h  P* s% ]* L3 s                     break;
" O9 W2 p, {% |0 s" t  R! @) \                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
3 n6 a# X( q5 g. r* Z/ O, W* D                     Pop(optr,opr_t);
) V, F4 g9 z5 C; i0 A# ~# s                     printf("optr出栈:[%c]\n",opr_t.ch);& p. e: d% _' d
                     if(Pop(opnd,b)<0)
& o) Z7 V& O2 [: h8 [6 Y                     {1 P5 {# V( c! @
                         printf("Bad Input!\n");# z" q$ v6 K8 r3 @0 l
                         fflush(stdin);
' p6 u( X- b. [8 g" p7 S                         return -1;
' v. F+ ?. Y( }+ y- r5 O6 x7 r                     }
1 B0 _) Y; R, J  O                     printf("opnd出栈:[%f]\n",b.data);; n/ j1 o1 k+ Q& E7 l  C' u
                     if(Pop(opnd,a)<0)8 H; a* I! ?7 z1 l8 Q1 ^
                     {1 f; |# M" \( P2 q  G1 ]) c% C& p4 f
                         printf("Bad Input!\n");3 c) i9 v* z: f8 W$ C; |$ P: A
                         fflush(stdin);
1 f/ c2 v/ Y2 q. S3 \3 o- v+ v                         return -1;: s9 r5 ~( W) c( l( x
                     }+ o# r$ B5 \. K3 {8 m$ f
                     printf("opnd出栈:[%f]\n",a.data);
; Y. g. U  g" V                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
8 k+ [3 o$ U. i/ p7 j. Z                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/7 X2 ?" s% T) f7 E; x$ o
                     printf("结果入栈:[%f]\n",opn_tmp.data);
' C# X/ g2 m  B                     break;: Z8 H, f/ O5 r' H
            }
2 N1 N, P+ z( g% i' V        }0 S0 E: d; H9 V6 x9 s  C
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                # {; q2 Z* x% n. o
    }
0 S3 h7 t) r: B' G$ k    GetTop(opnd,opn_tmp);9 n( A0 N4 }3 R' K! Z% y/ R
    DestroyStack(optr);
  Z) ~" |# \9 y    DestroyStack(opnd);
8 O! j% u% w2 d$ l- ~    return opn_tmp.data;
1 n1 u  v7 H! m/ E0 ]5 E- y}
+ E1 O- Y: Q$ Q
, l/ j  b6 Z3 [7 \1 n+ {- Lchar *killzero(char *res,float result)( }# S+ z4 P; J; ^* p6 S/ G1 a/ R
{0 h) f- P8 u. v) e( W% E- H
    int i;
" B; O$ ]8 F' Q4 D% V+ A2 l- z) v$ ]
2 B, n# E: ~; P6 D" Y    sprintf(res,"%f",result);
; Y5 @7 @7 p) w2 D# m" e    i=(int)strlen(res)-1;
6 f  I3 {6 y3 ~* E: b. u1 ]    while(i&&res=='0')4 L* I. V. A* R. k
    {& u3 ~$ T, k$ U1 q7 v
        res='\0';
1 U6 o8 S% l4 L% ^        i--;
+ v$ u# i1 g3 ]: O: d    }% l/ U  M+ Z4 P3 d
    if(res=='.')
; P- d) ^7 e( ?" ]; w7 v7 ^        res='\0';
8 `$ c+ O2 H% e0 B    return res;' I, G8 f0 C; U4 i- W( C& T' P
}
6 }9 L* j& i; D/ s/ U4 j
* z( U8 f) I7 L9 `" K: mint main()
( m' H, ]4 w' g0 U3 }{& L" ^. Q  i. @! `9 c
    char ch;7 \, @7 \6 n5 c. l
    char res[64];
* E, \( J0 ]9 F- g( U. b    float result;& J2 W6 o/ K# Z; D; K) D6 X8 h
    while(1)+ c! h6 e! D7 o# m% M* C
    {
: z) ^! P. c) q6 H& n0 N        result=compute();
* }+ G! m& `/ C- m- |4 q3 q        printf("\nThe result is:%s\n",killzero(res,result));4 ^8 k; Q( Q1 L6 z% I" _: S: F
        printf("Do you want to continue(y/n)?:") ;8 b" u. I( k) t" U- j
        ch=getch();" F& ~+ `5 D  W; r& D
        putchar(ch);3 S2 F) Z7 `' d+ |
        if(ch=='n'||ch=='N')0 w9 p7 u$ b% i
            break;( q1 c9 @% `& k3 c
        else" |: N$ P1 s7 F  g: z- l
            system("cls");
1 w' O7 e8 R7 J; l5 P    }
3 C. F4 k& s5 L" `0 D3 i+ k    return 0;
7 ~5 i4 b8 g* j" v# R3 H* c}

8 \! E7 N$ k# G$ d  ~4 Y% c1 ~5 A' U
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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