获得本站免费赞助空间请点这里
返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.- x, _6 @/ v. U  s* `% J) y
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=" q6 o4 Z" d# a7 e. R* h
/**************表达式计算器************/
1 y6 A4 h4 c# x: {! P#include <stdio.h>
1 a# s# T" e% E0 f0 K#include <stdlib.h>
4 x; f! T/ w/ D1 m8 d#include <string.h>; S. X- m; ?0 T# r9 L) P3 Y
#include <conio.h>: ]: s- B% Q1 X2 N
#include <malloc.h>7 l2 |- U) q! n
  s( ^! n+ l5 V, q; I2 D
#define STACK_SIZE 100
% O4 E4 Q" a  Z3 ~% [, s. }1 f. c#define APPEND_SIZE 10
& }) ^3 L* `1 y3 O
5 u. V- R" O2 T4 _struct SNode{! I- c' o+ Z3 K) Q, l# Q( S. D$ O
    float data; /*存放操作数或者计算结果*/  E0 P, G  w$ l
    char ch; /*存放运算符*/
/ U. E9 f3 P4 S- {1 x% g2 A};2 u2 ~& J2 Q4 O/ Z9 N$ g7 z# d
: g0 ?7 I. a8 j: h
struct Stack{
  B$ i/ y# D: F6 \; }: W    SNode *top;8 ^; p3 c) K6 H! e
    SNode *base;
: k, x2 X3 S$ O+ S. |1 l: a    int size;
. G8 i0 a) H+ b& r9 q9 X, t! b4 g};1 M! c9 f6 A" |9 Y9 q" O
7 }, S, C. [- O: i4 }
/*栈操作函数*/* u  {2 k  O# _1 }
int InitStack(Stack &S); /*创建栈*/, Q) k0 K; I! d( Z( }9 T* D
int DestroyStack(Stack &S); /*销毁栈*/
7 s# W& `  x) [! N' ^int ClearStack(Stack &S); /*清空栈*/4 D4 H4 X- L/ C. R$ e2 r; M
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/1 o  s: W; i, ]( F5 ~6 o& h
int Push(Stack &S,SNode e); /*将结点e压入栈*/& b' p: q) U9 R, \- k/ A  Q
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/  D+ m' H3 v  P5 v0 U+ V# {
6 H5 ^7 }9 _# n5 G* d, @' D* P
/*表达式计算器相关函数*// H: k: [$ X0 M: e! P' R
char get_precede(char s,char c); /*判断运算符s和c的优先级*/* i& A  {6 G) r
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
+ `0 n& V6 k: ]8 r& @5 pfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
. H4 y+ O: U* m9 s8 Q& A1 Ufloat compute(); /*表达式结算器主函数*/$ H  z# ?- V' G* @, A
char *killzero(float result); /*去掉结果后面的0*/ 9 N. z' t0 n1 _% W! j  l

9 \# u+ S/ J! G! A1 w+ e/ _int InitStack(Stack &S)( ], K" y; D9 C* j. C6 P
{3 X7 e6 u. {# Y& D) ~# p* _5 l2 X
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
, p1 w( |% g( P5 z  X( B7 ?4 ~    if(S.base==NULL). X# q4 E) J7 r3 q' K+ F
    {
( v& i& X3 S1 \& K' L7 n8 y) W        printf("动态分配内存失败!");
$ s2 y, p6 m: J2 x  D4 @        return -1;* h& v9 I9 L) c! S
    }& ?, }+ n. ?1 ?) P3 C% j% v: g
    S.top=S.base;9 V9 [0 J# z7 ~. T0 x% Q" S
    S.size=STACK_SIZE;
" O6 E% x% v! k5 `! t    return 0;
: `9 @; K; p. A$ d" ~4 J}
/ d. E) D1 H: w; X8 Q8 m, D
, u0 }( v' Z$ \( x3 d2 `int DestroyStack(Stack &S)
" L8 b& O6 U) O+ ]+ X3 ^{- L* v# K* f* f1 V
    free(S.base);
' S$ T# b  x1 h+ S4 S    return 0;
* n  m' A; D% `: m" r}7 V5 q& c# V: L7 R- o" f! c

) }9 T8 ~2 x; J& u+ I! s: T3 ?int ClearStack(Stack &S)! \/ [2 V$ o$ b8 ~
{; p" i* r% n0 q# E( q
    S.top=S.base;
' C; Y( k) C& |4 D, V( [% A$ O    return 0;
  s9 V! w, [: ~) t0 E. Q}! m. m$ s* F5 r% r/ ]

) J6 V4 J2 B1 B, Vint GetTop(Stack S,SNode &e)
/ a5 h$ V+ Y; }4 e{
0 n& s" U: r! x    if(S.top==S.base)
7 m5 Z* [) m$ D: t: y! [8 C! i! t    {2 ~1 {. A2 G) s- X1 ~
        printf("栈以为空!");
5 U: A4 a! r6 m+ ^- Y- f# Y2 w        return -1;5 r2 ]0 W1 T" c5 R. f. t! ]
    }6 b' J9 [( Q9 M' l0 \8 ^
    e=*(S.top-1);
% ~3 M. q) w3 m, h$ a" T' ?    return 0;2 x4 I' e* t2 r5 H5 R
}% k1 L) g' {' c4 {- q
$ v. U" x2 _  n
int Push(Stack &S,SNode e)/ A: ~  K# r7 J2 k. r) e
{
$ @& \/ B; v2 h; N    if(S.top-S.base>=S.size)0 A! s+ L$ G. m7 @
    {$ I4 U9 I0 M  @4 V4 i$ w* R
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));* O$ I. V/ P/ L
        if(S.base==NULL)# f1 r/ ]! U- N3 s8 l+ f1 d8 `
        {# E- |, N, H- t1 w# W, r
            printf("动态分配内存失败!");
$ e* n7 L0 |% y7 g            return -1;9 E5 J) ^1 N# w3 k( C1 F
        }
  R: }+ W7 m2 C% _        S.top=S.base+S.size;
! M$ X8 F9 P. n+ d        S.size+=APPEND_SIZE;
5 e! d& A2 e1 u    }( y6 |9 {+ ?' N6 @1 t# D
    *S.top=e;
* ^5 x, k! j, k9 n8 U) x- i    S.top++;& ^1 J0 x, k7 y( k' B" d& ~4 W
    return 0;. [3 `; C( \, v
}" a3 `8 V. T9 n! H2 D3 k& W- b

( G; t' c" c/ f3 ]! {int Pop(Stack &S,SNode &e)* g" d* P+ p; E
{
' v# z2 l# D2 C- Z$ |) _    if(S.top==S.base)& |% O; j( }, W# J8 h
    {9 F7 x) R: A8 q7 g8 C0 h2 M
        printf("栈为空!");
: B. D8 ^7 t: |0 Z( Q. N1 o        return -1;2 ]+ c! p+ t" z) O% h" `0 f
    }
2 h: ?' K! c6 W% R8 Z) S9 ~! x    e=*(S.top-1);; g0 ]) \: l8 ^- x+ v
    S.top--;. |/ `9 p7 H: O8 Q
    return 0;
% P5 n8 M( `4 C7 [}0 _4 G9 `5 n% Q# F1 F/ @, u
: a. `4 p3 D: O* T1 g  _' y
char get_precede(char s,char c)
  z4 y  s5 h( u& |6 {! ]{) f; G1 J3 O0 p" P3 |( \' ?# a
    switch(s)3 Z0 _+ D( {3 B1 ^
    {
+ i! u2 _) }; A! \        case '+':                   F6 t7 ?2 s% @( S) l- r& q
        case '-':
$ P( ^& s$ O, f3 @+ K; E- M; C             if(c=='+'||c=='-')% \& Y% j2 g6 _& H# C" o
                 return '>';  f6 N9 L+ h* q- j" Z$ N; Z7 T1 N  |
             else if(c=='*'||c=='/')
6 ?6 j" c+ r9 u! a6 W/ A                 return '<';; \* S* b! u$ ?" [1 x$ j( T
             else if(c=='(')
. `  u: B- }# V& Y1 Y                 return '<';# d: b1 A( l- l$ @! ?! B4 O+ A* r
             else if(c==')')) y# f. Z4 [3 Y1 g6 h
                 return '>';
. o0 }5 Z" T# r" u; E2 y: {8 |             else
, r" k9 s- c  _/ T0 f: |+ d                 return '>';4 B' X' H& t6 B& p: y8 @
        case '*':: e8 d/ @# N2 c/ h, p' v
        case '/':# n: Z5 i. {, {9 W
             if(c=='+'||c=='-')( _' g0 p! s1 z; F& z: y2 y- K0 |' b8 ^
                 return '>';
1 Z& Z* x6 [7 b" v8 o             else if(c=='*'||c=='/'): O; W9 I1 m2 W% V( w7 }0 ~
                 return '>';
( w: b% S1 W& t5 n7 {             else if(c=='(')
& Y2 n" e. H2 P* H. ~: r                 return '<';" O$ Q# l" E" Y! X  g
             else if(c==')')
, ]" O2 Y! r" U% Y                 return '>';$ S# ]4 C4 J2 a# ^
             else/ o# P. _4 c. {$ l5 |% k
                 return '>';
2 `' F, h# ?; V4 N+ X        case '(':2 D( m2 n* p/ |, O' O0 P9 N: ^
             if(c=='+'||c=='-')- b" S, y6 i" e. R
                 return '<';$ U: p1 {! e& d1 y3 \
             else if(c=='*'||c=='/')
$ C  E8 @  @  `# g& k                 return '<';1 G# h9 k; Z3 l1 L6 I( {
             else if(c=='(')/ o% N3 b0 ~& C: o8 {9 k) o
                 return '<';
) u5 E# v" D' Q$ O) X, h             else if(c==')')8 f1 w- @+ H7 U; U, M# N2 r
                 return '=';
( C% C! d- R. J  |             else
( e( t- R; _1 q1 `2 p0 x. e! ~  a) S% Z                 return 'E';$ l) W1 D* J9 ~0 k/ H; Z( d$ w
        case ')':( p$ U6 u1 w, ?; F( V6 Q! C5 O
             if(c=='+'||c=='-')4 g( o  k% k2 k7 u. `+ X. z
                 return '>';
+ o2 `& n4 T  B8 l) Q             else if(c=='*'||c=='/')
% A' }' L3 o6 S: e. r/ ?; j                 return '>';
' N! k7 S$ P3 X4 J             else if(c=='(')
2 \9 J2 M  I2 z( A  V/ x/ n7 o                 return 'E';& U8 C" O2 T, b% j& n. x
             else if(c==')')1 ]' R# p0 F2 |  R' G6 N/ G
                 return '>';+ \4 u2 d* F" \( ]! u8 {& U3 a
             else
$ W* g5 x# T1 k7 C( E                 return '>';5 x6 v9 z8 C1 d
        case '#':
* ]) `; }2 W5 f/ `  n             if(c=='+'||c=='-')
+ r5 _; L( R0 D2 h% n( B' R                 return '<';& R7 m  g. O9 e- c0 p9 S
             else if(c=='*'||c=='/')
9 O+ N8 }1 e) w5 x. e0 N" q7 ~                 return '<';% ]8 ~3 b( A4 S
             else if(c=='(')7 s% f* _( e; f. c3 S& z2 I
                 return '<';0 ~) `4 Q$ P$ o* X3 Y0 `, i9 S
             else if(c==')')
$ U' ]1 `, N% `, A                 return 'E';
, S; l/ A) H* ]$ L9 D3 B: o( k             else
) s- H! A  ?  i2 ~                 return '=';
4 f) U" |) {& l" b# q) S5 u        default:
. t0 Q6 h" i7 Z3 U2 M; u$ A             break;# {5 v' P- i+ u5 R$ S& G3 i# r
    }# A) R' k( X  z, i
    return 0;    ! f) W5 M! T8 u7 f! D9 D# S- O6 T
}
3 Z; f; E% E" c3 ~4 {: j
: z  _3 c1 o- Y, |: Iint isOpr(char c): }6 ]6 N: z4 a' A
{: {. w$ I- Z9 Z* Y
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')! a/ ]( \9 F; b  a: H
        return 0;3 ?8 a9 G$ O1 ^; D: f
    else
+ P; @2 W3 j- Z* G2 O. d, I        return 1;
9 c3 G- E8 Y& V. C' Z}
0 l- \: o! m# A! V0 [& ?
# e0 h$ f8 ^8 x- n0 Xfloat operate(float x, char opr, float y), p2 c' S$ {8 p+ p6 u/ C) m. R; X% A
{
. i2 i( Z9 k. ^    float result;  y8 C& U9 K3 Q' ^
    switch (opr)
$ q7 x* S" _9 C- @) o0 Y" M! c    {
) t: c+ @% T3 d6 I$ g: d2 d        case '+':
( x+ m. ~% n- t& x  G- W- r8 h) Q             result = x + y;( }! D6 z& \0 _' W* X, a
             break;
5 ?; N9 g& f, r. V1 |5 z0 @' z        case '-':
0 H5 m$ w$ u9 o8 Q             result = x - y;
8 `' ?  L8 l: T2 d6 m# W1 d             break;( H6 C$ G6 t4 n* P7 U, C
        case '*':
6 F8 Z4 ?* W" Q6 M- T' e             result = x * y;4 j! Y2 F  j) g3 _. |# D
             break;
" Z- t, P% s1 a2 ]# d        case '/':
6 i  Z+ E! i% j* e& I; n* {/ |# ?             if (y == 0)1 r" ~8 r6 T$ L, m$ @/ M
             {" Q# d9 w/ ?- {, ?
                printf("Divided by zero!\n");
  I6 `. e* d/ e: \0 d; a" }                return 0;
& s- ~! Y2 Y& `2 F( l2 O             }
! A1 Y* F2 F/ d& y  A: D4 L8 A! K             else
- @8 C* s  a6 w% g1 P+ C             {
/ Z  Q% h0 C  X$ m0 n# }' k8 o                 result = x / y;3 S9 s0 T2 L4 O0 N0 q
                 break;
/ A3 v4 r+ ~# g" ?$ f7 ?  c+ w             }2 H* w, {, |$ z" K% `7 k3 l
       default:
% X; O6 q5 i8 V# T6 h             printf("Bad Input.\n");
% u, T! ]1 ?4 v- K             return 0;
5 v% P8 V' P# q3 U( V: ]) d2 E    }' ~. @# ?& Q% W% R# v. p5 ]
    return result;* G2 ?0 ^7 \. e- X/ f5 X) u% y. r- [! A
}    % s" C1 S" }9 Y$ S, a" Z1 y; U' k
4 R2 O7 C2 R+ h) D! b
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/% f1 u2 b4 @" t( w% z
{
8 w3 ~* Y6 O* o8 |    Stack optr,opnd;: K4 q2 z- y# z8 j
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
4 x8 ~) E# ?" Q    char c;
' Q& B. B# `. {    char buf[16];
; e  b! K6 ^" I9 |0 T/ m    int i=0;
4 C7 o( o0 _# }2 L. y# }   
; ~1 v- R3 u8 h7 T+ h: n+ F$ B    InitStack(optr); /*用于寄存运算符*/4 c, }+ s) b, C5 |/ g* D! R
    InitStack(opnd); /*用于寄存操作数和计算结果*/; _; v! t) U2 o" z6 P2 w
    memset(buf,0,sizeof(buf));
4 J) @+ c# x) C, s  _- {$ f+ ?& x   
2 C, p% D$ N+ @2 u0 ?& u- @    printf("Enter your expression:");
) o7 ]0 A1 C" X8 K8 V        0 ]( k; |- E* n3 J% c
    opr_in.ch='#';- U# {3 ~6 g) d; M
    Push(optr,opr_in); /*'#'入栈*/$ C$ H$ d+ z, ?0 C4 c( q
    GetTop(optr,opr_top);
( `) a9 {4 [4 Q: b$ n    c=getchar();# p  I# g8 G2 U# H* Y( \1 C* |
    while(c!='='||opr_top.ch!='#')
4 b, K3 b* ~6 k7 R. P    {9 M6 t; ?* D8 E
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' s  P6 ]' W8 N" K" `9 i        {
) ^, R6 R/ l: j0 N" }0 {+ K            buf=c;
( {9 u' m7 m# z$ T* w+ D" F            i++;$ |2 J- L8 {* n' Q  i
            c=getchar();9 O; d; ~8 P7 _
        }
7 s" u. [8 f6 h& K        else /*是运算符*/4 ], i0 S( _5 C( g
        {
$ _: n) O, l5 d- O; n* y4 M            buf='\0';
* Q, t( W- W4 X" T$ T8 G            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
4 z' N, Q5 u3 N8 T: y& {- D            {
& J  `7 a. K. ~% c( c- f( D                 opn_in.data=(float)atof(buf);( ?8 l7 [) i, L8 a
                 Push(opnd,opn_in);
+ ?1 F, m9 \& o6 U, L1 I* h                 printf("opnd入栈:[%f]\n",opn_in.data);6 n$ P6 g2 B  Q0 u! C  q& b
                 i=0;5 S6 T7 m) U& U
                 memset(buf,0,sizeof(buf));4 ^4 C: }2 {0 X+ a  o# `
            }9 p" R6 r  H8 }0 ^/ C9 k
            opr_in.ch=c;
0 T) h1 y: p. E4 _* @+ B            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/( ~* n7 n! R* y, N) u
            {
9 K5 K; N8 ~3 O- o                case '<': /*优先级小于栈顶结点,则运算符入栈*/8 X0 }% j1 u8 r8 p/ d
                     Push(optr,opr_in);
. V) @! Z; w9 I: d( v                     printf("optr入栈:[%c]\n",opr_in.ch);% b3 K- p" r6 b
                     c=getchar();
7 p7 [: [+ F: n8 C7 a                     break;
- u) h. X/ M; a5 s                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 F" }9 b) ]& d6 t: l* x7 A
                     Pop(optr,e);" {2 P# }$ i+ Z0 i( T! K; e) ^+ d4 T0 u
                     printf("optr出栈:去掉括号\n");
* F2 c# x: e* a; @" K$ X+ @                     c=getchar();+ v& {2 ]( q" K
                     break;6 E/ P: N  w# z5 E
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*// k: a2 n; @6 C
                     Pop(optr,opr_t);, t' c# S; K$ }% ?
                     printf("optr出栈:[%c]\n",opr_t.ch);7 k, r2 A. ]: ]7 V4 F! E5 E
                     if(Pop(opnd,b)<0)
0 i- L! p' U6 r/ w7 R                     {
/ \( A; W2 f5 e; `5 e                         printf("Bad Input!\n");1 E6 H: k% t* t8 p" f
                         fflush(stdin);
( `# D5 |: O2 p& R- |                         return -1;, G" [" y2 }" D' I
                     }
/ Q- X  N: ]- L; K8 W                     printf("opnd出栈:[%f]\n",b.data);1 J2 \: ~4 D2 ?# B; U1 ~% i1 t4 R
                     if(Pop(opnd,a)<0)
. S- @! e: Y: t2 \                     {7 b  q5 |7 u, ^/ c6 d7 Y% u8 F! I
                         printf("Bad Input!\n");
# C! ]: r# R2 w5 \) a                         fflush(stdin);
; [  x$ s6 b& S# M6 e, j( ]                         return -1;4 y# V- z; F' w6 Z7 M3 N6 B2 t
                     }
- @/ P" L6 L5 }3 v3 B6 Q* L" H! `                     printf("opnd出栈:[%f]\n",a.data);1 t  \. U# E+ ?& p
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
2 j4 p/ `. a8 w& N  M' F& |                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
3 p0 f( K3 e/ f5 z# O: _                     printf("结果入栈:[%f]\n",opn_tmp.data);
3 Z' G( N2 o9 f5 @                     break;; D$ |% S( W* H# x% H4 K2 o, T
            }
3 u7 g! X1 L6 V( m9 \* N6 T        }
" E" h8 }, [1 u$ q, y9 e        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
6 h# K5 |. o+ x7 V    }
6 N& P' _+ b5 V1 F    GetTop(opnd,opn_tmp);( L4 S, {3 R6 s* R5 k
    DestroyStack(optr);
% H, \8 W. h/ V; M$ C: d    DestroyStack(opnd);
( x& J2 z1 Q/ d4 F4 ]; [7 v    return opn_tmp.data;
$ d9 e" x: v1 o" w  N& v; y}" j; K! j* ~- c3 \+ Z+ X  @+ }& p

6 e# d" _9 {  L8 h" I) |char *killzero(char *res,float result)5 z. z* V; x# [2 V) P
{
! @7 N) l7 {$ H+ }* o/ E1 K    int i;
% E" J, |5 p% z6 A0 f
" b! W4 a; h& v/ J    sprintf(res,"%f",result);
1 l: ?4 {3 o& p  \7 l7 R2 I    i=(int)strlen(res)-1;
/ b' ^5 h$ T2 c+ h" s8 E. j    while(i&&res=='0')3 Q% s' S1 E1 o* D
    {: H1 Y4 H7 o2 d  Z3 l
        res='\0';9 ?8 f- W9 X, [* W9 d1 g5 D% }
        i--;% ]1 S# P* g% m: b! P* f
    }
$ Z2 P* a2 m2 u& s    if(res=='.')
& s# J: |; t' F# w4 e        res='\0';# t1 i5 F9 K, Q3 W# r# K1 O0 f
    return res;
# A$ P. [+ n& [1 P; L, b) I. f; |4 N}0 p5 F: X0 w8 F; K2 v0 n1 K7 O

, ^4 u* i$ W* ?) p* t1 @: [" \3 |  xint main()
0 J/ s/ I& V# S; W% T) ]0 m. V{
: `+ @4 l1 K6 h/ T6 m6 }    char ch;2 H- z, ^( h! L2 n
    char res[64];8 @, A/ |- \1 [, z# ?3 b& f
    float result;1 R( _. d! m6 P! J, z2 e
    while(1)
) u3 w  p( o$ D' B    {
9 q3 P1 o% N* _6 j9 {( E  z( Q  J        result=compute();9 P9 {, C/ ~! @: D+ R% ?% v
        printf("\nThe result is:%s\n",killzero(res,result));7 c$ P8 s9 I; f# W8 H& q
        printf("Do you want to continue(y/n)?:") ;
0 q) h1 q1 u7 F3 d4 m6 u        ch=getch();5 T; _8 R- }# N1 D7 U) u; X
        putchar(ch);
" t6 C/ x' C+ g* Z) M9 U% s% T        if(ch=='n'||ch=='N')
+ p1 e; v+ E8 R. t, z            break;3 v7 m" i  t+ g
        else
4 c2 A6 W% _/ b4 w9 a/ F& R2 ~7 g            system("cls");, \0 X$ H9 H: Z( F: H  ^
    }) J7 h' Y/ k6 ?! B* U4 U) V
    return 0;
6 ^4 m% t+ U" M& y3 q* w: W}
  Z9 I+ a# U% w0 z2 u& D
% ~& P5 O& ]' [
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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