返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6 e6 [* A  N2 Y  u2 x
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
3 W, r- n3 @; Q/**************表达式计算器************/
1 d$ B0 {! [. p) J#include <stdio.h>* S) t/ ^+ z2 a9 c' }
#include <stdlib.h>
8 N9 c' Y- u6 J! M; t  {( ]#include <string.h>
3 ~2 e7 j1 p) e& Q( J! S! G#include <conio.h>
# B$ F6 |$ h% S% Y! N#include <malloc.h>
. x' }9 |7 T+ \; s6 R/ ]4 y% D
' w8 l* _( Y# _: l5 h$ s  S/ }#define STACK_SIZE 100/ z3 D( P. G: @- d- E) ^0 d
#define APPEND_SIZE 10) W  J4 @' r+ p- R0 z
( c, y9 O' I$ j  B% `7 Y
struct SNode{
6 c3 O( H: ~( P0 v4 s/ F    float data; /*存放操作数或者计算结果*/! ~; r. o  x  ]' D9 w) n
    char ch; /*存放运算符*/
$ A' n& y# {& i6 s7 l% W  E};
# E$ F# K: H, L! z
, u! ]) g7 R* T4 V2 ?3 ^struct Stack{# z. K7 w+ F6 Y$ z1 s; u5 o- e- F
    SNode *top;
; Q3 C1 g! T, i* ~    SNode *base;
$ ~7 |, c' N& m8 Z) _$ r% k    int size;$ A$ Z7 X4 u7 X, Y( z
};
4 a" f+ x7 L3 O$ J9 Q# V( e, h+ M; p
/*栈操作函数*/
' q( x8 F( v$ [6 y" H6 Z- L) cint InitStack(Stack &S); /*创建栈*/
" L( o/ M1 l7 v6 lint DestroyStack(Stack &S); /*销毁栈*/
+ g6 [7 Q. a* u  h; p6 L6 ~int ClearStack(Stack &S); /*清空栈*/' J. j" {3 e3 f  \# U$ n
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/) h8 \$ A5 a8 \5 \' e
int Push(Stack &S,SNode e); /*将结点e压入栈*/, C8 s% h  Z& @
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/' l8 A8 X! V( g6 u/ g$ h

) q" `, m+ m( g0 D! L' B" ]/*表达式计算器相关函数*/7 _$ Y, y8 x3 ?6 T
char get_precede(char s,char c); /*判断运算符s和c的优先级*/4 |3 [9 G4 X) |9 E0 I
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
5 w- N3 Y# L1 e9 P/ Y6 [6 zfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
- Y9 B# n3 T% v  J0 Ufloat compute(); /*表达式结算器主函数*/3 S3 w* \* Z4 O4 Y" V
char *killzero(float result); /*去掉结果后面的0*/ ; Q! L# Y; M5 t( I& u
% o+ G% n; D7 E1 R. q" K
int InitStack(Stack &S)2 s6 V3 K! n4 @: j" p7 G( U) f
{
/ b  P3 r" G) a3 g2 F    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
, n) b/ P- {$ G0 r2 V    if(S.base==NULL)
3 A8 o! }6 s7 y% I    {
. f1 D5 f0 }& I/ V! C* t        printf("动态分配内存失败!");
  r8 w2 L& d: F3 e6 f        return -1;; n" d# w) i1 y
    }/ ]  M" C9 R: Z6 f. C1 S) X
    S.top=S.base;( b; T+ [' D' ^: N4 F3 f- m" A5 M
    S.size=STACK_SIZE;
1 b. {8 w; m( l# z7 s    return 0;
. S7 H4 _# D; I  d" n' x: k  h% u}* {+ z; i- n+ W

, d# U2 y! a" tint DestroyStack(Stack &S)8 s" F$ k3 i$ Y1 k
{8 j3 Y' o& `" y6 \6 {
    free(S.base);
- f) g) Y% L9 X    return 0;2 M6 H# G! v: V: O8 l( ?# d; Q+ T
}
. w7 m; X6 L$ A2 A) t4 B7 g6 o; {8 o; @4 g3 F% B
int ClearStack(Stack &S), h* _* e0 \% m7 n
{
7 m  Z# _  v* N, D' n' t    S.top=S.base;
0 F8 n% L& e/ q$ K3 D+ L, v" @0 B) h    return 0;
! C& F* j5 j/ d& u}
3 c2 N* a% x& y+ F! R! J0 D! z1 h
! g2 k7 z; K9 u- ?* e; fint GetTop(Stack S,SNode &e)
5 V1 _+ o' G# O2 s5 }! I8 _{
! U3 Q$ ~. y3 G    if(S.top==S.base)4 @8 p- {6 o8 {4 V2 F1 c! x3 H
    {
  Y5 }6 c$ J6 u% f* h% l4 T        printf("栈以为空!");
+ N( p: b4 F7 E+ F6 `        return -1;* D, N4 _  F+ `
    }
3 l; q- Z8 L6 i    e=*(S.top-1);
5 Z5 K! V, d. ]1 L: y6 x    return 0;
( u9 S1 p+ R1 h7 R}
3 c' H6 o3 {( K8 g0 z2 p* k
' q0 n$ h% q* U9 l: R+ P9 r& K' Qint Push(Stack &S,SNode e)
4 Y; B7 v- s# C+ r: ]8 D6 E{
0 k2 h0 v; S& @  T    if(S.top-S.base>=S.size)
9 u1 }8 w& _1 y. C  j" u    {
9 ~5 e9 q) o1 V        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
; n9 @$ \5 C. T8 @        if(S.base==NULL): m5 R; U! m, C; U9 Y# x
        {0 n. w: ?* y# N/ f  w# B
            printf("动态分配内存失败!");
" m6 ]5 E) p+ [8 B: f            return -1;/ d0 V! @' Q! t$ \0 [+ \
        }
1 @2 K9 l. S0 h. A        S.top=S.base+S.size;& z. p- j1 s* P$ G- n
        S.size+=APPEND_SIZE;
3 g9 K+ H; Z% C; c0 H    }
* D: R/ v: d% _( G9 v    *S.top=e;
7 K; b/ E7 f0 i0 W! L    S.top++;$ H: N* E) O9 F) I' I, p) U
    return 0;$ Y8 O. I/ i) z3 d- A; p+ C
}
% v$ d- I9 X( r$ S4 Q0 j# u  K
int Pop(Stack &S,SNode &e)
, C0 _3 R. S! K5 H2 X) S{; z* K# `' u& I+ w0 H  q
    if(S.top==S.base). n  L  a& V' A& r
    {
! Y  ]7 ]0 k- b3 c, b        printf("栈为空!");4 P/ S8 l8 x$ l( b/ h
        return -1;2 K) S/ p- N) A( ~  _& q3 \0 O
    }+ L! @+ d7 O1 n( @
    e=*(S.top-1);
* H& _( O0 Z1 \. f4 Z8 T    S.top--;
, S9 P4 g1 x7 F% @) y    return 0;2 }% |% @+ I1 P) O3 j: l/ B! i
}: Y9 G' `8 q* f  d3 [+ r0 N7 \1 `

) X9 p' `& s+ B7 \  K! rchar get_precede(char s,char c)
; Q: b" H1 d/ V3 }( G7 _{
. O4 K. @5 z: y" Q* m8 `0 q- K    switch(s)0 S% H" x8 \& u0 R+ ~1 \
    {4 S7 U# x( f1 i& Z" [
        case '+':                 
; k6 s& Z; P+ k+ B        case '-':! [* N( b5 z$ l* d  U/ B' _
             if(c=='+'||c=='-')' G. E/ I* r! v; Y
                 return '>';) @, d. D# K6 j, R
             else if(c=='*'||c=='/')' r( L" n6 n0 J6 ^( O( D
                 return '<';
0 Y# A) k7 w0 x& g" R# m             else if(c=='(')
, ~5 H5 g) @& n- K  Y                 return '<';+ H# O, l; z5 F- u
             else if(c==')'). S' e4 ~$ m& j
                 return '>';- [+ Y* v& ]; C) B/ o
             else ! s* _' t5 V. t9 Q& s: Q0 P
                 return '>';
0 p% m4 g( ^9 f1 i7 K        case '*':
5 L* l. ?& w; O5 q5 ^7 P* T        case '/':
9 \  t; i, d  ^  C7 K! x             if(c=='+'||c=='-')% O( X: \" F* X% V7 H
                 return '>';
. w; v& ]  C  t9 x% u             else if(c=='*'||c=='/')
; O& k2 ^7 K3 F9 k6 M4 _                 return '>';
& K% n; r3 {% o: @             else if(c=='(')3 I* l+ ~! e9 i- `# v4 j
                 return '<';. E- q  C% m: V% l
             else if(c==')')
, e- p) @0 e  S9 y* l1 F                 return '>';
; ?3 u9 a) N. U, u# l5 A             else' r  e: m6 t) C- y: |% m
                 return '>';
6 n! p3 B3 e' J( k) U        case '(':
3 c* a% k; J1 _, Q. Y             if(c=='+'||c=='-')
7 f5 R& d2 P5 v' H! ^0 X. y1 N                 return '<';" C0 Q# K1 F9 x3 X" G" O  _: b
             else if(c=='*'||c=='/')$ B% e9 d/ U, W- G7 E1 Y/ [
                 return '<';
4 l" P+ [) R4 k             else if(c=='(')+ M) d+ P$ ~/ I) q6 I) `
                 return '<';
& {7 Y7 y. g1 h2 ^5 D3 [             else if(c==')')2 {" c8 G. x/ M4 ?( Q4 K
                 return '=';/ `% [7 K7 n. Y: I" x( j# n4 J
             else
4 g6 [) w/ a- J: r4 t+ C                 return 'E';
1 |7 h6 ~* @5 O# p+ C1 `        case ')':3 N6 v- M9 O/ K. L2 Y
             if(c=='+'||c=='-')
8 g" `& b: {2 T                 return '>';2 H% F' w. H4 `: a* n. L
             else if(c=='*'||c=='/')
$ u5 u, F7 d) D# T" {( W1 N1 q- H                 return '>';
/ e/ D2 j- I9 D! ?0 w( \/ @             else if(c=='('); A$ x1 P' n+ y7 g7 u
                 return 'E';) I: P+ f) S& r+ _
             else if(c==')')
& P3 ]* Y' R% c                 return '>';
" [  R  M$ o& P/ J4 u! [0 c  B% o             else5 O+ ^( s8 z! z7 k3 [  p
                 return '>';& i  N  d7 b  j/ y# ]0 Y
        case '#':
! h3 ~" A% n! a: K# N9 v             if(c=='+'||c=='-')
& _! `( x3 p6 S. L                 return '<';
( b+ ~% L) Q; T1 h! n. L7 J# E             else if(c=='*'||c=='/')8 O% V9 C1 Y% D; `
                 return '<';' t9 t* n7 V0 Z( G0 x/ T* }" s
             else if(c=='(')5 n/ D, ~8 F/ |$ I1 k
                 return '<';5 D! `2 x4 D2 G- u
             else if(c==')')
7 }0 w* @9 T) }! j# i                 return 'E';
& I" [, e1 u% V             else
' X" B! T$ ~: e4 d/ d) J& J                 return '=';
" F5 _2 R- b5 _! k" U4 c% r& U        default:
6 O0 \! ?) K' b% K3 }" {             break;
- X, T* L8 i; i  `) D9 z    }
3 M8 `! s3 e/ R& G( {    return 0;   
' B. |0 O; n9 ^, X}
! v/ Z3 G1 T$ C% U# A/ j' `8 A9 Y) ^7 d8 s3 I
int isOpr(char c)" k; E2 l9 O0 E' _
{, ~" }' _6 k' j. j/ J/ v0 I. @
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')& b, b$ _: v- Z# n0 W1 T. G
        return 0;
$ x6 a& i& Q. u' b( U1 K0 f! B- I4 r" N    else
& |. s9 p/ h' h9 d, [* g9 k        return 1;/ {. v$ k, J% y6 m" I: G5 ^( n" X4 X
}
: U! O( i- p. u3 D- }  S8 k5 L
7 E! g6 i+ c; ~' Hfloat operate(float x, char opr, float y)
& I& b6 ]0 ~0 z/ ~- J4 V; K% R. k{
+ {: n* `7 u* ?( }# U9 d    float result;
$ o$ H* R! l6 Y" ~- Z    switch (opr)
% p3 I4 E3 K. {' W! {    {7 c3 v& ]8 x  j5 k% h( Y, p
        case '+':
3 u! j" `' ~6 g5 o9 Q6 ]# X             result = x + y;! T# D& ]$ @" H' O' A7 T: Z
             break;1 Q1 {1 n- D0 R, A
        case '-':
4 j8 i1 n" @5 y/ A6 c$ H4 F, g/ f             result = x - y;6 a7 ]( T/ J- ?
             break;
/ S/ Q# V( M/ ]% i" E- P: N        case '*':
& `+ H! V4 q7 D6 k) Q$ ^             result = x * y;
$ F: Z7 |( ]7 l. m5 N+ J  b2 E) w' H             break;
* h/ C% j* x. w7 N* p        case '/':
% z0 x$ ~: }$ U( V             if (y == 0)
& Q9 s! D, e6 X4 ~             {. Q8 q# M9 c: w( g6 f8 w* q
                printf("Divided by zero!\n");4 r6 _5 F% H: u, k3 A/ D) {. R
                return 0;& \0 z, z- s6 Q
             }0 z; a& V& _1 @1 U9 x
             else. W( |; f. ~: W' k+ H' _( K
             {; S7 l  \1 V% L' S1 H
                 result = x / y;$ l! v  C" e3 P3 u0 R9 y# U+ N
                 break;
' X+ {) G+ G5 w9 r# Y) G, Y4 g; S             }
- ~: ?0 X; D( r: T' e       default:
7 j" `/ L/ u) x& R             printf("Bad Input.\n");
" E+ b8 y9 J" l  G& |             return 0;# q/ \4 I% `) f, @; `8 E
    }
& `% s; Q8 j4 v, k    return result;; m' q! s$ b) c6 c$ D
}   
* q' u: k$ w3 I# P- C: p7 C
6 `+ d8 s- E$ j% c; ^/ r+ S/ l* ufloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/8 ]2 |8 z5 W6 A/ _
{/ o$ D( \( ?* @5 |0 n- V
    Stack optr,opnd;
6 T" U# C! z, ?- g) A5 }    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;1 h! L' h6 o+ X+ \+ H; K' y
    char c;
% X( v0 _# S2 h- a    char buf[16];  h6 H6 O" j' O- @$ }$ f
    int i=0;
; h/ c. @6 W( b8 a# F5 W% C    ' x' G; ^: K4 Q% c/ o" j2 p
    InitStack(optr); /*用于寄存运算符*/; l( w9 q7 e. `! W* @7 d
    InitStack(opnd); /*用于寄存操作数和计算结果*/
" T. R) r/ |! y7 m! d2 j5 {    memset(buf,0,sizeof(buf));) a5 k8 g/ w  ?( }) {$ X+ J
    $ ~* Y; a/ w) V( }, L
    printf("Enter your expression:");+ t+ n! b! R4 g3 [! _
        
7 {1 S4 s1 w, ?+ U! ~' X2 P8 Q    opr_in.ch='#';8 E% [* ?7 A, K  j/ V' Q: a$ U$ ]
    Push(optr,opr_in); /*'#'入栈*/
8 d' j4 ]3 i: D3 H5 H" \    GetTop(optr,opr_top);1 v3 o- W, B: l
    c=getchar();
0 T' d- X2 ?& N$ z5 [    while(c!='='||opr_top.ch!='#')0 d; P" y! B- f0 |' E" @" B2 A
    {9 k7 }' t, c+ b) Q* K5 H
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
1 n- D- U- X, z+ e' q0 w1 @        {
5 m' Q9 |% Z* W- X( G            buf=c;
3 V& R, l! a7 I/ y6 v            i++;; }8 n# ~- s, S: o  i4 r
            c=getchar();- _& z5 q! U5 c. S& Y
        }0 P+ ?$ U9 T# M* T+ ^1 I
        else /*是运算符*/) R0 t7 o6 [$ X2 k7 S# R# L
        {
, ~. Q: K" w  w            buf='\0';8 z: ]: s+ |9 v$ w
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/) r4 I5 l( B( D7 \
            {5 L  J5 u& T4 ?: e) a6 k) h/ E
                 opn_in.data=(float)atof(buf);8 M7 j! J) f6 V
                 Push(opnd,opn_in);
+ v! i% [3 X: y% q                 printf("opnd入栈:[%f]\n",opn_in.data);4 Y+ W2 J* p" c; S* O8 F) R, `5 G
                 i=0;
. V1 O) [6 U" B( R: p  O5 [: T                 memset(buf,0,sizeof(buf));# g9 W9 C- H1 C9 C3 N
            }) g& ]: J6 ^& n3 \. H4 a! o
            opr_in.ch=c;8 H' h0 j3 ^; D9 i+ O
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/. P. G5 V! y9 W0 V* \- s
            {! }* L" }+ x2 S: v# a1 f5 h9 H
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
7 s9 r( B; t* N                     Push(optr,opr_in);
* [" f# e' k8 ?5 z1 h' _                     printf("optr入栈:[%c]\n",opr_in.ch);  q& |$ b4 w' _7 ~" `: u4 C
                     c=getchar();$ o) c2 F+ I1 I+ f5 X, S* @
                     break;* z" a. l: ~# o4 `) ]
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
0 V2 Q4 ]% s8 T1 i( T+ B                     Pop(optr,e);
' c8 p0 Q+ D! d& `5 q- E1 h                     printf("optr出栈:去掉括号\n");
+ Y$ X5 g3 d: B, |                     c=getchar();; P2 N4 X# d6 Z3 r# ?
                     break;
2 s- N8 M& O1 P6 ^( u1 g                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/0 g; L" N6 C- `7 C  E5 Q
                     Pop(optr,opr_t);
( N  O5 Q1 S+ t' @3 N. J" K; p/ `  R1 q                     printf("optr出栈:[%c]\n",opr_t.ch);
) F$ n9 n8 g: h; c8 q! ~                     if(Pop(opnd,b)<0)) I% _$ o& K; J9 r  R+ K. f
                     {  m2 s6 s: d1 A: E" d
                         printf("Bad Input!\n");: \" u1 ?' p0 t& n; a3 K2 m( ?
                         fflush(stdin);
2 f6 ?4 H+ k# ]$ y, B! P/ w" k                         return -1;
. l6 k9 a  u* T# l                     }
1 K8 j) D+ [. G                     printf("opnd出栈:[%f]\n",b.data);
" t2 V5 P" f3 ~7 A. A: ~# e8 l$ L                     if(Pop(opnd,a)<0)
3 p/ j) g9 B0 }; w+ y( ?                     {
( o! B5 F1 [/ U2 O7 @                         printf("Bad Input!\n");/ J4 H0 {; y4 G1 k+ {
                         fflush(stdin);6 p: G+ S0 D1 B! X* ]* o
                         return -1;
0 e3 W+ Y, C! O7 P0 G2 L3 ~                     }1 j) Z2 \# h9 f. h' h
                     printf("opnd出栈:[%f]\n",a.data);. c# F* H0 F: F* a/ X8 G
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
& X- D0 Z( k/ P3 z( W$ H                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/. x  S  n3 {0 b9 [# K
                     printf("结果入栈:[%f]\n",opn_tmp.data);- o" S, i1 k) R" a
                     break;9 ~" U6 g, c1 k; T' L: c# J& w' B
            }
9 T" p' q" g/ R: J        }
$ E! }4 _: s: G; Q        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
1 y) L1 \6 I0 ?    }
/ C+ R% k' \* `- l' g5 b. }: |  H    GetTop(opnd,opn_tmp);
$ {. [8 i) m, E9 L2 k    DestroyStack(optr);
. Q$ W( z- |7 X    DestroyStack(opnd);* `+ F: T' x# v( Q0 {" P, k, G# ?5 N' M
    return opn_tmp.data;
6 \- K5 ]# T% ]& g1 j0 i2 e" P. l: S- y}
+ F/ c/ C; p( W- {9 G! k" d' a+ N5 n5 [  |# Y- I( f4 c( f# h
char *killzero(char *res,float result)0 v( H8 k# O% _0 d. Y
{
. T( N) k: K. g* M    int i;3 S$ w) d0 Y2 X2 ^+ b6 z' W( a, N
( D% s* G# }. \3 ^' j
    sprintf(res,"%f",result);) X" u4 S" d3 z1 Z8 t3 r& L
    i=(int)strlen(res)-1;
% Q0 ]9 U6 E$ a5 S. z    while(i&&res=='0')
6 @0 a% G6 A, O, S8 O$ U    {+ j, c) Z- e/ h: R+ O9 h2 W. B7 [
        res='\0';
* w% z) }. \# W4 h        i--;
  k( u0 I' J- ]- p+ k; Z, [0 [    }1 m; [' O7 g. @9 Q( I
    if(res=='.')+ s- p: x3 a' n" X; z2 s
        res='\0';
/ }+ Q0 u, P5 {8 ^% S" y, b    return res;  L0 C0 Y( [; O! b. f% N# b# A
}
4 V5 j7 P% _8 j/ r1 q/ j
, C+ u( j& o3 ~" iint main()
) @' Q/ `, i7 H7 w- s{
5 G3 C8 B  U3 D# f    char ch;
; {" }2 d! ~( @! a; B    char res[64];, }1 _+ W% ]: O% Z" w
    float result;; A! z: k7 e# b3 E% ]6 @
    while(1)6 ?$ {6 `" u8 ~. p
    {
4 i+ J) r# ~5 S5 O9 k; Z        result=compute();- I) x* [8 S* ]+ i
        printf("\nThe result is:%s\n",killzero(res,result));
, P$ H1 F$ f1 Q- `' k        printf("Do you want to continue(y/n)?:") ;3 Y3 ]+ S$ j6 @4 n
        ch=getch();
* q1 q/ ^3 o& a4 X, p        putchar(ch);  J9 x6 Q+ \: q$ S) L
        if(ch=='n'||ch=='N')  l( T3 b6 h6 {: u* X4 f
            break;
% f% W4 A) A  @        else+ a, [' k, K3 P) Y& W/ F9 n
            system("cls");+ n3 B' u# q2 m6 L8 J* p# }
    }
8 _' f" y& v  c4 n: Z    return 0;
+ y( ]* M+ M, }( o/ \9 v  y9 `$ G}

  M$ O$ C, x9 c4 V2 J, [! d  F# ]; x
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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