返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5 }# J9 u9 }3 a7 M1 ]程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=. C( |# j, D1 \( D
/**************表达式计算器************/8 c- ~7 \9 a+ q! U+ V3 P" Z
#include <stdio.h>
0 D* o* ~" J* n8 _8 @#include <stdlib.h>
0 j3 @, B' Z. b3 u" M& ?/ B#include <string.h>( O; n/ A  Z* V
#include <conio.h>
5 X* {. r' Y5 |3 u+ F#include <malloc.h>  y; R7 U" f' e3 Z

5 Y1 f& L  T- U- c* ^#define STACK_SIZE 1005 C! V" u+ `# C9 O( Y* j  f
#define APPEND_SIZE 10
/ E$ {$ o: I& D2 T. N! f" @+ _1 r* J$ v2 U
struct SNode{
( e# Q/ b: q# K0 m  \    float data; /*存放操作数或者计算结果*/+ Q2 w8 b  [' j7 D* ]$ z2 T: u
    char ch; /*存放运算符*/
$ n* l' C. |* A. j  J0 ^; ~};5 ?0 ~% B: ^- L, ~8 ]' x- Z! k  _

% [9 H" Q# a- Ystruct Stack{
* v1 A: F& L+ x! e    SNode *top;
) D. q' W. ?5 c- o    SNode *base;1 U& h7 @  y, l: W, u  K% N7 r2 b& c( n0 W
    int size;
  _1 n$ u" \& \3 M$ G" ?9 P: n$ n};
& p  G2 v, s0 M6 ?
+ m3 r4 X9 s6 ~1 D/*栈操作函数*/
( Y& q4 p6 m; y# N3 eint InitStack(Stack &S); /*创建栈*/0 Y) J& Q/ a# `- `3 C8 H
int DestroyStack(Stack &S); /*销毁栈*/
* [+ o  I3 _- w$ p/ G' K$ kint ClearStack(Stack &S); /*清空栈*/
3 q2 h6 c8 }% y. `& B( Uint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
$ e, E# C5 b  k" @- \( Z! fint Push(Stack &S,SNode e); /*将结点e压入栈*/
1 ]( C0 @% @" @/ u/ {( W* uint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
* l0 g  h# L1 m+ i8 ^' ]7 p
) ^' l( B0 s4 q  x7 Z/ E( S. T) {! \/*表达式计算器相关函数*/
) {9 \1 B$ o. S" |char get_precede(char s,char c); /*判断运算符s和c的优先级*/4 I# f6 P& F' }
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/7 O# }  e1 g9 i, [% D
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
& _2 {8 \$ n1 z5 ?" J: l$ d( Lfloat compute(); /*表达式结算器主函数*/
$ C( `( y, E' w! r( c6 \char *killzero(float result); /*去掉结果后面的0*/
2 z+ ~9 a4 g) ?2 Q3 y! w5 ~3 Q
8 _$ y! u* W; i! z# Y9 iint InitStack(Stack &S)* t( m0 J+ ]9 I! U
{
# I/ _: i  y# o5 a2 R    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));( t  s3 J$ C5 N2 i. `0 b% T
    if(S.base==NULL)" C! m# E3 G! H, S, e
    {6 w9 x7 v8 p. _9 d' q  H3 A0 R: _
        printf("动态分配内存失败!");( D$ K- C# H8 G, I
        return -1;
! K6 a: k- e: y    }
% I+ s7 i! D" V, N  i    S.top=S.base;
1 @% |8 d& I$ T- g/ U; p$ Z    S.size=STACK_SIZE;
1 P& r/ s8 ^' p* I: u- s0 V    return 0;+ k  V" Y- b* r0 `+ K6 N9 p
}* \% j5 }# g: n; _. t

" C# t# J8 z+ f8 M) eint DestroyStack(Stack &S)' s8 d- E9 ~5 q/ A$ _/ d
{) C- q; y6 H# `! z' h
    free(S.base);9 I$ i5 y- w5 t" r
    return 0;
# W4 L3 n1 b0 G9 K3 C5 a7 t1 o}3 F0 E* b" V# c$ x/ l' y
5 {  @: J3 i) L; ]
int ClearStack(Stack &S)
: H% z' @' z1 v6 b{
+ N* i. Z: ]1 i    S.top=S.base;  n3 |3 l. d8 f  P! H1 y3 m
    return 0;
; @- i' O5 q+ k}! k: n2 s* J% D0 o
5 N" U* G+ r: ^' X( X
int GetTop(Stack S,SNode &e)* B$ ?/ h# z& @4 q, W
{
1 ^& X. @" n4 R! N7 M    if(S.top==S.base)& |/ A9 m3 z0 a( F+ G
    {
8 P. Y9 I3 h: ^: D0 K! [' W. k7 H        printf("栈以为空!");! C1 F0 u4 [# k2 k; I; s
        return -1;3 n: N) V& a( {
    }- K8 B& q- Z: p7 h" ?
    e=*(S.top-1);6 c# ]3 w# v- A& E
    return 0;
7 I/ T/ L0 x: C. \' J}1 ^0 Q6 a7 m* [8 y  S5 P' Q
- z* K  @' M" s, Q3 z- l
int Push(Stack &S,SNode e)
, W- H8 C( B* F5 p{4 N# \5 n" w  W1 _! G
    if(S.top-S.base>=S.size)
9 e" i+ E% y" K2 h    {
/ h% A& q* G+ C" _0 t. o! H        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));$ `) O- X- f4 i9 I( L7 r/ ?- s, O, ^
        if(S.base==NULL)2 M! P; O% ~+ X3 I9 m
        {6 c5 i' I2 c- D8 r
            printf("动态分配内存失败!");
0 {+ a5 _7 W4 @. B. q7 `            return -1;, R/ _* }* K% ^+ T% A8 a
        }8 @* s6 K% e3 y6 E4 U2 A
        S.top=S.base+S.size;
/ ~4 y4 d  S$ P9 v* E6 K1 ^        S.size+=APPEND_SIZE;
+ J  x; X0 M- w  v! X    }
0 \+ E! d' Q# H( o4 S    *S.top=e;
* j. D! g" Q: b    S.top++;1 k+ Z3 ]$ R# u* I3 Q9 ~0 p
    return 0;$ L+ f- |* \+ d7 g# k
}& ~8 x2 ]: p; H$ `# d8 l+ `6 k

3 {3 y' g; n* X  F6 qint Pop(Stack &S,SNode &e)
: g0 q9 b' `6 ]7 b+ c& l; L{
5 C1 w1 u* y& U1 j+ w3 X/ `" `    if(S.top==S.base)' r& M' N* z3 m
    {  {& C: m8 L6 |: f1 Q" b. _
        printf("栈为空!");
6 r$ I2 d0 H0 r2 t        return -1;# W/ e& _  u, W; k$ d1 q' s) b# r7 P
    }
8 Q( j6 b# ]( [& [    e=*(S.top-1);
4 v' ]3 C! k$ q2 Q7 p) C, ]    S.top--;
* B. ^2 W$ R( q% K: J    return 0;: }0 D  I  X% o4 M2 X' r! ^. r$ O; {
}( E# q9 F2 u4 ]6 u0 _, P

0 W( A9 \# G" v+ h- Gchar get_precede(char s,char c)4 S) r8 }2 H' v
{% n; N0 _8 a1 N
    switch(s)3 I" ^; n) d( ]
    {# i- ^: u/ J( h1 y" _" k3 Y
        case '+':                 
6 g  a9 ?2 V5 f; V/ b5 H        case '-':" a& }# d2 \0 R' b
             if(c=='+'||c=='-')
- Y7 f" ?, r4 a3 x( X                 return '>';- B0 K& p: l" r+ s! `
             else if(c=='*'||c=='/')
1 k6 y: |; w$ p                 return '<';
" V4 R% y; T" c: Q3 M$ g/ K5 o             else if(c=='(')
1 E8 \( N: V/ G2 }# v% o+ O  e                 return '<';
( V# O- \5 A( H/ I             else if(c==')')
/ v' e! K6 j0 T( y: m8 b                 return '>';
7 x, C1 J  a3 f. Z             else
5 m& @/ @9 b' a$ S; e                 return '>';
4 p" i* S& ~  S0 b+ |# X. y        case '*':
2 J0 k8 W9 y2 e        case '/':# Y" v; c9 M+ t  \9 {7 J4 \5 l
             if(c=='+'||c=='-')* ^* E% F) V; R/ D6 f
                 return '>';
# n( {5 K# R- G1 s/ \2 M             else if(c=='*'||c=='/')) J6 s3 v# e7 g% T) I7 c" Q  w) s
                 return '>';: g( _& s  l( Z' W2 t* ?
             else if(c=='(')
9 H5 Z5 h  a  Q, a                 return '<';
3 N2 ^" M, ?5 U- A) z/ G  i             else if(c==')'): s& ?4 a/ v( j" o' w! f6 c
                 return '>';
8 P2 X0 [$ s+ o6 O! a* J5 }+ L             else$ V5 c3 z$ Y: |- O1 g$ e; S
                 return '>';) |  k& ~# P) \
        case '(':
" b5 s0 z8 S- N+ Y2 q: d6 `             if(c=='+'||c=='-'): y9 q; f$ l4 O8 O4 Q/ [
                 return '<';$ j; H' ]) s4 E8 z0 F. l
             else if(c=='*'||c=='/')) ]7 }7 A! i* e; W
                 return '<';9 q" m( F8 t$ @0 e# g8 R9 J9 T. X
             else if(c=='(')
, {, M- c! X0 o; X) d                 return '<';9 k7 L! E! c( T" H  V
             else if(c==')')
( m( `! s5 h8 N$ u! a6 d                 return '=';
" ~" L3 j" \4 G5 ~$ R9 s4 D             else  N: e& f+ M! O0 \" K
                 return 'E';! J- C& [+ D8 d3 d1 p
        case ')':
* P0 z" j1 {$ i2 r" |             if(c=='+'||c=='-'). M3 T  N! i, M6 ]4 ^  F) `
                 return '>';0 m9 o2 }: y9 d$ c( u- p- U
             else if(c=='*'||c=='/')
; }2 U4 H/ f% F* y( R% u$ U                 return '>';, r" @# J' D0 |2 \: q7 v
             else if(c=='(')0 M: t1 F' t4 c
                 return 'E';
0 E1 A# U. H5 Y: d9 k2 c             else if(c==')')
( Y) w. h# B. U1 ?) B; o                 return '>';! T8 [8 t+ k7 H. a! Q# D& s
             else
  O. ^- _/ a$ b* ]) x) s                 return '>';
* k& p- H4 k' U/ n        case '#':/ M' V( E1 V/ B" d: I
             if(c=='+'||c=='-')1 o  b( h3 x3 K0 D+ A
                 return '<';6 s9 b3 I5 x# |5 g' D2 h$ q7 k) @
             else if(c=='*'||c=='/')8 M" `+ ]5 k6 ]: p$ Z7 s
                 return '<';
$ }7 b8 F8 x/ }+ s0 l4 l             else if(c=='('). T- C2 b9 p3 Z" ?% k
                 return '<';, |2 L7 q6 r1 L; R
             else if(c==')')0 a+ {& n; D1 B- K
                 return 'E';3 U1 c( G! z* h. {0 O2 u
             else
& S$ n* q$ R9 I/ q  K2 G- ^/ ^                 return '=';
* U. I8 [" a2 s2 F0 D( G4 Q  i        default:7 ^6 p* n" l+ ~0 d% V; P; S
             break;5 I  C0 U, Z" Q
    }( b7 x* J  f+ e3 o0 T, F7 q1 ^. X
    return 0;    7 m( [- c- b' O. v
}
# _2 v- X; m- x5 d! C8 n
# I( V1 H( v  J- n& Z  e2 Lint isOpr(char c)  s; Q0 u% p& N" Z, l# r
{, G& `* B$ P% M: d
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4 s+ l1 S( H. s        return 0;( U$ a/ `. L# |4 P  R: f7 Y
    else
6 G+ S+ ~# n& J. O        return 1;8 A! B+ H$ s4 [; c, l4 C
}2 B) t$ {  G8 A1 ^

0 P5 o8 z; w! ^6 ~8 ~( }" mfloat operate(float x, char opr, float y)
2 V! q. _: B. [! I5 Z) U{& r) x3 q5 K& w  D1 E
    float result;
% R' ~  ^# T+ c& Q* G    switch (opr)
, v  @7 v3 x2 K+ x# G& j    {/ g7 Y9 g8 P- c$ \6 J
        case '+':
6 x  R0 B8 @2 V" a$ l: i, f             result = x + y;# }5 D" R5 ^1 ?- c/ J7 E& z3 o  I
             break;
- G) t( C+ @' b. @        case '-': : R& Q: k3 x" d2 I. S* L& w, ~
             result = x - y;
# ~6 y0 Y& W3 X( d! A7 z             break;& \+ B/ K, s. m, m8 j, ?  T9 n
        case '*':
; @) G7 @* ~( \             result = x * y;
$ k) v4 }' x/ o2 ^             break;
, G: c7 ^* w7 [        case '/':
8 L& N+ z0 _" t             if (y == 0)
, y& B( ]( ]$ p+ O; T0 j; r  z             {( U0 a8 Q9 ^1 @# P: _* `. D2 ~2 ~+ P! v: G
                printf("Divided by zero!\n");! n* ~2 h4 X1 f( D" Q
                return 0;2 X7 X' {6 U" K+ n! v
             }- |' Z* j' J/ E" Z1 t
             else1 s1 g' ~( |' O" E2 [9 |
             {
8 O6 `2 d$ g  S9 P( [5 p. [% D                 result = x / y;
* i3 ^& X( Z/ _! T                 break;
, ~1 |. ^* H- b2 o             }, t: R1 `. o! ]- J  a; W1 v' r
       default:
3 R  O  ]6 ?: n3 o* C/ v             printf("Bad Input.\n"); - g9 P8 i/ o$ ]) ]' y, X
             return 0;" o0 L  E# ]+ }% F4 K( S. E
    }$ j- g4 D) w5 r5 y. u+ t8 u
    return result;, m" C* G3 P  y
}    $ A/ p7 b) v' y5 q- u; R) j
1 A! c! i7 m! T: [, o
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
$ k4 A$ c1 g* b; v  ~{
  {) Z" i7 i; }6 e2 s7 N    Stack optr,opnd;
2 w3 m, N6 a: l  @    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;% o& r# s! Y$ I% ~' S0 j- t  L+ w4 `
    char c;* C0 r2 I" N3 G1 |' w0 J% e6 I2 Z
    char buf[16];0 P' A& @: k  |+ d
    int i=0;
: _- x: D4 z, R/ [; ?7 q   
: N( K( p' s8 I" \2 O    InitStack(optr); /*用于寄存运算符*/; e4 V9 p$ N. S' ~# L
    InitStack(opnd); /*用于寄存操作数和计算结果*/
% B  H+ G' J0 z    memset(buf,0,sizeof(buf));
, |" B5 U6 \0 i3 _& g$ Q% W4 ~7 r    ; M5 P) E8 `# f! J
    printf("Enter your expression:");
, U0 L/ k0 \1 E7 d3 _# [3 U* k        
9 s# {: `6 m; K( m  i4 O    opr_in.ch='#';) U) v! f7 {0 w5 k$ j* }8 I
    Push(optr,opr_in); /*'#'入栈*/1 z: [- ]# g# [2 g1 j! o+ r
    GetTop(optr,opr_top);3 }0 K3 h7 _- K2 o/ o/ y5 u
    c=getchar();9 i7 p) `" v0 H( N' n# ~! `8 \
    while(c!='='||opr_top.ch!='#')
# v, \1 V8 X  C" l    {
8 |  p2 G# R0 w: Z        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
! p/ u: q/ _- ~6 a        {: K5 A" ^  m' s& ]0 Y
            buf=c;4 i& A$ m2 ]  H6 N4 Q6 |. Y6 u
            i++;
" e$ [1 s9 d+ A0 ~/ f; X5 A            c=getchar();* x( O% h; r0 r
        }7 d' x; ?" `- \  u( G
        else /*是运算符*/
- g: T7 |# G, x3 i: R        {
8 v: l/ p% |3 o; r  c. p            buf='\0';
5 ^9 H& `# n" h2 L2 d1 D            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/# n9 O/ s' p- N0 T9 r/ f* _
            {
7 u; N& J* R( F4 C% S                 opn_in.data=(float)atof(buf);/ u4 m% x% ~! C0 b: l
                 Push(opnd,opn_in);- `: v: |* y1 ]1 W7 R  b& x) O
                 printf("opnd入栈:[%f]\n",opn_in.data);
9 `8 a9 ?! M/ p8 S0 L  b                 i=0;: s, ?6 f  y7 J& z7 I; U3 K
                 memset(buf,0,sizeof(buf));/ Q& n% `) @( Y, E5 U
            }
# |9 j2 V  t2 N5 m$ n/ }( ~0 Y            opr_in.ch=c;* k0 O  c- {& K7 I
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
8 Q- X* g' f$ F) l% }; s& ~5 q            {
1 c/ a# s% n/ t* Q                case '<': /*优先级小于栈顶结点,则运算符入栈*/
9 Q+ r3 E8 x0 y                     Push(optr,opr_in);
* \. x6 a5 w( l: Q. ^0 a                     printf("optr入栈:[%c]\n",opr_in.ch);$ _* |" S1 g( H
                     c=getchar();4 k* ?; V; `/ O/ V8 q& u
                     break;/ z. c( I' y$ }; Y" E
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
& U) R9 Y8 O- \" _                     Pop(optr,e);9 C5 e, _$ p" L* ~7 N
                     printf("optr出栈:去掉括号\n");3 X1 m% d# \1 A  x' ^* p0 T+ D: H
                     c=getchar();3 _8 a* |/ c& I3 q( k2 P! w
                     break;
0 j1 C  t' {. a% c, N                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/9 i8 ]. U3 h. q3 B$ f
                     Pop(optr,opr_t);
! I  V  S% C  m3 y$ \                     printf("optr出栈:[%c]\n",opr_t.ch);
# s6 T* v: l8 X7 @0 o                     if(Pop(opnd,b)<0)
+ B' [5 q7 L# C) x6 z% A& }                     {+ e/ X2 H4 Y* M" I' E  H- E. j4 [
                         printf("Bad Input!\n");
$ o. z0 h8 p3 Q9 i5 p1 z                         fflush(stdin);% i; L) D% E  u( y& N
                         return -1;4 T% R4 N: z( D* A7 d
                     }: a( w# l: A1 M9 F$ G
                     printf("opnd出栈:[%f]\n",b.data);
" e% k7 e2 x' k. y7 v                     if(Pop(opnd,a)<0)! B* X3 U& I! E+ u  X& a' ?
                     {5 c" b* h- M( ~8 g" K9 I
                         printf("Bad Input!\n");5 \1 x5 C2 R2 F' y9 _
                         fflush(stdin);5 V5 ]% v- z$ m, z  |4 _8 [. T- Z
                         return -1;! f( A5 @& u$ E8 G, J7 ?/ r
                     }
2 l! b/ i3 _8 r2 n" ?4 ?% o7 Y                     printf("opnd出栈:[%f]\n",a.data);
; Q% I; L$ E' p) W0 t/ O, w                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/; ^. [" ^: P4 V# b+ P- f2 m
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
: B* n6 @  L/ M  \5 r                     printf("结果入栈:[%f]\n",opn_tmp.data);/ z: v) ]8 a8 B! {3 V+ C
                     break;/ \' c) Z% R( \+ y
            }
8 _& s2 x3 T# G, ^( C        }
; J! U, n& Q  E/ E, p) @& V        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                # U3 O. z: b! Z  h
    }
; I  u9 t: K( Z/ x3 {    GetTop(opnd,opn_tmp);) a/ f; f* X5 p" F
    DestroyStack(optr);4 q4 @/ I2 \$ d+ _5 U% w
    DestroyStack(opnd);+ c; r3 I4 g4 U2 V  `% Y; ]
    return opn_tmp.data;# e) t' ^  c7 ]. ~, Q3 x; }
}4 c) ^& D- f7 k* ?- J& a

# v; Q0 A$ w9 X, Nchar *killzero(char *res,float result)
* f5 o+ V- F9 s5 Z) b$ }" M{
4 l5 f& r" {2 |% h' G% P    int i;0 R0 w- f9 J; z: e1 u; N/ O& \

/ Z+ E( t2 v5 F' b8 p5 t1 b; o( n    sprintf(res,"%f",result);! ~0 U  W! |! y+ h; `
    i=(int)strlen(res)-1;# ?1 X# }6 W' m7 O, @4 u
    while(i&&res=='0')
3 b9 `$ R* Z% p7 U/ Y    {
' H2 ?0 J8 t+ A3 R/ ?# Z) O; [( C        res='\0';. @' ], @( E( M
        i--;3 Q; r- G. _( J& M, z$ e
    }
' A! A! i2 X# Z6 A7 G* }    if(res=='.')
# Z- K' Q% N+ y  K# g        res='\0';
) z' f3 x. x  a+ W    return res;' r9 W, c2 K5 ~8 U. \  N
}5 B' g  i0 Y6 J; a5 x% H
* w  f; L" Y0 v% F
int main()
* l! X( Z$ X( v! C. L" C{
; y: L3 ~0 X0 e    char ch;! S, }0 w; J+ U! a$ a! U) [
    char res[64];
  ^; R% [( r: ?" e5 M8 }    float result;
' u- e. R" F. s. h- f6 ?% [" s    while(1)
0 o) [' J& N/ c' K1 \& E2 O, |    {* U$ S; }( @- @
        result=compute();8 F8 y" x+ T1 n
        printf("\nThe result is:%s\n",killzero(res,result));
" w4 k3 C- ]) |        printf("Do you want to continue(y/n)?:") ;
# z2 q9 J7 E% r7 K, M        ch=getch();
  I5 ~, u0 E, B, p6 G        putchar(ch);
" c7 Q6 `# y* T* X        if(ch=='n'||ch=='N')  \! f2 n. G8 U) \  U) @
            break;
$ Y4 a& Q! F9 @7 l- m% w9 H        else' }/ u1 W9 C8 ^& c% d* }$ t
            system("cls");7 ~  G+ ], m/ [8 C/ n5 b& o" R# w
    }
& Q! m9 v( E7 p+ k; C4 c6 F8 t    return 0;# B! Y8 p0 B. g( E0 g1 {! u
}

2 }0 B6 @4 d2 d! @2 N, O
7 C3 D/ k3 S2 X0 N$ F9 g[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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