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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.8 y; g2 a3 b! s5 x8 l) R0 L1 j
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=. g. E. e( J; b% z) E; G2 T0 _6 V5 J+ v9 {1 Z
/**************表达式计算器************/
# s d7 f% T& r* T' G- Z8 d: A! Q6 H#include <stdio.h>/ H" c2 u0 ^; @) h0 f' A0 ^
#include <stdlib.h>
* Q# F; X5 Z. B; h5 Y: {! F#include <string.h>
9 S/ T* E/ @( Q3 E% G) _% j#include <conio.h>
8 }% b1 k! ], M4 Q, F7 E8 l#include <malloc.h>
- i5 B* q$ r: ~* Z$ G% f3 S/ g( b
#define STACK_SIZE 100
2 H8 O9 R9 I; B( _8 L% R#define APPEND_SIZE 10" G" I v4 K1 K: W, s
5 K# ~% q) z o5 C Vstruct SNode{7 }% _7 D3 M! R! n* a) K
float data; /*存放操作数或者计算结果*/1 v" m' ]7 I/ @# W$ N8 O) P
char ch; /*存放运算符*/4 L/ D. L: f* _; b4 {3 Q2 U' i- j
};
. f8 \- U9 G T F% ~ a' T& L, |0 H
struct Stack{/ a0 {% `% o* ~* h- N
SNode *top;
5 t- T7 _/ L! S/ a$ b SNode *base;9 P0 M$ C0 g {. N5 N+ C: s
int size;5 H2 {0 K) J4 E' r6 o
};
" t9 I- T1 p7 t) B/ x. Q& f. w6 @) q* S$ O/ r
/*栈操作函数*/
6 D, E/ C- L% F( aint InitStack(Stack &S); /*创建栈*/
' s. }" q) J, }5 sint DestroyStack(Stack &S); /*销毁栈*/' o6 D9 m0 e5 t- }3 f. v( y
int ClearStack(Stack &S); /*清空栈*/
' L$ |) V# [( i2 [& S5 }: e; b- V7 nint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
1 ?, H6 i* V3 F kint Push(Stack &S,SNode e); /*将结点e压入栈*/
4 H3 @; O; c; Tint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
7 |0 A( B& K5 s" c4 X, b, o
5 Q* g' m$ T* G c+ {& y7 G" y6 t, `/*表达式计算器相关函数*/1 I* u3 ^7 z/ |1 R, x
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
6 Z" z# Z# j0 U' B$ Z* aint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
0 W* ]1 |# p- B+ Y. [- {float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/1 P; V4 R9 T& e5 J5 p/ M6 F5 ^
float compute(); /*表达式结算器主函数*/
" ?- V- c& U, I9 mchar *killzero(float result); /*去掉结果后面的0*/ . D4 I/ J# A; u, c. ?& Y
6 i1 p) Y! U. iint InitStack(Stack &S)
$ b# ^# N' M) C5 h{
6 Z( B. u0 ]2 A8 t7 ?8 K8 U S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
7 j7 l) V+ _4 {( v if(S.base==NULL)
7 g7 ?' z8 f* C# t {+ B- L9 G& t. a5 ^: `
printf("动态分配内存失败!");
1 o& E5 K! X3 C: N N return -1;
8 J2 r7 m( x, L* k( p }0 ?! X9 j" ?) _& _# b2 J& L
S.top=S.base;) V" ?6 J3 [) P
S.size=STACK_SIZE;
. u, B& \- U% u# a$ e0 B return 0;$ m4 F4 w7 O( T- d8 i
}
: ]: L% i) ?2 }7 y2 v8 q
. j1 @. w- T: z' [8 k, U, \5 c$ rint DestroyStack(Stack &S)8 V H1 K4 `) \# G
{
8 w6 [' m5 S! P7 B, u; b free(S.base);+ k8 \$ z/ n; H
return 0;
: O( ~8 o! S9 u6 b2 i# N. |}
; F7 j, C( N. g* D8 [2 f
9 @. Y" X3 I0 O% Jint ClearStack(Stack &S)% c+ h7 `* g( ?' n' v% C3 q
{4 p; q' ]. d2 F3 }6 [6 `& n+ N" @
S.top=S.base;" _2 Y: c$ [. K0 L' B, P2 Q
return 0;
* C7 X* E& V* Q! e/ H1 c}
: V- s" F( a( W0 \) ]9 K0 d) F" S1 r) ?8 j0 P
int GetTop(Stack S,SNode &e): p& y- g7 G2 q) Y' @! n* C: v
{
( G8 f& Q3 X" M if(S.top==S.base)( j( L o5 A7 {+ w1 N
{
& c" r u) r3 M- R printf("栈以为空!");1 }0 q5 S. o _
return -1;
# M9 A2 ^3 V% N1 z% c* k }9 u4 |+ f9 J0 C. R9 P4 k
e=*(S.top-1); |4 i/ o S4 b* F
return 0;2 p' j' i n) p5 w# Y- i$ s
}! a- z% k: h/ L6 q$ `
$ U1 O. f2 R) _) x
int Push(Stack &S,SNode e)
" G7 m, [" y$ P2 U0 [{* c& K/ v5 S; l# A' b4 ^6 d. {
if(S.top-S.base>=S.size): O% a3 E0 w* c* c
{" q4 p4 ]% D/ H& @$ h
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
- P ]# S S& _3 |$ r- M if(S.base==NULL)
b. \/ u1 w. j% H- a; ? s+ W {
% T& M! o8 ]* E6 i printf("动态分配内存失败!");( B, o6 b- ~/ P! c
return -1;; \ K* D) C9 N2 m
}
) B6 V, u( z0 q+ W: T5 T$ b S.top=S.base+S.size;
8 S( {# w ]+ T S.size+=APPEND_SIZE;% h7 u+ Q* e' X2 ] l
}
, e6 I2 f3 D% W% J ]1 g *S.top=e;
+ o( { `9 B5 }9 R" c S.top++;
2 K- v f/ q6 Q' P A D8 F return 0;
8 K) v0 C! ]6 o}: T: b) }( o9 z% Y9 n
( Q- n0 n2 l2 Z) bint Pop(Stack &S,SNode &e)
) E& L2 n9 w& T2 F/ @" @+ p- n{8 a, v6 v- T6 T4 h7 ~- _
if(S.top==S.base)3 ]8 W- G( k- q7 C/ j9 \- `! u) P
{# R8 ^+ C( i$ j. R( o" m
printf("栈为空!");
! ?4 }+ ?; d5 \+ z* A% D6 l$ p return -1; Y x1 {& ~4 Z z7 k
}! Z. h: F; h2 l' \: y% f
e=*(S.top-1);6 j! m/ I* N2 g' \' S
S.top--;
) N8 w" ]# P6 S% ] return 0;
( D% O' B+ N$ ]}
4 R2 z3 ]# @- t: k! t# A2 N& J# l' _, f" F4 P
char get_precede(char s,char c)
$ S3 f1 \* t) L# U2 {9 Q t1 j{1 }3 i9 s4 T6 D0 U
switch(s)
8 J6 v b( v/ t/ x& z {. C7 d& o* O, ^5 Y& x0 o. U
case '+': % B6 p* I( J. o; E
case '-':9 A! i# A4 u0 K- K) j" L8 t
if(c=='+'||c=='-')
. n# W8 ?- M3 S& X% L0 }/ c% x+ w return '>';
* X( W0 ] V! N+ a- T* F" L else if(c=='*'||c=='/'), R9 I% f# Y: @ Q! S& y
return '<';
( \: U2 T5 @4 }6 ?6 G else if(c=='(')
7 h) n. o5 j) X3 ^# V# m" Q return '<';
, }( G# T4 J. E else if(c==')')$ h3 ^ V$ _. x; `
return '>';) g% r& p6 W0 {- v& m* j
else
W. K/ k: s: r. {; i return '>'; j& Q) D0 P8 }1 x" g8 t3 F, Q
case '*':
: D4 h- t. j2 i9 I case '/':
' i) X# O( \5 J/ I( E; { if(c=='+'||c=='-')
( ]1 ^. ?0 j3 w n) |8 @3 x: s: L return '>';
8 N. L8 [/ s6 `6 S1 ^% ~' K else if(c=='*'||c=='/')) _8 C% j4 h3 g4 n) K) V9 v
return '>';
, T9 d* O/ f* S O) ]4 R else if(c=='(')
) K- Z3 S! ~* c- I7 [% C' | R return '<';
4 u/ Y. i# j* o, b9 o) K5 Y9 b4 h else if(c==')')& u! K" q0 x8 M$ {! E5 f1 K- L q
return '>';7 l# W% ]6 Y* b6 K. Y' A
else1 p/ ]) {, {; F( B& G) y, z
return '>';) j9 T" B6 d2 S C" y
case '(':- c7 W) s/ I; R! U. Q* B: F% i U+ n
if(c=='+'||c=='-')/ x2 M. w8 g- e1 m$ b4 d( x' u
return '<';
1 g/ U% r+ s' ?4 z else if(c=='*'||c=='/')" @2 u: v2 u% H0 U
return '<';! k- r3 }; w! z. s- Q T% |
else if(c=='(')$ }* w* Y$ Q8 L; b2 ]
return '<';
* h) g; d( G3 Q& Q* H else if(c==')')9 o0 ~4 V% p7 K
return '=';' B' S) p9 x t3 w
else" u* G! z0 q1 R ^$ U& G* k
return 'E';- h6 s" q; \) Y8 N
case ')':! `' h; j6 S3 I: q7 Z
if(c=='+'||c=='-')
) [; y2 `2 j1 M+ W+ ]# [* e return '>';, ~# s+ {: E' j! z, i7 G
else if(c=='*'||c=='/')4 b6 v3 J& B) _. v& D
return '>';
$ M# B3 z$ t* n! t else if(c=='(')
. ?/ p+ N: N8 o; \ return 'E';0 B4 z% x- p. X5 Y$ e. V
else if(c==')')
6 U; N5 `' B/ g' ?8 J return '>';6 M% s9 E6 o- o" o4 a8 _% {- I
else1 Q' |9 U8 ] f. w4 J# i
return '>';
$ O, G0 B' z& b case '#':' Y$ D. F: G4 L
if(c=='+'||c=='-')4 H7 P6 w! A# _
return '<';) [2 L) A5 t# Q& R
else if(c=='*'||c=='/')
, ~1 z. N, ?6 G3 E return '<';3 e# T$ O. z( \3 n4 y
else if(c=='(')
2 ]8 @8 g0 ~: u/ R8 q7 }; C return '<';
# a" C2 Z" x- { else if(c==')')
( I* \3 f: _ m1 c" `9 P return 'E';
. l' B3 X6 v8 k3 O1 S% b; A$ v- k( Z else
' H" l. @0 B. X8 a8 { return '=';5 S# o0 |. b1 E0 V% }& b) z; e
default:; f( y( N W0 v: A& m. K% Q
break;) u$ o$ ?( x+ F$ E7 H" W& Z
}* [1 J2 z: U9 D5 }; ~) x. A
return 0;
1 Y# U- s& v- P! h}- B; [; x2 S5 G! c6 Z
2 T: ~& v1 R4 ]- }8 f1 Lint isOpr(char c)6 {$ K/ @- }$ R3 w- w% y( |+ r
{& y Y3 g+ g. q. {
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 O; n6 R- H$ Z$ }! g4 X2 z" p4 {. @/ E v return 0;
% j! c6 i% i/ H) o, j& p8 \, k else
5 Z, T: j5 ? ^3 V" q1 w4 B" k return 1;
$ Q5 D! @, V- T! |' D0 O}2 B; [6 B" d- V! s% A( ]$ n) V
( w1 }+ u. b. n9 \
float operate(float x, char opr, float y)
7 C& U9 o* B. i/ e{/ p5 x: ~7 k8 t) r
float result;9 V0 H& C; o7 G8 A4 f( ~
switch (opr)9 \3 }& q3 e0 n4 _
{+ _9 q& n3 m' x) \. A, p, c0 `
case '+': / [; B5 i7 t$ _4 ?2 ?2 @+ O _6 R
result = x + y;7 n0 ^! d0 z5 I! T. E" w
break;, _; c% E, u7 c
case '-':
* [8 R# e9 j+ X" d result = x - y;
! b& C$ v2 l$ r2 u break;
. k. s! E# ~2 M; ] case '*': 5 U/ g7 {& Q9 l1 B
result = x * y;
2 j" G) A3 N+ V) C break;6 R7 m0 I& Y- o8 \" l! n- p* C
case '/':
: r" V# M* { x' e# ^0 B% `! @ if (y == 0)" ?$ u |2 n3 N* h; n
{
1 a+ Y1 @9 ^9 D printf("Divided by zero!\n");( J# y* s1 F5 l
return 0;
( {. |6 S$ t8 N0 r0 ^ }4 r# d' m- V- y$ D z
else5 b# F# l( |! Q- i3 Y; H
{6 L- F/ O7 h: {% q) [3 V# |
result = x / y;" Z5 O: L0 }2 K P# C" T2 Q
break;: ~7 @6 t: k" U. n- a
}
9 p+ K# g0 ]* m( o1 s7 p default: g0 J5 N# t+ D8 @) B
printf("Bad Input.\n"); % @$ M% Y; _8 |. |9 ^! K$ {
return 0;5 d! D& W4 y# X& X9 [1 A# z
}4 R! i3 c- L$ H
return result;
+ L+ }% s+ N4 Y- P8 R) E* b/ }) f}
^" w0 f2 e! E# v5 Y, E0 g6 S* R0 W4 U5 c! |( v% [
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
; T/ y$ ]" W% z3 C: I1 q6 Z{: a* ? \ {, u. m% w1 t* M, T. I9 A
Stack optr,opnd;7 d& d" k/ K% b0 ?
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
6 k; {( F6 V+ C" t, w) S7 c char c;0 r- {: h, y m1 k8 T
char buf[16];
( p9 d7 [5 ^$ \7 i int i=0;
' ]1 N, [6 M2 [7 f
* c, d6 f9 ]: R3 T- ~) I% Z InitStack(optr); /*用于寄存运算符*/# O1 P+ J- b, Y. _; q1 E
InitStack(opnd); /*用于寄存操作数和计算结果*/
& h/ D& Z4 ^2 F4 |+ t' ]0 q- \, C memset(buf,0,sizeof(buf));' U! L# C% t- W/ P) S/ z
9 E6 @8 u- ?: w' ]: N& n) a, W/ ?
printf("Enter your expression:");% ^7 r' g7 G" F! k3 ~' A, k5 B4 O4 W
3 _/ |7 y: T( ~5 `4 B; @8 j' e) [, n opr_in.ch='#';
0 h4 W2 f0 p- @ Push(optr,opr_in); /*'#'入栈*/
4 Q' E8 T7 N1 ?6 ~1 e1 g, ^" G GetTop(optr,opr_top);
6 f1 Y; t4 D) U# |8 a. Z) a c=getchar();: i. M( r5 O3 h# b
while(c!='='||opr_top.ch!='#')
9 J: b8 |8 p4 s/ i i s {0 d6 T# ~1 o0 R" |' i
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ M4 X( J! s; t: t6 L9 \0 U
{4 o( }( ?/ y. t) O7 S2 G
buf=c;
! | Y5 j' f; p# I+ q8 R6 w# H i++;1 k$ W1 g! V$ u
c=getchar();- n1 s9 h6 [2 i+ I+ P
}; h9 m; b& \2 g8 D( ^$ q8 |
else /*是运算符*/& y/ ^9 i# `1 k; `
{7 }/ i" ?' G- g% |0 o: W
buf='\0';
, v# w6 _+ I( Y( H if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
/ D$ R& D+ A! f, J {
- {% Y! D1 n: B opn_in.data=(float)atof(buf);+ Q# s+ v( Z7 V: q4 w
Push(opnd,opn_in);
6 @" Y2 z k/ m! M+ p printf("opnd入栈:[%f]\n",opn_in.data);( C9 [- m, S3 R B3 y& `8 M9 y
i=0;& O6 q$ K" }1 z$ f/ G
memset(buf,0,sizeof(buf));4 \4 {1 a# u; }8 w; M3 Y
}4 c3 M& S( D8 d/ a' n: ^+ j* X& v
opr_in.ch=c;
6 T$ Z" _( s. x" l+ X switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/9 m+ q+ B7 S4 n. x
{6 R8 ^. O$ i; l6 t6 B" y [/ p: J0 m
case '<': /*优先级小于栈顶结点,则运算符入栈*/' ], }; j# M. @
Push(optr,opr_in);" I; W- v1 S* o" o0 z
printf("optr入栈:[%c]\n",opr_in.ch);
/ l$ p+ j+ E1 s& F# y c=getchar();0 X& g; \' V4 N+ [5 O; c. F
break;
2 c1 Z1 h1 ]' ~1 ^ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/' `# }$ c, \5 I' V
Pop(optr,e);% V# U/ O: J2 q$ W8 }& Y
printf("optr出栈:去掉括号\n");* _" \$ N- ]* U0 L
c=getchar();
+ b2 R/ r8 i7 h( G: J break;# Q) F3 A$ i) O, v7 g. U
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/' z, N @4 S5 d/ a! U: _: Z
Pop(optr,opr_t);
2 a1 @. S. @( F. p* X printf("optr出栈:[%c]\n",opr_t.ch);
- \: C8 P3 c8 s4 k* ~0 P* g/ g: \ if(Pop(opnd,b)<0)* ~) \% M2 f* e" w# y0 O3 c
{
' h' J0 `) ^$ u- e, | printf("Bad Input!\n");+ A X: q8 }6 y' ~$ o
fflush(stdin);/ J$ q9 E* A0 z$ c- X( A
return -1;
5 U+ `. A6 x# L3 E$ w* Z$ ]2 Q }% q# R: X2 A1 L1 a
printf("opnd出栈:[%f]\n",b.data);
7 L8 o* J" D( p+ j$ i if(Pop(opnd,a)<0)" b8 P% B2 Q$ e& F0 P7 z
{6 F% Q2 v5 r+ F9 x
printf("Bad Input!\n");7 `: q& W f7 {! k$ y$ v
fflush(stdin);% }: d' s4 \2 l9 S
return -1;
$ s: V5 g7 l# t3 A; p }
# s- ~* p) r. U printf("opnd出栈:[%f]\n",a.data);5 X# b, Y% [+ H- Q) H8 `
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
- Z2 u9 P- v( T8 W Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
6 X3 ~/ N, H' c$ _8 A9 @9 ]: d9 i printf("结果入栈:[%f]\n",opn_tmp.data);& _1 H% N. u6 T0 @& c! C" O
break;
2 I( o8 t' N7 [8 N }
: w" Y) T1 _9 Q7 L }
$ e5 B- Q0 N0 A8 n: `2 t9 e GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
% y. F! m9 A9 J' A1 V/ x" g' e }
^" v! X, M- W! m GetTop(opnd,opn_tmp);
, V+ |- R' u0 Y, k* J DestroyStack(optr);' k6 \9 \7 n8 p
DestroyStack(opnd);
% m% p9 `; h, V* a, `0 ~2 F return opn_tmp.data;
4 G0 S7 X6 b% R, M. B# p e8 `! h}7 `; r% b1 G! [& J0 R( z
% K1 W- u9 a; B1 `2 `& gchar *killzero(char *res,float result)
" F5 n4 x: P! S- [" V# m5 l{
4 S7 |+ c2 v- q- C* Y4 I2 d int i;
3 l* S- j p0 _' ? m L' g! T1 U9 o g: u3 v2 z5 }8 O
sprintf(res,"%f",result);
. v8 i. S! _' p i=(int)strlen(res)-1;
# @4 k8 N, @5 L' f) }% o5 J while(i&&res=='0')& A. ^8 x( a' I1 ^* I
{- l" e/ J- f. W/ t1 r1 Q X$ B; S
res='\0';
1 \; E. }& l3 Q$ a i--;
1 q4 S: H w+ }$ {" O5 Q }, [9 g; x" i$ T
if(res=='.')
/ L1 I6 H' h% o! [: W' O; o8 Z res='\0';
8 f' r! j, \! K, W2 m) @2 Q return res;
6 |$ ^' x. Q% ?}
' M# `, A- a, o# {+ i4 f0 x% l1 A5 ]/ }" W r& g2 U
int main()7 b# ]" L+ j% }4 q
{
% w; N1 ?+ N( E! c0 E4 p char ch;
0 s2 M# f+ G2 O; w char res[64];' I4 @. y! J/ H* Z
float result;
R. |: b0 Y( @8 r9 m while(1), @, @- q9 t8 @! z
{
$ u! X0 f2 {" m; `- J* m result=compute();. ]3 o$ Y3 t/ j3 [, Z6 r
printf("\nThe result is:%s\n",killzero(res,result));
( |: n# m5 Q6 c9 p- y, l printf("Do you want to continue(y/n)?:") ;
. a v: i. z1 G2 R7 x- W9 ` ch=getch();
+ D) A6 ~: |8 o' ?% U putchar(ch);
" W1 V4 C% X/ q1 A8 H if(ch=='n'||ch=='N')
8 T( v# v- R5 J4 S6 A% ^& O1 x break;
- q1 @5 I" \& [ else5 t2 D+ J, h4 ?0 d1 B* i5 c# v
system("cls");; Z# m1 W* |0 O
}- L) w6 v* V+ A, F7 G3 y
return 0;
. d1 L( g+ K+ l; w" ~}: N0 q5 j+ g# Q: u5 B" {
: Y+ q- V6 i$ d- i2 c( K[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|