标题:
C语言表达式计算器
[打印本页]
作者:
zw2004
时间:
2008-1-21 17:17
标题:
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
, ]" q4 r! X. G% R5 U4 {
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
: S C+ S2 s" `
/**************表达式计算器************/
0 T7 x `9 Q9 N4 s: B5 i
#include <stdio.h>
* t, P. c0 p, M" T2 q0 \
#include <stdlib.h>
0 n; B& W- h+ |
#include <string.h>
3 T# u' i$ ]) z) p. k% c% d
#include <conio.h>
( X: J }% o: v& v9 T
#include <malloc.h>
& S2 b- k. A' ]' {0 e( Z* D
* {7 w* B7 A0 e; I L& w
#define STACK_SIZE 100
! y& O& T% E9 W7 ]* \
#define APPEND_SIZE 10
) w$ z% D4 q8 i9 P' J
# A6 `5 d0 q2 M& Q$ ~1 C
struct SNode{
% o. U. |0 `1 t4 c0 J# U
float data; /*存放操作数或者计算结果*/
8 o2 e8 y% b. b/ y A$ v
char ch; /*存放运算符*/
$ i/ e0 r8 i& t9 [: X
};
: C1 g, o3 X0 c3 M( t) \
3 \ b2 w* _0 E
struct Stack{
9 Q4 g% J) n: v7 v8 C. m
SNode *top;
S( e9 Q- R& \ f2 Q( ], i
SNode *base;
0 K5 {8 {2 n8 a' J! U" h
int size;
4 @- d: U# S( g1 w! [& ?- k4 F0 K% d
};
. E3 k# @7 D `
1 M. q8 }, q+ ]$ N) n
/*栈操作函数*/
& x& J* T8 N' h" L* j
int InitStack(Stack &S); /*创建栈*/
; O2 |; i3 \5 o1 k7 r8 X) X
int DestroyStack(Stack &S); /*销毁栈*/
) M9 Q Z2 h9 @
int ClearStack(Stack &S); /*清空栈*/
' x! R4 N+ k- ], t6 Y1 B6 w
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
; n- r% a: R8 X+ Z; H9 y3 r- I' r# L
int Push(Stack &S,SNode e); /*将结点e压入栈*/
! N# r/ E* h. _0 q7 x0 b
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6 Z/ k# c% ~0 s0 N
; s9 \$ ]6 i/ p1 C
/*表达式计算器相关函数*/
* B; C6 P! S! U- S1 Y' b
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
7 }! {) v8 N' p) W+ R
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
( m" N$ ?: _# s. U! {* m. g) R
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
5 ~) c4 y; h* y j( V
float compute(); /*表达式结算器主函数*/
3 b9 V) u; O3 t
char *killzero(float result); /*去掉结果后面的0*/
( k% a: @) `0 L1 `1 D2 c ~# e" |
1 P: ~, M; m5 y( q& c
int InitStack(Stack &S)
* n5 K) [, w% j/ ]0 W
{
7 h% L" K$ s& X' |3 W
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
) R1 Y1 [" a, P
if(S.base==NULL)
3 N$ c7 Z* k- e& S, B4 w
{
/ t- g p' U8 W$ t
printf("动态分配内存失败!");
( K2 D. `8 K o2 P8 _
return -1;
9 W; q c7 J9 I$ ]8 N2 f/ D7 `: }& n
}
& f V( h6 a! G5 `4 x# w
S.top=S.base;
6 Y8 x8 ^( Z) F6 W. [' L& u
S.size=STACK_SIZE;
9 P3 W* w, I/ A0 N) i# }* P& J
return 0;
+ a5 R. F8 d# M9 E
}
& U% F w1 s4 V2 `1 V7 g
6 m) W" C1 \2 f2 {: L
int DestroyStack(Stack &S)
8 [5 q3 @, `! ~3 v
{
: C4 l( q2 ]2 @9 H
free(S.base);
$ W0 f: h' n+ x
return 0;
' A/ P* ^$ x4 x" `! p& `1 V
}
* a2 ~6 i1 @0 p8 d d1 W8 S
) V0 G, }: c3 V
int ClearStack(Stack &S)
N6 B6 V W" Z" T) C, j8 C
{
* d" [ L" m; b. y/ u r( c
S.top=S.base;
4 k& t, m/ a4 _. m, }- S$ J
return 0;
2 _1 b @% c8 D: c% @1 m" e
}
1 e* q% a; N; q) G( o
8 `+ I% m2 m; t8 _
int GetTop(Stack S,SNode &e)
% D0 C, X+ ?- r2 ]* C$ V
{
4 {2 O* s# }* i, a: x0 c1 e
if(S.top==S.base)
" L3 X3 b0 h' N/ H" N; d; T0 S. @
{
- M( g! s- ^, Q: B
printf("栈以为空!");
" N ]: }/ B+ g U2 _7 a$ p
return -1;
, ?5 @5 o. k* g
}
' {6 d2 s/ z& n1 Q! E8 T
e=*(S.top-1);
$ I" b: L6 ^( ^" x' r
return 0;
6 E1 j; Y$ f% l5 J+ w. H
}
0 j& Z9 L" ^/ N" s3 i# ^+ @
' c0 ^1 w8 M+ `$ l2 p
int Push(Stack &S,SNode e)
; S7 Q! U% y, o7 O
{
( T5 _/ ~+ l. M7 ^7 |1 U1 g$ V7 G
if(S.top-S.base>=S.size)
: Z [/ ?9 q. l W
{
7 ]3 u7 z/ Z- k/ b8 J
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
* o; I8 S& ]* I+ H- \0 ~/ j. o
if(S.base==NULL)
( E* c# J/ W% l
{
) r/ j) ]9 z4 m' x! l+ U2 j0 A
printf("动态分配内存失败!");
. L, M2 G$ a Q. a# a N4 u
return -1;
8 W& q: o7 p4 P/ i l4 n$ Z% s6 R
}
6 w1 T) `7 ^ E5 o. u! E! s9 B
S.top=S.base+S.size;
3 F3 s/ G) e" c K; v, @
S.size+=APPEND_SIZE;
5 |) [ T3 T' ~, F9 l
}
8 [0 Z0 ~2 B. J
*S.top=e;
7 n9 W' V! E; v4 J3 U/ ~. C* c
S.top++;
( u9 t8 P1 u0 \ H/ q( @+ L" H
return 0;
8 j- i' M ]6 [% @
}
# g, c( @* Z Z5 i1 m( j0 S
7 K6 r( C Q4 X# e' N0 Z
int Pop(Stack &S,SNode &e)
6 e! e) \; `1 ]# @, @3 |
{
6 i# i2 p9 C% v; i3 m3 z
if(S.top==S.base)
u/ [: B* a) k0 I
{
' T# O) `+ `9 ]2 H4 R9 k& |( o
printf("栈为空!");
4 L# i# i- K( }% z+ X4 j- e: E" {2 y
return -1;
: l! [. L" p+ F0 E5 H+ T
}
3 o* m+ \. q7 ?. G7 t: c
e=*(S.top-1);
' E1 H! O, U8 k+ F2 o f2 x
S.top--;
# d4 `) R) I/ U% E. Z# D4 K
return 0;
& ?* o" E. u, y# ]5 ^; I& Y
}
5 a: S0 i4 H3 T- j8 W$ \" @1 S! }
2 i: c0 r$ i! p# Q2 F
char get_precede(char s,char c)
7 J2 J* k+ G! {' I
{
; G) h' D( _9 w" x) u( n
switch(s)
+ x4 p" ]! Q$ f! U8 u
{
8 K5 _" N* U* S' |; N7 C7 S/ K
case '+':
- G) ?7 d0 [' y$ S9 x1 _* p
case '-':
7 s) E- [5 J4 R/ c: M* W2 R F+ d
if(c=='+'||c=='-')
/ C8 V( D" D, J
return '>';
0 G( S$ ?: l% |) Y- C7 v3 \
else if(c=='*'||c=='/')
4 a1 w/ c# m3 j5 F A0 {2 g
return '<';
4 d# H( X3 f. D. x5 I# ?* d6 A
else if(c=='(')
Q( r5 f7 P5 f* W
return '<';
% Y0 k4 e7 \1 ]; o( q" Q2 a7 w
else if(c==')')
4 h+ I" P( H- w2 q& |
return '>';
' r2 D$ V/ O# i* e* U; Q( T
else
$ {& \3 X' @0 n5 }0 H8 z
return '>';
. h. G5 k) P) a7 B/ N- G- {
case '*':
! C0 e6 ~3 H- v3 N
case '/':
6 W2 N; F" v$ _1 S( H
if(c=='+'||c=='-')
6 Q3 O5 n$ R, x# A
return '>';
) n$ I* F$ t i$ u: S
else if(c=='*'||c=='/')
1 _* @ I/ w+ B
return '>';
0 H5 H$ S, ]/ x6 _
else if(c=='(')
$ i& T9 e. G7 C: b
return '<';
; V, y, \6 @" ?7 V9 w6 X, j
else if(c==')')
- S- y- ~# D3 l( D$ \
return '>';
" N0 @1 I2 `+ _
else
2 s2 N' \4 j9 k
return '>';
% I. b& N( u0 M v7 ]
case '(':
. G7 u# B. O0 |- E6 \. Z" r
if(c=='+'||c=='-')
" q) o6 b }% K) n# o5 k, X% r' z
return '<';
5 K0 r# K; N5 L6 j3 x. x8 v
else if(c=='*'||c=='/')
5 P& n9 @' Y2 ^' x
return '<';
' k A* h* o+ o
else if(c=='(')
, A9 j" O; E. W w6 K: J2 ]
return '<';
) Q' C, a0 _3 D* m6 w. c* R9 u
else if(c==')')
3 u: u! I5 `% N& {9 ?
return '=';
# u* a. _5 {9 c# s
else
; s) v# `! t# r/ a
return 'E';
. u# a2 m* U; _" K1 v* |
case ')':
* O& e" q% X3 I2 @% i& g2 F
if(c=='+'||c=='-')
2 _& \1 K2 X$ }. ^+ E1 j
return '>';
2 {6 G6 X% C8 W. S- |; z7 T2 `
else if(c=='*'||c=='/')
0 n8 t* V2 m, \0 X \. K
return '>';
3 ^8 A8 h; I+ o1 g R/ g
else if(c=='(')
" f$ f' u) `3 T9 {- x [
return 'E';
0 T0 t2 I) i& Y a) R
else if(c==')')
) V4 \( r% a) K [0 `6 u
return '>';
7 D3 x ]$ N1 f4 J2 }6 w5 ]. w
else
% b) x- s- r7 o* k, X. _
return '>';
+ m3 ~; k' F9 O) t7 S) l
case '#':
& M0 a( P: X/ p# ?
if(c=='+'||c=='-')
1 i! m3 N$ i: D* n( I3 q- Y
return '<';
3 G# Q) l; ?8 r7 O
else if(c=='*'||c=='/')
( k0 ~" _; q- @& U
return '<';
; Z: f+ G6 f7 g7 X6 w* e% E! t
else if(c=='(')
8 a; m+ F* F X p5 q( }4 y& v
return '<';
0 s' R9 P. O) k# @1 ~$ j7 D
else if(c==')')
7 {% ~0 X* |/ R3 B! B. b
return 'E';
4 q) \* _+ p# e4 F+ H0 X% J
else
# ?$ h( Y( N- k# k; A
return '=';
9 l- g! p( E# h% ?: p4 S3 [
default:
5 n; z7 v8 T0 H
break;
1 [" T9 q+ n' \" s3 }
}
* d/ s( [& k3 c4 K6 G* H
return 0;
7 r% F8 }/ E% t( |6 L# r
}
2 w, S5 n( s5 H* k
( K! O4 _' {6 r; q' ?! D' G& n) H
int isOpr(char c)
$ E4 ?: x) k' K; D: A# o: [
{
3 t9 Q6 v- h4 _! W+ l5 t L9 P$ s( G
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
W; T$ k; b9 J( h! A: ~8 l6 V Q
return 0;
" |. J/ F. e0 a1 T7 ]
else
/ \8 F3 j' M9 P6 p: G, y
return 1;
1 ~+ |: T: Y- Y( X4 U2 L: L* r# _
}
' d' x; Q+ _$ g3 p
! T3 S5 \3 d9 X, c8 X& k& v: n$ @
float operate(float x, char opr, float y)
/ U; p3 b$ [; c
{
, i: D* F' p5 E1 l" Y: s
float result;
5 [. h8 J3 R. d: J1 F6 t
switch (opr)
: q( W' K" A: f( m5 w5 r
{
" v$ O/ u( X0 y! Q
case '+':
& `. n b! ?; z) b; J% o
result = x + y;
' D3 P) g% x B) f x+ V6 S4 V
break;
/ @2 W3 \' c$ ]2 A& ]' l, y4 D: Z7 P
case '-':
# ^: o# H/ @: @, L: I! l+ \8 J/ Q
result = x - y;
3 f8 m& r: p/ o
break;
) N7 I0 c9 r4 X! w! ]
case '*':
2 _( {$ R& K$ z8 B# q
result = x * y;
" E* e; i1 ]' c5 L5 E) D/ ~; A5 r, K
break;
1 w5 V4 w- j6 V% k7 D
case '/':
|! m7 N3 @1 r* ?% `
if (y == 0)
& W6 ^& S7 d7 K' G
{
/ o. _7 o& c% l* b( u
printf("Divided by zero!\n");
4 K: a3 m+ b0 \' ]9 U8 o9 J
return 0;
& i \; R9 f) Y! s; _1 T$ j2 b
}
5 D5 x! S9 I+ G; V' O
else
' r: s) N* P; L6 ^( s
{
9 t9 r! ^! s2 k7 F J1 g7 E
result = x / y;
8 z* {7 g5 N, v e0 y
break;
9 C2 S$ w7 v: k: d9 N- n
}
% A) u# x" s+ `9 o" ^- ]. A! P
default:
( J' E* [" J, V) I( X5 D
printf("Bad Input.\n");
1 @$ k! Q5 {7 W) n5 x# k3 I
return 0;
9 _1 r9 L* g+ S3 s: l5 \6 ~5 Z
}
( z7 M) X: f; h4 ^* E1 I
return result;
) a# D. C5 x8 Y( E1 ^( K- ]
}
# C, j4 b3 E# I# v5 [' O
2 [- N4 J7 L/ g" H+ Y
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
6 F1 ^# ?* m5 g9 T
{
$ |- U6 L1 A( x" P& i
Stack optr,opnd;
' M/ f9 j0 ^2 l' L* {4 H& n6 c
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
7 l2 x, X w) L. x1 v' w; C
char c;
7 @" } G$ `' R( [& x I7 Q
char buf[16];
8 w% g6 {* k) N3 r1 _; ]
int i=0;
! Y; K2 B7 t- j: {$ @5 E
6 u( T2 z7 P4 |$ r% r* }
InitStack(optr); /*用于寄存运算符*/
5 ~# I2 W j8 [* K1 x9 p0 k
InitStack(opnd); /*用于寄存操作数和计算结果*/
; I5 t$ o; f# b
memset(buf,0,sizeof(buf));
" T% f, M; b/ E" k# t6 c3 C1 L2 x$ K
) Z W8 p4 N z. G% X
printf("Enter your expression:");
; Q4 K( \& u0 h" F: V& H* R5 e- J
( r# r1 M9 b" ?. e4 t$ a: ]
opr_in.ch='#';
; x0 L& A) L1 w; \
Push(optr,opr_in); /*'#'入栈*/
2 K& D( {% k, V" C: f5 M
GetTop(optr,opr_top);
% X8 ?! i5 y/ e: n6 A) w. X
c=getchar();
/ n1 `1 r/ N% Y: S9 G H; I
while(c!='='||opr_top.ch!='#')
" f0 z3 d$ G/ L9 o- `
{
9 O) P0 F& I3 w5 Z0 `; E% Y
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
C7 m% _6 `( b7 e1 c7 ^+ v; P; b* s5 v
{
; t0 x m; j: \. b
buf
=c;
& ^! Y' U* O* I. K' ?3 F! j7 g
i++;
2 J. C" `: s( Q) x' q4 I+ N4 z
c=getchar();
: u3 a6 `, X( x. V$ X% L, Q
}
+ T, v. _: `" `) D
else /*是运算符*/
: H8 ]" W4 N9 o% U
{
6 ], h/ r% q* }; i6 W7 C
buf
='\0';
6 M- |; W" h r% u
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
/ C( u4 X: S. [. B2 j
{
# \# [1 |( p) C9 k/ e
opn_in.data=(float)atof(buf);
+ s: \8 l5 W8 q1 `: A: p2 s
Push(opnd,opn_in);
$ P# o- P# s+ M
printf("opnd入栈:[%f]\n",opn_in.data);
9 }6 s0 }) \" j( \
i=0;
7 u9 h$ B! {5 C* N/ W& y
memset(buf,0,sizeof(buf));
2 n: H5 c/ z( u, T* ]% z8 z
}
. v" y+ U7 y- N1 }4 D5 Q
opr_in.ch=c;
9 ?9 [* D% L1 f0 X' O
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
! a* A$ j1 k" Z# l
{
9 d: o( _$ B1 P4 U* Z
case '<': /*优先级小于栈顶结点,则运算符入栈*/
: O% O8 v" ?) x3 I1 a% |
Push(optr,opr_in);
0 X" |% }5 j. [9 m- V
printf("optr入栈:[%c]\n",opr_in.ch);
s' {/ A1 d) Z) e& x- f
c=getchar();
- U p$ |, {3 a: Q! a" G3 f
break;
" N+ u; G( Z# y- o8 S, Q
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: ^! B1 ^8 S3 c" O/ v
Pop(optr,e);
5 ?' G- d4 F! Y7 \, L
printf("optr出栈:去掉括号\n");
# x0 f' f* O5 }4 M% ^% Z
c=getchar();
9 l! T6 ~# z ]! w1 S+ o; H$ z
break;
: Z+ A+ S7 q) J% g
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
, \$ P: V, ?" z
Pop(optr,opr_t);
4 e4 V1 P) I9 S* {
printf("optr出栈:[%c]\n",opr_t.ch);
" O$ D. Z: c/ O# A
if(Pop(opnd,b)<0)
1 Q; ^: s7 `' B6 Q( [3 h
{
! w/ L. E8 b/ W8 O6 Z
printf("Bad Input!\n");
% R7 B! s$ F {! v7 ?! K8 b
fflush(stdin);
* ~. i {2 p% B
return -1;
g; U. P( e; ?) i0 ]
}
. n; |' T7 ]$ m" t- N+ G7 F$ R; ]
printf("opnd出栈:[%f]\n",b.data);
+ u5 j2 B1 p5 q! Z3 a: }
if(Pop(opnd,a)<0)
& c+ t/ }' v. o& ^
{
2 D! v/ m* @9 {( i# c0 E8 O& L& ]
printf("Bad Input!\n");
. \$ } a5 ?# b; L" C# K
fflush(stdin);
' N/ Z9 B. Q0 T/ E& g; y
return -1;
3 \3 `5 `. ^6 l
}
" \5 D3 e4 _& G) _2 B
printf("opnd出栈:[%f]\n",a.data);
- M- C" w7 E( N: G/ s$ _
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
4 S+ ^6 V" f9 v& }/ ~- u
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( o0 J1 j& E' y; f) J
printf("结果入栈:[%f]\n",opn_tmp.data);
2 g. a; f" r. l8 X7 U* L
break;
) u: T7 W& V8 `- W1 o, r4 i6 Q r
}
5 d/ }. s! |# s C6 _" r
}
3 \0 t( o0 A/ B9 z0 \! a
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
- t) B Q8 y0 j( R: z0 B$ W
}
. c; B8 P$ W* _4 { g1 n
GetTop(opnd,opn_tmp);
' [+ t: R, O% }7 C7 H3 u. a; Z
DestroyStack(optr);
3 O# T( x2 Y0 u3 ^& I( K2 w
DestroyStack(opnd);
; M; C7 l& D2 @. d: b
return opn_tmp.data;
& K# ~+ Y* r+ E" t
}
* c" u+ Z' }, \9 p: o4 Y3 |1 U
" n0 t/ E9 r* d* S- o
char *killzero(char *res,float result)
) A+ C5 y: f6 M8 s. q* V
{
$ o1 v0 e, a& _8 ]# u5 S
int i;
& d1 E) m& S- R: z2 C* V
8 k1 q& w- V$ U# t/ T( Z
sprintf(res,"%f",result);
& U- ]& @$ ]5 g% r! J& N
i=(int)strlen(res)-1;
- F, h+ n/ k; K+ `6 }
while(i&&res
=='0')
7 E; d7 [$ ~' b8 Y w# A
{
! t# {- h# U0 k8 g; L( B
res
='\0';
- X+ [; b# h) W0 t
i--;
! V( Z; P" k- \& R' E
}
. D" G8 W2 j" g1 z& A5 X
if(res
=='.')
6 m: L8 K& S5 G
res
='\0';
: j; J6 ^& U2 S3 G$ w' }
return res;
3 t/ { C; O8 G. X0 T
}
8 _ ~0 i$ i0 t
& ?: J$ d" k. Y. c. D
int main()
, ~: ]3 b$ {& k3 n
{
' I9 E) L+ D& v- [& C4 ]
char ch;
. S. ~" U. @; D/ x
char res[64];
) j# x p# ]( D+ v
float result;
2 A! D( h% q \/ M! z% B
while(1)
3 V+ L+ ^# J4 n. @9 d) m
{
3 p+ b; y# z' S9 \/ D9 ^; i
result=compute();
- j2 f3 i9 ?0 f) d6 @% _) O" x
printf("\nThe result is:%s\n",killzero(res,result));
; B0 [8 X# {) p" W% n. c
printf("Do you want to continue(y/n)?:") ;
v U# t& \( ]* D
ch=getch();
5 ~; ^3 M/ [. Z3 y
putchar(ch);
5 o& t# {- Y1 M' c9 k' D
if(ch=='n'||ch=='N')
% I; k) g; d- t/ f& p4 M( V4 X
break;
- S+ g# u9 ~* X4 u
else
, [7 x! M" n) j2 _0 ^, U
system("cls");
9 R2 a# d& }* x/ X5 s
}
% S5 W2 N. y M, M5 a
return 0;
( f2 e) }9 W, o, }! _. E; A
}
( y% F! ]1 h6 s% O; {' _1 n, q5 l' `
" Q4 L1 g$ x4 N9 z* A4 F2 I
[
本帖最后由 zw2004 于 2008-1-21 17:21 编辑
]
欢迎光临 捌玖网络工作室 (http://89w.org/)
Powered by Discuz! 7.2