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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.2 F+ c. e( M4 |1 h# J7 v+ y
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
3 f% ]% K9 Z# ]4 Y! l& s) B- m/**************表达式计算器************/
, `6 E, M q( q: r& ^9 \#include <stdio.h>0 {% V X; D3 Q1 n/ O
#include <stdlib.h>; |8 E) `) t8 W ?
#include <string.h>" P/ R* N- \5 q
#include <conio.h>7 D- x# T7 j6 A" ? n% `$ r5 N
#include <malloc.h>% p# O5 A. k9 P3 |+ ?
0 G' Z+ v. D" J% L) ?#define STACK_SIZE 100/ [8 d. Y* D5 D1 o
#define APPEND_SIZE 10
$ g! o& U) d7 p
( t0 O5 ?/ y$ ?& k1 Wstruct SNode{
, g1 g1 s8 O: r" `3 Z float data; /*存放操作数或者计算结果*/5 Y/ j$ a7 b, z# v
char ch; /*存放运算符*/# G! \8 h8 C9 j/ g
};
K4 E; @. f n2 x8 v! V; A
6 m( E5 V) V1 t& d* ^struct Stack{7 B- O5 o; `2 }9 ^) l6 ]8 A0 B% t
SNode *top;3 A' `6 \1 o" p: P! h+ t$ e
SNode *base;, F& u ?, c, U, V) f# q! I
int size; C0 K( v# n$ t5 y: o
};
* k8 X7 q. i! s' c) }% B K. {# u* G. q5 s% k- g$ _' a
/*栈操作函数*/
. c& k4 n) c/ J, X" k7 c. B9 s( uint InitStack(Stack &S); /*创建栈*/
1 ^- s4 m# @, L) d- K7 vint DestroyStack(Stack &S); /*销毁栈*/
' u1 p1 S1 J0 F. X% Rint ClearStack(Stack &S); /*清空栈*/
& ]# x$ @! R' h" C: x6 uint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/, R2 V$ `$ p" H
int Push(Stack &S,SNode e); /*将结点e压入栈*/- {$ R1 r8 S0 j9 W" j$ F4 L v
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
) l+ {: ^1 }" s/ N
9 C V# ?# t& }' V) e0 ?$ @/*表达式计算器相关函数*/1 m a; Z2 {5 y" |( b
char get_precede(char s,char c); /*判断运算符s和c的优先级*/' L& S% y: s! i3 f E/ Y/ @; d
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/, Q, g$ p: f; d* u6 u
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/. P) N. x& H8 U
float compute(); /*表达式结算器主函数*/
' T) t/ u7 d( C Xchar *killzero(float result); /*去掉结果后面的0*/
4 ]5 Z& N/ G8 {( [8 [+ E! P
7 p, G* H f0 l1 K6 Y. Gint InitStack(Stack &S)
7 g" J& P# r3 ?/ c/ c8 |3 _{7 U/ C7 E h1 a" g: r& b" x
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));) x3 q4 f- h# f$ y. i- a) U7 b/ o% p
if(S.base==NULL)* u! w4 J0 |0 R0 g9 C
{
8 T9 C; T5 y7 l9 r. E- B' D# b printf("动态分配内存失败!");
$ f, I! i" k# e' H: w return -1;
" b. o k3 L" S* G0 A, w; b }
6 f( g' M' k. l* {: v$ E S.top=S.base;
) `5 T0 v2 q# f6 A, H S.size=STACK_SIZE;7 a& K" ^ b' i
return 0;
+ S- `) R2 Z; d+ s}8 F; O7 m/ b1 x6 ^3 ?1 R+ v
7 j8 \/ U3 w, }4 i/ s; Eint DestroyStack(Stack &S)* H* [/ k1 a: W9 l6 x
{
/ f% X. }$ h3 Y$ } free(S.base);( s) v* v- x/ i( Y6 [) V
return 0;: @ X* E. i' v- H
}
! p* ^9 }3 w( a' _7 b' p
7 R5 h( y4 c( lint ClearStack(Stack &S)
5 ]& G$ Y4 e- ]8 E. l{
6 V) S& t% s0 G# ]4 C+ [3 W/ A/ L O, E S.top=S.base;! w7 @9 b# M+ i$ L0 w* l
return 0;
1 M1 b, ?0 j4 B7 R( w2 W}+ t' r; q& y/ ~, p1 \* c: t
% j; h5 G$ m. M# xint GetTop(Stack S,SNode &e)
) Y8 ]: @; ~5 [4 N* t+ u. E{" [% n. `7 D) p5 c+ o
if(S.top==S.base)6 T2 F9 _. E$ \* z
{' s0 D/ P, l8 T' b3 x- \! |
printf("栈以为空!");
4 A3 @8 k* g% P) V t9 g return -1;& s3 v* ^! n, }+ B/ ]& Y
}
4 L* [( Q0 F2 p" ?: T3 h e=*(S.top-1);$ o2 b- c2 O+ T6 v4 R4 a
return 0;" ^( D7 i: A- U
}/ l% g# U! ?" W/ }
3 b1 X# z% N1 Q& _9 w& O0 Rint Push(Stack &S,SNode e)' O9 Q3 S& t3 { Z4 ]0 g
{2 v$ k0 i5 n5 p
if(S.top-S.base>=S.size)1 V% \4 \9 t8 [
{# j& Z( x+ y# A# b0 ~
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));8 ^& g! Y# m3 A- B4 v9 j5 A$ i" d- [3 G
if(S.base==NULL)! T# L5 N$ b# k9 U
{
* D! E) }- V" u; R printf("动态分配内存失败!");* I3 c: `3 \3 {0 X
return -1;
6 W: A* t& d& J4 I. ~9 e$ L5 { }
$ k( c |3 k x" W( X S.top=S.base+S.size; l E" q5 a+ k
S.size+=APPEND_SIZE;6 e1 |. D; E6 f8 I" T6 W
}
) S, a$ Y+ ?' t *S.top=e;0 G) P3 a8 u/ x2 d2 |3 E0 J
S.top++;9 ]7 ^4 L# W0 ]: ?5 G3 H
return 0;( L, a" K E/ n+ H0 @3 N
}
0 b; c9 O* Q/ F6 \* V6 p$ L4 Y3 J" E3 S2 D; |4 A9 w' _
int Pop(Stack &S,SNode &e)
- ]% c, u) |/ x% N# ?" |{
( g7 z2 f2 G4 T; l9 p8 x; g if(S.top==S.base)! Z; ?) E h4 v
{
' c7 f- E, g7 d: s2 |) l printf("栈为空!");6 ?' k( Z. i0 |8 g3 o
return -1;
0 A4 q' m' Y9 h" |. e }
, S0 |) S9 ~6 b$ @+ t4 p6 L e=*(S.top-1);) M8 m6 I1 P# [
S.top--;. B- P2 a+ \( i9 q+ {. @' u; n6 ]3 V
return 0;
/ i& r8 b" f$ e% ?}, ~4 n% d+ x, n+ G( v: V
( r- L: `7 X! G% E& F, [char get_precede(char s,char c)
1 R S/ K8 Q! R1 s" P+ u{
% e. ^. `) {; c0 z switch(s)
' o# ^6 M% m+ } {
# j# d* f' T j3 r' d5 C case '+':
7 S1 c+ y; E) m4 V1 H. W# R; G case '-':5 o- P( y: h8 \' |- T2 H
if(c=='+'||c=='-')
; a$ D0 K3 m# T& b/ k# m return '>';
! O8 R3 P& X2 Y% `$ ]2 Q else if(c=='*'||c=='/')
; M0 I1 S4 k/ P, N return '<';
: ?" x- G) e4 u& b else if(c=='(')6 w- x* X- {6 Z( U" H+ X: O6 s: q' V8 e
return '<';
! {% Y3 m* _# A/ O else if(c==')')
2 ]3 ^/ X6 C: z" |. U- _; } return '>';
) Q U4 F0 a9 P( C& ^ else h) b! h- ~6 u8 ]7 B( D( H8 p6 F
return '>';
( z! `/ s; d- g case '*':2 w" i) ^$ A, P# ~& M. _
case '/':
% Y9 C, Z% m3 H. T if(c=='+'||c=='-')
) {) T. m4 j* m) c( |6 V# Q+ d3 X return '>';- B `1 c; w% y% B/ O: C" j# M# |1 G$ X
else if(c=='*'||c=='/')6 {& q6 Q8 }8 K7 j- S+ D2 U, Y7 u
return '>';
- j1 K! J! u/ N( Z" q' g9 U else if(c=='(')) q0 M. v, K5 N) r5 y- F. c
return '<';
$ b; S% O3 [& D: |6 Y else if(c==')')
' C8 w: D* m/ T4 G7 Q7 n1 | return '>';
z2 M0 T2 ]. u( Y" t. z' W- h else
6 ~& }( A; l! s4 d$ i% N; Q" A return '>';
4 I2 P5 C2 e4 V" w1 y: o& h case '(':
2 l/ r6 Y2 E' S! H+ a if(c=='+'||c=='-')3 b; y9 [0 M0 |
return '<';
# D* l a, k P2 t else if(c=='*'||c=='/')
) w' O4 x* I5 A A/ k/ o" T( c3 _9 y return '<';
* B2 I2 ?3 P0 f2 B; S) T' b else if(c=='(')
c6 o1 p" R2 Q0 P/ x8 V! x6 i return '<';
* a k! }, ]3 ?' _8 t% R E7 d else if(c==')')9 v! Q1 Z- M7 O, s" Y+ u. L+ ]
return '=';1 F0 _; w& W/ {9 d8 H
else
: F% k) ?# G/ Z2 U+ N( m0 n return 'E';
' _0 ~. f1 l+ t( I case ')':
O" ~& ` k1 ~5 R if(c=='+'||c=='-')
1 j- r* x! z' u9 P8 v return '>';. ~5 P! p. k$ {( p5 z
else if(c=='*'||c=='/')
7 S; ^" w: G5 l T9 @" { return '>';
! h0 }5 Z$ d1 j. k4 s! z else if(c=='(')' Y0 ^; B: _9 H; M U
return 'E';& m& [3 b, b3 _0 a$ f5 M
else if(c==')'), {- J1 @9 i* S
return '>';
0 p1 h' p5 A- R& ] else9 }( w* J; W5 ^0 i( \
return '>';
e3 Z( j y) o. Z7 X& f case '#':/ F1 j' {! F: s' Z( r
if(c=='+'||c=='-')9 f% F" `" }9 I5 q
return '<';% y4 Z2 g2 G: d& r% W9 W7 Z
else if(c=='*'||c=='/')* C6 j- t5 ~+ N7 Q6 D& e/ S
return '<';5 X& D# }# ]& `
else if(c=='(')
3 u* S3 X1 B! e% N4 { return '<';- d3 s7 w* p9 a8 H' T: g# b
else if(c==')')" @- H& l7 ~& B6 f
return 'E';
: Y* s; R* H8 C5 ~ T( D9 z else
& r9 ]2 `4 p3 {# { return '=';
4 b" N* }- J* N( }+ ]% n; S( L default:
) |0 h) Y3 K) L3 R0 G break;" f! V) U! I* K+ V7 g2 w6 I
}4 u: r% c8 H- n- Q; L: g
return 0;
/ r0 K* ^+ U% @+ ~& J' ?}) n8 D1 W4 \- n6 ^3 ^
5 n* z' ]4 l9 s6 x
int isOpr(char c)
/ E0 N" w3 l: z{7 h3 |0 S5 Y8 z) D. x4 Y- y3 e6 K5 }
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
' E& }4 h- f8 d$ K: R- u |% A return 0;* p4 F/ F- `5 f5 ` J2 U
else - J8 e0 r Z: ?) I* B! I3 ^
return 1;2 C5 g6 a9 A, g; b
}3 q5 A. l2 C' i$ s
- x5 y9 F: S& V- K" wfloat operate(float x, char opr, float y)
: h, S T7 Z# \! c- {% j{
/ P- k, C8 }, }, u- y* d6 p- e9 u. j2 j float result;
% Q) V* C% _& D6 I switch (opr)
5 M' ?# y1 T* \ a6 ~9 z; m6 W {. L# j* A# n, K( `& H
case '+':
- d, t d+ X+ t; D; Y z result = x + y;" c) H3 `7 R- I4 x% i) s. g
break;
; N' e6 `4 Q$ w: J' O case '-':
$ q: z' x, Y+ O( A3 I9 o+ K+ W result = x - y;- Z: y' J* q3 o
break;( Q, ]7 e. N$ j( b+ R% [
case '*': 1 q1 w( t u( ~) ?+ g3 w/ D' I
result = x * y;
0 }# {. H' |6 j break;0 _9 o# B% \- M
case '/':
% \) |1 f* P- R0 N% c: q: W. X1 i3 t if (y == 0)
2 T( A( K& Q, l' k# g {
5 ^6 v/ ~! w0 N9 J& ~' ]7 r# D printf("Divided by zero!\n");
; W9 C2 A, H4 D. m return 0;
$ E5 A+ C( T5 M }: Z1 N5 ^+ |8 Q) o/ S" w% | s' {9 R
else
# N I7 H% o3 w) j Q {
( i x2 G, Y/ f result = x / y;6 ?2 v" g( V f/ V+ P
break;3 \- E8 Y' r, N% j1 x
}, |; H$ o: j! F8 o0 T
default: / i d; V' o2 s% `: ^ A3 h
printf("Bad Input.\n"); " X( `% p8 T$ N. \, |
return 0;
8 t) k# ]: R: G$ L+ ^( g }
3 W. `0 h- u/ j) P0 ]) E return result;
/ c% F6 J& @( p$ I}
8 w' U; A; p6 m* d3 L- M+ p9 v5 t% s% h
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/5 w* G9 i) u+ c+ k; {9 d9 v! G' l
{
# Y& `5 b0 p: G3 d Stack optr,opnd;0 P m3 C4 s( J2 N4 H8 ~
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
9 ]' z5 t' v; D char c;5 \3 _0 W7 J& d3 v! m& H
char buf[16];$ [2 I$ b4 ]' |6 H! ?
int i=0;: D% |1 n% Q) r
7 D2 j9 O$ c6 e! f. Y InitStack(optr); /*用于寄存运算符*/
7 L, k) l! U. B* ~ InitStack(opnd); /*用于寄存操作数和计算结果*/
% N4 q& p! J: [- C9 {. W/ c memset(buf,0,sizeof(buf));0 L. E8 W& l4 ?: ^! S* @
: L* H6 @+ K; [& ?, R' J printf("Enter your expression:");
3 c$ N4 k2 d5 d: u" }: q" G" i) U
; s- n3 a9 K/ w opr_in.ch='#';! U- k+ K, ^4 G/ l$ B5 j; [
Push(optr,opr_in); /*'#'入栈*/
7 Z) W- `* f" q' N3 ~3 R GetTop(optr,opr_top);3 z( F6 D, l( r* |" G6 m
c=getchar();
) j0 e3 Y# s3 d! j) S while(c!='='||opr_top.ch!='#')
$ _; k/ T8 x. ~: X7 m' _ {0 a. m" ~+ y1 ?- K
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
I k2 ]! b. o% o( M0 R {
7 T5 w9 L+ E6 a# x buf=c;# m8 G7 S& b: o- F w
i++;2 M, y: \# w8 j
c=getchar();3 a6 A% ~" [% }; j; y1 x
}
4 s( Y+ h: L! e- ~/ g" i else /*是运算符*/
& c! g) _4 w- z {& p! W5 Q: X. ~
buf='\0';
8 {0 ^3 \8 m3 o if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
; O% Z1 I' j3 j# ? u" `( F8 e/ D {
- V7 O6 v5 f: | opn_in.data=(float)atof(buf);
9 G4 M* N6 {. v5 \/ ~3 d Push(opnd,opn_in);
8 e9 E0 D' I* ~ printf("opnd入栈:[%f]\n",opn_in.data);
0 \9 v" `& O5 ?' _/ J3 J i=0;
* S" q3 g" _" u6 X c8 n3 _ memset(buf,0,sizeof(buf));8 a4 c& b7 e9 V! J& {" c3 x
}+ d$ M, b+ G' q0 V: Q, Z
opr_in.ch=c;. L) q w. C( }. }% u
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
: a0 Z. b' g! z m" ` {
( J G* m! _- C3 {6 o case '<': /*优先级小于栈顶结点,则运算符入栈*// m8 |; F3 `/ Y/ A
Push(optr,opr_in);- r4 o: \* s- z6 R* q4 e/ x
printf("optr入栈:[%c]\n",opr_in.ch);4 J2 k$ s4 W: }- Y: R
c=getchar();
9 G2 D# `, W- e& V2 u5 @3 C9 y break;, W! c' d( ] `( u" \; r" o j% B3 s1 @% J |
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
3 m% w; t8 o6 I6 }3 S+ O Pop(optr,e);
4 Q7 y5 n9 {' g. \/ Q9 s) `. b printf("optr出栈:去掉括号\n");4 t4 v1 Y# }3 I; ^) a1 U
c=getchar();2 n5 h4 }6 O$ \" N6 E1 ?
break;
7 a* g9 K# ~& ]1 x7 d: P5 @ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
! B, v, @' x1 z7 \2 C& c Pop(optr,opr_t);2 b6 t! u$ i' ]8 x+ o1 M
printf("optr出栈:[%c]\n",opr_t.ch);
# L+ x% X7 I9 {4 U, ~- N; B if(Pop(opnd,b)<0)
9 y1 Q4 q3 N; w: z {2 D4 e( Y7 u* A" n* f7 B
printf("Bad Input!\n");
; q3 f/ ?4 ]" {, P( e# M fflush(stdin);' |) q+ _: M' H) {$ p
return -1;( x8 ?! O0 E/ D9 S
}
+ c E; {! P8 T( z printf("opnd出栈:[%f]\n",b.data);2 w1 K v& t i; Z
if(Pop(opnd,a)<0)- q. n! L& L, A5 o9 k- W
{
* w# T( Z% Z$ V printf("Bad Input!\n");
8 C! ?: V2 T/ m- G- g: J9 n fflush(stdin); M8 ^+ D. z: g; d3 Y, r6 v* T7 X
return -1;, a( J: F6 r' k; R5 r
}
: v# x& X% h3 n8 m# S8 F2 z printf("opnd出栈:[%f]\n",a.data);
( b9 B* j4 }! E0 M opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
; Y; \$ D5 q$ a7 g+ a& S Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ f% b) D; _# k! v0 S& \4 ?
printf("结果入栈:[%f]\n",opn_tmp.data);
0 v( q2 O2 j* D' t" j break;1 b8 Q: s9 @/ x0 [0 ~
}0 c6 ?! L" x& j) W, E3 G: \8 s/ ?
}& b2 {7 \% c& K A7 W1 C+ C( `
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
3 Z) d! g" K; d- | }1 }+ _( M* G; C& W$ z
GetTop(opnd,opn_tmp);
0 z1 a* T; [5 [9 n6 Z+ \ DestroyStack(optr);9 @. n( g5 m9 P4 j2 s) g# l6 I
DestroyStack(opnd);7 Z# E/ I7 I" B+ I$ V k
return opn_tmp.data;6 [* f, C# p7 M- C
}
1 q! q5 @& N! x: z9 a1 _; s! w; z1 g- A! y$ }) ]8 ?3 ^
char *killzero(char *res,float result)! F' [1 u6 c# ] g- p& |' C
{
6 e- B" U7 f3 a# o. c int i;
4 f" L, D( ]/ u, d% r8 R6 D/ P
% ]2 ^$ m& b1 ]$ U$ h! P+ N sprintf(res,"%f",result);
- o0 n6 D& v, T+ L7 g+ S [/ j i=(int)strlen(res)-1;& [9 I- Z' d1 n4 B" q& g, q
while(i&&res=='0')6 e9 _: ^- C: ]5 h8 F
{
! S, l% Q, k, z( V res='\0';
& n; i7 Q S# |+ ~0 X I8 t i--;
5 l b/ ~& J' c/ ?2 D$ k }" A6 t9 F5 |' `) w
if(res=='.')- ?6 \2 ]2 G5 |9 P& S5 @3 f+ c& L
res='\0';
# a7 X, l8 K0 \. i/ f. Q return res;
/ w/ x' G( v+ `% `}7 }9 {. B8 s$ p4 F# w& r% \
$ @1 @( {) J9 X/ b" W9 Y
int main()1 T( @* _; O" I& l
{% v6 x; c3 U2 D( }& Q5 w. R$ @
char ch;
! W9 _; g) V+ v char res[64];) }+ W) V4 x T7 \" e
float result;9 c t5 w9 R$ P$ m f' |" [8 A, v
while(1)) c& B' O4 p) F8 o" K! J
{
6 s4 F" m2 }0 k result=compute();0 P8 b. W9 a, l7 i5 b5 t/ f
printf("\nThe result is:%s\n",killzero(res,result));
' k: }. c f- N% W: r printf("Do you want to continue(y/n)?:") ;: j: R, a; B" M) l& E3 i2 J: S5 U
ch=getch();
( x T2 M- j6 r( u" P6 }+ V putchar(ch);3 c) L# C6 t8 L$ e1 b$ N
if(ch=='n'||ch=='N')
' f& Z* O7 t3 Z9 p4 [ break;
! ?1 E8 g6 R1 \/ H3 o# U) N% B$ S else
- {$ U4 O; C- R: j$ r. `2 D+ K system("cls");
# c" D: ?7 p6 x6 S8 T1 B" J }
* E+ V& p: E- R6 e" j return 0;5 l2 ~/ H2 c, ? @, B7 _
}- a2 u6 ~2 u! C
; Q/ J8 D! {) U: e4 y \: l[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|