标题:
C语言表达式计算器
[打印本页]
作者:
zw2004
时间:
2008-1-21 17:17
标题:
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
% [7 e. C* C- H7 b' M: q
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! Y9 |" L0 K# _6 M2 L7 @5 @
/**************表达式计算器************/
* l( n" r* x$ I/ C" c
#include <stdio.h>
) H# G8 G5 Q' @
#include <stdlib.h>
* R4 P, G4 A s+ F0 ]
#include <string.h>
5 ]* h# g& b$ j$ ?3 P, ?) @6 s+ y
#include <conio.h>
( z, {9 g. n- K) ]
#include <malloc.h>
5 N6 R4 J5 B1 D8 {1 N
! u- [2 B+ W/ K+ |/ z$ W+ t
#define STACK_SIZE 100
( D) x; M1 `: G5 h6 x8 z4 g/ l
#define APPEND_SIZE 10
0 ^% _- ?0 v/ [, ~6 c, c$ ]
3 [0 h4 K1 i4 ]* X# i q
struct SNode{
. D% r4 b0 [8 R
float data; /*存放操作数或者计算结果*/
6 k! S7 k5 U/ l: }; `0 M4 ~
char ch; /*存放运算符*/
+ k5 x! A5 l3 D) g
};
+ o% _ z+ k3 e3 ?: t7 @% a! }
* I9 P7 y% x$ Q% n' X
struct Stack{
- y( u$ I& L. C0 b; W& D; l
SNode *top;
: d7 A' O$ E' o$ D
SNode *base;
( B' I4 p. _' B
int size;
: T2 i$ S! i5 E# o
};
1 `9 `! q B0 ~
( Z8 D q, N* Y% V9 N" A- D
/*栈操作函数*/
" |+ _" R- I' ^5 F2 C% T
int InitStack(Stack &S); /*创建栈*/
0 n- e, P2 c0 F4 h
int DestroyStack(Stack &S); /*销毁栈*/
, o# e& @$ g ], i
int ClearStack(Stack &S); /*清空栈*/
; {& `- O2 n& Z* r' M
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( |) _" j+ J) J" a9 c$ n0 C
int Push(Stack &S,SNode e); /*将结点e压入栈*/
4 U* q* `1 H/ x$ E5 P/ N
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
0 S' O1 e/ j/ C) m {9 Y0 L P
- G9 m& F4 v/ P; M/ k, s
/*表达式计算器相关函数*/
) Q: R* [( y# N4 Q" c
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
0 U4 X: q P2 G( \" ?
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
& J( b3 P- k r1 ~
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
% V! f: ~2 C4 E! \7 p+ h
float compute(); /*表达式结算器主函数*/
& j; U0 ]; r2 A4 f+ D
char *killzero(float result); /*去掉结果后面的0*/
7 ~, Y c4 w8 Y g7 ]5 N
% u( Q# s% g5 c( V% q: C( c8 B' u
int InitStack(Stack &S)
4 ^* c! o( g* |! N( \% N5 S
{
( D% @- ]8 I9 B, e: x8 Y
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
! M, P2 E, e v9 V
if(S.base==NULL)
: i* R* \* O3 f n
{
) t+ q2 K; s3 T( a+ Z
printf("动态分配内存失败!");
! X( i0 Z- `4 D" T: u
return -1;
9 x6 T# {& E- V5 y* g2 t8 w* B
}
& S2 h9 p1 ~$ k$ t' Y
S.top=S.base;
$ {* Q9 _5 v3 v0 l* ~: h1 i( N1 a
S.size=STACK_SIZE;
1 p- M' {$ ?7 o$ s- J% r. |* d8 {
return 0;
! m6 x6 J$ ]- i( P) }
}
- Z' w) H; f$ [8 x: v7 w
6 ]1 I5 d6 [6 U
int DestroyStack(Stack &S)
# l% C% j- H. }+ A0 F' Z
{
# V& w* L' G2 r8 P. ?5 M( n* ^9 k7 l
free(S.base);
9 e0 a0 h& G9 v% V: T
return 0;
6 r0 c( f7 q7 X% I0 I7 M
}
4 O+ H2 b0 I" Y
9 B7 `$ z0 W% Z4 i
int ClearStack(Stack &S)
5 [ W1 i& l; p! |3 k1 H& y8 s
{
$ x( P8 L7 Q+ ^# p4 M
S.top=S.base;
: q# }, q! Z; H9 p: t
return 0;
) {) t! I. I' N* p
}
' b% W" A! |& J1 r5 s* K
# j9 M; d7 P. e7 U2 S) f. x( p8 a
int GetTop(Stack S,SNode &e)
% J0 m1 S, h! `/ \# i( ?
{
1 z$ p+ a" O5 _, u
if(S.top==S.base)
/ T) N( b* G2 I9 m2 {$ J
{
" K K s: w6 q
printf("栈以为空!");
$ @% n- N6 K; N# [; P# ]
return -1;
* \/ S0 q9 f) ~5 F! L/ u( S0 C
}
5 ?$ N: @' s5 v4 F: G$ S0 Z
e=*(S.top-1);
: l7 R/ b/ F4 n0 d. s
return 0;
6 \9 h$ _) B- r. J) U5 y
}
+ [9 G5 Y4 {+ M" G) w
! F( w8 O. S3 v+ K
int Push(Stack &S,SNode e)
- b f! I9 j8 S" j2 i/ o
{
+ z4 U1 [% U3 f) C) _8 N
if(S.top-S.base>=S.size)
) I4 W" }9 L. {" [7 h" F
{
7 C; [2 q" j% b2 z
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
. A1 N7 {2 g# l. E+ @3 r
if(S.base==NULL)
, \% C' b" x& y; R. h
{
/ c. |$ D6 J/ o4 r7 s0 R5 c4 j
printf("动态分配内存失败!");
& H6 {- [- x* Z, f$ i+ c$ Q, S& `
return -1;
+ d0 p$ o, j6 c- l
}
& g- N v _3 r/ _9 ]. @
S.top=S.base+S.size;
! g! D& R+ n' u! Z1 P
S.size+=APPEND_SIZE;
! l# p, {; j9 c7 j
}
1 r& r* U L9 l2 K7 n
*S.top=e;
9 F1 a9 Q0 ]) ~/ J% W# G% o; S
S.top++;
/ f! {+ y5 |1 q
return 0;
5 y5 n/ v4 Q- Q, V! K. s* P
}
' j) t: ~ o' k2 f% S/ P
1 I# Q* s# w4 J; j+ m3 u
int Pop(Stack &S,SNode &e)
8 V/ @: e" X d
{
/ @/ m: \6 ?. H E3 O$ |- F
if(S.top==S.base)
$ g) n& l) Y# N( m) E
{
! l. U4 G n0 b& V
printf("栈为空!");
- {2 E4 L3 H2 |1 E% |, \& X
return -1;
x; f6 v; ~) A. N0 e7 c. ^
}
6 J. L# Y+ Z3 ~: b* z* ?+ ]( A! ^
e=*(S.top-1);
/ B7 ]1 {) C s; x5 }
S.top--;
5 C, k: ~" K( `: s0 T! V
return 0;
% q1 P! N4 V& S
}
. A6 o. c2 I: [4 H/ ]
2 a5 c: n, n. x3 F. q+ z
char get_precede(char s,char c)
3 m4 y% R' I3 H3 e- |- m( X2 g, v
{
$ D* Z8 N5 X# D; d: w: z
switch(s)
" Y" J5 J5 o9 ]4 f3 O) g" W1 x
{
3 D0 m9 J: w. b5 |, n1 g
case '+':
! x0 K5 l/ D) C+ b2 R
case '-':
4 E9 @( o8 q( q, E
if(c=='+'||c=='-')
/ A s8 _1 p3 d0 j* |% M$ d8 d% y
return '>';
) H; q( c# P! L0 \. Z/ G
else if(c=='*'||c=='/')
. l% b- q3 L2 ]6 q- k
return '<';
y+ j* V& h- P5 Y
else if(c=='(')
! Y2 I$ C5 F2 Y2 p
return '<';
; p) m8 X0 T+ |2 h! O( e
else if(c==')')
# `; o' k0 [- K: U$ n* s
return '>';
! u9 |2 u: \' }& C: o* B
else
! W7 b4 K1 ~% S7 D0 t( H
return '>';
3 q, J2 y, O/ S" D# ?/ Z% Z
case '*':
6 t, |7 f0 [5 a4 x! W m
case '/':
5 H& a1 F$ q3 f
if(c=='+'||c=='-')
: q9 Z9 F: m- }3 T) w( Q3 j8 O' h
return '>';
: b, T; i$ |# J6 c: h0 N
else if(c=='*'||c=='/')
& I( U7 |; M: @ Q* F, j
return '>';
" ]9 j# J9 y* w% l; o6 _& N) ^% s
else if(c=='(')
0 I5 ]+ ^: ? c: N, T( A
return '<';
) {: E! J: t; P0 u
else if(c==')')
' a" k- v- L0 b+ h
return '>';
# u/ X$ g1 T6 n( g G6 j
else
# m C' S/ f3 f, E. ]$ r
return '>';
1 B9 Y! d3 d) @& D0 R2 @5 S
case '(':
, f ]- i/ M8 k
if(c=='+'||c=='-')
3 H- R; Y9 G7 A; W! X) y
return '<';
. R! i# A+ c: C" y
else if(c=='*'||c=='/')
& J. i, a/ E1 Z7 {6 T
return '<';
9 Q8 }# e) W1 Z) T( r" Z- \, |
else if(c=='(')
1 A% x# n$ ?: V# |+ f, O- h$ R6 y5 p
return '<';
P1 f# w" x; F7 G1 W( d7 V2 k3 Q( D
else if(c==')')
4 d0 g% w+ t. c
return '=';
# b2 k% Z8 j9 |! L! Q- J
else
- u/ T& W, N- _. h
return 'E';
9 U+ e- T% U4 U% B9 |" I
case ')':
4 z4 W2 }4 _: Z# v; X3 S
if(c=='+'||c=='-')
7 I$ Q: u D! Y3 e3 K
return '>';
; C1 Y- {# J, t# l7 W9 ^
else if(c=='*'||c=='/')
# o6 H5 Y% R; H( v( H* T n
return '>';
1 z+ N6 q% [/ `. H( S/ K( Z. w3 T
else if(c=='(')
- W2 j+ V4 _+ U$ Q' R- h
return 'E';
/ D. N3 r% ^7 j) V9 B* H8 [% m3 U) A8 w
else if(c==')')
. p, Z' `) X; |0 s6 G. j# R
return '>';
' _9 w# s3 U3 r8 J4 t. M" o
else
# A% S/ e I6 v, S
return '>';
! p- E b S3 g" K0 i: n1 ?
case '#':
8 ]* [+ D( A: q
if(c=='+'||c=='-')
3 Y+ `$ i: E' A3 a
return '<';
% o( c" [3 [$ Z( }) ?8 u' {
else if(c=='*'||c=='/')
0 [! U* S M7 H2 O- ^
return '<';
7 r; c& S9 T# z. G; g& I
else if(c=='(')
6 U2 E {; d: P- U3 Y' Y& K5 t
return '<';
/ @* d& f5 y$ i( Q+ H0 p
else if(c==')')
8 @% i5 }. O U& ?& e% [- M3 |, f
return 'E';
: [' ?0 E2 ?. S$ t
else
# Z) @- Z% [- F% A* _8 }) e
return '=';
9 s6 M0 ~+ J, {, m/ a* _
default:
+ I, _5 o7 T1 }
break;
0 O* r$ e. v; W
}
7 v3 o' y! f+ N( H* O, w
return 0;
6 C1 C- g* n4 X6 U
}
5 p1 V6 [. y: m: k% ]8 i6 G
+ K+ I5 V$ {) Y+ b+ S3 p/ Z2 a; p2 Z
int isOpr(char c)
+ o3 S$ F; H4 F/ A6 Y4 X9 a- h! P0 a
{
3 M5 Y \; p0 w& u. \; v
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
* x3 {3 n4 _; W1 A3 b/ @
return 0;
/ L! I# w3 B) i+ C: ~) A
else
% D; A5 j6 L4 Q; s9 |% K3 h. a& s
return 1;
4 ~ a4 T& o- r8 ?' D
}
( y" R5 K2 E8 D& G8 c6 p
6 |2 r/ L4 o4 d
float operate(float x, char opr, float y)
% W; M4 i5 l# J8 u+ ~+ Y9 _# F9 B4 q
{
) J# R& A" w4 ~# G, o/ i3 ]
float result;
, c4 V6 H: K; n: K
switch (opr)
$ a4 S! I9 u* H n3 d# Q
{
" \$ [, q/ ?+ O+ |. |4 \ p' I8 o
case '+':
4 Z$ @4 u" A# N: Q6 d; ~, _. Z
result = x + y;
* u" m5 d0 Y- x5 h0 S0 @/ X& k5 |
break;
2 I+ n8 }* H- V- z6 \) K, P
case '-':
, S b. h! Z2 t
result = x - y;
: _, U9 o6 G! U+ f
break;
# ^4 ?; d7 J3 J0 m& Q
case '*':
' t" _& P; S+ [! L
result = x * y;
# ]$ }/ _% p; C. s+ k. ?/ I2 U
break;
: `- J! u$ c( U
case '/':
4 R$ F$ o: [: I' s) X
if (y == 0)
6 g. f7 c6 | C8 Z/ [& u' ^' T
{
2 w, Z4 p# k: k& @ M D" u6 ^( \
printf("Divided by zero!\n");
6 J% v8 n9 {/ N, C! I1 T
return 0;
& f% D1 q* f6 o2 X0 m: g) |
}
) h9 T4 Y8 {2 U+ S% r! @3 ]
else
* `9 x0 E8 `/ ?' y
{
3 N9 A6 ]1 M& K- J9 P) f' X0 Y& C
result = x / y;
, C1 S x# }; G: M2 V7 R- U
break;
6 W/ l. a$ Y, ]7 L; e |
}
1 }& U( C$ |7 B/ {
default:
- s6 I% I4 r; h- [
printf("Bad Input.\n");
9 D2 _% G" `! w2 B# v3 X
return 0;
* O+ r; L: T3 p* f( B1 t
}
! i. B& N, u) ^1 b( g9 A
return result;
4 d9 Q) C. d$ ], w& Q C$ I# y& p. c
}
, u; r; J' D2 {' o1 K
/ O. [1 K2 q* I( U
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
$ ~ A* E" C. ] H2 }- d7 B' j* h* R
{
' `9 a; W4 \7 A, E
Stack optr,opnd;
; u9 `" Z0 N j0 S$ k O
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
) w0 o6 y0 O/ Z2 d
char c;
" d6 |. r# a5 o4 @- o: c- U
char buf[16];
# J* p& R7 G. l6 K! {8 i& r
int i=0;
$ R0 n3 k1 ?% ^: |6 ~- F1 P2 z
& o, t. ^3 }/ o9 c) e* T, P( Y
InitStack(optr); /*用于寄存运算符*/
( B6 J4 Y' i; f0 O8 ]
InitStack(opnd); /*用于寄存操作数和计算结果*/
- ^; P9 u N* p& t! _. k
memset(buf,0,sizeof(buf));
4 B" H) H9 @; E3 V; X; N
. f1 y' }; @5 ^5 e# P1 n( V
printf("Enter your expression:");
5 U; T7 T1 K' ]" O
h4 E/ n+ |4 j5 v% p; G
opr_in.ch='#';
7 ?7 K8 ?0 w/ v- H5 L
Push(optr,opr_in); /*'#'入栈*/
7 q9 S! i. ~" H) L* V
GetTop(optr,opr_top);
8 t7 H& P! |. L* p3 i
c=getchar();
, s) \1 }7 J8 `. X
while(c!='='||opr_top.ch!='#')
3 M. f+ l- u. p3 D
{
) z! |5 v9 Q8 x, D5 p! B0 n# x
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
; }2 ^# x; E# ^( T+ X5 ^
{
3 d( }2 D" i k
buf
=c;
. s# o8 Z% q. \& c* |5 L
i++;
. ^; Y" G$ R/ w; v0 ~& a
c=getchar();
% ?! g- i" o s/ m j, }
}
\' F% \2 B$ s# T; X
else /*是运算符*/
8 J6 N0 Y5 N) {6 W
{
$ M4 y: }9 E8 D
buf
='\0';
9 Z e2 H, E, j; I+ \
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
& i) |* g8 w4 D) I) o, ?# M- G- B
{
1 H- }4 R' A/ v8 Z
opn_in.data=(float)atof(buf);
1 c9 o1 B! q& h5 Z) `, E& C
Push(opnd,opn_in);
6 M0 y& C7 ]( {. Y; z$ r T
printf("opnd入栈:[%f]\n",opn_in.data);
l7 M$ z2 `( x. E o* f8 y
i=0;
9 c: b8 H* p* A/ @# M6 _
memset(buf,0,sizeof(buf));
( p: ~0 k. w/ B! U% y
}
6 [& s4 g( S2 W$ P3 k; s' ?
opr_in.ch=c;
, O' ~8 R6 ?2 c+ O7 |' b
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
2 k4 B i8 ^3 ^7 _0 w, i
{
$ A6 P0 o( n" l! O' S
case '<': /*优先级小于栈顶结点,则运算符入栈*/
5 W9 I0 B0 c5 a/ n
Push(optr,opr_in);
- r) T9 X: Y+ F; `' F R
printf("optr入栈:[%c]\n",opr_in.ch);
1 F, Y4 P' m+ U8 l) Z" n
c=getchar();
& b, h+ A0 u/ {1 R/ D
break;
3 M n9 [4 i- ^$ e! e8 K
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
+ P3 d0 P5 G' F8 D
Pop(optr,e);
2 y8 w1 ]2 N' p
printf("optr出栈:去掉括号\n");
: ~+ B: r. _: U+ `9 w2 B
c=getchar();
# b1 F! G% M0 r) Y2 w- c" W
break;
; Y1 e t6 i& \. O5 e- V
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
+ x' D( U! j/ M6 b3 E
Pop(optr,opr_t);
+ m- ]0 D' ] z, P& g
printf("optr出栈:[%c]\n",opr_t.ch);
/ w6 e0 D+ B/ ?/ O
if(Pop(opnd,b)<0)
* ^9 B6 s$ `/ E- _1 g1 y
{
0 z4 F4 I' m0 C* @# i
printf("Bad Input!\n");
- g: k5 W8 ?) Q5 S9 ?8 z
fflush(stdin);
% T$ V6 f2 c% o- w: g3 S
return -1;
; X9 n/ O) p$ }+ `
}
# V$ ?3 h* }2 Z$ k3 ~# o( b
printf("opnd出栈:[%f]\n",b.data);
8 {* ?* k! p. Q0 ~' W7 s. e# X6 r
if(Pop(opnd,a)<0)
0 ^4 O) U4 Z* n8 _$ h `' P
{
& X2 }, G% v9 U8 l! \
printf("Bad Input!\n");
* @/ h( s$ E' }* a
fflush(stdin);
/ J1 \5 B; Z: R& F
return -1;
5 z# R! e% ]4 q/ |2 M4 o% g
}
S0 \$ @. h. @9 K
printf("opnd出栈:[%f]\n",a.data);
% C( B7 L: R' I. \( p9 h
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 O* F! S$ _2 L) [& u$ k$ a$ s
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
7 C1 d, S a$ a3 @" j5 r2 s- b
printf("结果入栈:[%f]\n",opn_tmp.data);
4 h0 B T) {6 B2 w: O$ M7 H, B
break;
5 M: n0 X3 E$ |/ G( f V- o
}
6 H/ e% P% P) n5 N6 p5 X
}
P' J! G" I8 i0 V/ V* O5 c$ u
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
0 x* j8 F" ] d1 m. o5 \9 {
}
* y/ J9 c+ g( ^" O9 N! Q0 G- c
GetTop(opnd,opn_tmp);
% n$ T; i6 z1 ?8 Z6 A9 q
DestroyStack(optr);
" J5 W7 }2 X3 j& \- C+ N& s
DestroyStack(opnd);
% G- ~2 Y f9 L! ]; w4 F
return opn_tmp.data;
2 \6 D1 q* ]/ c8 y1 q
}
6 F4 f, U* {" G# `
. U) c) t% L4 W% k
char *killzero(char *res,float result)
E1 G( b& ?! w
{
) b6 e! Z# o( Q: u1 N( N
int i;
7 H& \( R% X+ }' Q$ Y7 C: O5 N- G
6 |9 e) b) A0 T9 x6 e* r0 z
sprintf(res,"%f",result);
2 l! ~8 e' L- x. `
i=(int)strlen(res)-1;
# \0 p* y' C, N& l, `1 F; W
while(i&&res
=='0')
; q1 p4 l# f) K
{
% h) C$ S" T( W$ J4 d
res
='\0';
* j) x; [" ^5 k+ }' m
i--;
' o4 v: w! b3 b
}
" |( v( m) Y: Y& j
if(res
=='.')
G' M9 X& n$ x2 n
res
='\0';
2 D! U1 Z4 m* D: d; X
return res;
9 c2 f) A2 u! n- R
}
9 `. P8 S3 b' A$ A( Y: C
% X9 O, ^! C0 I. a$ ^& U
int main()
" y: L) I4 S! _) z! g
{
0 } }8 ]3 I% }& z; M, d, ^1 |
char ch;
/ t3 A3 ^) a) R8 Y* C9 J
char res[64];
0 U$ Z- l/ ^! N, d
float result;
' U. M( C& p" V4 \, e( \3 [% Q
while(1)
! |7 M$ e7 L% }1 H8 d' P. Y; Q2 i
{
! f& {# Y7 k/ E @: x
result=compute();
$ b- o+ R! F w
printf("\nThe result is:%s\n",killzero(res,result));
' E n9 X. ~) {) e
printf("Do you want to continue(y/n)?:") ;
y; f9 A' `2 w) Z" \# j6 c
ch=getch();
: a+ Q+ K6 `9 ?( O4 u3 j7 b
putchar(ch);
2 o/ _7 C- C v; r C
if(ch=='n'||ch=='N')
! E+ T0 t% M8 z! J
break;
9 O( y7 t1 I% S' }) E5 i# m. q
else
! ^/ p. ]/ Y' I. K7 l/ ^
system("cls");
* v& w1 `* w, Y. B1 C
}
. p- {$ _5 o9 u# W5 A A, C
return 0;
" A1 L2 z( i, ?4 _/ {& p2 C; s' K
}
3 d: {8 F: B& w" E0 h* K5 {4 P
: X# ]1 i$ \0 x. ^5 @* B7 Z1 G" }
[
本帖最后由 zw2004 于 2008-1-21 17:21 编辑
]
欢迎光临 捌玖网络工作室 (http://www.89w.org/)
Powered by Discuz! 7.2