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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
9 Z9 _7 D2 i6 s3 v& J: A程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=8 J+ J' I( c: J s
/**************表达式计算器************/
1 v5 {# A* I5 c5 C' N#include <stdio.h>
6 c7 I! q0 Z# w#include <stdlib.h>& D3 m. q5 t% o' Q7 ]
#include <string.h># B, V" Z+ n; ~: U6 G$ h
#include <conio.h>9 `$ [4 D) i3 l. \' M) m
#include <malloc.h>
3 l9 D5 V. v5 M& \7 I3 w1 v3 z6 L* @3 h6 l
#define STACK_SIZE 100/ @ p) f1 x1 E: a$ m
#define APPEND_SIZE 10
9 [ H& b9 z: L' ?6 O% p
# x1 N) }9 y- K; ?/ @$ j1 | Pstruct SNode{9 L9 ^# W/ S) K) P9 j4 f$ F+ {
float data; /*存放操作数或者计算结果*/
3 K9 j& D0 w( ]5 }5 ^$ { char ch; /*存放运算符*/
! a: G4 G5 {4 w6 Z& t2 i$ N* w};
: X7 s" Y) m0 J. {$ V' l/ P4 m, D' t$ Z% u" u: o
struct Stack{ j8 x. v: S+ P' i5 l- d, n$ O
SNode *top;
0 j2 s' l" h5 T0 ]1 J/ x SNode *base;
+ P" z6 E b; F7 }( H int size;
' i0 [; ^* v5 ^" _" c% N};
6 J- ]5 X$ ~8 x7 y8 a. F7 `- N
7 e0 `1 g6 L" ?& X3 C/*栈操作函数*/
4 X2 T$ v9 [ }- x' F5 ^* Sint InitStack(Stack &S); /*创建栈*/
; x4 C! g, o# T8 ?$ K. Rint DestroyStack(Stack &S); /*销毁栈*/ f4 V- ?) n2 M8 ^
int ClearStack(Stack &S); /*清空栈*/) y1 S" T& j. N7 ]: g8 H' w
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/- ~9 Q, n, f1 @7 A- c3 ^- v
int Push(Stack &S,SNode e); /*将结点e压入栈*/
% y0 L5 E A1 D) B2 nint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2 { J9 A7 {. \ y( y+ c
; I( c/ m: \& R. i7 ~) r/*表达式计算器相关函数*/! E. N; u: D3 {4 x! ?) j
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ b0 v6 `1 |6 [, `% R$ K8 {int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
, @" }, N. ^/ P& t, d7 W) Qfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! o: o& s# H- L7 h' ^( ?+ r- Rfloat compute(); /*表达式结算器主函数*/
) ]2 R, J( h* n- f/ z% Pchar *killzero(float result); /*去掉结果后面的0*/ ' @% P* s) k3 a5 A
0 U V9 _- q+ [
int InitStack(Stack &S)$ L ^0 L8 ]. Z* L7 Y5 B
{
5 c1 m! `& b# _) m S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));" j8 j3 @9 V3 T) r- o% V! p7 o9 v
if(S.base==NULL): h! O2 _' l/ j7 C: Z+ F7 d
{4 N. T3 p/ o7 _. ^1 z+ |
printf("动态分配内存失败!");
& `, j- N- K( b return -1;
5 E: P) N5 M( M$ f }( e8 Z" Q6 x5 v# B* B
S.top=S.base;
; S" M9 ^2 M" @: l* z. Q S.size=STACK_SIZE;
5 ?7 g! N5 d7 Y1 J& a4 t return 0;, E4 D2 f8 {5 c" B, U# a1 d( V
}( M, l% Z3 B8 S# X# p
- |7 F$ |3 i; s- h7 [7 a
int DestroyStack(Stack &S)
, F6 }/ ?7 @0 o7 Z( J( l{9 F4 B/ g7 S/ }, a% x/ r$ `
free(S.base);
3 I l/ @2 p* Y' I% _) w& m8 @, _ return 0;
1 X9 n7 J" n7 T) T5 n/ }/ O- l% l}
6 f1 G* \: M- g! I0 [- G( t8 P) N0 D/ q/ D
int ClearStack(Stack &S)/ i* @% v5 R6 M D; Z
{
; Z$ F; a+ E1 U1 o: Q# @) _; a S.top=S.base;
3 K! e9 K. o; k. R+ O- \6 N return 0;! I! l0 H- Z; R* B; R
}
1 [8 y, \: p! k% q6 m2 U6 |; @! n2 p p& t j+ C
int GetTop(Stack S,SNode &e)% z# f: V9 F1 G& k6 f
{
* s! p9 d& A. ?" s& \3 u if(S.top==S.base)
& O1 E+ m8 U; h' @ {$ C& e2 q# X F2 k- g1 A1 J+ |. Q
printf("栈以为空!");
) |/ j3 y2 g$ c' U. C, B return -1;5 k( ~: w2 F1 l+ I$ f$ \
}) r( K& y9 M/ y0 a6 Y
e=*(S.top-1);5 l7 b: t! {$ x3 f/ E: N7 x, }
return 0;3 z6 { Z7 a4 h/ u- {
}$ `4 Z, V8 v. Q- Z
' x' H4 U n o8 X$ T
int Push(Stack &S,SNode e)1 M/ b3 f2 E6 V' ?1 J+ I
{
/ d" P$ J) z" X1 ^ if(S.top-S.base>=S.size)
0 d/ `8 P$ J, f {6 R2 q7 r' u# K8 e
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));* ?( y* W& t; M6 v9 i, L$ ~2 ]
if(S.base==NULL)8 M+ ~6 t3 k/ J& j1 O; V% y" Q3 h+ z
{
- Z0 f% U7 L" c) S3 N printf("动态分配内存失败!");
" u" F6 Z* f( c: G return -1;
6 a1 @0 u: y1 z5 j/ ~; S2 D* ` }7 D! `7 q) k" @& O
S.top=S.base+S.size;
. A/ [: U9 N3 f0 t4 I( } h S4 S S.size+=APPEND_SIZE;( D% }+ W0 X6 m$ X3 C4 v$ ^
}
8 @ Q! t$ g; N7 j' S$ B& w/ ?# [ *S.top=e;
2 k" t, {/ n0 n) R6 r( x S.top++;
) p* L5 K& |7 n) y3 \ return 0;8 s% [, p* D Z" l6 D
}
+ Z t4 r. I; _3 y7 @4 r; z6 H& x* C
! g& N5 L: j! }int Pop(Stack &S,SNode &e)
! i% U0 y( D! a$ U5 {$ c. V{% _6 C, {( ~% C/ Y( ?" x
if(S.top==S.base), t# W6 r7 I5 ~( X7 l J, |9 C
{. h3 x) Z) S" a1 ~+ |
printf("栈为空!");
8 t2 @( m/ H( b5 T5 R( \8 h return -1;
6 m# S- ]7 f( q( _ }
2 A7 s2 s; d" ^* |% k" } e=*(S.top-1);
& z4 a! n! r$ } S.top--;1 E; P/ D* L/ W p- w" o6 T7 d" C
return 0;
* E! D- d/ _$ R/ d5 ^- z* l$ s}
0 w/ W# l1 E3 r/ y: A$ z/ q; P/ L) T$ d" \' n" Q$ x
char get_precede(char s,char c)8 k2 K$ N+ y) U5 {, c t4 @
{/ q- i3 L6 c% c$ J/ C' a
switch(s)
6 K! `4 t. g" D) B. c7 Q { R- N/ p* J, J$ i6 d; s# v
case '+': 8 n- f' r$ G% \7 Z: ^7 ^5 Q0 f! e
case '-':
8 I$ k( ? U( o* u& v8 r# }9 ` if(c=='+'||c=='-')
# o; S! j7 |* H8 P8 C$ E1 O- i return '>';
5 _3 j" F% ~1 a& G1 G5 u else if(c=='*'||c=='/')+ O$ q5 K- D! A0 c5 g# v
return '<';2 R- J& x0 H5 T( U
else if(c=='(')8 M- { o8 Z k6 m% C2 q y9 C
return '<';/ u7 `& _1 p0 d# l7 y
else if(c==')')4 \$ C, j3 h0 _
return '>';
- S i& P0 H) U4 Y* U8 ~ else # o) r$ F. A6 Y" \
return '>';) g: d! x$ y; r
case '*':
) j) t& n0 N6 v9 X u; M case '/':1 V. S: l# W/ a! Q' O
if(c=='+'||c=='-')" U5 k8 \- E: ^/ x0 k, \
return '>';
- @5 `& j' M% \ else if(c=='*'||c=='/')
: y/ T. Y, [$ G- i5 N return '>';5 `8 U7 x1 h2 S
else if(c=='(')
" g* L4 X9 u' O return '<';
* }9 p8 g) T3 {) z9 P else if(c==')')
, O% T% F% b% u3 X return '>';6 c8 k# R1 X# z1 [3 H5 P5 p& n% l
else
8 J. s: B* W+ k return '>';
# t8 X% n+ f7 a2 U/ u0 W8 t case '(':/ a7 l6 t8 e! j8 ^
if(c=='+'||c=='-')/ U `9 z' {1 i. n- P
return '<';; |3 m! ~% [8 L0 q; d0 s
else if(c=='*'||c=='/'). I1 |* I/ ^) G; D8 ~, O" t( T3 j% j0 m
return '<';& b2 D. o$ h, R8 C
else if(c=='(')
- N7 H) o( r) A3 @ return '<';: l5 S0 m D. v, m. ?
else if(c==')')
, S5 s1 W6 |$ _& u0 `8 G return '=';5 u6 B* f1 u: y3 E" p
else4 N2 {2 \: W* o: a- {7 k
return 'E';
+ i. f* l, b. Q! @1 }2 Q+ e2 ^/ q0 y% G case ')':5 [- d2 \( D* l; r
if(c=='+'||c=='-')! c' D7 j* j7 a; \3 N
return '>';
6 p9 Q$ q, |% Y2 B) u3 r else if(c=='*'||c=='/')
! w- M% o4 X8 E8 S/ [) T return '>';
T$ s8 }& d# a9 U( {( n5 w2 \ else if(c=='(')
! w) B/ v, m$ \/ \ return 'E';
4 E; K' n3 r, C! m else if(c==')')# J7 t- z8 c( O/ q$ k! V1 L
return '>';$ b/ G) F( [$ g% w3 Q
else8 B+ |2 ~6 e! l e3 h) v6 c
return '>';
! O) B. K8 i @/ @' Y& f case '#':
- p; T/ c. Y Z3 u" s, c+ I. i if(c=='+'||c=='-')
) K% F* k* q3 K( ? return '<';
! f" N' t9 C. \ else if(c=='*'||c=='/')1 S- o: Q5 X7 d1 _: h, t" C! H2 s
return '<';
L& U. V/ f% x* B: e1 ^% N else if(c=='('). Q3 e6 _: j; H; y' M: P5 U
return '<';9 J* ^3 n+ G# X6 K* w: S8 ]" Y
else if(c==')')
$ p6 l8 X2 W' n( W3 f& f return 'E';
. M' M9 h0 I* y$ _ else2 E; `+ O |/ c X6 p& s( m
return '=';
1 @8 y% `6 L4 y9 U# X default:. Y( U" k7 _; V5 L( L9 P3 L+ y2 o
break;
2 f3 v* A, }; {, j }# l* q3 l0 R" a8 {/ i
return 0; 5 Q) A* U5 F! x7 A& o# Q. M
}
. a3 e% F3 L' D( r
; w/ T; ^# J4 J u1 W3 O+ Iint isOpr(char c)$ ]! p% r( V p- _
{+ u) Y. o+ W7 s, T7 f( y# R5 v
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
5 D' q- x- M1 G% b$ ?8 Y3 O return 0;
* C' o# S5 q6 P# K! G0 ~ else : z9 I- D) q1 ~2 P, b. T2 L: f
return 1;! _; \, r% M/ X6 a1 A& H9 a- \/ E
}
: l$ X4 d6 w1 M2 I3 i( g5 \4 R# ]" p0 j
float operate(float x, char opr, float y). ]- u5 @$ ?2 C0 j$ r' h. I
{) s( Q1 l, S/ N4 }/ e
float result;
% a7 G* X0 C, S! c9 n' @( @ switch (opr)/ j* g. o1 m6 Y( I) _
{: z' @9 ?4 p' u/ W+ _
case '+': % g- v. ~8 n: c4 l
result = x + y;
. P/ n6 @' s3 t6 s0 u- G% m break;& e1 e" f0 }' T, h' t, M
case '-':
2 G/ N/ M2 B- {: f4 h result = x - y;1 \& K0 _: N6 o; N _9 ?5 X
break;
0 i- i! ?; r( J$ j& ` case '*':
7 a, K6 d9 J' ^, h1 V, N result = x * y;2 S, [ V) Z* H% K+ w
break;9 b! ?" z- G$ o8 K5 T0 i' G
case '/':
+ d: |. ~6 x+ K- e6 k- W8 k) { if (y == 0)0 |, ?$ I1 Q. W m# M C; Q
{
0 I/ z% ?* v, ^, ?0 o printf("Divided by zero!\n");
; I3 V4 ^7 Z3 k1 L( K/ K* }2 G return 0;
+ O$ z9 V5 M7 v l' o; M }
5 Y0 L: T* ~4 K G7 J1 s0 p else# q5 w# V L6 D
{% r% p' Y, J( }, _- a2 z0 Q
result = x / y;
; j$ Q6 ]( O; e# V1 T* o. J3 r J; p break;
; c* |8 e0 d& e. B }
& }6 x$ q0 ?% s" k default:
5 R4 ^/ H& N: @" }' E9 a& N printf("Bad Input.\n");
) z) {$ u1 \7 O v' r: z1 J; K# `3 a return 0;
: I, k n+ `. v8 H) o; { }) l7 V4 W4 |- C* ], y; N# g
return result;
" ], z0 _- c9 P# K/ M) @}
2 Y- V. j; X+ k( [( N W+ Y
! g, v, e6 C9 u& t8 Lfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/+ }; u/ {0 F7 N, i, e P
{
6 o; Y, B: u( j S4 u) r Stack optr,opnd;
; @/ ?3 s- C7 w$ O, e; J/ ]1 x/ j0 p struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
) c3 Y2 g0 F% A char c;
, U( j6 h9 @) p char buf[16];& v& O v8 M' p8 L9 j. U
int i=0;4 {. q' Q/ ]% ^3 a% Y
- ]+ d( z/ S C1 b1 E InitStack(optr); /*用于寄存运算符*/
+ r) a9 V: |. ~ InitStack(opnd); /*用于寄存操作数和计算结果*/
8 o. u9 q2 j" }% h; | memset(buf,0,sizeof(buf));" }# V' v) w! v- s
& V3 Z+ z! ~: X6 q; G, @ H printf("Enter your expression:");
! D& D1 h0 t. g1 ^ - U4 `* Q# j8 B' V6 P
opr_in.ch='#';1 _& B+ p6 Z* X& s) H' X
Push(optr,opr_in); /*'#'入栈*/
: H! ~5 Q2 R& I( F GetTop(optr,opr_top);
2 c. r) {8 f, k4 A c=getchar();
+ O/ C+ n( U8 G8 x0 e3 Z while(c!='='||opr_top.ch!='#')
6 s- O v! i) o' e) w# r9 H- r {4 ~: B: O [ W2 d0 e
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/0 [( p& S4 `& I- F
{. }+ R7 q t4 O) @2 \$ \: H
buf=c;1 r! s9 G" S$ Q* u, |" H
i++;
5 c2 ^; u0 c9 q( a0 N c=getchar();9 E1 R+ j `6 l6 A" D' b+ s# @* t) W
}
9 d- Q0 k. ?* k/ X else /*是运算符*/
+ v4 @7 l/ J+ a p {
* H4 z ~9 h, k7 D% _! C buf='\0';
: Q% E- f4 o, y if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
+ L3 G# `# n P5 ` {) d. Q/ M/ _9 C" Y
opn_in.data=(float)atof(buf);
) J$ ]8 G" K- C# w' T8 k* E Push(opnd,opn_in); R; ^' E- b8 g* P1 s2 F$ e, S' a
printf("opnd入栈:[%f]\n",opn_in.data); T2 ]1 n) X# A# e3 z$ p
i=0;
/ u% L4 t* c3 @ memset(buf,0,sizeof(buf));0 R, y' |5 c5 J2 X
}: z( y$ p p% _- U6 x# ?
opr_in.ch=c;) V3 x" V Z1 }! u
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
' c7 y# K6 d9 G: P0 [: W {1 O/ `* |; [- o- N: k
case '<': /*优先级小于栈顶结点,则运算符入栈*/# ~& F% S: m. l) J0 [) Z- x6 Y
Push(optr,opr_in);
- I# f2 U4 h* I% { printf("optr入栈:[%c]\n",opr_in.ch);
# @; H6 u1 S! L3 n! b c=getchar();
1 |. O+ E- }3 l% J0 D0 b break;
. C) e. N9 T0 L4 n3 P# m" N/ z case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
, t- a0 o3 y, Z! b2 ^9 m5 x Pop(optr,e);
j% [- k2 z$ n5 M2 I% ?1 Y( @ printf("optr出栈:去掉括号\n");
2 {5 g. W* L! C' ~ c=getchar();7 y v2 Q9 x# t1 X7 ~+ N
break;
7 g$ c: O8 q2 Z5 B" S" _4 r case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/+ E( n6 @& k- E
Pop(optr,opr_t);5 a- `5 G! ]$ M Z) e
printf("optr出栈:[%c]\n",opr_t.ch);
u, T+ y" N% S9 e2 [, ~ if(Pop(opnd,b)<0)$ `% ]7 z- c: l2 t
{
' }$ m! W& ?8 Q8 G printf("Bad Input!\n");
h7 N. t6 c2 ^' D7 T% j; [ fflush(stdin); d5 e9 S ~: V3 J: s
return -1;$ \* K; F, \2 ^. v4 Q
}, ?2 N% Y/ U+ B" |; b6 c2 H
printf("opnd出栈:[%f]\n",b.data); G" J6 Z- ?4 @$ m( b% [" {
if(Pop(opnd,a)<0)! c7 i, n0 a3 ]1 x/ F8 v* ^
{9 l# m% O; D( ]8 K8 X W
printf("Bad Input!\n");' f/ c$ X" x- Q0 [
fflush(stdin); V! f* S/ y6 f4 D0 y, V
return -1;
6 }* b0 D! D, W3 A9 {! D' C0 { }/ d. n( Y* Y4 W
printf("opnd出栈:[%f]\n",a.data);
) t' c' p0 S; w opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/7 b* i+ O/ q1 ]; A0 a' v& {5 f* N) U4 R
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/$ ^) X0 w! N& {7 R* Y1 j
printf("结果入栈:[%f]\n",opn_tmp.data);
) j: `4 M5 o5 r f: t8 e- j break;
, f; z1 H) u9 Y+ p# g }
2 @8 @- N6 }( @3 ~. O }" i2 k# q4 v! ~7 w
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ' `, T) X& M9 V3 E! d7 W7 | X
}
: {* H7 r! S' H9 X! _- \- j' ~ GetTop(opnd,opn_tmp);' n1 K7 s( a% [. F7 |$ J) X
DestroyStack(optr);
6 u b0 l7 O* d4 Y DestroyStack(opnd);
& n! q L& J1 t$ i) ?1 h return opn_tmp.data;
; O7 g) F, p+ X& q% H1 s}
3 t; f9 n- Q1 U" a( B9 V' P& G% k/ g( {* l$ H4 R9 n+ O
char *killzero(char *res,float result)
- o3 C* e' ~5 y+ ^0 l! s( l{
7 I6 ]* H5 y) @# ^) j7 e+ K$ Y% K int i;) Y+ ?( z( u( o) X2 _" h2 S
; Q, ]( j% f3 }! A. ]$ y. S/ T
sprintf(res,"%f",result);7 k( t/ ^: A" n7 p% e
i=(int)strlen(res)-1;3 Y, n! K7 G+ H4 H9 v( D h7 t* n
while(i&&res=='0')6 K( c6 @' k O4 E
{3 u) {5 {+ f7 T1 d j, p
res='\0';: F- U! W W" L- Y& L6 g
i--;
9 r! i. c6 z+ Z! m V; M } n0 u+ V' v' E& H* S( X" j
if(res=='.')
7 q, E" {+ O) _3 G4 V, x2 { res='\0';
6 h, s! B3 r) [" @; } return res;# d. ?8 {, M* w4 a
}4 a3 W9 R( ?- R, @$ x
2 S X0 H1 ~! ^' Rint main()
6 X, ]: w- o2 J2 @2 @/ K, o# }0 ?{, U' \* u+ C: Q$ }& i( G
char ch;
1 I' y" ?5 A5 w. v char res[64]; B. l* W% ` i! X7 n4 K: ~3 N6 h
float result;
6 o5 f% `8 y8 l" R4 O% P while(1)
5 [, t' L) y% R% U {
. u1 o1 i- P9 Z8 L; F5 x. j6 V3 @ result=compute();: S4 N! J" D( ?3 k$ t$ E
printf("\nThe result is:%s\n",killzero(res,result));
2 O, o8 c/ E) f$ K, n printf("Do you want to continue(y/n)?:") ;
$ x9 \: g; @/ n" E9 S$ L, ?6 F ch=getch();2 E1 v" D4 n; R) t3 ?. W' H9 E
putchar(ch);
/ Q* K2 H: c3 ]& i4 u' j if(ch=='n'||ch=='N')
4 ?# [+ A: h( {2 I0 E break;/ N- G/ F, l/ ^0 ?) z# r. A2 l( b
else- x, v- m1 G- ^* F
system("cls");1 K& m" M6 J9 T$ w8 _" W
}
1 D) Z' a# e& ]$ _' ]; Q return 0;
0 ]; e3 S1 t6 y+ p+ k, u6 Y}
: T( S7 d$ w( @) `' l o; ~3 A/ @0 u5 y; z* H
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|