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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
2 @+ v& o* R. H" k程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
9 r# p% a- g1 w/ z1 }7 C/**************表达式计算器************/
5 r9 E; w/ \2 G9 h& u#include <stdio.h>4 g' C4 e0 m: A4 i8 R# Q) C4 M
#include <stdlib.h># b" x0 j+ F3 L! c, e
#include <string.h>
5 V. ~* i) _  k#include <conio.h>+ d* d  i/ _9 g
#include <malloc.h>; z! x( S% c) n' W( V& c( ^- J4 O
: ^  ?7 p) M; R. e7 B. {4 g  U
#define STACK_SIZE 100
+ p; r+ J- V7 B2 {#define APPEND_SIZE 10
" T$ q* E0 z5 h; _! }+ i
* M5 @7 v. c$ b2 [8 f2 }* b" F+ Ostruct SNode{9 n' I# Z. e) n! D
    float data; /*存放操作数或者计算结果*/' m3 ?& R% B% ?6 B* X* L
    char ch; /*存放运算符*/
, S: s1 N4 C, J0 @- x" G0 R& E};
8 L0 a2 {" O& F+ c: e+ L4 N* h7 @  A9 B8 C: R' w% i0 `
struct Stack{0 R: t6 |, ~, c/ U
    SNode *top;
3 B+ s( a; ^$ g7 h    SNode *base;
) E2 L" ]3 y4 N+ @    int size;  ^% B! `* T- F4 W
};
1 Y: a" S+ ?" r5 ]3 P  x5 d1 _8 O1 _5 M
& X9 V5 s" p+ u) x. g( @$ j) ~4 [: v3 c/*栈操作函数*/  g& k9 L! w/ `# m
int InitStack(Stack &S); /*创建栈*/
$ x: _! o" n4 |$ j4 iint DestroyStack(Stack &S); /*销毁栈*/
8 m  p! ]5 e/ ?" i7 f! kint ClearStack(Stack &S); /*清空栈*/
/ Q+ N5 V( u# C; dint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/7 H$ V$ x2 t1 A: v/ ^+ U
int Push(Stack &S,SNode e); /*将结点e压入栈*/* i/ c) D8 u* x6 U0 c
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/  @8 {# s0 z4 r4 i  \, ]3 i
4 E6 u% L/ Z* s; g
/*表达式计算器相关函数*/
4 K9 g6 g. p0 g: Ichar get_precede(char s,char c); /*判断运算符s和c的优先级*/
' {% D7 l& P; ^/ c4 pint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/, H; H1 x! y6 a
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/% k% R' C$ G8 [+ p; K# Q  k; B
float compute(); /*表达式结算器主函数*/
/ J$ u: F( [5 P2 t% x* `char *killzero(float result); /*去掉结果后面的0*/ 4 B7 K, T% Z1 N2 B; U
. @$ ?: n' y  U% f9 O
int InitStack(Stack &S)
9 R1 h2 c* G& q8 j/ p: ~{9 n2 y) Z7 z0 m" x
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));. R- t$ z/ B) p5 f2 c/ u+ D
    if(S.base==NULL)& p1 p3 ^" [) Z- B, C& |) I
    {
2 k' _# h- H& T% I% e$ R        printf("动态分配内存失败!");
) D4 _3 U' ?4 u% w! ?4 s        return -1;
  P! F5 Z- k7 O7 c" q; q    }
1 e1 Q  P, F6 u7 @% n    S.top=S.base;" r" L, P  F1 K7 p) q/ }
    S.size=STACK_SIZE;$ s6 g7 K. m3 }7 o1 b
    return 0;9 c6 A4 C1 i5 ^- f7 o
}& ?% P' |- G' I4 {* ]

7 k% D6 ^- V# ^% M" w) g: E. g; dint DestroyStack(Stack &S)/ u5 K" k# d3 Z& n- \
{4 ]6 g5 |4 J  b: y) ]3 i" O
    free(S.base);
. P% n5 V+ j3 w" V6 {, V    return 0;$ ^2 L1 N3 b- U- ^4 d: o' ]
}3 }  q8 Q# t, p- \' _, j# C
8 B2 V7 Z# z9 \2 J
int ClearStack(Stack &S)
$ l! e# }& @" E: n{
3 V$ @$ O: `2 H, \. }0 j, n8 b" F# A# ]    S.top=S.base;
9 W9 w' B  G9 X    return 0;. n; e6 B- y. R, e$ }2 d" ~5 p) y! `) P
}
1 l- T& S6 X: w+ w
+ j- A6 h0 n  v, k( N# eint GetTop(Stack S,SNode &e)
, L" q# |* f2 d* S, r+ N  V{
$ s7 V) ?! P3 @) }4 m( b( S) @! H    if(S.top==S.base)
4 E8 R1 o% B( `; n    {  H  L( h- c8 j- S
        printf("栈以为空!");
$ K5 \  N% \  U, N( Z- X        return -1;& ]2 y2 C0 q5 ~+ b8 A  Q
    }8 Y6 e' g  w6 |! B- ]; Z
    e=*(S.top-1);
# w3 n0 g+ I; K6 \, }9 x9 l    return 0;
8 ]) f" s! Q  s9 v}8 p3 P0 |# a+ m4 e
8 E" k% {3 S0 P" @
int Push(Stack &S,SNode e)
' K1 C. W* u/ Q* c{
: o% \) c4 F* D3 W1 u$ X    if(S.top-S.base>=S.size)
3 D' G9 ^( J& L' l3 `    {
0 N1 h! u3 y8 p. s0 ^( S        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
. B" P4 s$ O( j3 d0 |, N' |" i        if(S.base==NULL)( }- m" z5 I5 L  b( f
        {
9 j0 S: @5 P8 G6 \/ @            printf("动态分配内存失败!");2 u" M& h; x, @0 l" p, r" x5 Z
            return -1;
  q. _8 N) c9 R$ I        }; j$ m% }1 J7 l/ t$ Y0 J% k
        S.top=S.base+S.size;
! x' \2 }* ~  L        S.size+=APPEND_SIZE;; D9 i! R6 h3 C9 i, L
    }: B+ O- A2 ]( ?7 X3 r
    *S.top=e;
( A, V: o: V  T% j& n% e$ m    S.top++;! I7 Q& c0 i' i# D
    return 0;
' ~0 l) [! Q% C- N9 [, j}# f* D( ?$ f- C3 Z
  _6 p1 K* N( f* a+ @( U
int Pop(Stack &S,SNode &e)
% p4 Q; T, m8 j( k{
' G7 K0 S, S2 j( j% P5 n    if(S.top==S.base)* m/ Q) ?0 s- D, j9 q& B
    {6 f0 u) m; F' D
        printf("栈为空!");' W/ c- l8 i3 E3 H. G
        return -1;  q! r6 c8 `" I# [
    }
. j+ n! S) x8 k4 O  a0 F: f/ }    e=*(S.top-1);- R% ^; j7 h' m6 `, ^
    S.top--;
" h9 z0 x0 |' d! g" R    return 0;' \  Y; _" w9 x1 n$ U7 d& U
}
8 L! v4 N3 `, [
6 L+ c- ~6 p$ s/ k2 o8 N( Pchar get_precede(char s,char c)7 v. x3 G4 @* b* J
{
/ e1 I# D, I0 a    switch(s)
$ g$ y% t! w% r! A6 q- k# i: a: i    {
5 H* t% J& A2 j- e1 E% O/ C        case '+':                 
! ]3 w/ A6 S! k        case '-':
1 q1 T) F) C( K9 Q! Y             if(c=='+'||c=='-')
, J- U# M3 Q/ [: s                 return '>';
' M3 _4 `0 K; n7 W             else if(c=='*'||c=='/')9 A8 d& o9 I2 S3 w* D* k- q$ O
                 return '<';) c' `! h+ N) c+ n# o
             else if(c=='(')* ?$ y2 x0 B7 [! a
                 return '<';
' B/ I: k+ h  h' W             else if(c==')')7 K/ k9 M( c+ }% u) D8 _9 i5 q7 x
                 return '>';7 D: V$ t% q4 `( S. n8 b3 N
             else . r+ s* J7 J% c1 s) w
                 return '>';% ~6 o3 X  [" B# Q
        case '*':8 c7 p) f, s, {+ ^( E) Z$ V* P
        case '/':1 a) N9 z  I6 e! }7 E
             if(c=='+'||c=='-')
/ R. J) _/ f2 @- m/ l1 L                 return '>';. S0 m+ _5 I& h" G" z1 Z3 J6 p2 w
             else if(c=='*'||c=='/')
9 l) x6 b0 A: U4 V: ]0 V                 return '>';
& s4 C# X" K  [3 \2 E             else if(c=='(')
5 D2 J4 f* r  z: ~: V' s                 return '<';
0 G2 s& Y* \9 {! B5 D             else if(c==')')  l7 V, |% r; \& q9 F
                 return '>';
1 e4 g6 }3 a( n# f  r, O! y             else
' L- `1 D5 d+ T5 f3 b5 ?0 z                 return '>';' O- `. Z3 S6 }6 j
        case '(':% \8 |. \' Y  \
             if(c=='+'||c=='-')6 B9 a4 [* `0 n! K3 [8 e2 N
                 return '<';! V9 t7 K2 K# g- l
             else if(c=='*'||c=='/')
( \) ~% L9 K  a' x, K. D                 return '<';
) A- N' r) i/ k0 W             else if(c=='(')
7 W7 {9 j4 f% e- R                 return '<';6 n' b7 [) @% w
             else if(c==')')
/ X+ F  r+ e% y# H) ]) e                 return '=';
5 p" T# u* @: m. c+ D             else
: k# S8 l2 x* G5 U$ {) ^                 return 'E';
( p% N  W5 |  x3 b        case ')':. X+ N5 `. T8 {& O
             if(c=='+'||c=='-'), r2 |& @3 H# t* ?; l+ @" U2 ~: f
                 return '>';% w3 y9 x6 N4 h3 J# p$ L$ O/ _5 {
             else if(c=='*'||c=='/')
1 e2 B( t2 ^3 F                 return '>';
9 h4 o* F/ ^: L4 K9 H5 c9 h6 m' r             else if(c=='(')
% N6 O! D) d% h1 f                 return 'E';5 Z" D- }# Q5 K( r4 n/ O+ g# M$ A
             else if(c==')'); ~# U9 V) k: |4 D& B; t
                 return '>';  r8 t7 [+ Q; k
             else+ N. o: A' i, T4 A4 E' }0 s' ^0 f
                 return '>';
  F/ Y" y3 A8 g) o8 ~        case '#':8 Y5 k. z! g) x6 Y/ Z
             if(c=='+'||c=='-')
  X4 y8 r: b! n. {- ^- X$ {# X3 t1 M                 return '<';% e! |( k) H+ l1 p( f( s. F
             else if(c=='*'||c=='/')
1 ]1 ]& T8 E& \; m" u                 return '<';
( O+ U# P% Z# r/ j% A  n/ Q             else if(c=='('). X7 w8 r& |3 \' A0 W! G
                 return '<';
; c. A1 O4 ]& S' m- @8 x/ E             else if(c==')')
: Y; m- r+ X' J: ~1 ~                 return 'E';& @# p5 \  y& j! |
             else+ i9 p3 ^7 F3 \" ]% b
                 return '=';1 H" R! Q" @8 {/ ?0 j* y* g
        default:
! E) t7 D1 Q, u+ F- _             break;; d* f/ M  H+ [4 F
    }, j; m  s, B% A' L
    return 0;    " m. |# C5 `. u. c6 }/ l( ?7 E$ c3 F) P7 k
}5 Y8 k8 `* O4 H' Q: _- G

' T9 y- z2 g6 R9 ~0 \int isOpr(char c)
4 N0 Z2 A: _1 K/ j4 h! h2 |{
3 s* k) N* \3 T& S. _+ y0 w7 I    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
" }  @+ P. U+ Q        return 0;
$ D' E) @5 Z( p  W. E7 p    else ) p+ ^8 i" M6 t4 z& w
        return 1;! m% L) \" N/ w- B
}: p+ r$ s% W  K0 Q) _( F

& F! X2 N# W. l0 ffloat operate(float x, char opr, float y)
( q( {' b& E1 n5 N6 g! U{
* p2 }! ?0 B9 h9 G0 i; f    float result;
1 H) N! R  r6 }+ \; |- P1 u9 d    switch (opr)$ h. c% `$ ?; @! }, B" U' y1 U
    {
: G; B" k; V1 I3 ~        case '+': ' m4 t: W1 k' i( W8 I
             result = x + y;
! X! ?/ D. Q3 `# v  Y! a7 i+ B             break;
: O$ c% b0 H. c  f* b  d. |        case '-':
2 ]- S: @  v: ]8 h4 Q& g5 S             result = x - y;  h( {8 F5 I0 \- j! j
             break;
: w. l9 m% O% B        case '*': / E) z, v1 s6 o: t7 h3 x
             result = x * y;
$ p1 m( n* b" v& S  R# V             break;$ \4 g' y" @+ m2 K. ?& Z: E9 T
        case '/': % v/ m# k4 J* V3 f
             if (y == 0)
; ^$ x- J/ O; I: z             {
: P1 x1 A; f4 g& H& l, ?                printf("Divided by zero!\n");. C% G; n; q% k; B$ v( G0 T3 q6 Y
                return 0;5 a* q0 p. r! x6 p
             }( H3 L9 `8 M% @
             else$ p" ?: S; j0 F/ w  J# S5 s  n
             {* T6 d8 F9 p0 J% M% e0 K
                 result = x / y;
3 |$ d' C  a! R2 p                 break;3 e; R/ C, X3 `  v) e, U) }" {4 H; D. l
             }
& n; J9 D. v. a       default: / x( m1 G* K( ^
             printf("Bad Input.\n");
! t5 p. h; _$ Q8 e             return 0;9 z/ x+ K1 D5 u4 E5 K% r
    }9 ?% F) N5 V  j" g5 B3 v
    return result;
) d" p/ [1 x+ D! S" X}    " N' {/ R+ d0 m1 B5 `0 L

- p* J' m5 e8 g7 A1 E! g% Wfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/! o, e  C  |0 m* o: m" ^
{, V: k, L/ m, N) H- h" Q6 C& @" T4 ~, x
    Stack optr,opnd;
! J. R  l% N0 O( n    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;. B. Y: m5 h3 c* p8 @6 P
    char c;  L# h% j9 L0 V  m. o
    char buf[16];4 a) z6 x1 l. `5 {+ ?9 ~! G) Q
    int i=0;8 Q% n5 G9 U2 F# C! j+ b' ]
   
1 v! t- ?( ~0 a# y* e7 H    InitStack(optr); /*用于寄存运算符*/# u3 m- D2 M0 t
    InitStack(opnd); /*用于寄存操作数和计算结果*/
9 }% s. [( \. K4 Q/ B# e    memset(buf,0,sizeof(buf));
# @. I! X. F6 s, U. `; C   
0 @/ x$ q( H  `5 A* g" j3 P    printf("Enter your expression:");
. v: a% q  d8 |* s        
& ~5 g. h2 U2 F. J& J) y/ D# y* b    opr_in.ch='#';
( V9 K8 y% H6 t8 T4 g8 b    Push(optr,opr_in); /*'#'入栈*/- Y$ n' D% P8 q# K
    GetTop(optr,opr_top);6 ?: V+ y/ i" @
    c=getchar();
& [. x; P; h+ \+ ^5 R. M    while(c!='='||opr_top.ch!='#')
, |- z" h" C* V) j1 k    {0 F* a9 Z- t5 {# A2 K; f* {
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/* ~! u! ^$ N  p
        {9 D, T' u# h% [0 R* V, V
            buf=c;
% N7 \% L( _/ i1 g4 N5 s            i++;
' E" u8 S* r8 K3 {            c=getchar();
9 f8 E/ m/ q: `; v        }) O0 `* c+ L' N3 W; R5 I
        else /*是运算符*/$ b* n3 L8 j2 a& F. y
        {
( I, D2 O3 J* I% Q0 x            buf='\0';
# {% D: c( X. G) K. I% @# }* p9 n& U1 `            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/7 y- x' l/ O, g( t. y1 M7 \
            {
' c0 c- V9 f3 v+ y, C- H! i- M! K5 g                 opn_in.data=(float)atof(buf);
9 L( Z$ |( e  Q; a$ ~8 V3 j' m                 Push(opnd,opn_in);
+ Y' b: s* g; J+ x8 V! r' \4 V8 @                 printf("opnd入栈:[%f]\n",opn_in.data);
: H! w: L: W2 ]                 i=0;! |  @$ u: r( V8 }: \. d6 F
                 memset(buf,0,sizeof(buf));
1 D6 R( o. ?  c, N            }; q5 s2 }# f( m4 }9 E
            opr_in.ch=c;7 h0 p7 Y& N/ K; i; v
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
/ p1 J/ Y4 {5 M# I            {, k. j. }$ G) ?
                case '<': /*优先级小于栈顶结点,则运算符入栈*/3 e9 S  c& K9 O/ m2 N
                     Push(optr,opr_in);2 z4 C0 s6 D" r) M4 Y+ O
                     printf("optr入栈:[%c]\n",opr_in.ch);
9 U. R: d& N  N! {( J4 ^                     c=getchar();
! R% x* Q0 }0 E( j! D. @0 R                     break;8 m+ E, X3 X3 G) C' U0 C, J
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
8 J' p+ Q, u7 v/ u6 w! v; s' d/ |9 p                     Pop(optr,e);% s1 L2 Q* U$ L$ D: a
                     printf("optr出栈:去掉括号\n");
0 |, P6 }0 u: t8 M$ Z! K- [                     c=getchar();
$ c: l' o* T: D* \7 _' d6 W                     break;
; b( z4 K7 e" R                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
8 u& w: E: a8 U$ H! C2 J1 z                     Pop(optr,opr_t);
. g. t: r+ P: I" g' B9 f5 i. S                     printf("optr出栈:[%c]\n",opr_t.ch);% P) {: \& I' o$ S
                     if(Pop(opnd,b)<0)& M, A% v0 G4 z' V5 ~! Q" L1 {
                     {5 L/ I9 Z1 u$ \7 k/ e) Z8 O( }
                         printf("Bad Input!\n");0 b& M" d+ P/ h
                         fflush(stdin);) v. C$ D+ O3 |) ^+ _  A
                         return -1;
$ z: V& H' D) r! l: K, c                     }5 N9 {9 Q' O( M
                     printf("opnd出栈:[%f]\n",b.data);9 D# z. ?7 \( r) t
                     if(Pop(opnd,a)<0)1 M) N( t+ s, q% I8 ^; B' Y
                     {
9 M! y) o. I( ~+ s% V                         printf("Bad Input!\n");7 D  v( I0 \/ k& N
                         fflush(stdin);9 T! p5 _! m1 U' g
                         return -1;
: D3 J/ J( l  r* w# ]                     }( [) r+ U: l0 ~0 h4 x" x4 `1 r5 z/ J
                     printf("opnd出栈:[%f]\n",a.data);
& Y& q. b- |4 l                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
" U$ ]  M  t' G0 w% U# N                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
" E) I& R; v; e- c4 ]0 Z# W                     printf("结果入栈:[%f]\n",opn_tmp.data);
# n& A8 m8 @. e( l                     break;- \+ |; C7 C' T2 j8 }, N
            }
( L5 e$ ^" F5 P3 v1 A        }
; S+ r4 }4 a  Q1 V        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
/ R9 [: ^: S/ W2 m- S  N5 O+ _" i    }# Y! @) y5 @. W3 q8 d) X
    GetTop(opnd,opn_tmp);" h$ J8 q' r4 S
    DestroyStack(optr);
) A; I5 z. r7 [. S; f" G" |% B    DestroyStack(opnd);
. z. x% c- w4 F# l    return opn_tmp.data;. n3 m' q' r# i) j; M. L5 Q
}2 Z3 M% K- G* f3 b/ ?& f

* k% n8 ~8 \- \% w2 [. f% ^7 \* |' Cchar *killzero(char *res,float result)
4 M' h0 l/ s% d; x1 p+ b; e# _+ U{. B7 @0 t0 l) F3 L: F0 c
    int i;6 J; ^# K) |% Q' X: Q; c- L

" z9 I6 ~0 v! J# O& v    sprintf(res,"%f",result);. W) L) s5 y7 z+ c! A
    i=(int)strlen(res)-1;3 m' |6 S( Y$ W5 \! s. I1 J
    while(i&&res=='0')$ J& O2 _  }5 w9 x" r# S( x5 m* y
    {
8 Z' L) i* T: }' g' ~        res='\0';: T; s; [. D9 n  m& W) [
        i--;* P' E  f4 K: Q6 z
    }" z9 A* J/ y! R* ?3 f$ ~5 |5 L4 d
    if(res=='.')( i2 u! Z6 L; E
        res='\0';& D( t, O7 p7 ?' L" o& V+ C
    return res;' q% J! h5 f/ m4 j# f
}1 K( i1 \- B2 z5 ]  X( F

: n5 I% O$ m! L2 M9 r1 Nint main()/ V; [, |4 k+ o& |! o0 o+ A
{
# o+ O4 n5 m0 p' z# K- W    char ch;' ^7 ^. r; l  B" s! P, e3 X
    char res[64];
# a9 q* f- X# R# G4 T) P    float result;, P2 P1 x1 m. H* n0 {# n  ^
    while(1)
- {0 C: s8 P- F* n0 Q    {
+ Q' M, u/ `% g6 ?$ H/ F5 o2 S        result=compute();1 H  @9 k# q0 {# n' v9 }
        printf("\nThe result is:%s\n",killzero(res,result));+ E* D: G  l! h. g
        printf("Do you want to continue(y/n)?:") ;, D1 k. _+ V: u- o- ]
        ch=getch();
; P7 r' r6 e5 T, u- b3 S& B$ N0 ~        putchar(ch);/ M' C" J& O* y9 _0 L# p
        if(ch=='n'||ch=='N')
5 S1 z7 ]" _: z            break;
0 p5 b  m! }% x4 R: p        else) \3 d- `% \) d* G2 ?( P' L
            system("cls");5 r  P5 o5 ?, {$ |% J
    }
& F- t; Z2 S- J5 I& F! W    return 0;4 N6 Z) e2 A+ ?/ h# l
}

  G) d, n# [. P8 i' v% g) ]6 ~* S" a. Y: ~
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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