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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.- F: J" [" a) R$ O- v# A. e; }
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
. X, z' F0 u/ j' y7 p/**************表达式计算器************/! D- v0 k6 d4 o- `3 M7 s7 X
#include <stdio.h>
% i4 F; Z& @8 `4 {! P#include <stdlib.h>
+ u/ s5 i4 N$ }: f: y: f7 o#include <string.h>- ]3 ]' D3 }4 _& X0 q3 Y
#include <conio.h>$ \) u x' z; i: @
#include <malloc.h>; N5 X# f; u9 R% k* h% k. P
8 `' F* d% J8 P6 o#define STACK_SIZE 100' |2 O0 M4 A2 l! p' m
#define APPEND_SIZE 10
! {3 p T8 J) f. x* G% ~
: g* o% z- N8 f. |0 _struct SNode{
% G; p* x7 e) m3 \ float data; /*存放操作数或者计算结果*/" S6 F1 f, G4 x# E0 U9 p
char ch; /*存放运算符*/
3 c6 ~7 Z( K2 y};
1 Y' g% F% G/ t/ x7 i/ Q7 U" \2 H i# Z/ o6 ?( P9 w
struct Stack{
0 ^+ X2 i; L+ A SNode *top;5 A' G: h9 l, _& w$ [- D; L- B
SNode *base;
& J, C0 N4 A* X4 ~6 R; i" g0 M int size;, W: `& Q" @" }# `) e$ h: K
};
' w' g# Z0 f, K6 K: G. c# f7 f! M) K0 m
/*栈操作函数*/
" a6 |% c' j* M, R3 j& { Tint InitStack(Stack &S); /*创建栈*/9 q3 _ F! k1 U- P9 A
int DestroyStack(Stack &S); /*销毁栈*/# a3 w; v2 m s) S% P, `
int ClearStack(Stack &S); /*清空栈*/
3 C2 |) U2 F4 H! d% E! Aint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/" \. n' ^: e: `- U! m- n7 J
int Push(Stack &S,SNode e); /*将结点e压入栈*/
4 a' ^( G4 o, E9 A, p0 x6 Lint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ \8 @( {" K0 _. G7 C) ?/ v- a5 z4 v
/*表达式计算器相关函数*/# W0 [5 |/ k/ P0 X1 l1 N3 P8 h
char get_precede(char s,char c); /*判断运算符s和c的优先级*/5 X; j& s% I$ F: ~, a
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/# z' ?* f5 J: A' n, {
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
0 l5 n5 C" H4 x B" Rfloat compute(); /*表达式结算器主函数*/
. e d+ j( d7 e6 o; C5 O/ Cchar *killzero(float result); /*去掉结果后面的0*/ # ~0 N6 J$ f: l4 w" Y5 R
) p0 g% d; [, [$ {' v+ h. F
int InitStack(Stack &S); F: `! T, c" Z4 l4 q9 h- d
{, [4 X5 y3 P5 N3 L1 _% V* o
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+ m6 X- ~ H( @0 z) j if(S.base==NULL)
4 V* j; e+ g4 }. z4 ~! M {
m" P' r' u" @* F) D( P printf("动态分配内存失败!");* s: h! J7 S9 |; B. }4 Z2 E& G
return -1;. I6 D& T) h. G
}
6 S* n0 ^2 z9 v( q3 ^0 O* R S.top=S.base;3 l5 R) M3 S7 A: r# f
S.size=STACK_SIZE;) m \: v H' L* ]3 l
return 0;) G1 l2 j$ S: @! ?7 f8 p
}
7 K6 A. v* N, S% W$ \3 J
8 O! L; }/ w# M1 J' h {7 @int DestroyStack(Stack &S)1 T) ?" i* d y! W8 ]' d2 C
{
, K4 }" i2 x* ^! c7 r free(S.base);
! F6 F! S6 v. E8 U# [ return 0;
! M9 X' v* [( G' }/ p6 z) I}
D0 q2 T8 m P4 M) N% [6 h) O8 o9 a: p. V1 m; @% z* W M( [
int ClearStack(Stack &S)6 V5 X; l' i6 n; R( x
{0 s/ E0 S# b. @6 {
S.top=S.base;) H7 a+ o9 P/ e; k# Y
return 0;
x% U: h" f4 W( r8 b1 o; h7 R}6 P3 w; |) A" b2 C' s
9 ?# b8 g& }1 c# {7 l: g2 R
int GetTop(Stack S,SNode &e)
~& G. }8 p- N% L: o{
: S& g3 j4 M/ h/ M% `5 @" I7 e if(S.top==S.base)
X( `4 m. n; z. x7 G9 a; X {
; f. b% m- G: R0 r" R" a) T printf("栈以为空!");
! P9 w h6 J# J+ G return -1;
( Q$ A( f9 t9 b, Z7 L" U. c }
- D. ^; b- ~% J6 ^$ O; e$ s6 r e=*(S.top-1);- h8 {; `* _1 `& Q* M' ~9 r
return 0;
" q9 r' `0 e, A& Y}5 D) D) \, |0 F( ]: Z
: c! `9 m) y) ^int Push(Stack &S,SNode e)+ K' ^/ c4 u2 k4 O1 Q0 O, I
{0 z; B6 c$ [0 @' O2 |
if(S.top-S.base>=S.size)
, l9 P; Q5 w1 R/ _ {$ D0 P/ s t9 t' \5 W1 x# \
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));' z6 i3 K0 J* S; o7 \# i
if(S.base==NULL)3 T: R' U5 L# }; p2 S
{- s+ d- V; ]( ?! L) W
printf("动态分配内存失败!");0 k; \0 i8 X' ]* Y
return -1; u5 Y4 T ]! v4 q1 ?( ^
}. J3 q4 R0 T- e
S.top=S.base+S.size;1 z: ]9 P9 P# J/ o, C
S.size+=APPEND_SIZE;+ z! p4 B0 k$ R t' i1 t' Q
}
$ X1 t9 ~$ j) e, j *S.top=e;- L3 D0 _- m( K
S.top++;
7 J& E. E9 e1 c) ?9 Z return 0;* q4 ]/ `2 l' J6 F" u0 e
}
+ @* D# [" C' l* i4 U# _% M/ {9 v) V, H* w' L% N0 z
int Pop(Stack &S,SNode &e)4 A/ ~9 K& i7 I8 c% E3 f& H8 D' H
{
' b; ~3 p4 I( G& [ if(S.top==S.base). I# z: ^8 U/ C- E# I
{
( \! J4 R# X' O7 A" H4 D5 v u) M printf("栈为空!");* i4 m1 `5 S Y; }$ M. F$ }/ w v
return -1;
3 a3 k& C" K- _# O' c) M+ l }
& ]" k& n3 w3 c7 J5 {3 o( | e=*(S.top-1);
% Y$ P9 j# g# T; l S.top--;0 l8 Z, {' q. D% y( e$ O
return 0; Q' }& i4 y0 u$ ]6 G# K
}
# t2 K3 H% a5 i' T# v9 V6 Q E7 Q$ A6 W/ j
char get_precede(char s,char c)
9 _; E' N+ X9 D3 G5 ^4 h' K{
6 E5 l/ H9 }1 S5 D% h- f switch(s) H. n* L6 f' f! G& X6 z
{+ \: I. A+ F9 {& Y0 B1 }
case '+':
) {# L2 ~4 x' Z. q! l( [6 n& { case '-':
' i, A- J. b; ]; J% w# a if(c=='+'||c=='-')
! {0 U% k F0 Q6 I3 B return '>';% R3 \' j1 w' B ~0 _9 q
else if(c=='*'||c=='/')
: |6 x! }% l* v1 a return '<';
; X5 _% q I; ^' M- s/ b' U else if(c=='(')6 {! J$ ]+ g' T! C( E1 [
return '<';$ t' N$ n( Y8 q. n
else if(c==')')
Z( `: f. i4 O( R' l return '>';
9 ^; X P7 \9 L- F1 P else
' f0 P% H) b2 L3 t2 P, O2 ]9 d return '>';$ z7 f' J% u& v) \& t7 l/ T4 q
case '*':
`; u n3 z$ ` q+ z$ t9 M; ?; ^; h case '/':
( V3 E# p: K z$ D+ L$ s2 B+ z) S z if(c=='+'||c=='-')
4 j' A" |# Q! h. v; G/ ^ return '>';
( `/ o; N8 E! G) U: S! B5 h else if(c=='*'||c=='/')
( P7 a6 ?3 ]) X2 {$ _# j! A! ^- I return '>';) A" a m0 {' N4 ^- [& m: f8 x
else if(c=='('), \$ x [7 `. A6 }. p
return '<';) c: O' z2 O: A$ V4 a
else if(c==')')
4 G/ Z5 N5 M/ N# b" y return '>';
* V7 x) `' R1 K. W) c& z else2 S2 K# U# ?- D3 ?3 a7 ~! e
return '>';' a' U% B" M- [7 @0 C* F7 ~
case '(':3 o+ j5 v n: L) x
if(c=='+'||c=='-')7 X5 d6 z6 j! l- ^/ O4 V
return '<';
/ J% J; K8 G3 B0 V0 S else if(c=='*'||c=='/'). x6 l% K2 p6 r6 W# q8 r% [
return '<';
. ?5 R2 U: ]4 v5 P" v k* E6 u3 } else if(c=='(')0 X V9 G+ g$ k+ p5 z$ N
return '<'; t9 r, O& p9 s/ n1 T; `
else if(c==')')' Y J: l V" k; q. I1 u
return '=';
% p) E; [0 h, \/ A( T9 S5 t6 M$ R else" u" f4 e- ]4 E+ i; p1 x" Y4 o+ h
return 'E';
* H1 M7 g4 ]+ r1 M0 e case ')':
+ p: j( P( \0 Y$ E5 q" a7 d9 ^ if(c=='+'||c=='-')
6 w9 O) g, U3 Q return '>';
S& c1 T; @- I2 @# [ else if(c=='*'||c=='/')
6 m$ r3 n+ `: ^# J3 B return '>';0 e! p* Y9 f/ H* k+ s0 u; z+ s, E" k
else if(c=='(')
4 D# ?! s8 y0 D return 'E';
$ e Y% P0 @9 d4 o$ {3 a else if(c==')')
) J6 R2 r: r- T* e) U return '>'; `, K: [4 ]" h
else- e8 a8 c# G: H) z
return '>';) i) D9 e' i2 n# E) c1 a' A/ e
case '#':
: i! C' Q1 ]; \ if(c=='+'||c=='-')) @0 {. d; Z2 C$ z8 z
return '<';
" `/ I( n" k3 V7 Q else if(c=='*'||c=='/')+ [4 o$ s% U+ l% D% `
return '<';7 P G+ V% l# v7 T$ z
else if(c=='(')
: _+ L- k' f% S9 S return '<';0 @; F9 k( ]. y' c/ Y1 Y5 M5 H
else if(c==')')
( L1 }1 S: [) p% Y2 \ return 'E';& u/ r% ~% C1 P' w0 g, z
else" u7 E* @$ n3 ~ N7 V
return '=';
6 u ~9 Z9 D( c' d8 @* r default:1 R) b# Z% f( J5 O9 j
break;
/ {$ D: p7 g( o: H8 S! A8 n }$ P4 z/ @: z* ~* x z8 E/ |8 A
return 0;
9 Y5 T. b1 i5 _2 _/ n, a}
! K5 I, j& Y+ Z3 F0 y W& B; ]' C8 x" u8 Q e2 s
int isOpr(char c)5 ^/ {8 A3 R8 \& k7 g+ v' ^" f
{
& w7 e+ ^2 p- }& Q: } if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')1 }; V. G9 ~( |. L( H, E
return 0;
9 K! x: t; v, k/ v/ t else 8 T% j) b+ H1 x, Y" \
return 1;
6 X' l/ |2 \4 ]}+ y( ~0 o6 s1 f* o
1 t4 m1 X2 H' V$ Pfloat operate(float x, char opr, float y): p' H0 N7 _% e7 \ y; t
{7 \) |+ r p! Z6 r/ n
float result;0 X- l; v) k C) T/ A% b4 z
switch (opr)$ S# |9 D( n. q- Q
{- `. K! x9 E& m) w4 r( d
case '+': / B6 J$ Z# ]' y2 ?( S
result = x + y;2 U' Z* `" q5 `/ l% f9 C4 _) {
break;
9 u! F2 S. m+ s( f8 X7 k case '-':
/ G8 A9 M- \- H" t1 ~3 ?! D result = x - y;
$ x; ]' @) m4 u2 |/ @$ x break;' G |4 o/ B$ U7 F
case '*': " |9 h1 K5 X; Z2 v+ N
result = x * y;
4 F2 l/ X' C8 Q, C* y5 p( k' @; } break;7 N6 ?$ N2 l8 X" F3 L! b7 A
case '/':
0 E8 u( y" g$ g& o if (y == 0)
6 y4 T) \" A) f" J6 d& ^8 r {# {, G" `& i$ ]# Z. ^. b( m
printf("Divided by zero!\n");
4 f8 W# t1 x3 R9 y- {7 W8 L' B return 0;
# y7 v+ u# w* m& I }
( Q1 k0 I& R9 @ else4 v1 D) \9 V2 ~7 T9 A
{
2 `# b h! ~, I, ]. g: R. R; m result = x / y;
* {0 H* |: \- f2 E break;
4 E. T* H3 A" l: }1 L4 j, A1 G. d0 B }
0 f! T8 q) y% G6 ~2 s* O0 d" o default:
4 H' _" b6 `- Q4 |. o printf("Bad Input.\n");
: }/ ^6 R3 o# }4 C0 D return 0;2 _& o! W0 b# h4 m
}
3 A( ~6 b+ p/ f6 r return result;5 @. T7 z8 m6 E8 f
}
" c. d" | i4 S" t; J" I* E3 X. O' x% v2 y2 V7 P$ w, C
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/+ v7 \# Q7 N5 l5 z+ C l
{* n' x( s T2 H2 w
Stack optr,opnd;0 r4 v( w- l1 R ] i" a3 |, Q
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
' c; w* t/ A! J) a char c;: m! S7 _$ Z( h/ l* X" K
char buf[16];5 E( P- e( i9 ?) {
int i=0;9 ^* B5 x/ r: t: \- S8 M( x
, s( I3 e6 I1 m# I0 f( X
InitStack(optr); /*用于寄存运算符*/
: e5 i! U- t* D; W2 h) \0 c* \8 O7 D InitStack(opnd); /*用于寄存操作数和计算结果*/' l9 S( m' ?, [% O1 r
memset(buf,0,sizeof(buf));
0 d) Y- @2 A6 q
) ]3 m' e' X) } printf("Enter your expression:");
6 B4 k ?+ C( F' D ( U4 ]% g4 O) a, Y7 B
opr_in.ch='#';: Y# D' K. v% V
Push(optr,opr_in); /*'#'入栈*/
( ?& \. a) @; g* q# z! E1 i. s GetTop(optr,opr_top);
3 Y0 f5 X8 U) [ x5 U$ G c=getchar();/ u8 z+ X% A2 ?' u% f9 `6 |/ _
while(c!='='||opr_top.ch!='#')
5 E# X; Z3 B6 ?/ [9 m/ } {, f! w V1 S0 g+ Z. _ {
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
; a2 N# G/ Z9 v {
9 X i/ T, G( n9 c; \ buf=c;
& j# L# @3 `+ Q1 B& l8 z/ G i++;
5 t! n6 M6 L$ q" H( y c=getchar();3 U1 T8 I$ K9 A9 M8 v, W
}6 S3 i" ^7 `% U: R& k) w* Y L
else /*是运算符*/
5 l) m( Y8 L( b { {
; _& v o" p6 Q2 p buf='\0';
: w3 ^' T4 Y: n! G* J if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8 L( `! i1 H$ F0 o+ V {& M, e6 ]+ w) {$ O1 A
opn_in.data=(float)atof(buf);
0 I. F; T3 m8 ?4 o0 l# ~1 l Push(opnd,opn_in);+ S% P4 A. A9 M; X0 p8 s
printf("opnd入栈:[%f]\n",opn_in.data);% S0 K* W2 y$ c. ?
i=0;0 ^3 B& I! ^$ C/ v- Z
memset(buf,0,sizeof(buf));
( t4 p; u6 }6 s+ j% S1 B }
7 i! I; s- V1 r6 Y& N opr_in.ch=c;0 v8 J# i4 Y) Z/ A4 U
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/' T# Z- M) c$ k/ _& s
{" u1 p% N# N5 t0 y
case '<': /*优先级小于栈顶结点,则运算符入栈*/
" G. H& [4 r/ S: k- w, h' } Push(optr,opr_in);1 i6 l a5 K, O9 F+ l2 [' J
printf("optr入栈:[%c]\n",opr_in.ch);) G5 |- v( x. j7 \! g: K+ [
c=getchar();3 }; g/ X- ~$ P! a& S# @
break;; n, m% R( r* X
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/% N2 F, J3 P& y6 m. l
Pop(optr,e);
2 g0 K" g n- ?5 m9 N printf("optr出栈:去掉括号\n");3 K6 l5 P0 v2 H9 x5 A& K4 H- O
c=getchar();
4 {! Q1 Z& @7 U$ W" u# Z break;
5 e7 S, [- p4 R5 S* g case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
( w* @1 T/ o& ]4 W3 ]$ j: d8 j Pop(optr,opr_t);
$ [; @7 X3 R: M printf("optr出栈:[%c]\n",opr_t.ch);
( n* X( N$ \& f) F/ s! ?7 j; b if(Pop(opnd,b)<0)
! u/ R9 u3 A' b {, X. r- v# C% Z
printf("Bad Input!\n");
4 L" Q' [& a( N r: T2 o) k" Q fflush(stdin);; |: R9 W4 x d+ W
return -1;8 ?* e+ e( b1 K- E3 V3 y
}% a5 I1 W5 x, X6 a1 H7 w
printf("opnd出栈:[%f]\n",b.data);2 j" @( G3 O4 d8 w& y
if(Pop(opnd,a)<0)" n6 t* G8 x) M+ w5 ^
{
0 Y! F3 U- }# W printf("Bad Input!\n");
* B7 v, Y! B; i% R1 u fflush(stdin);
; @3 v! z; c' l1 b: | return -1;7 F/ p; f$ d& s- s% {
}, l+ R( R0 J) y( O
printf("opnd出栈:[%f]\n",a.data);% w5 Y4 j; S, u! P
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
4 D8 F. h; Y: {8 R8 {" G+ U N) [& m Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/" z) E( W% e8 Y! V- }
printf("结果入栈:[%f]\n",opn_tmp.data);, z7 _1 [" w* B n7 o: N
break;
# Y+ d" a; p8 Q1 g- b N1 n }
; v8 `. V. u1 G' q7 K; N }
8 X' b/ v' f: K$ T1 A GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ $ `1 X6 k5 W' q1 A* v7 H
}4 q9 O" s: Z( `
GetTop(opnd,opn_tmp);
- U6 u0 @1 r& v6 N) W" x6 q* s/ G DestroyStack(optr);
5 W% F& f0 I/ H! d" p) h8 K DestroyStack(opnd);7 B! l4 y+ r8 L' G. @, {2 I+ Q
return opn_tmp.data;
/ g4 c5 c. K; w0 Z3 r0 M( K9 p% ~. u}. f; ]3 n, K( J& H& g6 a
$ W6 z' a, M! Y4 K2 Uchar *killzero(char *res,float result)3 i0 p7 V5 N7 G+ o
{; q- o4 e! O: B
int i;& X6 |- E: T$ {( `6 n. _
9 F% j* [" U( v1 x5 { sprintf(res,"%f",result);0 w! q. h$ V5 B1 @
i=(int)strlen(res)-1;
N2 r! l# `, u" _9 `7 n* W while(i&&res=='0'). p+ T- [( l& Z* C# W
{! c1 c5 A1 J' Q
res='\0';
3 ~4 z1 n- X, M i--;0 [, M: ?/ y0 u
}( p. i' P3 ^% }7 W# K+ _& x
if(res=='.')9 ?! Q& c# k: m5 N1 T
res='\0';
6 [: {% d) G. `. g return res;! a* R) m, J4 B$ o( v& n
}% z% p3 V$ T* ~
R8 Z5 [# B5 _2 ?int main()
2 G9 L% |# P' C) j# i9 _ g{
4 h% `; G$ M3 v$ c. u4 p char ch;" h- x' J1 K9 \# E5 m/ P0 G. ^
char res[64];
1 X% f! ~/ t2 i1 i$ A- W5 @4 L float result;& d t, Z7 [) [8 t- c8 c
while(1)
% \: H$ M3 r/ p, _. A t3 O {
* i4 q; T" M2 w6 n, F result=compute();3 A/ N' h, @6 Q3 I
printf("\nThe result is:%s\n",killzero(res,result));- a2 z/ _, l3 i- z+ {8 X
printf("Do you want to continue(y/n)?:") ;" |2 {: V" O! P; {9 Q
ch=getch();
6 ]0 o% I9 x' n, |/ g, i1 K putchar(ch);& h' g% X" `4 _# \
if(ch=='n'||ch=='N')
4 h. y7 s$ x* W! Y, q! J$ t! m break;
2 L6 M0 }& D) ?$ F else0 ~2 ?. T i* V3 e8 s" v
system("cls");
4 Z: F j8 j& Z$ h4 l+ ? }6 G" W% R5 y6 ~) m
return 0;
% _/ c2 e4 M0 E- i}! Z4 P6 B" b+ [$ I% ^) D C
% V* _# d* L% F2 R0 t. ^[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|