标题:
C语言表达式计算器
[打印本页]
作者:
zw2004
时间:
2008-1-21 17:17
标题:
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
9 k1 _& s6 K% \
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
2 D, ]: \& X7 x! {0 p& N# O( E
/**************表达式计算器************/
) r9 P3 L7 E9 X! h
#include <stdio.h>
$ W4 p% B+ H! [* V) W
#include <stdlib.h>
; X: ~5 P3 z- N8 i4 _
#include <string.h>
0 k; S4 B7 ^1 N" h
#include <conio.h>
0 k4 Z& p% [+ o( _
#include <malloc.h>
8 q8 M7 t- G# M+ `
( a. Y9 F' n/ {5 ~- d" T$ R
#define STACK_SIZE 100
3 A/ R& G+ Q) I' M
#define APPEND_SIZE 10
r4 b3 ?8 y1 u4 ^* C8 [: H9 Y* D1 x+ d
) @- ^! _3 _0 D
struct SNode{
" K* E/ c$ q. Z; r1 l- U
float data; /*存放操作数或者计算结果*/
+ b- m% O/ Y( @! ?( Y* d
char ch; /*存放运算符*/
" u0 n+ Q- R, G) i# n
};
: j2 P5 K, o3 y; q+ k3 ^% l
& }' O1 m( I- ^- d( v' d( n, f5 W
struct Stack{
& x9 k! X( U+ V. h
SNode *top;
' a: t+ A& f2 W% q$ u
SNode *base;
) U' K1 ]7 |5 `0 s% ]- Y, z
int size;
9 X3 R2 J; Z' C
};
+ T3 [' \; @5 k( Y: K1 ^
+ b. \ w: V# O2 P9 ?8 w
/*栈操作函数*/
* n( p7 D( Q) B ~
int InitStack(Stack &S); /*创建栈*/
6 R. z; l, }+ } s
int DestroyStack(Stack &S); /*销毁栈*/
/ W- k9 |8 u( F& o& g$ p
int ClearStack(Stack &S); /*清空栈*/
# z3 P1 }+ ]5 P
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( `3 R/ L* U( R" V% w3 z
int Push(Stack &S,SNode e); /*将结点e压入栈*/
' A( }/ f J8 L, i3 j/ b( b& e
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
' f2 p2 F( R6 j) T
. `; S; }# Z# J1 L+ t
/*表达式计算器相关函数*/
^9 a8 [; R" x% E4 {7 `
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
0 I% \1 d) q( [# K3 ~
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
( S& s1 M# l" ^' w
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
% ~6 E, r7 |. r% U
float compute(); /*表达式结算器主函数*/
7 V/ a3 T7 w* _% p a: y. v
char *killzero(float result); /*去掉结果后面的0*/
) k" r+ [ E! D' O) o( ~4 W
0 j$ Q7 I5 J. E. v, S
int InitStack(Stack &S)
, A$ E6 V; T% r5 d" r1 e# F0 u
{
- P+ m- x) }) ~2 ]# q2 M3 h$ R/ a
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
2 L2 W+ U! u, s0 @2 ~ W. e
if(S.base==NULL)
) C$ i6 \1 m) ~) _4 N$ [
{
, \7 h5 Z" y4 ^+ U' B! Y
printf("动态分配内存失败!");
4 W+ l0 u" u& h' ?& h! ~
return -1;
/ O" h) e. M, {3 l# z
}
. n1 K4 @. H& K+ W. V9 q) c
S.top=S.base;
& }; |2 g: F6 c" ~7 l9 Z/ U
S.size=STACK_SIZE;
; c( }7 B) [$ B3 j4 c8 ^
return 0;
7 G- K9 t' y7 N& m
}
! t; f; C' c, s6 _) U0 e) `
G9 }0 q1 n* C% n% I4 @5 `- i
int DestroyStack(Stack &S)
2 y0 L- c* x* x
{
7 r o4 Z" J0 D3 e9 f- _4 l
free(S.base);
0 K( R! G; W" j- [- c: u1 H
return 0;
9 H/ k5 [' k- m( j" s& B
}
: _$ D! g3 T3 _) J3 I
; T" [5 L3 `" w. z) k' M+ p
int ClearStack(Stack &S)
* ^$ w) Y$ ~5 P4 u6 S5 n& Y! L9 W
{
4 \9 D) M0 _) k; [ n2 d9 V) ~
S.top=S.base;
. K. \1 F6 d. |. j
return 0;
: g, q5 C: X) M8 J4 y. \; t
}
/ R( ]( N3 C7 c9 J, t `; o+ X' ~
5 K' g- [( b4 W- k
int GetTop(Stack S,SNode &e)
5 v# ~4 T0 \3 d' I' U
{
! T8 |; p6 _. ] A8 X
if(S.top==S.base)
0 q4 c {+ ~( ^$ y/ R
{
7 L4 k5 O& s5 F0 a" h
printf("栈以为空!");
. E$ N8 A: z% S7 z( R- o
return -1;
% m$ r: _! ` J& b% Z
}
2 [) `! X D" \1 p
e=*(S.top-1);
9 } T; t. K$ u2 h5 ]% y: R5 M+ Z5 |
return 0;
* ^3 f" K; R( S# V- |
}
- b1 |8 F0 {2 [8 H' k
4 h) I l4 |3 ]* t: I* \. z
int Push(Stack &S,SNode e)
# ?0 y' L9 L4 ~: a8 }3 z" e1 w8 u8 |
{
1 V- D' I9 f+ ]! L7 p
if(S.top-S.base>=S.size)
* P0 H, o% R" Q9 s. n, r# J
{
4 a) Y- t3 E8 l$ W
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
/ ?+ v- W! I$ L
if(S.base==NULL)
6 B6 [, V$ n J! M! S! N2 h9 U8 K! c
{
+ Q) `: H# w2 g1 L/ `: j5 w
printf("动态分配内存失败!");
2 F% y% o9 R+ s7 I
return -1;
J2 G @$ O, R1 I
}
8 D; A: F8 Z5 G4 }% E# Z
S.top=S.base+S.size;
8 w6 o& N% _0 c( w2 M
S.size+=APPEND_SIZE;
1 h# k# l) Z ?) Y- R1 S% s
}
! O( d- v3 D# ^1 } I/ C. c
*S.top=e;
. s. H# M: w# C S ^
S.top++;
, p: ?8 T* ]4 j" h7 R: y. R
return 0;
7 O, K1 P# v9 T( w9 a
}
0 k4 t- I8 z' ?" [
! a1 m. R. l8 D8 ^* s
int Pop(Stack &S,SNode &e)
; z% R) }6 A' V
{
& ], j7 b4 E; `: n) i+ l
if(S.top==S.base)
2 M+ y7 E. ?, a; D! q/ j- K
{
" F$ l; G! b6 X/ c/ s
printf("栈为空!");
/ f: d/ O" b' |. m9 [1 w" Y
return -1;
0 l8 w5 ^8 J8 { E7 G$ G
}
, _; r* e& W! y" u
e=*(S.top-1);
, V" P. j- G) k9 O7 \
S.top--;
, C( z& G* J! ~0 K7 w
return 0;
& {) e- F; ^, m0 H* F" P2 a
}
% ^& Z& ^' p9 {2 v }7 ~- Z
$ g$ x( I+ y3 L( R* S( Q, l
char get_precede(char s,char c)
1 S7 @' S9 g7 Z3 ^2 Q
{
. X8 K- b7 h5 C- B7 V" f
switch(s)
+ P* {9 A) |1 k$ M5 g8 \
{
- s" l7 J- v" p$ t+ D. m) y) K
case '+':
7 l0 K1 W/ z; V
case '-':
$ |& ~/ }) b0 B3 B4 Q1 O5 ]9 @ D, A
if(c=='+'||c=='-')
8 l: K& a0 a3 X; p# P# J4 V
return '>';
3 D) d& ^; e- {3 m4 s! W% I# }( B
else if(c=='*'||c=='/')
' E4 X; c; N8 R; [% r% U
return '<';
" k/ O( s( Q4 L6 [, J
else if(c=='(')
: l' D, t* d) ~( ]0 X b8 z% H% z/ E
return '<';
8 e$ ], Q+ A8 ^0 A( s6 T1 K
else if(c==')')
" x+ u2 s& l) l
return '>';
; X A. s/ t/ b7 y! w! P1 f7 r' {. R2 a
else
: W$ d, Q: Y6 r, \2 [$ o1 V5 K
return '>';
' T3 s4 `. R3 B
case '*':
& m; N5 _' z- j# e" L( `
case '/':
" `0 A/ `" f% [6 c6 l
if(c=='+'||c=='-')
) h% `; Z4 |$ I8 X( f% b H6 q
return '>';
" S; r2 `6 [! l2 z- S A
else if(c=='*'||c=='/')
9 W4 m _& O+ c; X
return '>';
; ~1 s3 [$ Y2 R9 Z# t0 q/ U, {! u
else if(c=='(')
4 B: N, k$ `/ \1 j) I9 o
return '<';
. s) C% w+ [8 a% y: H. V
else if(c==')')
: _. B: i7 {( N" G- H
return '>';
S7 v4 L4 c3 e: z% `1 z0 U
else
) L5 L& D) Z/ H0 U) C- R0 g0 L
return '>';
* _- u; `" o+ ]* g2 i, f5 W
case '(':
! V) j5 ], ~ \* l& _6 d
if(c=='+'||c=='-')
x+ D& d) |& ~& l0 p
return '<';
: J" Z/ i" H1 @+ |" [0 [4 ^' A9 N- O
else if(c=='*'||c=='/')
2 h* q# L+ n5 k1 Q% v
return '<';
; i- V) ~- Y) l! `7 r9 b; Q
else if(c=='(')
\& \$ E5 [7 u; o( c! {
return '<';
- m& e4 d) Q6 b
else if(c==')')
$ @5 W N$ Q' v6 S- ^1 A; B3 C. C
return '=';
$ ^; ~% w6 n7 y, w1 J$ J
else
3 F+ u0 _1 I5 d
return 'E';
/ p9 X& P7 o2 ~: c2 t; B$ ~
case ')':
' B g8 W3 }, [, J2 i1 }- N# z& t
if(c=='+'||c=='-')
6 }+ F. K! X% A, I+ i' a) [" p9 h
return '>';
! ]9 S3 X) D, U& h) _" w4 F
else if(c=='*'||c=='/')
5 m5 B9 |( b9 t6 O) E0 v
return '>';
! m$ \- H, e3 o3 w: K E- L, c7 Y% C
else if(c=='(')
( m3 e9 f" @4 H) o+ p
return 'E';
0 j- _9 S1 K! R; S* S
else if(c==')')
& a$ v5 Z4 w/ {5 v8 \5 X% v7 [2 A
return '>';
5 S: v( v E$ D9 f
else
6 z$ ]' R6 a/ U" ]. q; W" n' G
return '>';
; n/ N y$ t% _6 I- q
case '#':
4 H1 {# ^1 e. s- w: j* g( x, s
if(c=='+'||c=='-')
9 Z7 f5 R; Q/ i5 g5 K( l
return '<';
) K' L$ u9 @( G
else if(c=='*'||c=='/')
G4 `, T1 n; z& E- O, ~
return '<';
1 O6 L( f+ g% L; \* U: i
else if(c=='(')
6 M, u3 }# ?4 V
return '<';
+ n+ t. y/ d9 }7 ?% x$ \
else if(c==')')
8 |! z% e6 R0 N. }
return 'E';
5 H( Z! F3 I+ V5 T1 l* L4 W0 w
else
( Z: b2 X2 S: V. k# z# }
return '=';
8 `8 W$ [* U5 ^' b
default:
3 j- t6 f2 _7 q+ w) p
break;
8 N. K& X O. U* C0 p) t# E% j& x
}
9 Y7 |. z e1 Y, Y ^
return 0;
3 W" c( @- {7 I7 z
}
/ o) I6 A n1 b( E9 n
1 j" S* U( k6 I* I
int isOpr(char c)
' g% T# n+ z/ b7 H
{
; Y9 b+ |5 \' Z6 c- g
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
5 [- \! B1 l+ o2 \2 T
return 0;
9 k1 i: U5 @2 B" A( o1 l+ |% l
else
: i& m9 \$ m) M) l
return 1;
1 \3 f) A% k' y9 n
}
7 t0 B1 ?4 h* z
& ~8 O' p; m; @& b+ I3 Y8 z6 r$ c* u
float operate(float x, char opr, float y)
1 k# L7 _* u1 _* l2 d6 h2 Z
{
/ W/ X" X6 e: l# w- s
float result;
; v, J9 k# f( X a* Y' M# k6 T
switch (opr)
; _) q" t# `! P6 {3 c2 L! ^* ~
{
, H0 i$ j( n4 z& m s/ }
case '+':
! t4 z9 l* ~7 m3 R; @
result = x + y;
6 s+ H7 y# T( ~0 D$ E- y! G
break;
+ z( X9 u9 h( m, l. z' t
case '-':
: f$ G8 R. A+ i
result = x - y;
- d, w1 p+ x' n0 Q4 b% `% C
break;
, H1 ]7 a3 z! U" H4 d
case '*':
& g- e D; z' F
result = x * y;
" W, \, Z3 G$ c D& L6 [) x2 x
break;
" t) v4 L8 P5 n8 p, f
case '/':
. k- y6 W; ~: F( Z
if (y == 0)
- Z' m; r8 f& e4 @
{
3 c+ [# e1 S3 N" J8 B/ t2 \
printf("Divided by zero!\n");
' b* {# a% w+ W$ W$ V( @0 a
return 0;
3 \* ?7 Z+ N. w# \) [' h
}
2 z& B9 Z" G$ k% ]7 ?& H. A
else
: g* w7 r: E1 x+ K9 G3 W9 L, g
{
* X5 j9 W0 T( }4 x% L& W
result = x / y;
5 S0 c4 B% T" X" ]! H
break;
" ]& z* X7 d- U0 @6 p. Q
}
* _ p! n( g, b. n' H! E
default:
$ [) w) A5 y8 _% m* t) @) g
printf("Bad Input.\n");
$ \3 M: {" w& D, `
return 0;
+ M+ Q$ N+ t6 r9 M+ U T7 K/ ?2 J
}
d6 n7 C- @ D. p& V7 C
return result;
2 E! c- |$ i2 j' n' @+ W
}
4 B r8 }+ P" D& l+ \+ q6 N. G j
, C6 d5 x* f3 {
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8 k' ^' x+ g9 B
{
, H8 v7 S( b1 Y2 Z4 b4 s5 K
Stack optr,opnd;
, ` _1 ^5 Y9 z2 m( \5 F
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
) [, [1 n/ ^$ ~; Q/ c/ R
char c;
# }2 x1 q4 u7 H
char buf[16];
) ?! s! o' Q) R1 B( |1 e
int i=0;
. ]' b3 R8 Z: |+ w' b
1 i0 I, ~ y) X: u: E) t$ [# ]; G
InitStack(optr); /*用于寄存运算符*/
8 [5 Z: Q) ?' `& w/ W/ A% k
InitStack(opnd); /*用于寄存操作数和计算结果*/
' k1 v. ?; P8 i( D4 c; t6 z
memset(buf,0,sizeof(buf));
1 j9 `( U% C( g+ }
- v) c7 }+ {! y: w
printf("Enter your expression:");
9 w1 f2 \5 S/ x& X
' H. l) S4 ~) B: q+ e9 {2 {# x2 @
opr_in.ch='#';
6 Z' y: }% N2 }, z# K E
Push(optr,opr_in); /*'#'入栈*/
: ?( u4 J {5 l4 t: Z6 [
GetTop(optr,opr_top);
$ j% _4 X: [) c; t# Z
c=getchar();
1 Y+ K$ j# ]$ }: v) f9 m0 `
while(c!='='||opr_top.ch!='#')
' A# d( a/ u# ]! e$ e7 P+ B9 ]
{
* H9 Z% O0 X. D4 J
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
$ Q' B& ~! c/ R% U3 n B3 `
{
P' G, v" ]( v; b; l4 f. [9 E
buf
=c;
! T: \. r, @# Z9 q6 X+ m
i++;
$ d3 b% C5 ]7 B' K3 R
c=getchar();
, \, n9 D9 } \ R# b" x8 H
}
8 P3 [( Y* W- r! p3 I
else /*是运算符*/
: z7 j" b o d: f; \
{
! l4 w; X B0 d% `# G! i! m/ c
buf
='\0';
3 _! ~7 j, a* f+ `$ ]) j; M
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
% c# ^7 a5 _% ]* p
{
! t* {4 V" P- ~" H
opn_in.data=(float)atof(buf);
% R. O- m) m/ g0 n/ c+ h& M# ?+ K: H
Push(opnd,opn_in);
. z/ U; z" Y0 T9 _) j+ W( O
printf("opnd入栈:[%f]\n",opn_in.data);
V0 W/ b H3 M: C1 o' e( T2 ]) A! P
i=0;
- z* R7 m( Z" p; f. a
memset(buf,0,sizeof(buf));
; c! j0 q5 H6 H; S# @
}
. s% k) b8 _! a6 x p7 \
opr_in.ch=c;
$ N+ D" v% q7 U- e, H
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1 X4 I G6 A/ M+ J) u$ W- A
{
2 ?; o5 w/ m8 W) ~$ n% {
case '<': /*优先级小于栈顶结点,则运算符入栈*/
{5 v5 R, g" H
Push(optr,opr_in);
1 D! W! ^4 b/ R9 u- p
printf("optr入栈:[%c]\n",opr_in.ch);
9 u( ?5 M+ p9 A; Q' W- S
c=getchar();
/ V6 }9 w$ g% F" k: v
break;
8 l5 L9 }, R/ ~
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
4 b7 m& o w" k
Pop(optr,e);
c3 j0 I" {; ?4 r2 j7 [4 u
printf("optr出栈:去掉括号\n");
+ I( W s p0 R9 x% k
c=getchar();
8 |9 C. E( E. u5 O
break;
- n3 S6 c7 `- Q
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
0 j U# H# {- c
Pop(optr,opr_t);
$ K' J' ]8 H8 H6 X% E) ^
printf("optr出栈:[%c]\n",opr_t.ch);
! K. J a" X4 p
if(Pop(opnd,b)<0)
5 i3 c8 E' |5 T. h1 U# Q1 [
{
' f$ `" P+ c* `5 ^( M) l b4 V
printf("Bad Input!\n");
/ \8 h4 E Y5 v2 p4 [6 d
fflush(stdin);
# h5 M; T1 Y* [ j5 A; `: H
return -1;
, Y ^* g s4 w4 V$ n5 ]1 Q
}
3 K+ y$ c; i/ O% H2 K
printf("opnd出栈:[%f]\n",b.data);
$ K: R1 _ _4 i/ f3 N
if(Pop(opnd,a)<0)
; \% }8 B+ \# {0 U
{
+ |4 y! w; W1 A9 C
printf("Bad Input!\n");
2 ]. Q% ?2 ?9 ]5 e1 X) ~/ ]
fflush(stdin);
/ A0 G s- @" y; O# i# c
return -1;
8 {6 s& U- P! Z0 A, r
}
/ x0 g/ Q! [5 F
printf("opnd出栈:[%f]\n",a.data);
$ u/ e3 J& h! T
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
+ ^+ l5 s+ p5 E9 |
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
. w" S) @3 w. O; q: `' J* k
printf("结果入栈:[%f]\n",opn_tmp.data);
1 B: L) c) p0 a' z3 g
break;
( i4 q& l" Q$ d& t" W3 i$ C6 J. T
}
, {) X: H4 B! c1 u, m7 J: s
}
5 g2 L6 Q* f/ b. Q
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
L m0 P) W# d! s! l
}
5 R& w# @/ ]' ~. |; `$ p, Q! W7 l
GetTop(opnd,opn_tmp);
* Y& k0 P) \/ G* `( n, y+ Z" K
DestroyStack(optr);
) [# t5 h8 T( h" B
DestroyStack(opnd);
/ ^; I, w$ v7 {( {+ j
return opn_tmp.data;
/ j4 j' ^( B$ |, o% f& S
}
7 j) Q/ o2 m' b Q U# [; q/ G
G2 j ~; d, Y* ^% F3 l; e5 ^
char *killzero(char *res,float result)
3 T' l3 c6 J8 ]: c- o% g+ _
{
! p% L0 K( J$ }9 A/ D# u4 @+ Q
int i;
3 U1 P, {2 u2 z1 M5 p
7 M7 ?+ r0 e" l; o5 V' F6 n
sprintf(res,"%f",result);
, U% V3 I8 A0 h B) g. H h
i=(int)strlen(res)-1;
% f5 E+ f2 ], h8 v" o0 B7 O
while(i&&res
=='0')
; b7 q3 e- |: a
{
& h' X# u# c1 }" F, A/ S# S) _" P
res
='\0';
9 h f8 X6 K" m
i--;
+ v9 H: c1 d+ Q9 [& H0 K; Y; l
}
( D6 w- I s9 K+ n9 o) L6 t, I
if(res
=='.')
7 u$ X* Q2 B, D, [* q: I8 T( g: E
res
='\0';
) F& t! }# @2 r( j- o
return res;
/ z7 Q# t& w$ e5 I& u0 _
}
# E1 j8 g: b# e! m b
7 E8 Q! i+ U, n0 \ g
int main()
F8 M( P1 C+ @
{
9 s: {9 C' `* g$ c
char ch;
' J. J/ [1 ?3 x( g1 v w5 ?
char res[64];
( E4 o$ I ?& C! {
float result;
! C9 Y0 {/ E2 i3 s
while(1)
; t) Q) V, J9 P3 C2 a4 @' Y" }
{
% v5 P7 I6 l+ U X+ K$ u
result=compute();
; a! z* k6 u( Y: }9 v- L
printf("\nThe result is:%s\n",killzero(res,result));
( E7 L2 M6 X* K( t# M% B7 k2 R* `# J* [
printf("Do you want to continue(y/n)?:") ;
% b M z1 n* K5 @" a9 d
ch=getch();
2 W) i- S- o% `' |" v# Y
putchar(ch);
. |! o, L$ L( r5 `; |
if(ch=='n'||ch=='N')
( E4 e! r! }' Y/ l
break;
' n0 r: ^; ~+ r, M
else
* q, n! \0 c2 R& v
system("cls");
" J' V# K; m! _5 Y+ y3 U
}
' v# W- |! Y' Z( h
return 0;
+ d9 w! P ~+ O! t: P0 \9 Q D& C1 C
}
6 d# ~$ i& c: x; E6 l
) Q' e1 L v8 Y( P+ \% V
[
本帖最后由 zw2004 于 2008-1-21 17:21 编辑
]
欢迎光临 捌玖网络工作室 (http://www.89w.org/)
Powered by Discuz! 7.2