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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
$ x1 @6 E' p; F$ H2 k8 {* Y- n8 K程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=9 Z0 R" m' m* g& ^
/**************表达式计算器************/4 ?3 q0 C7 I9 v, \% D
#include <stdio.h>1 z( h# n6 e& |
#include <stdlib.h>
P1 t. T* Y( a9 y7 {- r, e2 K: w#include <string.h>
+ z$ t! F9 _- J6 e7 l" i5 d4 z, x#include <conio.h>
+ Z8 Z0 S$ v4 W( z1 @/ H1 O4 q#include <malloc.h>! v8 l6 b- |1 M
@/ f) E7 Y Z! H+ K
#define STACK_SIZE 100
( Q1 i/ f3 ]+ Q; V$ k$ s! w3 t#define APPEND_SIZE 10" X) u0 X& J& t! O. |2 v
+ D5 ~7 i" U+ Lstruct SNode{. H" u& f/ W6 Y. j
float data; /*存放操作数或者计算结果*/6 z! C3 r4 N& ^4 q% d' L+ s# x5 t
char ch; /*存放运算符*/
$ @8 `# ?$ ~7 ?, `2 s) z};
d. I+ N: n3 {
$ Y& V- x; j* ^6 o8 H dstruct Stack{" Z" y; E# d- d+ x: W# u* p
SNode *top;; t$ H$ K1 c6 {+ X, b6 i
SNode *base;
0 y; E! V1 l. s, `& c* { int size;; ~$ |9 l) j1 X3 H) Q
};5 e8 N8 Z" Y' s0 ?8 H; J
1 _4 i* f+ S& a: I ?4 `1 x% Q! K; [
/*栈操作函数*/
6 ~5 r- c1 e! Tint InitStack(Stack &S); /*创建栈*/
2 ]" f: h. D2 g( ?5 b) tint DestroyStack(Stack &S); /*销毁栈*/
9 m7 P }5 J* x" H+ u5 j0 Yint ClearStack(Stack &S); /*清空栈*/
' B: p2 }$ h$ |3 W. Rint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
3 I7 m( i' v' B1 L. ^5 zint Push(Stack &S,SNode e); /*将结点e压入栈*/
/ \1 |3 K2 H) z- [int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/; }0 H6 ~% U) y' K
. b6 E% ?: Z" C# S$ S0 x6 h/*表达式计算器相关函数*// T: `, F3 E! l: \2 {
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
8 l& B2 r0 @0 i) Y+ }int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
, @& T0 A. Y- t+ |float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
+ c# T" f( Q) J* s0 O, g$ t- d9 Ofloat compute(); /*表达式结算器主函数*/: b/ h( X% r: ^/ q" o
char *killzero(float result); /*去掉结果后面的0*/ 7 R" x5 s& [8 K( L% q# `
9 c; E( K$ U$ p4 F9 @0 Lint InitStack(Stack &S)
8 [: ]2 x: ~; ^% A6 q{
2 v/ F& V1 A3 m3 b! e S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));( b0 ]" A2 I" |5 K. W0 a
if(S.base==NULL)
2 I) j/ Y* w0 |3 e' |1 A4 W {
2 X3 k- c* ?2 s; S# j8 b7 { printf("动态分配内存失败!");2 D8 ^$ V- G. H) Z
return -1;; L: L A1 f3 O
}' G; P0 h+ ?( A9 P; a. ~7 x/ D( q' C
S.top=S.base;
1 V" J6 i" \$ B- p S.size=STACK_SIZE;
! s' f, d. a- L' T' L {6 v8 N- W5 [0 ` return 0;
o1 D# S6 Z. D% D}
; I8 n1 d1 ~# h
) ^. [* l6 [- u! c( @$ Mint DestroyStack(Stack &S)" f/ W2 l5 q7 f
{9 N5 s/ D$ A1 k6 `9 x3 Y$ F
free(S.base);8 O7 I3 r" Y7 k2 K3 V: Z
return 0;
h6 M: m }; t}" k/ Q/ z7 S8 J" v1 x) Y \
$ k3 G: L; d3 P. q9 z5 I. @2 \int ClearStack(Stack &S)9 N; {9 ~* j, W$ o) k2 Y2 I
{, T8 q, |5 Y; r7 |) ^
S.top=S.base;( ]/ k% A; V/ g$ u7 L, R5 c
return 0;
) d3 ]# G# m# k}
. a# Y/ t! i' W
4 W' U& h" a- s5 i6 [1 G" K+ ^ a& bint GetTop(Stack S,SNode &e)0 `1 [7 u7 a2 ?& ^
{
( A$ v* V) @8 m& u. i if(S.top==S.base)
: ]# d* f- X3 E5 S. Y- \) l {5 f( k/ |5 E. j7 R" U
printf("栈以为空!");5 V' a' u+ @! l2 x1 \% ^% L
return -1;
5 R2 D- g& @6 k2 v$ u% _( o A1 N$ w# v }
* Q0 y7 q1 T* n6 G" I e=*(S.top-1);
; L: f9 D+ A4 }# {4 N return 0;8 z q8 u1 \/ m" i
}- B- K7 y9 \- C" I: [ a7 B/ [
! @" b R( _* V% D
int Push(Stack &S,SNode e)
5 j' L3 o# D# u, D{
2 @" o; ?7 W' t! m if(S.top-S.base>=S.size)
, |0 d1 f8 A9 n& k K {, z) z7 z3 Z( W- K$ h$ P# L
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));1 Z* h3 _8 V, k' K$ k2 g J
if(S.base==NULL)1 [ Y9 K+ ~( A
{
2 s: S" Q& w) A$ `( h5 i printf("动态分配内存失败!");7 F) o6 R; Q" o ^. _0 v9 s
return -1;
3 Q2 L$ t: Q9 a }
! |8 ]) _$ m4 A p; J5 {' m/ Y% t S.top=S.base+S.size;8 K$ i6 l3 R0 W- X5 ?
S.size+=APPEND_SIZE;0 r1 N) p: V/ i6 E; p3 w6 `
}
! G% b5 _! x" D! V *S.top=e;! ^$ ]9 J9 ^5 _' c
S.top++;
2 a3 y5 |! l& E5 u- V return 0; U3 U( S9 x% P+ b
}
$ d! @5 J+ E; e" t+ W/ C4 s; f; d# o& _3 Y+ \6 z& E
int Pop(Stack &S,SNode &e)4 G9 Z- }: w, K1 z
{( ]$ H6 d( o, W# {& P# T
if(S.top==S.base)
2 w q" X4 T: @* U: h L! D% M* S {
1 v1 `/ j% g1 U& | g U printf("栈为空!");" w( `- @0 l: @5 ~. e, n! S
return -1;$ V: D+ W7 k: j) W9 O" ^. _( `
}% E# e( N7 B& g3 @
e=*(S.top-1);' J8 R- i" L" i& M0 Y
S.top--;
" D* g+ V- P9 V+ C4 Q& ?5 G/ u return 0;
" a% r# N$ P' e5 O/ p; P3 e( A}. H% g2 ^8 }& {9 s
* \2 k J1 E5 X4 @4 {. e7 I- Achar get_precede(char s,char c)
; k% U$ f! h6 `7 l$ a0 v! q ~8 b{
6 `0 f2 d3 W" [ switch(s)0 B& s- ?9 ~% @) N
{
9 r& r# `, \# l4 W9 w2 Z7 x case '+': " Y3 T- b, y; k. B1 N7 v; @& j
case '-':1 S {' `" u4 h3 Z8 E, j2 F
if(c=='+'||c=='-')7 D+ \: a$ n3 I( `+ S8 \
return '>';
; }8 L; _6 b6 F' d else if(c=='*'||c=='/')
: h* ~1 \6 K* s. y( [ return '<';
' K! u5 d8 v, t8 L0 o' \0 z else if(c=='(')
2 z! q/ D: H3 @: K$ }( D. L return '<';
5 t! D, \5 M5 O. M% f* _8 W else if(c==')')" J3 A5 w: ?( h9 G' t3 ^4 H
return '>';% v5 V, C9 a# p6 N" h
else
. @" }5 T4 A. h3 R* Q* H return '>';
# G9 T0 |7 {. e8 z% a case '*':
+ ?/ |) Q- u1 S case '/':
# b" T/ G1 l; C. G2 g9 X/ S if(c=='+'||c=='-')
/ w, n. C! M, a% W return '>';" d/ @& Q( ]1 I& L# C( R/ H
else if(c=='*'||c=='/')+ G0 I; h8 m$ V* a. ^/ ]# X
return '>';
. S5 O) g( L, `5 v else if(c=='(')
$ A+ ? m) F6 d1 U1 \' ~* l' { return '<';* S2 R3 G5 f9 `5 y2 _- w- a$ |
else if(c==')')
+ v( U. o, i5 `" U return '>';
6 h; ]! c' g1 ~* f8 z else
2 u9 d8 N1 E, b' s return '>';
) ]2 b! `, F2 M3 a1 V; I case '(':
+ H' t9 K) n2 _5 ] if(c=='+'||c=='-')) {+ Y& E! x" }
return '<';
' T2 A3 R/ e/ S5 @+ U% } else if(c=='*'||c=='/')
% S! b1 B5 ~% Q8 \' [ return '<';
4 N3 {' H4 ^8 X5 F& A else if(c=='(')
' M0 V& z& S. {7 e3 y" E# k return '<';- Y( z& U$ w& |; f
else if(c==')'). B3 [- I+ Q9 g Y3 G, a- p8 r
return '=';) ` \$ j3 G. p
else
; Y0 L/ W4 V Q: q$ w7 C2 C: e8 B1 o return 'E';
0 u8 r" _+ o) G; z4 X/ A& N case ')':
7 G! g) |" x0 n* l if(c=='+'||c=='-')) o/ Y ?& ^( _$ L
return '>';
% }5 V) n- _4 ^! Y& O$ e* R else if(c=='*'||c=='/')4 l M% e" ^% E" f1 N' a# T
return '>';
6 m; o0 j5 s- b6 ~- @ else if(c=='(')7 i. i. e) M1 @+ i
return 'E';. U2 S: h$ v& \2 @5 i$ v
else if(c==')')& o" G9 p! g e B# c/ ~
return '>';
! Y$ x6 u) }! A0 m; O( l$ g else
; e9 w- R5 C) |7 d return '>';
2 C3 m! h4 }" P- P8 j case '#':
) l# l1 H3 F4 o7 I if(c=='+'||c=='-')
( C& z' w: z9 v% x6 i* h; ]6 R return '<';
. U8 `2 ?$ ` @- J# @ else if(c=='*'||c=='/')
/ e( r) `* C) z return '<';* Y) ?9 B, M( b) T
else if(c=='(')1 e& j+ d, q% ~ L4 m" _* P
return '<';
6 L) u6 E: L" @3 C. x5 e else if(c==')')# y" A$ n( r i2 J/ _
return 'E';' v+ U7 i& q4 i% S. N& L: ?: g
else G7 F( e0 g" o4 R) c' p
return '=';
4 Z5 @( u; Q |. ^* d+ L7 L default:
5 z# B0 @6 X1 w4 j, z% v- {; X, l break;
& r% A! t. a( L$ T }1 g! l4 U( P( h. M* [5 V; V4 O
return 0;
7 S1 \0 ^: B, Q7 C0 {( q" W7 P! J. ^}. a5 Q1 n0 D' T6 [" |
# v4 v! q1 {: g6 K7 m9 b) Aint isOpr(char c)
+ s% v1 q. M. H( W; C+ |9 A{' A1 y5 o* q- [1 n5 C6 u
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='), G% w: G8 P, n" m- D o' P3 n, Q
return 0;
5 u2 V$ {/ H- h) c. p/ H% H$ f" P else
4 `2 G) `% Q$ p' j1 r) ]( L, ] return 1;
$ @* h9 \8 E. _( X6 R6 Y, \}
4 W& X5 K; i/ |. i, H6 u1 r! ~* N9 W+ e5 L; j
float operate(float x, char opr, float y)/ K2 S6 G/ ~) ^) [$ [3 G
{. x% ^: X, L9 Z& I
float result;3 l8 Z6 s4 b8 E7 {
switch (opr)
3 g% a3 [# i: U& q$ g {
5 \, r/ n6 B8 ]( |+ U8 U case '+':
2 l9 U# o' h/ Q' g result = x + y;' B4 t# f/ j! Z5 ^
break;/ t9 q; B7 ]9 Y
case '-':
; z) Q! C) p" r+ \; ]7 O' _% C result = x - y;
1 U! U' G2 r1 ?0 g, e break;
& Y, w/ Q) P8 q5 j! i case '*': 7 F; q. ?1 g8 y) x, M
result = x * y;
1 K* Q# W' L5 i break;
. z4 M$ \. {7 ` case '/':
+ C; h; r; e& b- M, \ if (y == 0)0 H+ n8 x, ^1 C9 S- @$ h8 W0 Z
{6 m3 H% I* S% e
printf("Divided by zero!\n");8 {- k+ H# H# V0 V8 x- R$ ^( B# a s, b
return 0;
3 V! b2 J9 Z2 v0 m e }7 K( L! z1 s8 L6 }4 u( c5 p! T
else
. ?7 s+ S$ _) T+ U; y, ] {. y7 p0 D& A$ @( t- @7 _$ M; i% r8 s
result = x / y;/ F) c6 [- z0 D9 z' e, l
break;
& A+ R- M$ ~% F2 U. O }
$ x7 o8 q1 Z# |7 r8 ^9 i6 C4 Q default:
$ h, [2 K3 B: _+ \! T9 a printf("Bad Input.\n"); 3 I9 H- A2 z5 x, i- X/ P
return 0;1 n0 M8 K; C- ?' u8 Y) T) j9 }2 k
}
5 C. N5 u* A5 N( l/ Q7 p return result;5 o. F2 E* j; ~
}
6 ^$ ?+ t( L& I0 _/ H+ J1 `% I. N# K
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/4 B) Z( F; R; U
{
7 z( {3 k) {' \( R3 {1 T Stack optr,opnd;, {, N( U- l2 U# X9 e
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
. n0 m% t" ~ L: q# V/ D, g; L2 T char c;
% H2 t+ ^$ `0 E) A5 {; w4 F) l) k char buf[16];/ }" C1 p9 c9 J/ i8 [; d* p
int i=0;
- [$ L& O8 ] X9 F
1 i. d+ D7 w0 @" { InitStack(optr); /*用于寄存运算符*/% V, A/ l) d2 H8 Z( i
InitStack(opnd); /*用于寄存操作数和计算结果*/
) k% ]7 C3 @8 @ memset(buf,0,sizeof(buf));$ X1 g# O& r( W. Y4 ~
/ X+ d5 Z9 E( S0 I# o
printf("Enter your expression:");
# z& \5 w$ Y& }+ }
9 f7 P0 b( S7 `* ?; } opr_in.ch='#';4 Z6 I' p# a4 ]& M/ {9 h8 C
Push(optr,opr_in); /*'#'入栈*/8 |( T0 ] d1 V; a$ m/ E
GetTop(optr,opr_top);
% l1 ^& j; H; o c=getchar();2 o9 s& H; I: ~3 M1 J# D, A5 H; |
while(c!='='||opr_top.ch!='#')( ], }+ p9 L- \* @8 S4 s* n5 g
{
# A$ E0 _( s, J: R- \1 {+ W if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/% l6 J; W& e' d( S) b. p
{
$ G" f; o5 i1 s* b/ G9 x7 B buf=c;
. ?# o( C2 k4 H6 n7 N! | i++;& X8 E4 X' b/ D- F0 x9 s) q: h
c=getchar();
3 C: U/ r [& U# X }+ O3 N0 s) n# ~; g1 |" ]
else /*是运算符*/
9 N8 ?) g8 \4 q( X {! L7 ~' p" w5 l5 `! l
buf='\0';' ]; |8 {/ `+ o0 r
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
. C& Q* ^' }; k5 @ {
- u; y, |) E! p- c4 k0 a opn_in.data=(float)atof(buf);0 `" h* {3 E+ M& H6 u, o3 r+ h8 B. B
Push(opnd,opn_in);
) b1 [ x9 c# [# t printf("opnd入栈:[%f]\n",opn_in.data);0 ~& G( T3 ?. p9 p2 m; ^2 d1 e7 g
i=0;# R; D' G; c6 n: Q8 q9 u
memset(buf,0,sizeof(buf));
`& N/ v: Z' C8 v) {) A }
/ e+ `4 ~8 }3 r! }5 \1 m" a6 v w* f opr_in.ch=c;
`1 N. Q* W4 S: g8 h switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
/ J3 F/ t/ Z0 |$ N$ e* Y {% ?0 n6 H6 B& D' c$ {' y
case '<': /*优先级小于栈顶结点,则运算符入栈*/, M) B& _- T, ^; C2 ^& B; J
Push(optr,opr_in);
1 B6 \+ R9 L# W3 X printf("optr入栈:[%c]\n",opr_in.ch);1 x2 T9 M; G- X; D1 z6 T( O
c=getchar();6 W) k9 M$ R0 z
break;
0 z$ S0 P d! G' F; ] case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/" r' u& A/ s. k* A
Pop(optr,e);
4 W0 g# I3 M s$ a printf("optr出栈:去掉括号\n");$ u; k' ]& c6 W1 a- m( ]
c=getchar();- Q4 C$ V7 H) B. s, A
break;9 @% P, ?! i' _' S5 j* K, c. G
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/! R& C/ t! l9 p
Pop(optr,opr_t);; _- A. r- }1 f+ L1 f
printf("optr出栈:[%c]\n",opr_t.ch);
* V8 k) `. \- b& _( ~% C if(Pop(opnd,b)<0)8 G1 h$ C& P" t& x+ @0 R: d
{' \" `* t3 S2 s+ [3 v! ~' I
printf("Bad Input!\n");, K, j" f' D) G) h* n
fflush(stdin);
: g3 d* s, r. V! Z9 Z$ \8 X return -1;3 _3 R- |4 `6 k( ]* y3 S
}- i- @3 Z8 _6 } L Z
printf("opnd出栈:[%f]\n",b.data);
" c/ i% ~$ X7 j7 h. D if(Pop(opnd,a)<0)
7 L9 G8 l% B+ R {
1 ?% M) _% U1 q+ ?# [ printf("Bad Input!\n");) i5 T) d6 d' l, C, ~& J
fflush(stdin);
/ q2 w# Z% c: X: v( R return -1;) @3 b; k5 Q7 l: x5 v+ R
}
" Z; M/ f$ E; e3 z printf("opnd出栈:[%f]\n",a.data);
+ X' Y. E+ V3 c! Q7 O) H! `% Q$ @ opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
M+ ^( }5 p: l& n; G+ N! S Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6 s6 o" G. y; |; t5 g
printf("结果入栈:[%f]\n",opn_tmp.data);
6 C! E" l, c7 B* K* [; ~/ e1 N( R4 D break;( f( y; T1 Q( ~" W- F& C$ \
}7 |, h7 w3 D2 S" ^3 e$ t( O9 l5 @
}& P6 T4 O' p5 D7 d" ^) [1 c
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
# g3 B7 o6 Q- h1 z. j0 J# |) E }3 i* M8 @' }3 ~/ @7 p
GetTop(opnd,opn_tmp);) X- E$ l8 e1 C4 q8 d
DestroyStack(optr);5 T' k' w" |8 O0 \1 {; E
DestroyStack(opnd);
; i L: m5 Y+ [ P9 |* G8 q% a; [ return opn_tmp.data;: h4 \- n2 n) ~3 r; ^& q0 q
}
k9 W& w* x H1 w, h! v: n, A
1 Y/ U- G- U) H- S* T' S% G" ~char *killzero(char *res,float result)' l( k8 o I7 m
{
& \; t B! b8 b3 { int i;) x6 Q' G Z b% z
- n8 q1 z6 c$ I m4 z sprintf(res,"%f",result);
1 |6 }7 ?0 f( ]. R8 L. i6 ?$ `# _7 O i=(int)strlen(res)-1;
7 s3 l/ B8 \# G- p4 d9 F% _ D, t! P while(i&&res=='0')
5 G1 {6 R$ N/ U {
5 T2 q0 Q$ [) n6 t6 m/ I" J res='\0';: |6 Y; R* V' {( P8 }
i--;; b# l( H% d8 V9 T; [/ n+ K
}
) v1 k. R1 @* p$ U if(res=='.')
, P& R* w; g8 P1 e! ^% Z( _ res='\0';5 ^/ J- Y: H8 e- c) P6 p
return res;
$ |% y: f5 E3 D& N* k! U, ?. G% ?}- G& Y6 Z+ r t a
& B3 \1 z, N- [7 g r- T" Aint main()( v% o$ T% ]# `7 o. T5 `" N
{
* r% K7 @) ?7 Y: Z! A/ w) e2 a char ch;: e* ~3 v: n' N" u
char res[64];9 c1 J& m0 @" R8 l* D7 p, X
float result;7 {$ H% H ~9 Q" h ~
while(1)
5 C5 f# _) @% a9 B- g {, E0 y+ R) M L; g
result=compute();# t* w; a- f, t0 p* t( d I ?
printf("\nThe result is:%s\n",killzero(res,result));
) Y! _: J+ n1 F1 _% P printf("Do you want to continue(y/n)?:") ;
1 V9 I8 I' I; |. p& {0 Q2 j) m( R, y ch=getch();1 Q0 d/ Q, D" m5 j" z3 m) F* `
putchar(ch);8 t+ Q! G# s) g7 m5 V7 H
if(ch=='n'||ch=='N'): S0 w% Y2 K# j9 x
break;
6 l6 n) j4 D+ m else1 K- u0 A# G) I8 J: S0 _" `, U
system("cls");) W1 J/ [* M% {( e
}' ^6 t% G; ~2 Z' }
return 0;' a3 a3 f4 Y S8 D+ ]1 y" h6 j
}
' X$ S1 [5 o3 |" ]% `; Q$ F
* \/ }0 Q1 O4 H% s8 V- B, j7 v[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|