Board logo

标题: C语言表达式计算器 [打印本页]

作者: zw2004    时间: 2008-1-21 17:17     标题: C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.8 S% ~! f/ U! c1 l$ {
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=' R  D  I; m9 e$ `( n
/**************表达式计算器************/8 z" C; y6 ~& M2 \
#include <stdio.h>
% f- |% }- r( K2 B5 V* y#include <stdlib.h>
0 K: j* d; }: M/ d' b7 L( W3 D#include <string.h>- ?7 s% l1 A$ G
#include <conio.h>, c2 g$ t( P# I- G8 W$ v2 n
#include <malloc.h>! y) _/ a3 J7 l2 P
  X( H( }7 }2 j% t- `1 q# X
#define STACK_SIZE 1001 L, u, O5 x+ J3 Z5 o8 }' s5 L
#define APPEND_SIZE 107 C1 @; r: b9 U6 l2 L
; E! g$ m& Q  F6 N  a
struct SNode{
9 H& N8 x. e; y, R    float data; /*存放操作数或者计算结果*/
. {. [5 D/ h# L! }# p2 d- C    char ch; /*存放运算符*/
* ]( e, `$ Q$ t1 `% {};6 H4 y7 c3 |$ b- R) V+ {

' O4 k: o. X0 h3 \% }) M3 \6 Tstruct Stack{. v) O  I. W9 h
    SNode *top;
+ A. @- \7 c- D" K    SNode *base;
7 D# M7 Q. S; A/ O1 h    int size;2 e/ \4 ?0 ^; l5 E
};* [" A/ |% I7 P- g8 z3 p
' [0 Y' t' K0 D; a  C; ?) e0 x& z& A
/*栈操作函数*/( Y* y' T- x- d0 R. R1 z$ ~
int InitStack(Stack &S); /*创建栈*/
3 w8 q, x3 X  M) c  E* iint DestroyStack(Stack &S); /*销毁栈*/+ G# Q- }4 z+ c6 O4 I
int ClearStack(Stack &S); /*清空栈*/
1 Y% w- ~8 e! T8 u) {) lint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/' a/ C/ Y) n3 u' a
int Push(Stack &S,SNode e); /*将结点e压入栈*/7 Y5 Y# O- B( g7 h' ?8 P  w* T
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*// j& A) T# I0 t) {* f7 ]3 l% D
5 Q: K, Q' J; j# \! H
/*表达式计算器相关函数*/! P# O5 T2 j  X' Q( C
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
' ^7 C# N7 \0 T3 Sint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
  x2 ~* p! t9 @. N- F+ {& p0 b$ gfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/2 u2 _" X3 N* i
float compute(); /*表达式结算器主函数*/* o. j# a# `$ @7 [. N" O6 t. y. M5 t
char *killzero(float result); /*去掉结果后面的0*/
9 O% A6 i( c9 ^5 `# y9 S9 ^% w' ^$ k5 ~& J2 V3 N3 @
int InitStack(Stack &S)
7 Z& n+ Q! i' {{6 d! ^& i- H/ F2 F+ v
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));; `4 h8 R+ t; l7 j; [
    if(S.base==NULL)8 J. ~0 K# {. u2 a( b( x! c
    {) t7 L, [3 g0 A  }5 G" A
        printf("动态分配内存失败!");' {* N6 x! C- r* e+ f0 z8 j* Y
        return -1;
, D. X' g: ?; R4 E    }
. i4 J; w& o0 q1 e6 w0 T) h' l    S.top=S.base;$ l* w; _) X* j% P. G
    S.size=STACK_SIZE;1 I* k- \8 l2 u$ n' d
    return 0;! R- x, L+ R  z1 Y; M# S3 a7 s
}
+ l) y, R0 M  p- ?; }, ]& l# {1 U
! Y2 T9 g. U) Z2 `/ _! Sint DestroyStack(Stack &S)
" s+ q  v3 N6 @9 k{
% M5 M2 r! \8 o) ], \    free(S.base);& _5 b9 P6 T' X0 A5 q' D* y
    return 0;' X3 p2 ~; Z- N' e/ T( w# [
}* L6 Q1 f$ N" u+ ~+ Y5 ]

: t, t! p) }6 |. Zint ClearStack(Stack &S); `. O. r+ N# R  U
{
: b& m  [1 y. m2 z) N- M    S.top=S.base;: X+ D: o% J: J* y, T$ @
    return 0;
8 ^* q! u( x+ k$ M  `* b+ H% o) y}. w* n& Y; q& D$ h& C

: p0 U$ k/ p5 Nint GetTop(Stack S,SNode &e)1 \) h( s9 S, G$ v
{" B6 G6 E! {# S" {# Q7 F
    if(S.top==S.base)" ]! Q$ T0 T+ ?$ y
    {
0 ]& d( H' x* B! G        printf("栈以为空!");9 f1 m. s4 i0 }1 Z
        return -1;
) J! P4 q; [5 W) J, J4 v    }% M' O- A3 ?' M0 r  I
    e=*(S.top-1);
1 L  {4 K' v- m2 b5 N8 y    return 0;
3 S9 l7 U3 a+ C( @- h! C$ u}' \# U% N- N4 E+ w
( j( J' h1 X0 K, q6 G: Q
int Push(Stack &S,SNode e)
$ Q8 ^/ j% A1 R" D9 X{% c+ ]  c7 X" `- G# f
    if(S.top-S.base>=S.size)7 W3 `7 {1 n# v. |' J! M2 `
    {
' w+ t: M3 g5 X3 ?1 L9 V- z4 V        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));) _6 ~- |# ?* Z" ~% b
        if(S.base==NULL)  c0 g, x2 ]$ [! G! L
        {
: |% z" t. v8 H: n: L/ z            printf("动态分配内存失败!");; u! w0 ~4 A; }# J5 E% P
            return -1;
! g$ h8 O# \( f- [: P" j2 F- g5 N  {1 S        }
- K6 y8 d! @4 ]% }        S.top=S.base+S.size;+ S1 _1 F5 J; C- b/ }6 p
        S.size+=APPEND_SIZE;8 G% B4 H- g! {, R
    }
% m+ D5 p, v; ?  p* [' e    *S.top=e;
2 v( K  h9 R, _- q6 M) _3 M0 m    S.top++;
" m- N2 r& J3 B' e7 ~    return 0;; p5 J$ C3 @9 p# o
}! G6 L  V7 f& ]- [, [# T4 X

( g4 j2 n& i6 u; n; |/ M* Hint Pop(Stack &S,SNode &e)
' m3 d9 t8 O' A{+ W% Z) Q) w& Q$ @  n
    if(S.top==S.base)7 j; R- l) v# r3 u! A7 w  \$ j
    {  Q7 `5 y5 y+ |$ o& o* o5 |
        printf("栈为空!");
+ Y, v1 y! D( Z$ s        return -1;- q- a) Y: t. A  X, w9 W
    }: g; n4 l) F; \$ ^5 ^7 r' X
    e=*(S.top-1);
3 \7 G" a. C) ?/ w0 r    S.top--;  ^: e! t' R6 a- K
    return 0;& Y; s6 N0 _- B, A' l: C# ^
}
% ?& w* l. \+ n/ q+ |+ k$ m* l
# J; M& Z3 A% @& tchar get_precede(char s,char c)' D: |8 H& W1 I3 G. _
{
* [# b( D; k- ?0 Q    switch(s)
# ^! ?+ u0 @* x/ O, W) ^1 I    {; t  \. A  W6 t
        case '+':                 
: P; o3 e1 Y- p, q# i        case '-':" f7 M, M& c( k$ ~) T! j$ z
             if(c=='+'||c=='-')
1 l+ K- O# p# Q1 f) P                 return '>';4 W" z; T1 c' K+ @& N
             else if(c=='*'||c=='/')8 S9 k  K, r) E, [9 H% I
                 return '<';
( C" F7 C0 [3 ]) s( K             else if(c=='(')
, ]+ n0 h5 D# c# ]                 return '<';  H6 p* M6 Q& d: A4 a8 {
             else if(c==')')! {4 _  u, L( U$ L& n; H! @
                 return '>';
. i6 L3 j! g8 e! I2 X5 s6 Q$ \             else
+ |1 J6 n: W7 |7 A" h                 return '>';# F' v" S( q9 l) [. g2 F4 c
        case '*':. o4 {+ r6 }+ X
        case '/':* M! w& D( X5 u1 z, `
             if(c=='+'||c=='-')  m7 I) P) Q8 ]
                 return '>';
; |$ I: Z2 i8 }) d/ }; v             else if(c=='*'||c=='/')
* `2 O; k/ Y; F" O4 b' Q: I! o' N5 d                 return '>';
6 J0 A! q# J& V& `+ E             else if(c=='(')+ J4 @% L! \$ ^8 M
                 return '<';) m: Q4 Y3 B1 W# F5 o0 o
             else if(c==')')
9 J, v( Y2 t/ |3 l* ^& z  K                 return '>';3 H3 d; ?: C8 M" C. c- g1 h! f
             else* v8 M8 N6 t' J- f
                 return '>';
+ Z8 w8 v! A4 L, g2 l+ f8 j% f        case '(':
$ o9 N' ~+ H4 I2 b9 w             if(c=='+'||c=='-')/ i1 b7 c! A; q
                 return '<';
  K& f4 K; [6 O! @$ O! P             else if(c=='*'||c=='/')
% t& _/ u/ t  T- p0 S4 V                 return '<';
4 q# m1 d" _- b% E             else if(c=='(')
* F- P& p2 E) `; R: ]3 `1 _                 return '<';
7 b6 j. x/ S9 [- [. z# e             else if(c==')')
  S8 x! [  m. X3 e                 return '=';
: H3 ], S( \! U8 g5 Y8 o             else$ W7 Y/ t+ }/ B5 b$ B
                 return 'E';; C# ~( `: E' h% x0 S! P: S
        case ')':
7 M2 `. Z, s  m6 {! B             if(c=='+'||c=='-')% q3 O& R1 l9 |: U9 o2 L( f4 V
                 return '>';
6 r% E! M1 q  Z( m2 I) ]             else if(c=='*'||c=='/'), P  [4 \) D: E! B2 q
                 return '>';
0 y4 ~# j' ~# b- Q4 Q7 @3 n             else if(c=='(')  n5 D4 F# ?# j. h7 X2 C
                 return 'E';
4 {' p' H! P! o- a4 m+ U             else if(c==')')
! N  b. H7 b  p, V                 return '>';
# l$ R' [# ]8 [2 p, N/ V) l4 q             else
5 d" ?. G7 O  D& M( V                 return '>';
; q" B7 M2 O6 G: }  D: u. p        case '#':
1 u: v4 u9 x' L2 B$ L! A             if(c=='+'||c=='-')- o7 X) j0 a' T
                 return '<';
- Q7 R, F' C7 g             else if(c=='*'||c=='/')/ j5 a5 S4 S3 x3 V6 P( f1 Z5 H; |
                 return '<';
. f* P5 e5 x! q" a  N7 E5 \             else if(c=='(')
$ H5 Y8 G$ ]& X$ u5 m; {                 return '<';
9 e& z5 |' p7 G: L7 X% F) K% d6 i             else if(c==')')
5 S4 U3 Q0 ^/ [5 B0 u! U                 return 'E';1 u' P$ |, S5 F' [" D8 w4 G& N1 w
             else6 c- {, l! V( h" w. M! |
                 return '=';
/ F. X# y9 ]- x$ {( e' M. ^5 }        default:0 G- ~. E3 d) j/ g* ]5 B" v
             break;) u6 Y: B5 v: a; {, ]0 M3 ]
    }) E7 x6 r' }% L* u; H
    return 0;    1 f" r9 I' G# Q% a
}1 p. F# ?5 W# F6 p2 Z# n! @! n
! Z9 o4 |# a6 F. O; m2 ^
int isOpr(char c)
7 H! d( r! n) k# h& z- h{) c6 b7 u+ D6 p2 b
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
2 P  @3 M6 t4 @! y$ w        return 0;
0 M$ k. r/ {1 R  h- U8 w    else : i. C: Q( b4 H
        return 1;
1 r! f1 }( r' f' P* H/ ^$ X}
9 x# u1 A+ J! \" Q6 ?, ^& ~9 n& y* q- T8 O$ f- w- e
float operate(float x, char opr, float y)' ^* K8 ^) Y+ \3 `9 ^: ^+ y
{6 @: A0 U" A3 F. @, K8 K
    float result;
# u4 R5 _8 l! j* T4 F: j' o: x% W    switch (opr)
3 k+ C% M1 z3 e5 r; e2 U/ O    {1 m' W" M( m% |$ e- D/ P& e
        case '+': & M: _3 |1 \+ K* W. g' i
             result = x + y;" w# P2 ~$ p  W2 i9 L1 l
             break;$ g9 Q+ u5 k2 V
        case '-':
8 _% _& u; Q  ]9 P- v3 V" @. {             result = x - y;
( b' n. k6 d# x9 H2 C4 z* z             break;
9 M0 \  L( }- a( B; w3 o( B        case '*':
& y# L4 n. M, G& f             result = x * y;, D0 y  Q: Y, v9 D! c6 `) P
             break;
& `( A" p/ i; m+ W        case '/': " J" J2 y* T( l
             if (y == 0)7 z! o' l" M& \9 l9 u  c8 [% r" ]! F
             {
" C8 I2 t* I* P& y* H. }                printf("Divided by zero!\n");
0 \1 X* V( j5 R" B                return 0;
+ c, N2 o( o' E: M- q             }1 g3 K1 K) A0 C; P* O3 ]
             else# O9 `9 R) K, V6 @
             {
& ?2 S: A1 Z' E: H. O, _) V: V: @                 result = x / y;
& u0 D) o% S; ?. t- v7 D# L                 break;
- C) U3 x( P" T7 G& a             }
9 R; X" R+ Q% U3 }* j. c- C       default: ' ~$ T, i! w  c' G
             printf("Bad Input.\n");
/ F9 l, T0 F8 P; k- F             return 0;
1 f3 f, I7 o' m+ p& a4 x    }
3 Y8 c3 `& V6 g3 X    return result;& [. Z6 M% Y6 t
}    + j6 o% e" u- z1 t9 W. J

& B! E! {4 `! f0 ]* x9 O% Sfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
3 _6 u/ T, h# }- i/ ~  |- w; v{; _+ p% t& s% e
    Stack optr,opnd;
( a# k$ P. X* [7 d4 d    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;* x# t( Y: i! |4 @  @8 ^6 Z
    char c;% }0 c8 Q$ l0 n2 _  }! r+ W+ [
    char buf[16];/ ]( f& G  o( [
    int i=0;
& ?. k% T) F! p. J$ D& q& D    2 j0 G3 G) m. f; o
    InitStack(optr); /*用于寄存运算符*/2 f" @# t5 E- E. b! w' o1 |
    InitStack(opnd); /*用于寄存操作数和计算结果*/
" A& |% }, _" R7 V% g. u% [, [    memset(buf,0,sizeof(buf));
$ |- G: k" I% Q2 N/ j+ x    9 ]3 ?6 {+ G5 A( B
    printf("Enter your expression:");* O& t; Z1 P  Y& p- }
        
! e. r# Q% B0 I8 c9 @    opr_in.ch='#';
6 C2 q: {. b/ a1 t! H0 r    Push(optr,opr_in); /*'#'入栈*/
! _1 A, {, D# n7 U6 N/ O8 K. K& H/ B    GetTop(optr,opr_top);# G: Q3 S; z' p2 ]
    c=getchar();
8 Q8 \5 U6 u' p& D. ^    while(c!='='||opr_top.ch!='#')* b" I9 Q* @3 J" d- G5 J
    {0 e4 I1 I  ]' v: n5 V# H3 l
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/4 e* A0 W, q; w1 O; R$ q
        {
4 k% `9 Q/ O2 S. [$ l# Q; L            buf=c;; m6 \" b2 V% a0 ?
            i++;
/ N% F4 q, o* J. b- W            c=getchar();
3 l+ b0 S) ~- Q& u3 {+ Q4 M. |) u        }1 N8 F3 R# R0 l, @  s0 t6 g) W
        else /*是运算符*/0 _( b; w) c/ M8 a. ^- h
        {6 @% p+ h. O  p- y9 J! E; P/ x
            buf='\0';2 E5 X  L+ g% G2 o, A
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/  F  H5 X+ W; K
            {* }- H# x" @9 Y. A
                 opn_in.data=(float)atof(buf);: h$ ?0 x6 X- _! _9 x* T
                 Push(opnd,opn_in);+ e* P# a, j: S
                 printf("opnd入栈:[%f]\n",opn_in.data);
( c5 H2 D( g3 o% h! ^% e                 i=0;' i$ Y! V- v! O+ E* t3 h7 _
                 memset(buf,0,sizeof(buf));
! ]- G$ n! E% f9 d4 j7 R# b# E            }1 k. {# @) n8 b* q1 f
            opr_in.ch=c;
8 |: F. H4 {) Z& U+ G) k9 F            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
3 Q/ ?  j3 s7 Z& L. X            {( q  W0 K( b% y  S
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
3 ]- g7 }$ [7 R/ R+ ]* {& b' n                     Push(optr,opr_in);7 e) ~: _9 t2 `; p. J5 m
                     printf("optr入栈:[%c]\n",opr_in.ch);
2 Z, W; P  a' o' }# F                     c=getchar();
  ]( J. R9 L8 p# w4 Z' _* U4 K5 [                     break;
: N" S/ G: n7 G% U% k8 ]                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/3 {/ @; \3 ]5 [0 ]# K+ Y) d" S" `
                     Pop(optr,e);
8 V% I3 ~4 C9 y                     printf("optr出栈:去掉括号\n");4 A5 V4 J& i. L5 v
                     c=getchar();6 |; X+ P' P0 Z. Z
                     break;
3 I4 W7 t) V3 [5 o' q3 O% S                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/0 M8 r2 q' T+ l) ]* y
                     Pop(optr,opr_t);
' z' J4 T$ a; D5 ]# h                     printf("optr出栈:[%c]\n",opr_t.ch);
9 k3 K, n$ x4 f; N" U2 e* L+ W2 g                     if(Pop(opnd,b)<0)6 f* p6 G# f, O
                     {% P) c* y3 L" U
                         printf("Bad Input!\n");
6 _  I7 M0 T+ A6 Q, o                         fflush(stdin);( |* P# F4 n$ J  d: [6 o
                         return -1;0 R2 E3 f+ c, g4 P1 q
                     }, [/ D$ Y' ]7 x
                     printf("opnd出栈:[%f]\n",b.data);4 e- ]9 o; h( j
                     if(Pop(opnd,a)<0)7 _! r$ B" I* Y
                     {
. a8 [% W$ @1 Q# k6 _                         printf("Bad Input!\n");( U; p; }; Z4 G6 f" x9 |: I# s+ m
                         fflush(stdin);! I" n% j& B8 M% v" F+ ~1 I
                         return -1;# y% M  _# _2 s9 Z- y' w; }
                     }
0 o3 _) u: I' ]4 ~  T, f; z                     printf("opnd出栈:[%f]\n",a.data);
$ o4 R& ]& h5 `3 [" x5 D! R                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/; \) c# c/ f2 L0 S
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/1 j5 l- @/ S5 A  M# }
                     printf("结果入栈:[%f]\n",opn_tmp.data);
0 H0 R: h/ q& E4 ^" D                     break;
6 }' P2 L9 `, P4 F            }+ J0 [. c+ j  F- E, j
        }3 j0 H' R  N2 U1 k
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
8 ?' t, [! U' C$ W    }( Y% I7 _4 Y  p
    GetTop(opnd,opn_tmp);
: I- z' w, Q) i  U4 N6 l/ M    DestroyStack(optr);
8 g: _& b& Z: y    DestroyStack(opnd);0 I' k% w! Q, E0 q9 U; s3 Z
    return opn_tmp.data;9 h6 l' a' O, y& I6 c9 b
}
& ~9 \8 h+ ?8 Y7 V4 E, k# g$ H4 z3 E" V+ I; Q
char *killzero(char *res,float result), S, t) a# Q- g- c4 h% x
{
% E: q1 h4 ~4 V1 ^    int i;: x! g0 j2 e$ F

# Q5 M+ E* }2 \* y! a- Y    sprintf(res,"%f",result);
; \+ }0 e/ t( z. P1 \) T& }    i=(int)strlen(res)-1;* y$ |* x* }; a$ \( w. @. l
    while(i&&res=='0')
! A, w* f3 X5 v7 R- G    {7 Y1 k; \7 ?9 y! r( x
        res='\0';7 f7 y5 \5 d9 H9 ]# O
        i--;
7 ~0 ^' I% R5 a, M( c2 L' v( V    }' z# k. d, m4 H( \8 H' Q! L
    if(res=='.')
6 ?" J) e( y( D  @1 J        res='\0';
( S+ m* E  S5 F: ]    return res;7 V: o, T- u6 ~6 A
}
6 Z4 A6 k1 l  `9 n5 \3 v+ B" y+ r% n- A" p% ?7 g2 |& ]; X6 p
int main()
( _3 K. N# l7 F8 M; _  t, O4 }{' A# }% `# f2 p
    char ch;6 T0 z$ P3 R. Y% H, s# U* I
    char res[64];  l6 X# d" P5 R9 e/ l
    float result;
/ I, R8 A; ]' h! x. v, q' a    while(1), e" J$ Q. r, H4 M2 H3 g
    {
1 Z% N. Z' C6 m4 y& a) J) X7 u, N9 q        result=compute();
" G  c/ G% u( i) m" Y        printf("\nThe result is:%s\n",killzero(res,result));4 b  l* Z2 Y0 U5 y2 `! O) S
        printf("Do you want to continue(y/n)?:") ;
/ N! f7 W2 ~! k- m* l, f        ch=getch();/ v9 I& T  w, ^% H- z2 U& t
        putchar(ch);) v3 S  y! a" K. I- @+ G
        if(ch=='n'||ch=='N')
8 v; Z6 ?9 A; H* [. r# n. ?5 Z  N7 }            break;  w0 ^1 E$ ?7 F7 u, I. w
        else- @' i; m( N) f7 S
            system("cls");
( E! F2 f: ?' C    }. p+ H1 z* ^5 p
    return 0;( r2 r# P6 z$ B9 F
}

4 H+ d8 W) y: z+ }' f* }8 w+ l6 x/ u3 B) m
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




欢迎光临 捌玖网络工作室 (http://www.89w.org/) Powered by Discuz! 7.2