  
- UID
- 133
- 帖子
- 51
- 精华
- 1
- 积分
- 186
- 金币
- 55
- 威望
- 2
- 贡献
- 0

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.: F3 Q4 _0 m& Y% S% f% U' X
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=# |% `6 |3 ]( t( E# h4 ]1 ]) `# z
/**************表达式计算器************/0 r, b: f% s3 G) E
#include <stdio.h>
3 `% f G% M! I# z#include <stdlib.h>
9 r4 Q5 S/ f( w3 p8 C$ N1 b#include <string.h>
# `2 X' d+ a" L( b#include <conio.h> V. P5 M% W% [( {
#include <malloc.h>& |4 M# @& F; |! x. m1 u
7 c' p' F7 V3 F' B, T#define STACK_SIZE 100( O8 s$ O( B5 \3 z! G" B' q
#define APPEND_SIZE 10( e8 F$ V8 D% [/ I5 i# z
6 W( b% E9 a0 S) d8 `struct SNode{
( q7 R9 B% w" h8 k6 ~; @ float data; /*存放操作数或者计算结果*/ F7 l' T4 E9 f$ Q4 y
char ch; /*存放运算符*/
. ?% `4 i1 L. w9 u' U# G};
0 ~( z2 l# m* r3 e1 U. p0 u+ K" ~9 F6 t9 D. a" f1 k: \! m
struct Stack{
1 G: D, N) j+ ^$ K SNode *top;9 y) [$ Z' x: N, r+ p6 [5 r5 ]
SNode *base;
0 s! C1 u" I" |4 v! t int size;
" W+ `' f8 n& q: ]- S};8 }8 y1 H5 |% ?% @9 |
# M. R, b/ A. c+ J: J0 b5 g5 Y" Y4 r
/*栈操作函数*/
6 i( F; e6 N/ i- Z. P6 v+ N+ iint InitStack(Stack &S); /*创建栈*/$ ^; \# g& a) V( f3 ^
int DestroyStack(Stack &S); /*销毁栈*/
2 v t( |* X+ b- ^; W3 ^% R! C# iint ClearStack(Stack &S); /*清空栈*/- _ ^" t$ g; v7 t H
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/' D4 A) w+ s6 ?* Y; b! X" L
int Push(Stack &S,SNode e); /*将结点e压入栈*/
- l" O! I Q. O7 t( ? ^int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/" r; H6 R# P& B9 S9 O$ Q
- H/ E3 o. _: V
/*表达式计算器相关函数*/
& G2 n& M8 _5 b% [9 }: L2 q3 T7 Tchar get_precede(char s,char c); /*判断运算符s和c的优先级*/( h+ d1 e5 j$ g+ E0 @5 X' _ p
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/. t+ ^; u' C( L9 e( U
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
- Z: F) t" i/ I2 S, p7 K. Jfloat compute(); /*表达式结算器主函数*/
. l# A2 v2 B# A8 [* [ ^char *killzero(float result); /*去掉结果后面的0*/ 5 i# } p# B2 ^8 ]' R" j
! e4 L$ L+ f1 C/ D+ \
int InitStack(Stack &S)" a1 z4 S- x, o: r( @. d0 H
{ Q8 `2 r6 Z* ?
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));. H2 X0 f! ?! G, R* b
if(S.base==NULL)
2 v L9 R4 L1 @ {& l A3 d0 ~8 i9 r' y4 n8 j' ]
printf("动态分配内存失败!");
' A$ c! B. e" T+ ?8 g$ @4 |4 S9 ? return -1;1 n% G3 |$ D5 Z v$ w3 X
}
" x6 p/ H% B3 Y& X S.top=S.base;
1 q; [) Z$ b3 D, s$ ? S.size=STACK_SIZE;; x) j7 _' z, `& P' l3 X
return 0;! ~( D+ n) S& I/ a
}
+ b: G) V1 G E) ^% d4 ~
/ ?( N8 l. J5 G: Xint DestroyStack(Stack &S)
; t! B7 i7 {) Q- L. ^; B9 S{+ g1 Q. x$ \$ A$ m
free(S.base);3 E' c! M- j& G
return 0;
- e% k9 u4 U$ }' Z}
6 q5 z" [% s* S+ M5 A
; P1 H7 G, a2 f: l! {9 M) gint ClearStack(Stack &S)
; v0 u; d1 B* E. q{
, y2 [2 t" |. r' B" H S.top=S.base;
3 m0 m, W0 @, ~6 R; ^' a return 0;
# V% Q- o2 @8 Q" W& `}: E! d. O1 _& L( k1 n8 T
: v T( `( Z. W/ l3 a- _ c
int GetTop(Stack S,SNode &e), C) }% _3 q$ B) W! H
{
9 W |$ |# e0 ?1 O/ w if(S.top==S.base)% B+ k2 N; J+ O' N7 Q9 T) K" {" Z
{( v5 o# [8 h$ A1 O/ c# T( @! G, H8 E
printf("栈以为空!");
! b$ I3 W9 I% S7 q5 K return -1;
2 Y: L: r! X' Y3 f/ S }
" }4 q/ h1 Q" G. s+ q e=*(S.top-1);1 [* H' W8 I Z) h9 S# l6 K
return 0;: Q' P H! x( q; s2 U b
}
2 X) |5 c- t, i7 H: O6 s
) U6 a& y! V& N4 t$ p: yint Push(Stack &S,SNode e)
9 C$ o# u5 y' U7 o1 O0 t{
1 G$ B+ u/ z8 d4 |0 \ if(S.top-S.base>=S.size)* n8 i- p% J. b$ i! ?6 w
{
. p/ K- r2 X* ~1 W; i S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
& l$ q9 _4 G) K, Z5 b# u5 @; \$ v if(S.base==NULL)
5 G7 `$ T6 d* j3 e {( ^2 a) `4 w$ U& N F
printf("动态分配内存失败!");
' A5 ~& V( j2 L* C( c0 I# k return -1;- b; E2 s6 K: O! y
}
7 h! [* U# g9 G# G S.top=S.base+S.size;$ A' @8 T1 c( J
S.size+=APPEND_SIZE;) p! o# f; p6 a
}
* u! F1 c9 u" s# j7 _ *S.top=e; B, _3 _0 M$ l
S.top++;$ C& q) P4 J( [ r
return 0;
5 K$ l# `# |3 B; Q% S" Y}. C2 [( E9 @; a- H1 c
9 Z% A7 E8 y# l9 i& `3 H2 }! G
int Pop(Stack &S,SNode &e)( D. b- e6 T. B0 D$ r* {
{( V5 ]6 C/ x6 B1 T
if(S.top==S.base)3 L, T3 D! P2 y) [: }
{( W |3 S6 ~! X; V* E! V( H
printf("栈为空!");
2 D* j( @$ `* w! T: S return -1;% {- i) p0 d0 J0 f K
}% D/ p! `4 w( k/ Y( |9 ]
e=*(S.top-1);% K$ M1 |8 S3 _
S.top--;! X1 Q% g! A6 S1 H8 L
return 0;
- ~# \; P6 x. p% w9 U}
* U* R- [3 F! t: v9 t
1 Z9 |- }" m0 X& D; }: {& Gchar get_precede(char s,char c)4 [- q9 {4 q D* ^
{
8 q: Z1 S; E5 Y8 V! o! b. s switch(s). A: y% ?, j. t% Q
{
+ N1 d0 z. w1 X( k case '+':
0 B) Y' X- o4 I9 P& E, j8 d case '-':
( h: P$ u3 r* h6 |$ r, q, Q if(c=='+'||c=='-')
) a0 n( L. ]8 M6 F return '>';6 s6 M4 j; t% l# s& p0 ~! O' S4 t
else if(c=='*'||c=='/')
: x; t H. W' h( y& v/ d4 z; z return '<';0 x# S$ m2 `6 l$ F5 B- u
else if(c=='(')' {) `0 f- O' `3 Q- K, P* l; Q: C
return '<';/ D/ N% j4 K0 k5 h8 h
else if(c==')')0 p' ^' V# U8 D2 z9 ~ a4 U
return '>';. h1 a" W9 C# `. X3 n
else ; x# `( b( @0 i* p
return '>'; ^. }& V) x! |& L- u: a
case '*':8 p% _3 u3 o7 ]' k+ N0 n6 {
case '/':- B/ D2 q$ d4 o0 B w' ?( H
if(c=='+'||c=='-')0 D8 e, K0 Z' N& L
return '>';" \. t! E$ {7 `
else if(c=='*'||c=='/')
/ N; b2 i- y. ?: s# H return '>';4 n/ m4 H7 k2 A! S! Z: f7 g
else if(c=='('), h7 w0 j1 W! }% P( p
return '<';+ R( X$ q( ~& V, c7 q( ?; z
else if(c==')')! t' \& d3 [, m& P9 u
return '>';
) A3 e* c6 S6 S2 f5 a else
+ ~0 z% a. E& b+ E return '>';
3 x2 a" d% R1 M L9 K case '(':
8 Z# L' E3 T, w/ a" [ if(c=='+'||c=='-'): U! T0 |) u2 p, r# X+ G7 ~1 w
return '<';
9 A3 u. v/ N% \+ ?& k5 P7 |4 B else if(c=='*'||c=='/')' t; e$ j8 B" \! t
return '<';+ C" b' ^: S1 a4 p1 L, y d* F4 T* K
else if(c=='(')
. a6 Q- y- O6 ]# a return '<';, f8 ?! X/ v" q) K3 L' h
else if(c==')')
- A# ^0 h: b3 s |( Y; r return '='; B( S) g) t% B
else" i( r& B# {2 O! c% G
return 'E';
& Z( g7 p8 Q) ~% \4 W. g case ')':
1 j1 U2 H+ T. C$ A if(c=='+'||c=='-')& c' j% F7 D. ? G* N& b' R# @( i
return '>';
+ H1 V: Z9 o8 m) X5 Q6 D else if(c=='*'||c=='/') V/ x0 B2 Y9 R/ C) {( L' S
return '>';3 i* z8 H/ o) [ ?, e5 i* [# e4 e
else if(c=='(')
$ |2 ?4 Z0 S- ]: a' W return 'E';
5 ?) N8 u- h3 P; `% }& [$ M* j else if(c==')')* i A3 R( y% d
return '>';
5 u6 g/ R6 y. A- A0 `: E+ l6 m2 Z6 k else
# V( M. K* f/ U% s. k& ^ return '>';* W5 b" F; ]4 J6 }5 P1 }7 o
case '#':
( U& F0 N; W" r if(c=='+'||c=='-')$ u: L4 k3 m1 j; Y9 F! v
return '<';, W& U0 e3 j+ c3 z3 x
else if(c=='*'||c=='/')9 U; R" `! E( l% H; [
return '<';
2 ~# O7 w2 V' k4 t/ k( ? else if(c=='(')4 ?! p4 g" [# @- o% ?: C! ^
return '<';0 M m: N: o4 l. l. D
else if(c==')')
, R5 Q; A+ P$ N3 }4 q9 V return 'E';; h- b- g9 z5 {
else
! C7 e E9 H0 a& U0 j( q6 U' d return '=';
O* V# K; `& B. M# E% v default:
/ q+ p1 Z( c3 m& U. h4 ]0 [7 `- h break;( D8 |/ D$ r0 o6 d* y; {5 p: @. Q3 W2 S
}
: Z5 K3 Y& G4 A& p% x* g return 0;
; _+ ]0 {2 O0 H1 X6 b. p}) H+ N# h* I' s
% d. C7 c; F9 t$ vint isOpr(char c)
g d7 g4 P, C' j% k5 A{2 b+ S" I( q, f
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')1 r3 m& _7 e: l( k- c7 V% D4 @
return 0;
1 X' W, y6 [/ F( f5 j2 Z' h else u) N# X) R. g* @
return 1; q8 [7 \2 h. G' y/ e( g/ `+ U4 l
}
* x5 p @! ?/ H& i f5 x3 L$ X. m' {2 H* ^# ~0 [5 G" R
float operate(float x, char opr, float y); O/ W# g* @3 p- R
{
$ Y4 }3 N. j3 ]7 C) E% D float result;! w' k2 s$ `( G4 ]
switch (opr)
) T; w5 t4 j+ q Q {
2 j( Q5 l4 ]. s( _( ?$ ?% ^ case '+': 1 \- L) s( \. x# v* e
result = x + y;9 t1 {( z3 ]( M
break;
3 u& \1 E8 ^; ~2 r# W case '-': 7 t- a/ t1 n4 C3 j4 t1 m% [4 Q' t+ K
result = x - y;$ o3 h( {: I5 ]2 f9 l
break;
" m2 p" |/ c' m; x case '*':
O0 Z0 @" y( r/ M" z J result = x * y;
1 _+ J8 G( Z3 I9 H$ N( ? break;- {; m- _; D3 T$ j
case '/': ! E4 |1 h5 g. i, P7 W
if (y == 0)
: p- r- Y2 l9 w. m: N/ b& F5 J {
! G0 Q5 ^" Z+ s: |- L7 j printf("Divided by zero!\n");
# _3 B1 q) s. ~1 e! E: J return 0;
) C6 N/ M1 r' o5 W( ~ }. \6 [( v: ~4 D& g9 C
else2 |0 ^% S' X3 ~% g
{
9 y ?8 V U8 F1 r9 W result = x / y;1 p0 H: \. I% o
break;
' J8 P$ V& U4 A# A% ? }- F/ L8 l, |1 G/ e4 O
default:
# j+ ]5 `5 A4 k, L0 X/ E. l printf("Bad Input.\n"); ) G- J- D: n8 F& i8 M' ?8 ~1 j4 N
return 0;
- ^- u: n( V- s }
! F7 g- V4 ^0 V* Q; Y return result;9 H. W. r* Y K' [- Q
} 9 `0 s% i _- _& O7 \" {( ]
$ h/ |$ q3 [ i7 ?1 E( I
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
6 M+ ]4 C8 c3 K8 g{
6 j! z5 @. m. T0 T& }! M m Stack optr,opnd;
7 O" M" ]: o; A( L! b struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
* V9 c* z6 W- [% S# p char c;
9 r" ?/ Q6 G3 Z( x+ e J9 c( X char buf[16];
- `: Y$ U5 s" O8 a2 X6 y int i=0;
. g$ D! c, \" U1 a K* n# w
: ^" Z1 w2 w. e) b- c% S InitStack(optr); /*用于寄存运算符*/
: f, N% p2 i( b InitStack(opnd); /*用于寄存操作数和计算结果*/" x# }1 C X N' |* } G% W
memset(buf,0,sizeof(buf));8 b9 l' e, ?/ l" S; Z/ i
; P8 p% s. K& _ ?: w9 @ printf("Enter your expression:");' t4 h! q( B% X5 H+ M, j/ _/ r
9 i8 J( W, Q4 D- P6 | opr_in.ch='#';+ }' ?, ?2 R* _( J; O8 C6 g9 T
Push(optr,opr_in); /*'#'入栈*/5 c% F0 T1 K( @ @# e/ f
GetTop(optr,opr_top);* d/ l' r1 C; u& [
c=getchar();
8 |9 }( h5 z0 ^# Q while(c!='='||opr_top.ch!='#')
% ]" c5 L2 J( U# E. L: O# B# u( p {
9 v, l* j3 x' c5 u0 n if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/8 \' c5 B* S. {7 N4 ]1 m
{# \$ F( {) ?+ r( A2 @4 N( Y& _* r
buf=c;! o) Z" N( A$ g% |! o. |9 |0 w$ F
i++;
; b7 X) ~. [% z6 W( b6 e- { c=getchar();
/ `. C4 T+ x* i }
' o) d: \. Q# T3 |+ W! i else /*是运算符*/
# r8 z$ p' l8 a" _- c {* W& x/ t0 u# p8 H
buf='\0';3 M5 `" r# \, ~4 t% e& ^
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
( H1 H7 M3 X4 o/ ~6 o {. s+ i- z3 k" N5 q" q4 o
opn_in.data=(float)atof(buf);0 A6 {/ I8 E) ?$ J/ F& w' K
Push(opnd,opn_in);& u# ? c- g& |1 z
printf("opnd入栈:[%f]\n",opn_in.data);
" w1 x/ q; F' {$ ~3 y i=0;' K9 q' i* E* B! x$ v
memset(buf,0,sizeof(buf));
% B6 a4 p0 A3 M, `) L2 g0 G( }( x( r }4 |6 k. I ^$ f( h: ~
opr_in.ch=c;
, |) J8 o4 L$ `8 b6 D# P" L& ^8 G switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
" s/ _' b* ]/ i% `7 S {
& \; a" @: P% f8 q4 P case '<': /*优先级小于栈顶结点,则运算符入栈*/
! b9 W7 v9 ]0 z: I8 s6 a9 C% h# d Push(optr,opr_in);: O* C7 k2 [- ~/ a; T3 Y
printf("optr入栈:[%c]\n",opr_in.ch);( c6 Y* m8 r6 R/ @- Z: D$ H8 e$ ]
c=getchar();5 D. c* j. ]& C" ^) h' ^, V: |9 y) n
break;
. c, ~3 |' P1 O2 x case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/5 ~" ~; O" k$ ?( k
Pop(optr,e);) H! _! q7 x) B* U6 ]
printf("optr出栈:去掉括号\n");
2 v2 Y G7 e* W c=getchar();) Q7 K, Q' b7 g, g7 t
break;
! T) D6 Y3 N2 l& f* n: ?$ I case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5 s. |/ Z4 C- C
Pop(optr,opr_t);
+ F# R4 p+ X! F5 p, @6 Q# j printf("optr出栈:[%c]\n",opr_t.ch);! v6 P( n) |% o5 U6 W2 R: ]0 ^! B
if(Pop(opnd,b)<0)& R( p1 d$ D$ S2 o" Z) \
{: \- j* I; N' D7 _# y" B* M- n* w }" T
printf("Bad Input!\n");
" b7 z+ [0 O5 F fflush(stdin);1 d2 j' S/ K9 X6 {+ C& C
return -1;6 D' M0 r ?: Y. {* L
}
2 k0 z# h4 G: H2 L# n2 A+ A# J: `' } printf("opnd出栈:[%f]\n",b.data);$ @9 ]% G5 o! ]
if(Pop(opnd,a)<0)7 y8 c( | I6 F+ z {* L8 U
{
. y# G+ k$ x& u; q9 q7 I# v% Z1 P printf("Bad Input!\n");- m9 J& H5 S, |" F+ c4 q
fflush(stdin);. t( Y$ k- c( S. I. U' Y" r u2 C
return -1;) T9 u7 T2 y6 f2 Y
}
+ H+ \$ h' o: N; r8 ?" _ printf("opnd出栈:[%f]\n",a.data);
0 T6 S8 ^, @( P7 h! q' _' m9 k6 E) r opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
; r( W8 c* F. O' o Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6 q% m; t. R% |+ p1 L: Y. ^& @
printf("结果入栈:[%f]\n",opn_tmp.data);8 y3 m* h8 n$ a
break;# F! I: Z' e& B8 c S
}
3 {+ D* q5 G9 s* O0 k4 w: F, C: o }* U2 K$ N0 L |
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
4 Q5 q4 {, ~3 M a4 d# v u }, L; T9 N1 a3 ^& ]9 X1 t
GetTop(opnd,opn_tmp);3 r# o% |2 |/ e2 U9 P- y' I d
DestroyStack(optr);6 q$ v6 Q/ h8 _1 k
DestroyStack(opnd);
) @$ h6 g2 J; w* |+ P return opn_tmp.data;: l1 y4 L2 v& p) Z. n0 I
}
* z2 h- P7 J6 K3 P5 M0 D F: {) ^9 {
char *killzero(char *res,float result)( }& k/ X9 J0 x; N1 |
{4 u1 A7 j4 ]! c j& {
int i;9 D' c4 d$ a; R& y
/ o( N2 }" }+ r& A* E% h sprintf(res,"%f",result);
/ o# G7 `! p5 X( A5 W+ H8 y' V i=(int)strlen(res)-1;* E' i' }# C/ K# A$ i5 S
while(i&&res=='0')
( z; s }6 ^- D2 b) p* @% T {: p2 H6 V# ^) z6 `; N" B2 X" C K
res='\0';
# |# a4 _9 {: e2 m+ Y0 n i--;$ ]" g- Y$ D- X" z& d
}; ]6 w4 [& e8 o1 I8 I
if(res=='.')5 S b* X* W1 B, @3 R
res='\0';
9 K; W- }3 y$ m+ b% l7 [/ j return res;& \4 ^8 p2 b3 a5 |$ I$ b
}4 o2 p0 \7 k! `; K) y
& b9 ~: Q5 z$ ^+ n5 d' jint main()) u+ G/ l _- V6 g! Z. D6 G, {. n
{
5 t$ \1 M( I0 {0 D& l6 n* L char ch;
; b7 e5 w5 i" E* ~: } e char res[64];
; L3 Y$ h! \* H& H b8 Y float result;- C" L. f" B' q% \9 X
while(1)$ b# M! q- r% y3 o) r
{0 b/ Z7 g2 D8 [3 ?8 R! Y
result=compute();
& ~! F1 G$ }$ j1 z1 s6 ~ printf("\nThe result is:%s\n",killzero(res,result));' I8 {" W; k5 d+ n; I
printf("Do you want to continue(y/n)?:") ;8 ]( F, ?( y7 G, j9 j% P8 S5 J' J
ch=getch();& R2 P; ?1 B9 |! u! m0 [4 ]1 A
putchar(ch);; s# O% P: U, E4 M* C( z8 d4 T
if(ch=='n'||ch=='N')
# J7 r3 r8 U) A N4 Y break;
& n/ O e R% _) q1 f else
) p9 d4 j% J4 |/ o" z3 d) i system("cls");# D/ v8 Q: Q* L1 _
}$ B5 M& \% E) _5 s( H9 R
return 0;
~, V, a5 S9 {, |3 ^. O} I3 `- x( D* U
% _2 X4 U7 s/ ~
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|