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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.$ Y3 g E/ i- Z5 k
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! D+ {9 \( P5 w, N8 p7 A* T/**************表达式计算器************/
j6 t+ k7 Y. S5 k9 X! L#include <stdio.h>: N( D# `3 @) }0 a, }
#include <stdlib.h>
1 i) U0 C1 @* _& J: D#include <string.h>
4 z0 R% s1 m1 @: E7 v#include <conio.h>2 t C7 v: J/ a& j* O5 ]& V! n
#include <malloc.h>
: d& \2 _# }6 X9 ~ m5 g8 E$ D# r$ Z0 {" }$ @( n6 `
#define STACK_SIZE 100
9 H* ]9 m; q" F0 G#define APPEND_SIZE 10; U7 v: }$ r ~/ S- z( i2 R' X
* @2 O7 p! U& c0 I& F7 e6 jstruct SNode{
6 ]; o% U. A; j! S" ` float data; /*存放操作数或者计算结果*/
/ C) s7 ~2 |' S char ch; /*存放运算符*/0 Y) e7 H, @, M; R# f
};. @2 U1 @8 A. \$ y# R
) y6 K4 v* h: R( O4 T- S# L2 ~
struct Stack{
3 {: m1 }1 j: b' p. I SNode *top;# O5 W# R- j5 T( E. ~8 W
SNode *base;
" X2 O% q& i; D) j4 T W int size;
! V4 E. f7 p5 ]5 y3 M" p+ u& y};
0 G' D( U# h+ r- b" p6 e
- A; W' K9 T5 o0 `, I. r" o/*栈操作函数*/ Z% M4 P6 F, d- c% B' O
int InitStack(Stack &S); /*创建栈*/
) |3 f' B d$ n [ J5 j- [int DestroyStack(Stack &S); /*销毁栈*/) P, Q M, k! h- X
int ClearStack(Stack &S); /*清空栈*/
$ O* Q" h' }1 D+ _1 U7 Aint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( J9 X# Z$ o p% j p, Kint Push(Stack &S,SNode e); /*将结点e压入栈*/- ?7 |7 C- ]. v1 U/ {; l8 `0 y
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/0 @; z; F: V+ O* k0 n2 K
: O2 ~ M! e) [; G/ `* a/*表达式计算器相关函数*/
( `# t4 \& I& a6 z0 Q$ {" v; ]char get_precede(char s,char c); /*判断运算符s和c的优先级*/) \4 o2 ^- e6 A$ ~* I4 M0 e! A( U
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
' k; O$ a0 \6 A8 G3 ]# V ?- Vfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
) W' H! m& S$ q# M: Ffloat compute(); /*表达式结算器主函数*/
8 d2 k4 h2 r7 \; {$ c b rchar *killzero(float result); /*去掉结果后面的0*/
- j# L( V! q" ~+ |7 F- m
# Y) A1 b6 y# t% d: hint InitStack(Stack &S)8 \/ V3 k' }+ B8 N9 A0 q) U+ }
{$ w4 t7 K* ~9 q- g( I
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); S# p. I' C8 t
if(S.base==NULL)
& _$ r8 g( k" Z* f1 @ {; Z7 `7 ? p% f# v! O" n0 j ?
printf("动态分配内存失败!");) z/ r& o d% L
return -1;
* j0 ~+ E4 L v: L9 W }
% y! B8 ~" Y& ?$ C3 F1 l7 P( `9 F S.top=S.base;
\2 z% L! V8 [+ ^ S.size=STACK_SIZE;( s1 o9 G2 O6 u& Q# Y( x
return 0;
# ?% f" D _; H8 V6 s B7 V: X0 ]7 F}: Q/ s7 W4 a% c
2 D4 e7 P$ t4 v2 Wint DestroyStack(Stack &S)( Y& d) H; k6 n$ B
{
/ t. j$ c( ]& K3 P4 d; @" C7 f7 ^ free(S.base);
) d: a' w: E* z6 [! p2 y m return 0;# Y1 W, y' Q5 `: p! i) T. o
}
( `: `. V, Q7 g& ? H
. z# K2 T# F/ \* tint ClearStack(Stack &S), P. _) B$ E4 D& Z( ]
{. s [- X. F! _- {
S.top=S.base;/ a; j* E+ {( v
return 0;
9 w" y5 M# t# m7 m}& G6 y1 ?, j4 X# x3 o7 A+ F
5 P" |: w- c8 o' O8 s( Rint GetTop(Stack S,SNode &e)2 N8 m' d: z/ e8 A9 t# s' j* R! W
{
0 M/ c% ~' P) j3 N3 \# _8 o4 k0 V if(S.top==S.base)* q9 _6 z; w9 [4 `5 ~0 I- I
{' E K+ G5 `' ]+ n' E, j. ?
printf("栈以为空!");
2 |" A" D7 @. I. Q return -1;
9 P: B( n5 ^8 F4 k% I* u }
6 U9 u1 M) r f+ {! t* | e=*(S.top-1); J0 K' q A, X6 n% ` G1 O3 X& y* U; g
return 0;4 @6 f$ ^9 ?3 |
}
* o- K) a' E" H4 U; E$ H: x j9 v" e3 c. L! o+ B
int Push(Stack &S,SNode e)8 ?" i! s5 e" A! V! g9 i9 \; g& \
{: V: X6 d- Z3 ]
if(S.top-S.base>=S.size)) D$ t3 L/ I" ~- N$ q
{8 m7 Y8 }) a" Q% n& t9 v- c
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
_' ]- o( u8 ^; U h if(S.base==NULL); l) _; L/ W# C- t& r7 l& o' s
{9 l. G2 }/ x0 T! Y. [& h" _
printf("动态分配内存失败!");
* ^! ^9 W. [; [1 J: n# E, Y return -1;( h6 w5 G5 D3 n: ^
}$ f2 D: P3 }4 v$ B0 g
S.top=S.base+S.size;
4 U! e$ R1 d( d/ q S.size+=APPEND_SIZE;, X5 `/ C! V$ ?, I5 X4 E7 P' z
}
( T4 |+ N( Y. ?$ O9 D3 h0 F *S.top=e;
& M9 |6 c. @( e& \; f S.top++;# @/ _' r1 ~$ |* x
return 0;7 I1 v4 e7 z: r( v' v' d( f j
}2 t w. x' n2 `: b5 ]# [" C& Y
! e0 Y: B! O! A' I; W$ m3 Lint Pop(Stack &S,SNode &e)
- m4 C9 {7 B( `. Q! Z, b9 b{
3 y1 p7 }0 x# \! M5 Y if(S.top==S.base)) p- o5 }1 `9 T7 v3 n
{
) U. E4 q2 U8 u, O8 C printf("栈为空!");
2 B: }5 [8 _6 ^ t return -1;) x2 ?$ { k. B# ?) W/ o- z
}
- F% l/ b+ F2 B& q e=*(S.top-1);
3 J! G3 z6 q1 |7 q- u0 [- \- v S.top--;3 Q8 L. D0 O0 c* \$ ^7 J" H
return 0;4 Y3 Y+ x5 E$ m, T, |- v6 `1 o- H
}
; A a5 M* G6 ~8 x- N1 N. g' z: R3 q' U. V9 q$ m# f, Z: r
char get_precede(char s,char c)7 a: a/ @& P) G$ i) @8 r- |
{6 _* ?- A( \- U" z7 r2 W
switch(s)
( r5 c' M$ b/ _" @ {6 v- G4 B" k( S+ E7 U
case '+': 8 `6 |- j0 k( I' ?, h7 u$ V
case '-':
1 Y9 p6 ?& F+ X" w/ R0 L if(c=='+'||c=='-')
) M* n: d0 }( m* L& w4 f, | return '>';6 Q5 r( p/ I0 }/ i' G; g
else if(c=='*'||c=='/')
$ q" T, m1 v! r/ } return '<';5 d" @# P% l; D* v% \
else if(c=='(')
9 h' h6 g3 A) R" o0 R& y n8 q) R return '<';
3 `2 i$ H% F, C! ^ else if(c==')'); g& v$ x* U3 N' g# k: A. @; t7 y
return '>';- V& W5 z* d4 C7 ~3 T
else
2 M; f- n" C: J t) i5 V; o return '>';4 p6 N2 g9 Z4 B w1 F
case '*':
8 E' J) W; `5 d. z' { case '/':
* F; ^. w' X* o7 r0 C" Q if(c=='+'||c=='-')9 O, i2 C9 {8 @0 d9 H
return '>';$ n- C) A6 L& g) V1 F
else if(c=='*'||c=='/')0 M. \9 A1 R- p* _; P
return '>';
# w! V8 ^& e9 W% {6 e else if(c=='(')
) B% Z2 v: @2 Q! @ return '<';
' Z( L9 W3 U. O7 m else if(c==')')
5 [$ i; E: o4 H return '>';+ T; ?: W9 o ?: L* ]! I
else
. w3 _( @) _3 a" o+ {1 p8 P' D8 ^ return '>';
$ {( M. Z T. n, ~8 @, M case '(':
+ A' w4 S' H( l, B if(c=='+'||c=='-')
- T3 R- ^% J) R& K* \ return '<';
3 V3 v8 X2 N9 q3 f8 m; [$ w else if(c=='*'||c=='/')1 v4 z1 V' J6 b/ g, w
return '<';- Y% \; D! ^& u) s* |
else if(c=='(')
1 t2 D* s$ {9 \! j, @ return '<';, D# X2 r* x/ r
else if(c==')')1 B! o5 }: _2 h3 C
return '=';
) @+ P9 C/ H* P, [# d else
0 x; b# s C- O; J; [ return 'E';: @6 j5 I/ n+ S7 C. W0 A [
case ')':2 s* ?' R1 h" Y" m+ N
if(c=='+'||c=='-')
$ }4 C- m$ T% o) K! Z return '>';
1 Z! p7 ~6 a+ W1 d6 b$ \( e else if(c=='*'||c=='/')
/ j* z* Y5 n# @$ l& n8 \ return '>';
# I# ]. T' ?& }, Z! s else if(c=='(') m. a" v& [" u, E, _
return 'E';: e S1 P. z/ f) d# n0 g" { P$ X
else if(c==')')
6 k, P5 }& J. e6 C5 } return '>';& }0 B0 i0 C3 ?9 U2 C4 ~6 k2 Y4 v
else
% N( R+ H7 @ y: ~0 P& f } return '>';* T$ I/ e& s( x, t
case '#':& F* ~6 K! N" k N/ a! i7 U. p
if(c=='+'||c=='-')
- P6 l* H/ o7 y3 ~% Y* j return '<';
Z1 Q/ }! p7 _% k else if(c=='*'||c=='/')/ Z+ n( D7 k3 s* [% M
return '<';
# P& X' t" k! q% E else if(c=='(')
2 U0 C5 r! v! K: M4 w0 @ return '<';) z5 j0 Z8 M( _4 f5 x+ Y, X; [; u) T
else if(c==')')
( v% J) F8 U% X+ _8 m9 V* `8 t return 'E';
+ B1 D* @( k4 Z, {0 r else- `0 }5 y, N8 S$ a
return '=';
: U3 _: V( Y9 x# o4 W1 F' W default:
- J9 y5 G" a6 v! A1 V6 V break;! v- d/ r% c9 \7 N' n: e' X
}1 v) n+ p8 m: D* l9 P
return 0;
# q. U. _+ w6 n+ U6 F0 X3 r! ~}% W2 n8 ?, k$ @, R; R
, J% I$ M4 i2 V" p7 N/ ~; a0 q8 Pint isOpr(char c)
5 _7 S7 v3 Z* X8 u{0 G% i2 i& I9 Q% Q) M* @% F' s
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') J. S. r# f5 S4 s2 M6 f5 l2 T6 G: _
return 0;% k# [6 M( T- p* \
else 6 J* ~, g* P( _* s8 ~
return 1;
: s, _, K3 O4 q- m$ ~}
: ^- o% ?* O1 i/ }& u5 u! ^7 j, l3 Z0 q
float operate(float x, char opr, float y)( W) L( w8 \# u. V
{
* M8 M4 g2 [* y' \ float result;
/ u. ]* e+ ]& p$ U6 I5 Q4 o3 k switch (opr)( Z# y6 J* `- ^( G% e x
{
6 q( J# b" Y" [# l5 r f* ~6 }5 r case '+': . E1 f' F. Z% _! v7 h
result = x + y;
6 L: a% k4 K; k break;# L, E: H. j! I/ i# y
case '-':
1 m9 i% I! |1 r; [ result = x - y;3 ~/ f4 G5 d0 k P- P
break;! p% o0 S( j7 d q7 \
case '*':
- n. i( M" B1 i/ S' u result = x * y;: \# {1 v" F+ \" f
break;
$ e) h+ j; b9 X$ s7 v5 P6 x% E case '/':
3 l: p% i& R/ q0 V" m. P if (y == 0). }3 N7 r% i j4 F" K8 O/ t x
{" I2 J3 j' b$ D" g1 ^& I
printf("Divided by zero!\n");
7 i* I! b( H4 A/ |% b0 U4 G$ E return 0;- W9 N5 R* ]/ J. n
}
B" @, v5 d5 ] else
; b% a! B+ f+ S+ J" R- f- v( Z {8 S9 h X' w4 u# @- e6 v
result = x / y;- ]$ d$ p2 J7 M
break;
* J' p% B6 n9 F$ P; `6 T }
! Q7 J+ D$ y/ H; z( L default: ' d4 C9 L, E5 [3 {
printf("Bad Input.\n");
% @- q9 e+ Z3 S; }# z return 0;) z4 x9 J; k6 H% m: i3 N7 q0 T
}6 c5 e% _) C% `) E6 C
return result;4 K8 @4 s/ W/ P7 y. @
}
# g' Y4 T9 a& M$ s }& ]9 W/ F5 s( y
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/3 W1 @& p: m9 D( R" x! b+ T( U
{
" y. `' a! O: l, @ W, d$ [ k" ` Stack optr,opnd;
! _5 m- o o5 I6 k4 Q3 L struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
% Q0 ~: `8 x) T char c;. l6 z+ F c0 A, ]: h
char buf[16];" R% X4 J: X" V6 X
int i=0;
) [; g3 s4 o) I+ T; Y
7 _& K: |. {3 T' r! m; L6 v InitStack(optr); /*用于寄存运算符*/: y# S1 l# W* e V: Y* H
InitStack(opnd); /*用于寄存操作数和计算结果*/; c4 h% v! E2 Q( j% O
memset(buf,0,sizeof(buf));" ~0 d! J, B! A9 V
3 k/ O: g4 ]" V% T% B3 ?
printf("Enter your expression:");
8 _1 d k6 q7 D* e
% r0 U6 \" Z" J. k O opr_in.ch='#';
& P* I% X' r. o$ p3 r Push(optr,opr_in); /*'#'入栈*/
! e. i/ P0 H1 C% ?- O* I GetTop(optr,opr_top);
5 Z8 r" D4 T! T) h* B ~ c=getchar();
' P9 ^9 V/ v$ r while(c!='='||opr_top.ch!='#')8 e6 M7 s- d5 e2 f
{$ F6 a# Q* N# [3 q
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
% F+ N( r# X% e% D' R n {
. p# [" b: }% S buf=c;
1 k! L( o/ U3 ]6 R i++;
/ A3 I( e! f8 ?. Y: u7 e/ X c=getchar();
3 I% `; D* b* u }
( r- s) Z7 l5 B9 G8 _ else /*是运算符*/2 D2 @1 u/ ~6 z8 @1 B, E+ R" p
{
. b7 A& G1 A! j buf='\0';* y5 C$ Y, G$ N0 c8 S% V
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/% w( t: ]7 n. E+ G
{
+ B- X* G* @5 X2 b! ?# Q, D opn_in.data=(float)atof(buf);' J6 F7 Q/ I" E) p5 p- p' O5 H! E
Push(opnd,opn_in);! [6 \& F% h0 E0 h0 O3 m! Y# F
printf("opnd入栈:[%f]\n",opn_in.data);0 D; z5 r' m! h+ [" e" | O/ R7 k
i=0;+ |, K% S1 f2 c W! V) U9 n
memset(buf,0,sizeof(buf));: Z3 H+ r5 @, C1 k% y+ L) D
}8 E& y: ^+ ]6 M# D- p, c8 q- f& |( l
opr_in.ch=c;' q# C/ g6 }+ L5 I
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
W- r, X- c$ I; l4 m# A {1 i: A# |' |" ^/ {
case '<': /*优先级小于栈顶结点,则运算符入栈*/
6 ^* @( D! ]7 x" o/ V0 b Push(optr,opr_in);6 b$ f( ^# X `) G* h
printf("optr入栈:[%c]\n",opr_in.ch);% Z3 C" f, a! l; n M9 p
c=getchar();
+ \, N" c9 a; ?5 p break;
2 Z4 H6 h w" f0 B/ ~$ B- B ~ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
5 `8 f8 E- d& Y% |5 q Pop(optr,e);$ ~5 j; e$ s, v0 h; d/ R' \9 f- O
printf("optr出栈:去掉括号\n");$ D5 j7 n3 R) Y" Z& |
c=getchar();: F9 q) e; S* ~0 r/ u( ]0 a
break;( m7 s6 z2 |: m. A
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/3 m! }, B8 { o/ b8 I
Pop(optr,opr_t);# l7 z7 I$ x( P C7 R; f7 e
printf("optr出栈:[%c]\n",opr_t.ch);
$ r5 p7 }- \: `' F& f j if(Pop(opnd,b)<0)" W9 [3 G- \6 I" q0 q
{. h3 C2 B7 g; P5 j$ M
printf("Bad Input!\n");2 e! V* I" a3 @0 p7 J
fflush(stdin);" o/ ~9 C3 b2 @' F
return -1;
) Y# c9 x, y" Q' ]1 t }
$ V4 s4 k, p. L- [1 l' z& F printf("opnd出栈:[%f]\n",b.data);" a1 [, x7 u4 i. L) V3 @
if(Pop(opnd,a)<0); [8 L) X' t# V8 \5 B7 n) V! f4 V
{
- k# T2 [: g6 s8 W printf("Bad Input!\n");" \ j' N5 H" }3 R* ^0 t. B) J
fflush(stdin);( c2 P/ J7 w" j- k/ W3 ^
return -1;. [2 \9 O3 H+ @( e6 S+ l9 a: i+ y
}8 M' J0 O$ e: b7 G2 Y/ g
printf("opnd出栈:[%f]\n",a.data);& {5 A$ A/ J' Y
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
" G6 b# J* n( Q# ?( D3 Q Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
" j2 x4 y- M0 S m printf("结果入栈:[%f]\n",opn_tmp.data);
g% H5 A/ }1 u: g2 l break;
# A) H8 t1 F% x3 c6 A3 h8 l$ ~ F s }* b6 t% [. G2 y9 O4 J& x
}
5 U' O3 U2 r# W) D/ O' i) I GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ; q# T/ v# _( @: b& f
}' d6 L+ `: T0 l: |* H7 b! K
GetTop(opnd,opn_tmp);
$ J5 _ a! L8 I# D. M. d, Y DestroyStack(optr);; L2 V' N3 e8 N0 G- ?6 r5 d; M
DestroyStack(opnd);
8 ?' l' H, b3 z9 ^ return opn_tmp.data;
7 B8 \ D0 |! D$ u. M `5 u7 V}+ I/ t0 }1 q9 b% ~* F
4 }" b- m: ?0 Achar *killzero(char *res,float result)
" t6 L @4 u: ~" v{
; H+ N4 f0 _+ M( O. {# p! E int i;) _( S" g( X6 I2 z; M* `) n
! p! c( M, }. I+ K4 G sprintf(res,"%f",result);
+ Y( p# I$ [) G% ? i=(int)strlen(res)-1;
* }7 w, {- N- s while(i&&res=='0')# v- W3 W! O' `7 U8 E! f
{
: q8 s8 g. a/ z/ z+ i: n& I res='\0';
. |; |) t8 n; i! b! H3 q! f i--;
( n6 x1 m/ ]3 g" q0 K }( v8 Y6 ?5 m2 m( {$ |. T! _
if(res=='.')* a# i" Q' B+ F# a2 t; y) h3 M
res='\0';" d J5 O# ?1 B0 I# m& m
return res;9 i2 o( N3 A1 }6 M: O1 V, f% C
}7 k5 V) J( A' ?7 U( T
! t+ X! i7 C4 @% \# b' Sint main()6 U7 k. ]. k- f1 u+ `: C! _9 P
{( p- T, ^ l1 o3 O# R
char ch;
O. ^; T# e6 z char res[64];9 b" W( h; v3 D7 D+ K. v! I
float result;" ]6 m$ y" n* D
while(1)
* |# \' C( |8 N. @5 [/ W1 d- Q5 @ {* Z. t! F/ z- h/ q
result=compute();
, V. R. d+ {# Y! r/ s' A printf("\nThe result is:%s\n",killzero(res,result));2 J' ~" |( h4 u( b2 [* N1 Y
printf("Do you want to continue(y/n)?:") ;- b$ c9 `0 I k( @! d
ch=getch();
! Z) V' S$ S. X$ f, }* J* G0 O* R putchar(ch);5 s9 v; S) G3 B2 c5 }' O/ q
if(ch=='n'||ch=='N')
) I3 J! {3 k; \; G6 K break;! ~% m# p( [7 Y8 t" l: F6 K$ q% }
else: b$ [7 R& }# E! m8 J
system("cls");
5 ^3 ]* s$ g* r" h }" w+ U3 u; ]% b4 f5 Q' Q
return 0;
8 |& n- L M9 w9 B$ z}" R" m- x2 m! ~5 Y
; k$ `' T" K" O" V+ E# U
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|