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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
9 f9 G7 Q8 o: z& y) Q% h程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
1 s1 J6 j, A( b9 w/**************表达式计算器************/
! P+ \( ?2 s( u2 k. l/ t. b# G8 t8 _#include <stdio.h>" c. t9 F- `$ k  f9 T$ z
#include <stdlib.h>- X8 E/ K9 `" P/ I
#include <string.h>
! Q0 V( w9 G8 R0 d" G#include <conio.h>
+ w( y0 x: `, u# g* U4 t#include <malloc.h>9 M$ a! c% ]9 Y2 {( z: Z. X2 v- F
% N, v5 ?; D: S. D( y( V% K
#define STACK_SIZE 100
' _' u6 o) ?9 G! [  t#define APPEND_SIZE 104 j) @% d: W( _1 }& n; b

. w! B  L+ K, I+ Qstruct SNode{
3 y6 Y1 u# l; ]8 m, H# U3 L; N    float data; /*存放操作数或者计算结果*/9 L8 T9 }9 v% v
    char ch; /*存放运算符*/$ [+ |. L" w/ s& A
};/ H/ y) B+ t9 `/ l" v3 g

: j; _4 y% ]7 `" ostruct Stack{: I; V" H$ Z9 Z$ s9 {
    SNode *top;; ~1 M- e$ V) K( n( O: P* i
    SNode *base;
2 w" b$ i! `  C% x+ o$ c    int size;
' V* R6 k) }9 C. D/ z: N6 q};
4 j$ |$ _+ _+ \1 L1 x! c$ W/ _/ X: p7 _. S
/*栈操作函数*/
% I. g$ E# b( h1 }& Q' wint InitStack(Stack &S); /*创建栈*/
& O" p9 |5 o8 z) l9 s6 \8 W7 Fint DestroyStack(Stack &S); /*销毁栈*/7 y, N2 t5 _. E! X4 ]. P
int ClearStack(Stack &S); /*清空栈*// n$ R% g4 _$ \
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/& e  ]# `$ Z0 b, e
int Push(Stack &S,SNode e); /*将结点e压入栈*/5 O! ~# c% G* f1 Q9 N9 F" v0 K8 A
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
# P- A0 ~: h: i( [6 g9 k' E6 J$ F1 [" U. c6 m% k5 U
/*表达式计算器相关函数*/
/ f8 O" T; a9 ]8 O4 S" Q  tchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
" u) ~& _% O4 \" n3 Cint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
2 a" O& _% D3 W3 n  a- sfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/( S, ^3 h& w1 R$ }7 i' q
float compute(); /*表达式结算器主函数*/) A! v9 q" l$ Z5 h  ?
char *killzero(float result); /*去掉结果后面的0*/
; a4 O) u3 n8 O2 a
  Z; R0 X* b) }. e2 J% g+ uint InitStack(Stack &S)- N7 i5 J: }* l- a+ I$ D8 z
{
0 w8 W+ y% J' @3 q; I# a+ a% @    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
/ i4 D) N) z1 O3 l    if(S.base==NULL)
+ v1 q% I( G; \/ z3 A  k: p    {- i4 j* E9 O' i. t) [
        printf("动态分配内存失败!");
& f$ u6 v# F+ O, g        return -1;, O/ W& p. ?- ^# F8 s
    }- x5 q* P4 \9 a  |/ x6 D
    S.top=S.base;2 n$ f7 r: y$ X; b7 P/ w9 l) F7 e
    S.size=STACK_SIZE;6 W& J! V: o* H8 V$ y4 V; E
    return 0;) J" e6 F5 n/ ], q& I: u
}
/ x: d( }- }" P. Q( L+ S# u& T) c( ~1 }/ ?1 a2 p7 z
int DestroyStack(Stack &S)
6 d/ L1 j( Q7 N; j" ~1 [; z{
1 {( i( w$ X4 w: z( L    free(S.base);) ~( s5 B" k, f- C1 R% g/ h
    return 0;6 R/ E* ?0 H8 g* U; Q. z
}4 p) E# S1 I1 z7 T+ ^5 M- I6 d& t

* l6 @4 r0 V9 _int ClearStack(Stack &S)' ?* H2 l3 P) X- p+ c
{0 s3 ~8 {' U# H& _! V6 @
    S.top=S.base;
' c; ?: f9 h4 i) X+ i8 h* P/ k9 y: y    return 0;5 f8 d- h0 Y" r$ |- D$ }( w
}
; ?* I$ c1 ]* k4 B4 O! t- D: f" S9 ?" w4 d- R8 z
int GetTop(Stack S,SNode &e)
& G; a1 R0 ~) [5 K7 W7 e{" r  A2 a+ D) t/ x4 {% Y
    if(S.top==S.base)
' R: m9 h7 q- L7 a  [    {7 s3 l1 j0 l& v# W( V2 n# I
        printf("栈以为空!");4 J! f( b2 g" Q0 r
        return -1;- Y  [# W" D+ x  R/ W' H
    }
7 ]) D+ |. A8 i8 F5 G/ A& b    e=*(S.top-1);, Z9 W- q: U! j+ O/ w
    return 0;
4 b# E% f# u% f2 O/ S}: A4 \" s( [9 `* |! H

; z" N" C: Q& f8 Nint Push(Stack &S,SNode e)3 @$ }2 d) `) k
{
& q. Q4 P, S( x/ n' S$ N/ l    if(S.top-S.base>=S.size)/ q2 v" q1 v3 l! k4 H
    {3 ]3 o3 U0 }4 o. ]4 c: I
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
/ x, m) h! ]6 X1 ?" ^2 H7 V        if(S.base==NULL)! ]( i1 f6 ?6 M2 d& U8 {
        {
1 x! W- K! r# m4 T: M5 G/ P4 p( x            printf("动态分配内存失败!");
' L2 w8 h0 O' w5 {            return -1;# {8 C- v$ E" Y9 {: i% m; S
        }
; r( w8 D5 E" ?: j        S.top=S.base+S.size;# t  n( P- x5 _4 X. s+ ]/ A
        S.size+=APPEND_SIZE;# |- ?& h: Z3 A
    }
( V0 Z: |/ F" |7 P    *S.top=e;
2 _9 |% @8 L. I9 O1 Q) l2 `' }    S.top++;& m3 F, ~. n' \9 p
    return 0;6 z- I# I+ Q, r2 q6 c/ K3 Z
}
6 j* L  p5 h  W1 T! B5 M  U: e& S. y
int Pop(Stack &S,SNode &e)
, O3 o" }3 F% N0 H2 O{9 P% d( \! E4 H
    if(S.top==S.base)' O! f6 N4 ^# L# w/ u! A: [
    {+ b9 p8 z. Q; `# i
        printf("栈为空!");
9 f0 i% B" h. r& F* [& P8 w        return -1;! _' b/ R7 x5 Q; W  _
    }3 `/ W2 F$ l+ R0 x* o
    e=*(S.top-1);
4 X+ F- e* t5 _* @/ f    S.top--;! Q) j2 C% X7 k2 u) P
    return 0;
5 ?5 M1 W6 I6 s0 A6 i% ]9 F}4 f7 ~; Y2 S9 A1 F- z, @- R

8 j: V, G( o0 f- Q* ichar get_precede(char s,char c)( q* c. T9 z; b4 C; H
{( S# N1 ^2 {# O
    switch(s)# Z4 E$ Q! v  y. A' }5 H/ N# a0 Z! O
    {
( L4 N+ A% `5 u        case '+':                 * i$ F; I2 S& }' e
        case '-':
4 Y. z# f. U% `! u1 u, A  T             if(c=='+'||c=='-')  ?( Z" P% {5 K  H
                 return '>';
0 t* v. q, \/ a7 p/ \             else if(c=='*'||c=='/')( X, h' ^& }7 q" p* G  c
                 return '<';
2 T7 |# G7 o' T! [7 G$ I6 |             else if(c=='(')7 \; @4 s1 O( M( m: D
                 return '<';
/ |0 p$ t" N6 U1 M1 m4 ~. P0 S# l             else if(c==')')
' f" {5 \& V- E5 h                 return '>';
% _, J* D, ~  q             else ' o4 K# S$ N4 C: J
                 return '>';
! H2 n2 ?2 V6 D& [        case '*':$ S  W* k# B2 g" ?
        case '/':
* k' v1 O6 L! u5 t$ k5 m* h: ~0 |             if(c=='+'||c=='-')8 X- Q: w2 h) q7 s2 q. |
                 return '>';
( ]- k8 d+ _0 O' x4 U; h             else if(c=='*'||c=='/')$ d+ ~. C6 U; e9 P
                 return '>';; w; G, ?$ M/ P4 X; t& N! w. m
             else if(c=='(')0 \) w& T* m2 Z6 W
                 return '<';4 y- Q1 @1 w( U: Q1 M4 D  o
             else if(c==')')
2 U$ ]9 }4 f1 ?1 c* U                 return '>';4 `0 a% ^5 q7 F3 @5 Z
             else
- [% Q! j" g8 M- d                 return '>';
( T/ i8 l5 A6 J8 s" i0 o& @7 O, p        case '(':
. R! W  R3 d$ M0 U4 b             if(c=='+'||c=='-'). \5 t9 O" ]2 v% j( o: g
                 return '<';! k% \. L5 m5 M7 N% Z' L
             else if(c=='*'||c=='/')0 T+ \  t3 {+ {
                 return '<';" F5 ]8 i7 N4 t5 z6 n! |) k
             else if(c=='(')
5 l# |; Y, G8 q: Q                 return '<';: j5 F% Y; K4 `, e3 q$ t) A
             else if(c==')')
; j( m) d) w* _1 a' X                 return '=';; \" X8 |/ C2 k# P7 F; u2 J1 {
             else, a& I9 p0 W, Y, m' B
                 return 'E';
+ Z# I4 I0 \5 I# W/ J        case ')':- ^' G, V8 y/ |6 a$ {
             if(c=='+'||c=='-')9 O% L4 M: _0 z6 O# y
                 return '>';9 m% ?) [3 {- ]
             else if(c=='*'||c=='/')5 W/ C' N5 o! Q' X
                 return '>';) e* Y+ i3 o) z
             else if(c=='(')
* D# s: J( w* H& m( E                 return 'E';
6 V5 ^' W7 ^- d! k2 _, Y' o             else if(c==')')2 R6 w# s4 ]# i8 W
                 return '>';
! V/ H% H# X" @1 e7 j             else! I" Y+ U4 A: L, }
                 return '>';
5 @& w- z' ~7 g" u. X+ v# `& {        case '#':$ L  h5 k' ^" X1 e* E8 P" n& {
             if(c=='+'||c=='-')
: L3 u0 _: L- ]- P                 return '<';
  X( j5 K. L( v5 w$ x: q& X             else if(c=='*'||c=='/')) o  f# u/ z5 e
                 return '<';" a. K, r3 T1 E. ?
             else if(c=='(')% i& ]0 ]3 D4 V% _
                 return '<';
3 X+ Y9 ^/ v$ o. _/ p  r$ z. x             else if(c==')')
, Y* I9 C+ ~+ {0 a5 o, Z* _0 y% t                 return 'E';
- E- n: u7 D. ^7 U& E& X             else
" Y7 m  |, a) ]" c                 return '=';
! {# _. G# Q; o: i/ y; A        default:
: _6 P" V* j9 X             break;+ V2 x! `: R( G1 y) W# T
    }5 e# n) D. \4 M. {
    return 0;   
+ m% s8 v% b, e' Y9 X: ?& U, r}
8 U5 [+ U, k7 p3 \) g/ i. ^
5 Y. z' M4 R  t# ~6 r" d. b4 O: ]int isOpr(char c)* P) k7 ]; y+ F) }  L" m* ?6 o. A
{, N% h' H9 S$ v1 E# ^; a
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')6 Y" e. C$ ~' t4 b" L' _, C3 j
        return 0;( ]5 o% y; l8 P8 o% M- B
    else " H) g' `" B/ ]
        return 1;
8 T2 z3 G8 c6 K  w, p- G0 ~- h}
+ `. a4 o# Q8 f" D" @4 v2 p" S; R& `& v; C' A( O$ @
float operate(float x, char opr, float y)
8 ?0 q( B+ ~( I9 ]8 u6 k% k{
& ?0 i# t$ \& i( @$ j5 K2 F    float result;
. I0 Z4 f4 i( C; a+ i    switch (opr)
& c' F, {* A0 C9 m    {
2 r* U7 w- S' h9 ^* u( h        case '+': 1 s, i( `% T5 m2 ?1 k
             result = x + y;
( z1 p1 e8 W: }7 ]4 T+ b, @             break;: z* M8 f3 i! S. ?$ l9 c. v+ c
        case '-':
8 A5 J3 x6 B/ |( s! l$ a' U- t# T             result = x - y;% s8 ^0 D9 o! y4 R
             break;
& W2 r% @% q$ e3 d& ~5 G% c        case '*':
% P1 N) C7 P1 s. I3 r             result = x * y;
4 M2 v) C9 B) F* E2 [8 ?             break;2 l6 ~, \/ c# o# e
        case '/': 9 v! n& N' i& H  I4 G$ a
             if (y == 0)
& c3 T& |  i+ T5 P6 V* C! Z- e             {
( B! y1 O* z  t' s$ }% a8 v6 k                printf("Divided by zero!\n");( `& W5 e% N8 M# S: p* W7 P8 k
                return 0;9 B/ B# O. l8 B- ~' M
             }& l) z6 k( ?( T: x' `
             else2 T/ d, x6 m. A) ~) W6 k' I
             {
% Z1 ^( ^: l: Y) s                 result = x / y;* H+ f+ I) z% O
                 break;, ]9 ?( @  _6 O0 d- x: Q5 x
             }# d9 a, u/ M- S8 A
       default:
9 }4 Y0 ^" h  [, C; _5 k* s             printf("Bad Input.\n"); + ^$ E6 I1 Y4 N% W. ?& I
             return 0;& \1 u2 {  L2 K& ~! ^9 G! l6 T
    }2 h' @6 p6 ]' {' L2 s4 }
    return result;1 N: e8 z6 G4 O
}   
$ B' j7 k; |, _+ v$ a& I6 R* L% S# ~* i0 f
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/& I, r0 X% V$ R0 F) x
{
4 [7 a9 w# z; |4 A7 d    Stack optr,opnd;* U3 e% k5 q! o) m
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
- y6 V6 f3 n/ M3 K' `    char c;
4 _9 N% N3 l/ S* y4 `    char buf[16];
& W9 ~8 F. W9 n& u8 C    int i=0;
! ?$ T' F1 n: X2 \" i6 \   
% x# M4 A1 J6 @( i# B9 z    InitStack(optr); /*用于寄存运算符*/
: P* s# F- R/ |7 E. v, S' o    InitStack(opnd); /*用于寄存操作数和计算结果*/7 J& P9 _5 A+ d3 h
    memset(buf,0,sizeof(buf));7 i; w* b) J: j$ V" M- q* x" S
   
6 W. j4 l2 o- G: ?    printf("Enter your expression:");
8 ^$ e1 J& P) F( r6 E, w; {4 n        - Y) O, ^8 P4 i, I  q/ r; k1 H
    opr_in.ch='#';/ ?4 i% S& y% P" X
    Push(optr,opr_in); /*'#'入栈*/
9 W" U3 }& }; t+ q    GetTop(optr,opr_top);
8 \! i. }# o" ]7 D    c=getchar();0 Z5 j1 L4 S. M
    while(c!='='||opr_top.ch!='#')
( l& M/ ]/ Q# a0 |4 t+ d: }    {
  m: C; m$ o1 Z  h) f        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*// a+ W7 v% G1 H; \
        {
/ D8 g, x  y$ A3 l! Z            buf=c;' p- b1 D' P. A" j( e
            i++;$ a& }3 x* T5 a$ O
            c=getchar();8 P1 L  R! f$ n- i
        }: D5 N, G" T0 `8 r9 D
        else /*是运算符*/
0 j, i: w& L! o4 X- F        {& I. Q3 G( n. n# b. O3 G' H
            buf='\0';
, T* r( Z2 L: m+ p" i            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
+ K1 x! c3 ]3 j; i1 {" j' s            {
# E$ R9 y, N* L, w. l                 opn_in.data=(float)atof(buf);
2 ^" L. ?) m3 F' ^* c7 R  m7 K                 Push(opnd,opn_in);
) g  C. W% {" C! {4 K! N4 i                 printf("opnd入栈:[%f]\n",opn_in.data);
; i% Y7 Z0 s) C# _                 i=0;( E3 W0 q$ ]9 E6 R/ m2 u( l. e
                 memset(buf,0,sizeof(buf));4 l% W+ s  e% R2 X* ~
            }3 Z% i+ S! W3 n1 |
            opr_in.ch=c;0 }2 ?7 c/ |% r% Z
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/- t' w% ~9 I( |5 |
            {
8 g, X- A% ^3 h' _6 @# }% a% B                case '<': /*优先级小于栈顶结点,则运算符入栈*/4 h- N8 }- v) G
                     Push(optr,opr_in);
4 g4 v4 j, I& f. v4 g8 L                     printf("optr入栈:[%c]\n",opr_in.ch);
. b. [9 a9 h4 y- X" g+ l2 Y                     c=getchar();' b8 I7 P% v/ j
                     break;; L, o, d1 {/ v( B6 Q
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
/ N3 t6 r( d' L2 W! E                     Pop(optr,e);
8 x' |$ I" C5 n8 P" @                     printf("optr出栈:去掉括号\n");& T# K; V( b( ^) y7 ^3 h
                     c=getchar();4 x4 h7 _1 F7 o  Q: x& i" t% N
                     break;/ V- {: @" e! g( I* z7 E
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
1 ~0 t8 d6 F+ b7 h                     Pop(optr,opr_t);* P+ [  r3 O" D/ d) B" q+ B
                     printf("optr出栈:[%c]\n",opr_t.ch);
; s& R$ N; L$ k, `  k                     if(Pop(opnd,b)<0)- z0 e  m7 b4 Y* e" ^5 r7 {8 |
                     {- y. H9 G4 f; I* M
                         printf("Bad Input!\n");. r0 ]" W4 z% A
                         fflush(stdin);
) Y( q5 ]5 b1 B                         return -1;
" y. S9 x! N. E# c9 A                     }
0 i) s7 B# e' t' E                     printf("opnd出栈:[%f]\n",b.data);! _1 c4 _$ R$ R5 t+ ?! V; U
                     if(Pop(opnd,a)<0)
- n3 T5 O! h+ ?, N2 C+ E% w/ U                     {
; L+ c' c9 v* s                         printf("Bad Input!\n");: r' y8 ~5 h3 O! _
                         fflush(stdin);: y6 m; b% W6 Y: o: g
                         return -1;
3 G/ v1 I. L! _& L, T                     }! j* m8 d, C! q' F7 T
                     printf("opnd出栈:[%f]\n",a.data);
: @3 `; n% y+ |5 k                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/* L/ Y6 b( G+ U4 {. J% {
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/0 j9 K. D/ S% \
                     printf("结果入栈:[%f]\n",opn_tmp.data);2 B" C3 {6 P, F* z% m! H
                     break;
  e/ s4 c3 b% M2 {" c5 [            }
0 E- u  @0 N1 F+ C4 J        }
; P2 f: b! B! }$ J9 K        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
- s$ }2 @1 r# l# m7 T9 T    }8 n+ q0 I$ D% ?# T+ S
    GetTop(opnd,opn_tmp);8 N1 @- P& ]  ~5 m" X' b
    DestroyStack(optr);  R3 Y. G, E/ B
    DestroyStack(opnd);
) P5 f- d  c5 A/ x: |  {) _    return opn_tmp.data;
5 H. e( m& v6 u0 @; n5 n}0 C! M4 R0 P5 o! M2 T0 c0 P
' @0 a" V% r, Y* L; \# O: P5 U
char *killzero(char *res,float result)8 S& Q  |+ n+ J$ D
{
. H3 V# m. v/ K- E    int i;
. m* g% y! ^" e+ k, K$ ^6 K7 _
) ^5 t4 n& ^: N3 [+ ]    sprintf(res,"%f",result);+ z* F6 R# {3 ?. g$ V! m1 \
    i=(int)strlen(res)-1;
; F' W# N$ z* L- d, V; T    while(i&&res=='0')0 Q6 [1 _2 @1 _& i, a0 x
    {
7 s0 h2 P5 S7 ?        res='\0';5 I) @1 j: [3 Y0 a( f
        i--;
, _: {$ [' l) Y3 K+ w$ Q. ]$ [    }
7 L& z) T+ h& F; ?1 i! L    if(res=='.')
' d& V* o. l1 }* V) S" e- Z        res='\0';" p: z) m$ A& d9 h4 T% ], Z1 ]- |
    return res;( U. i6 C. N' f
}
, s; l* O, _9 Z4 A( O' k6 e# D+ z9 w: C- [4 f
int main()
% r5 K  m2 l8 h7 n{9 H: S/ c* x5 H6 {5 Z$ |1 d
    char ch;* g& C# D1 z8 b, g# L
    char res[64];. C0 c9 t8 {8 F, M# X5 j  h# `$ O
    float result;
9 H& l) W, }) J8 M0 g, [    while(1)
2 }' O0 Z) t3 t2 x* Q    {7 E1 j% V% T; S+ P. Q
        result=compute();/ s# ]; F" G$ q+ A& {! v# f
        printf("\nThe result is:%s\n",killzero(res,result));
$ M; _. l+ v( E$ B0 a* Y0 t9 Z        printf("Do you want to continue(y/n)?:") ;
7 |1 H1 e4 z, V/ w5 N) O        ch=getch();- ]" e' ~7 s$ E; n0 N2 j6 e, c
        putchar(ch);
' ?6 K; s) I/ `% B, K5 C! ^        if(ch=='n'||ch=='N')
( D6 N8 K. C% V( L            break;4 s8 Z/ ^+ R; C
        else0 D5 [3 ]3 N" f$ S
            system("cls");
( p' i1 h1 s3 M$ _# o    }' B2 w! }$ t0 V6 e/ N# B! Z4 Z
    return 0;
( n# e+ h+ v4 M3 I- W4 [}

3 k9 ^+ o5 X% O: y( i
, K* q/ Y5 d, N- g% @[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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