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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
# K# u( F3 _& Y程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=; c; K+ O# Y9 y3 K s! [! ~' g& R& {
/**************表达式计算器************/9 ` _# g$ W) ]5 u. X6 \/ T& g6 S
#include <stdio.h>
9 w) C2 Z$ S# [1 z! ~- v#include <stdlib.h>
( B# d9 G d1 p: O#include <string.h>
' u3 W, e2 a+ P2 E0 x0 c. E- ?#include <conio.h>
* ~; h. }7 F. b#include <malloc.h>
8 o. h1 t6 V" e# r5 @* U/ C% Y/ q" j6 Y8 c! S6 Y! y5 r8 P5 s* B) k4 I
#define STACK_SIZE 100
! |8 F, V) _. U& u9 H3 I2 N1 G#define APPEND_SIZE 10/ U4 l6 U! O3 k$ F- |: _% x
5 q+ a; o/ ]' a' g, N. r6 fstruct SNode{
+ n b& V" L* y8 ?. a) { float data; /*存放操作数或者计算结果*/
/ i) g w3 h' h. s, y) C char ch; /*存放运算符*/; }9 {; ~4 [7 C: A' J
};0 m- q) O! S; _1 U
% T0 s0 H' T/ D
struct Stack{
/ x" T, c& s* t4 H9 Q SNode *top;7 k0 S+ n4 `- i: k
SNode *base;
; V# ~8 d1 t7 W+ \! Z int size;7 V0 ]( A% @. X; J6 Z$ H
};! u# Y$ _( r1 A7 c9 V* K
- K4 O* S- ~' U; I2 f2 j/*栈操作函数*/
3 @, R+ I* b( k7 V" r |int InitStack(Stack &S); /*创建栈*/# N) m( B6 E d$ X- E" B0 J
int DestroyStack(Stack &S); /*销毁栈*/
3 k& y* c) c1 fint ClearStack(Stack &S); /*清空栈*/* k# _ C# E9 u* y
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
8 @4 P/ |: l3 y+ b" |int Push(Stack &S,SNode e); /*将结点e压入栈*/. `0 E# J8 U4 I8 g6 \
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2 |3 ]+ n+ S" ^+ n. n& e( t0 d0 ^" p1 f; A; H- N @
/*表达式计算器相关函数*/: d, n9 j* W( i' x/ n- }2 e9 B+ O
char get_precede(char s,char c); /*判断运算符s和c的优先级*/ J$ [* n7 I( n( d7 [3 b. a
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*// F$ v/ I5 V3 v( A/ D6 e
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/: a- @* R3 j* b1 m% z5 @
float compute(); /*表达式结算器主函数*/3 M) a, W2 `; s: \3 y
char *killzero(float result); /*去掉结果后面的0*/ & z& a! ~6 \# \) h
8 k& b8 D- @1 T5 T% W+ kint InitStack(Stack &S)
' G: p6 h3 Q" n3 M) P8 M3 b{
* v5 A" R/ `% w1 H S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));4 V6 P5 i% c8 \3 P% g
if(S.base==NULL)% M; r+ X# L* I- Q: R7 z
{8 Y0 z# R- X! V
printf("动态分配内存失败!");) O0 u" T& l9 p, X% T
return -1;9 `; y; b' H$ H( w6 i% C% ?+ F- U# }: H
}: V$ c$ v$ j3 w M' f# r) k' ^3 P
S.top=S.base;" A$ V1 Q2 A1 o' o& b3 {, d' U
S.size=STACK_SIZE;
" L" c# o( \! O9 h, z. Z* f7 {1 g8 a return 0;. ` ~/ P+ t' z3 q% Y
}
& m7 e" z4 D" L0 U) l/ x7 s! e* q( h; m
( ^$ S0 _+ i3 \6 yint DestroyStack(Stack &S)! j, m6 ~7 V) ?# P# q$ P
{. |3 M- [" t8 g4 O$ ]
free(S.base);8 x% o( [. g1 m6 \# Q
return 0;
8 _1 D, h5 A! K; ^2 R& U0 f}4 N' r* b3 t5 C- i) y7 c
2 d8 V, \) p7 g) R, L4 |- J
int ClearStack(Stack &S)
_. B& c1 ~% n9 G0 x{) Y: O( Z) @- ]5 I
S.top=S.base;0 a( I- G) w* t- P& P' t9 G
return 0;5 f0 p9 K6 L( a0 t3 ]) \
}( j- k+ k% }. W+ n4 _
* p. V! w1 }8 o1 U7 n
int GetTop(Stack S,SNode &e)
) _& N$ U# R+ S0 S{
6 X. y- X" M* t7 b if(S.top==S.base)( }0 n" T1 r8 p
{* i, |' M. m3 n8 n( z
printf("栈以为空!");
$ u ?2 b' Y: }' H8 N# B: n return -1;% z7 j; r% c4 X1 b4 N# a5 R; b/ [
}
+ x1 \% O6 o7 ? e=*(S.top-1);
1 w: `: @5 F+ H$ e4 f return 0;6 X: j( j; W4 {% O
}7 u2 L6 i- {; }
; b5 _5 F f' v) Z3 t. E
int Push(Stack &S,SNode e)7 F" c6 K2 T Q; n
{0 v& t. A) K5 c" g2 V. ^
if(S.top-S.base>=S.size)! ~" ^) X6 J" G2 S; h
{! I" |( y" @$ X9 P
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) v7 g: \% @ H1 L( D; r5 }4 ^( { if(S.base==NULL): F, l3 ]8 s) u1 c' b
{
% M2 }8 c) T& F) x* J' v/ T$ m printf("动态分配内存失败!");
" u7 }% w: m: q$ O* s return -1;
0 O: V( p+ V/ s3 f2 t. w }
* e$ m& K. v2 t% [9 @ S.top=S.base+S.size;
- f- f8 [" }6 B; i7 h0 Y0 t( L- c! p S.size+=APPEND_SIZE; d$ M; x: r) q t/ X
}
* r8 n8 }* _5 E* u *S.top=e;* I8 @# r' M* J Q; f. X+ P
S.top++;
& \' Z- M, M6 E, @4 g, s3 q9 A+ F return 0;! p$ m/ W' W+ ~1 s5 ?6 q0 P# g* A6 U/ \
}
% r5 ~% y; a3 _+ q% `" ~' ?% T* ?: ]( t, g' k4 Z
int Pop(Stack &S,SNode &e) }5 B1 }9 N, c* V, X; k- I: r9 U; d
{2 y5 M) D% ~4 v s* E. W
if(S.top==S.base)# X' {, z- m) b1 T
{
2 B- x, t! D# t printf("栈为空!");! V$ `& n- V$ j/ `
return -1;- l% L% l- o7 L8 |$ X
}
2 T& {) R( h9 u8 J) ~ e=*(S.top-1);0 m; h z! z ^$ O# C5 O
S.top--;3 A! B2 [& t; l1 `
return 0;: \1 ^( n* k* ]# s+ s
}
2 O- v1 O& ~2 o% P; `1 D
9 H, A ^) S" R. N' ochar get_precede(char s,char c); Y3 {& ]: E7 O$ M: O0 L
{4 b" ~/ j" I% \" b/ }6 b; ?% P. F
switch(s)0 c, J6 @+ y I; x0 T; C( q
{
. Z" X1 G8 W& H! L" |1 p, T, v case '+': 2 S1 X+ ?7 O" u1 D7 `0 Q7 n
case '-':
$ V) g) p' L1 ], d( } if(c=='+'||c=='-')9 D6 s G, x! ]9 Z( ]( m
return '>';
1 t. p/ e. f7 H; U else if(c=='*'||c=='/')
" y3 M/ ^3 w$ T2 q, p return '<';, b9 V0 ]) m5 X
else if(c=='(')# t9 I! O# |$ t) G( ?
return '<';
/ m* a% j+ p, q f" L3 p0 A, D else if(c==')')
% j5 x8 P# _, G1 y0 {# S( I3 J return '>';$ n% M. W, s% L7 j& K$ }9 D
else
2 a) D9 \! H, M9 } P5 W' F& L return '>';
9 W Q/ h5 u8 J ]7 l case '*':
% _3 \9 r W8 B$ e; c9 Y case '/':
4 S8 t |: ~1 n if(c=='+'||c=='-') f3 Q4 R( ~0 q) W& X8 I& O: I+ l
return '>';
$ y$ v/ k) ^$ O) J9 h else if(c=='*'||c=='/')2 c, P5 W2 b! ?
return '>';% E7 _4 X: J1 d2 u
else if(c=='(')) h; l5 Q. X3 \; P" Y
return '<';
. @ d. a) G6 q else if(c==')')
$ c$ R4 o% n1 o$ H0 b! ]3 u+ Q return '>';
8 [4 v$ Z" e- }& t6 ^ else
( t6 P3 F2 G3 O6 @0 A& ~% N return '>';
& l) d% R$ s0 w case '(':# T5 X- ~% m5 \: {4 b* x4 U
if(c=='+'||c=='-')
( E" n$ i; q7 {3 W8 o% ~ return '<';
* ?5 p: i/ Z6 X' M' ?* ?- k else if(c=='*'||c=='/')
* T" k; F. @0 a J' w4 Y. D return '<';
" t- ~+ N& Y1 Z5 H else if(c=='(')
9 w. B# s) ?5 c. a# S9 K9 p, q3 a2 z return '<';% r/ v. ^7 D: J( m* Q, a3 @
else if(c==')')- [& {; m; I# o4 r+ k
return '=';
& {" N4 h- r, e+ U4 T1 Z else$ d% Q" C2 L j! ]; Y* m3 w8 l
return 'E';4 Y' }2 c l6 k. u
case ')':
1 `1 @6 c: ^) f% a* Q' R8 M' H9 @ if(c=='+'||c=='-')
! B- O8 J* b' N- v return '>';+ s2 H1 W) Z _0 P, E
else if(c=='*'||c=='/')
& V! L( v5 @! U3 Z% I/ _2 Y return '>';% `( T; h- Z6 l1 _1 c* }5 U
else if(c=='(')
6 ~9 t. h }* T return 'E';& p; @: k9 {3 S2 W1 r% X: A
else if(c==')')
- @7 i! y+ \; ]+ T/ M* J! k/ O return '>';
; u2 z% p8 X" x& A6 N$ x& a else
9 f& }) W! h9 C. n9 F1 o9 p# _5 S return '>';
: }- s' q0 @8 N7 ~. L! _ case '#':: t. N" ?: v" l8 t, S
if(c=='+'||c=='-')) @5 q! S( j) F4 b# U8 h
return '<';
( J& H; U; S* ` else if(c=='*'||c=='/')
* y, c" V- L& h0 c, l- ~ return '<';
e& Y6 M2 r2 n- l else if(c=='('); V$ \! Z/ e( X% J
return '<';+ j5 E1 h+ b# M/ E
else if(c==')')+ ~/ g. H) a; F$ g/ \' r
return 'E';
+ A2 D% U2 d: B3 E else
4 i2 D; q n; Q! e6 @1 A; H return '=';
8 ?, [- A/ U7 K4 t4 @% G$ O: a default:
( \& F. `5 Z b6 R7 z break;3 D; k. i/ U; C9 L' v7 w" N. P
}
" J) O; l# }. z; T& K return 0;
2 U8 z, o) C! d7 A}1 q9 R0 b- F: B' A% T: {! h! W8 t# n" W
G' r% e; @1 a! r' wint isOpr(char c)
1 ?$ O. P" ]6 |{! y! F" t& o' `( @- ~4 a
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 G: M" E% m; S j$ i& H" |0 `
return 0;
2 }, b4 d3 J0 s1 _ else / m% ^! R p! C+ K* N5 M
return 1;$ y! G& P1 ~$ i. d4 O/ r
}
( q* N& V4 H# P, b2 l& [. A0 K# | `! P4 E
float operate(float x, char opr, float y)9 m( R) t' n" b3 [+ G) d
{$ p5 i2 c2 h6 X6 m& V/ g4 u$ W5 V
float result;% W4 j; k- o, D, s4 I7 j4 j
switch (opr)
+ z+ P* L9 ?) K* w4 k. }' F {5 ]! [7 _2 x; c+ j/ G, m
case '+': 7 X- W, f7 c: z0 C# G; n0 K$ n
result = x + y;
% l1 {1 e1 S& s+ V; B break;) X3 \6 N4 L8 n1 v# P
case '-':
+ n9 M$ q: C$ [- M& _1 h* E; ` result = x - y;
# U& E' c0 E5 H2 x1 K break;
# W$ }% A/ E# g6 d case '*': " t& o. {. s9 Y/ R8 h
result = x * y;7 S- f& J3 h5 E! M
break;
- A4 t$ z5 l0 C8 y( j7 ^& i case '/': ( o; q6 o7 m& Q2 J$ Z
if (y == 0)
2 f/ Q; s) T7 i/ h) ]- U8 } {: O1 z5 _4 s: _0 w' ~
printf("Divided by zero!\n");7 M% |+ u; L0 y7 T( V
return 0;: x, Z/ d8 e3 L4 E4 D
}0 R- M" K: i! Y7 V! O7 ] h6 ~
else/ b0 C. N3 D) u% N' l+ a4 [
{
! p _0 c& a. x8 d result = x / y;
$ @/ L3 ^& N0 D* S& E break;5 v. H" O; I; t' Z5 I* R
}7 k% K. G& q& Y" k4 ^! U+ p
default: 9 I. _: d) l9 W# O
printf("Bad Input.\n"); w* \3 ]' x, k- j" K" c, }! ?5 Y
return 0;
) e) t. k. H% X6 [! O* m Y }
7 E1 B6 b: O: H7 J; r% M return result;: Y7 @! x0 j& W, z+ H
}
1 t, Z# n5 p/ Y2 `, M
- G9 @- F* d$ a: U/ Rfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
* d0 y' `6 Q( \( e7 p8 u! i{
" E0 j4 ~2 {; J( }" `9 P Stack optr,opnd;5 I; @0 @2 G, z' b- I
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;5 z" r8 B6 A( q7 S& i7 J& p1 o
char c;
4 R! Z" b1 p& B4 q" O- ] char buf[16];
8 H/ W3 K: q( ]8 p5 Y4 A, n, B# H/ r int i=0;
0 P* M, ^: M- D [4 Y; d6 j
' X9 L3 i; H) p9 q) {5 s% c/ d InitStack(optr); /*用于寄存运算符*/1 W l/ z8 u* k7 y
InitStack(opnd); /*用于寄存操作数和计算结果*/: |+ l* _# o1 x; E/ Q) v
memset(buf,0,sizeof(buf));0 X( D. M. M, D J8 [) ]6 M* h
# d4 u4 V# Y* x7 z% C
printf("Enter your expression:");
9 G( K. K# T. M6 l3 l' E, V5 X+ R$ h ' M8 h. `0 @- i
opr_in.ch='#';* V. U" i1 @: F* i
Push(optr,opr_in); /*'#'入栈*/. u0 } a! p3 N: \
GetTop(optr,opr_top);
- I. H! L2 J; e" @3 S0 B* v c=getchar();/ a |/ e q) Y, [# i8 ~
while(c!='='||opr_top.ch!='#')
: n& g1 c& ]9 n! J0 e {, S% w8 `0 {) T- L
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/5 B3 n" ^2 ]' x; `( m
{$ v) h, M Q. ?$ P& B# D9 F: q
buf=c;
2 r; I! ? `- P7 G2 k i++;
+ O0 A, j9 X( m' b6 }; Z, u M {/ Y c=getchar();
5 m6 i \: u+ {2 ^- T }
* M. ~0 _2 r- @# Z else /*是运算符*/ ~" ?8 a8 _4 X9 H" @8 L8 o
{
2 o; L. O$ a, l4 c$ M7 v- T buf='\0';
, X8 X- a+ `+ ~* P2 l$ V# r if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+ m" c. y# U4 G& `
{
o7 x: Z4 a; r" I, Q7 f opn_in.data=(float)atof(buf);
! t) e- s3 c* {, _ Push(opnd,opn_in);. L+ U3 A+ v# v0 G: l
printf("opnd入栈:[%f]\n",opn_in.data);+ e; G4 Y( k9 q6 k% |0 x
i=0;- R+ n u6 ^: d
memset(buf,0,sizeof(buf));+ d: U% K4 @3 U* k: |- o
}
+ O) O/ y: R5 v* N opr_in.ch=c;
+ a3 {( Q! U( v! O, P switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1 o$ D+ c s. m4 f- R3 b8 t {
' a$ K- ?8 R x# N: X case '<': /*优先级小于栈顶结点,则运算符入栈*/- |6 U* g/ h9 r
Push(optr,opr_in);! y7 ~! N& v9 Y: i7 @* T$ m+ m
printf("optr入栈:[%c]\n",opr_in.ch);- _4 s% }- W; c: K9 B
c=getchar();& _- G* j- p( e) H- R! y2 K
break;
% t/ ^5 L0 k' Z" g4 ?2 X) s8 o8 _ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/: O) J4 u* k9 y
Pop(optr,e);
# d/ C; l1 h7 k/ k9 w% W& S printf("optr出栈:去掉括号\n");
" B( _0 x& T& N2 O q: C$ O0 j c=getchar();( n, H+ n# [7 p& d* r Y3 z3 ^; n1 J
break;3 [* ^0 W9 d6 P6 _- [2 i
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
9 s! O" ~( j: g0 g Pop(optr,opr_t);
* }+ v: V! t, J4 Y) L& n printf("optr出栈:[%c]\n",opr_t.ch);
0 G' x9 P$ r* ~! z if(Pop(opnd,b)<0)
/ }0 L, D# E- `" R7 R {6 n s0 w& W7 b: q* E
printf("Bad Input!\n");& G' ~' w) i# b7 t5 w [
fflush(stdin);% u; n+ z1 e4 y- w
return -1;
9 u2 T, F. y. d! u1 W }/ F! Y% ?# s% h7 A7 R& [% E
printf("opnd出栈:[%f]\n",b.data);
1 [; C) N6 e! | if(Pop(opnd,a)<0)2 l6 _: t; |9 D) u! q5 Y/ D
{
+ W+ ^8 j# C; c printf("Bad Input!\n");
" u, f9 }4 U( X fflush(stdin);2 c$ q$ G F. S: d' Y
return -1;
: I' ]$ B; J/ P( j( C- V& A- J }
" k) d( @& Y" e printf("opnd出栈:[%f]\n",a.data);* v, V, P# C R' a# s% `
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
4 I' \5 r6 y& }' a: C) r; H) b Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/: X0 R, Q- u c8 Y- F" ?$ ?
printf("结果入栈:[%f]\n",opn_tmp.data);
: T9 `* C5 F' p, ~ break;
0 i0 c( o8 D% M8 A# V }
1 e: l% e2 a( g/ b0 i }
C2 O" e- M5 R6 N1 e# |! d" [; @ GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ! b2 I2 \9 I/ g* i9 f7 c
}/ I: ]% r- r- x
GetTop(opnd,opn_tmp);3 u% _" @ S2 `
DestroyStack(optr);
; a1 {3 [$ n l$ H/ f; | DestroyStack(opnd);# c5 |$ \. N/ S, c& I h) ~
return opn_tmp.data;
* c' t* h( A# d5 l5 U}. A8 r0 `: f$ D4 E
& [4 ^! ^& V3 A/ d; Achar *killzero(char *res,float result)
7 _5 N/ r9 }7 Q+ {% d1 Y. w& H4 I* l{
1 x% c! c2 \; m3 c3 f5 g int i;4 V3 {& M, H- q+ \, l& U
' y* ~9 r, B1 S) R! |) q; ?
sprintf(res,"%f",result);
$ C l. k: C9 i( N% n i=(int)strlen(res)-1;
5 ?' Y" q' A @5 _( i# W: |& i while(i&&res=='0')7 L& B5 Z) C& k
{! ?( r" Y2 Q: V- H! x% R+ U7 i
res='\0';
3 c9 ?; q5 O9 [* j' C i--;
! A O. Y0 T+ s0 u- z }
1 H/ }. b/ \) u: y$ h% @/ X! ? if(res=='.')# U+ Y _4 O9 b3 G4 X) s
res='\0'; }4 \& O" v3 y5 j# l4 H2 [9 ]
return res;
. A, a: Q+ c/ _7 ?. T}
/ I. n" b2 [0 L' `/ L2 @- _- H
int main()
: ?$ v, s- Q" l: b3 F{4 @, G( a# | m; g* a5 |
char ch;6 u# Q8 x# v! ]( D5 x
char res[64]; H0 v6 S% Y7 p8 Y+ K
float result;/ B' N0 k$ `+ g0 O6 m/ y
while(1)
: Y1 v; X- E" k. i' g {
" l. ~. B; b% c2 R' @# ] result=compute();
. m7 X \# C. }/ V: ] printf("\nThe result is:%s\n",killzero(res,result));0 z+ @4 q8 h7 p& H# B
printf("Do you want to continue(y/n)?:") ;
5 c+ O& \0 i# A- d1 v/ @/ u1 Z. d ch=getch();2 Y0 g* d3 v: T9 c, ]
putchar(ch);
. Q: d2 u- ]* Z" n+ b* } if(ch=='n'||ch=='N')3 T4 {( G/ X+ h( B6 b7 L5 c
break;" | i9 ?' ~/ A6 q8 s1 i( s
else
) c* M( p, ]' W- m- r! N, c system("cls");
7 k' q3 l0 J+ n; T( \1 m- D8 f }
6 u$ i) H, U+ B) t% ^: [ return 0;
3 u# X* W$ F) r}% m! l; f. { w$ b. c0 Z8 x
5 S! ?2 C/ s! S R& a- W$ |
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|