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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
0 P) f. R* w6 K& E$ D' j& Z程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
$ @8 P1 g( j+ X5 ]9 @) v' E/**************表达式计算器************/
& W8 l" r; L. @; D! I#include <stdio.h>
1 [2 v" {! c1 l: z9 x#include <stdlib.h>
! g! N9 a; n+ H& [3 |" `3 r8 I#include <string.h>- ]/ s1 @! c& U& w, f
#include <conio.h>5 ?2 z v; v& e+ \, Q: P1 S( ~1 t
#include <malloc.h>* x3 u: T+ u0 t3 k- D- @
9 X* D( ]; k$ h' P
#define STACK_SIZE 100
% F( S, f, S- S# O, M* P3 e#define APPEND_SIZE 10
. I4 e) y; d. `# V# S
2 N+ F' t; l4 `! L, T( D0 }! l5 tstruct SNode{
9 `* ^9 ^; m+ l2 K! ?# r4 @9 i float data; /*存放操作数或者计算结果*/
, D% g( }% f: R& l ] char ch; /*存放运算符*/
$ Q4 I c1 W& e6 _};( V2 Z0 Y" v$ q% z+ T! Y
* P* n$ {: m) ystruct Stack{
* w: @+ d6 c+ M7 P" Z' I SNode *top;
! x1 t) G$ k& h* E# y& b SNode *base;
9 O0 J' w- ~) Z/ q% P int size;8 Z* S8 D) a: U. W* E4 v* i
};( t, v( }' M! Z3 P! g7 c- U5 P
) L; m2 z3 `/ X9 E
/*栈操作函数*/0 E& K" v4 X5 n. h& N; W
int InitStack(Stack &S); /*创建栈*/1 X: M& b) Z! V. P+ T' R
int DestroyStack(Stack &S); /*销毁栈*/% {+ U+ ?9 v! d/ E
int ClearStack(Stack &S); /*清空栈*/
1 z9 M+ V( {; z1 iint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/+ U8 y B7 L% B) |: G
int Push(Stack &S,SNode e); /*将结点e压入栈*/8 r, @: D* ?% N- M. e' b0 o
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/; o" J9 }* r0 Z: ?- F) w+ e
* v3 O- i# U% H# ]$ r; ~3 L J/*表达式计算器相关函数*/
4 T; ?( ~0 H( O3 L. bchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
5 b4 U( ], @1 J) @' G4 X+ R; _int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
K, |1 Q9 h4 j* n. ffloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
) o+ e+ `' C) u0 E9 `2 R7 B5 J: v5 N1 {float compute(); /*表达式结算器主函数*/
; b, L! O9 A# f3 f& I6 Rchar *killzero(float result); /*去掉结果后面的0*/ . F/ i- I, ^7 C% [
. H- Q- v# |5 F0 M( U) Rint InitStack(Stack &S)
3 T( u$ S8 \/ o. m- ~$ D' L% p J{3 g' C; r/ P% O; m/ Y$ }: @
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
" t8 X9 `/ b" }5 d+ x- r if(S.base==NULL)+ J1 l! o, y: e ?" a# {
{" {/ v# b d- l+ ?9 z
printf("动态分配内存失败!");
) e( P* G0 m p" X: V return -1;0 ~9 y$ E. j# U
}
) I$ Y, B6 Y! m; \+ D# c, K1 D3 l S.top=S.base;
, ?0 L T" q$ |5 x1 S I8 @9 O S.size=STACK_SIZE;' u3 }8 ^3 ^8 ]2 x& N5 k
return 0;1 j/ g2 l) E$ V, ~* F& ]
}: d. n8 Q* L' Y0 G. I- |
; n4 g2 `* I' C) ?7 w) Uint DestroyStack(Stack &S)
2 N, Y; _3 L4 \{
& Y' T2 P: T ^: J2 d free(S.base);
! u6 s$ }: e3 {$ \1 ]+ e' d7 ` return 0;
- [: k4 R- y' L}
4 [4 W) V5 v! J$ r+ d; u3 k( o; K O- r
int ClearStack(Stack &S)
: H' o ]5 ~) ]{- q: M/ y/ }2 a4 h: @7 _* m7 Q
S.top=S.base;) R8 z( G: ~5 d% X- b
return 0;
6 L2 B& q0 ^ z9 ^; k}0 [/ w0 C2 T" W; O
5 l+ G1 g. I5 ~' s2 M
int GetTop(Stack S,SNode &e)
3 j, h+ K' k& @$ x4 e3 ?9 P1 J{
( G" z% I; J s) H D) I( { if(S.top==S.base)
- h- a( m' B0 L8 n/ a- ~ {) z2 ?3 ?9 \* ]6 O d D0 {
printf("栈以为空!");
/ b) H% K) b) s" a- X return -1;% e( j" i3 _) A! X+ P' Y
}( C. [ N5 p( U8 _1 b
e=*(S.top-1);( [6 r, f( l5 }8 h, l
return 0;
+ x' v" Q1 a6 _, Z) v2 y$ p}
8 c, ^2 j4 j8 a% B# O- j; q
) t6 `, q5 v M' ^, ?! Lint Push(Stack &S,SNode e)
2 ^. e# T Z5 G! S{
; ~: _" n4 a: N6 j/ V3 g/ f if(S.top-S.base>=S.size)
4 K0 U3 v- ~& X {. o6 C' V/ O# _" k
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
M* g! ?$ \3 O5 {9 N: Q' f# x2 N if(S.base==NULL)
( V8 g2 ^4 J% i; v& R5 S {
3 U/ W+ R0 S( T$ C printf("动态分配内存失败!");
+ a6 z3 r% R4 M, W8 ^* O- y return -1;
7 X }/ o* Z8 u+ W }+ x' R: T2 L5 g% v7 S. q0 D- o
S.top=S.base+S.size;
5 Q H+ B( j1 |" R S.size+=APPEND_SIZE;+ ]; v! h" j, t2 S. Q9 I7 n
}
) _; j5 h/ f4 n+ V* f4 O *S.top=e;
: b" G w# Q5 i, U. K& ` S.top++;' h4 W" g, L" K/ `
return 0;5 S! g5 [5 s' q2 I" }: B
}
P6 d1 }/ \' A4 V, F
9 }! k9 F( E# p5 n0 B5 e4 U. X7 R3 jint Pop(Stack &S,SNode &e)/ f7 L: Y) D- P
{
; j1 j. o7 ^, Q if(S.top==S.base)
. {5 r" I' T& `* B {
" Z \/ |- L4 h: c printf("栈为空!");$ g* f m' G) W& m* x; X
return -1;2 I9 C9 x$ O. }& f# j2 N0 s! c
}/ {, E$ L2 A0 J6 x/ c& h
e=*(S.top-1);# o5 X. b# K; \
S.top--;0 X5 B6 q& y0 W' \' e6 c
return 0;
3 c( S* I/ ?' o4 w' h}2 d$ E! b1 c/ {& |5 k
4 L! B; g" z4 l8 u$ Y- s6 J, _char get_precede(char s,char c)
* {9 P4 E7 n) ^4 w: B/ q( H& l{6 W0 |" u' g; R& R: I
switch(s)3 r: ~9 n9 u& X5 C9 K: B& U
{4 P& w T# J4 V
case '+':
1 B5 C9 B6 ]- B4 u' C! \* l case '-':
# n1 Z% H* k2 ? if(c=='+'||c=='-')
# R/ _! Z9 X X/ s& X7 y return '>';
2 p0 g/ q& o9 A* D, k else if(c=='*'||c=='/')% b4 Z! B' U# I( C
return '<'; t2 e1 ~# I. Y9 U
else if(c=='(')
) {2 _; c. k" J. u) M- }2 R7 { return '<';
. S# P F* p0 \: |1 z1 d8 L else if(c==')')
! a. J2 t; I4 G; r" J# Z6 z, R return '>';
" {- U- u" R3 P0 L else 1 e2 J: U1 ~2 p% O0 E6 c: Q
return '>';) B# k/ z7 F t0 I/ Z
case '*':9 J$ c/ j! ?8 B0 V# r2 L
case '/':
% }" W1 ^4 B. }/ m if(c=='+'||c=='-')
5 F4 N) |9 g& H7 n+ c return '>';: ], E5 O: b7 o/ b- Y
else if(c=='*'||c=='/')" j! L- y+ }# y# B8 l2 e& h
return '>';: _3 `: @' l7 P+ A4 U3 U% ~
else if(c=='(')
/ p$ Q: I* [) B' E F return '<';
0 A8 a" y# i5 D: G else if(c==')')0 b' H% c' c& `
return '>';
4 {4 k: w9 u9 m3 F/ \/ a5 M* E else
9 i7 @" b7 T( v return '>';$ C, e) ~3 j; K0 V/ i
case '(':
9 G% d2 e, ~( a. o4 x8 } if(c=='+'||c=='-')0 y1 z6 n- m* v3 y/ Q8 [$ \
return '<';
2 P; ~6 V7 t0 Q5 L4 }; r else if(c=='*'||c=='/')
6 F7 R$ Z9 p$ A* K6 ? return '<';
9 y. c7 S }3 N) B* o# N( [ else if(c=='(')
1 p4 O& U" m# t: L* h" q return '<';
4 a4 Q- n9 N& G4 ]" `0 d( |* `# s else if(c==')')
8 `9 B/ D! g+ c return '=';8 o+ {: r' b1 F2 k
else
K8 K0 n: l* r9 k( X- z2 ` return 'E';
; H6 V/ Q4 e% f) J* C8 f) } case ')':
9 z' N u0 q# {# L$ [ if(c=='+'||c=='-')3 w8 ?& f( ^6 a% P+ O
return '>';
, O7 A, A! ^% O/ `4 }. O1 ^3 ]( P1 [ else if(c=='*'||c=='/')+ Y6 s8 {3 A7 a8 \7 Z9 w
return '>';* U7 V4 L4 d5 _" o9 V$ V
else if(c=='(')/ }. W2 ^( a, Z4 c# `! I$ i8 X# A
return 'E';: d1 V0 D8 \, m; r3 g, o" ?" B, f' A
else if(c==')')9 [' F8 K$ T+ G9 ]$ ?
return '>';) Q' e- a8 O5 g) r0 g
else+ {/ s0 f |; C& L7 n: |
return '>';6 m0 ?5 |- R& \# b
case '#':/ L8 I) ^5 C& h" c ^3 o- h
if(c=='+'||c=='-')" Y2 @8 k: p( E
return '<';
) H+ Y9 y* `; Q else if(c=='*'||c=='/')
* S; Z$ l6 x+ G4 f, J5 | \; t return '<';
1 f6 X- N S* }8 l* {5 M6 `9 v else if(c=='(')
. E6 M/ p8 k5 b$ Z. ]3 I return '<';
* r9 R# N2 v: w9 n- M else if(c==')')( G% D9 n& ?( B3 J; N
return 'E';
7 Q2 e0 T1 Z0 u a' g# w( H/ D else3 @4 o* C) F/ H4 N$ [7 f0 y
return '=';2 A: L' I( B9 t% y4 k" @* a
default:2 j: O. i; d- T+ G
break;
4 o$ o5 ~0 C6 b- Q5 ~* [ }
8 {( e6 V8 x$ z) r: l: A return 0; : a- y3 |' v7 v( Q p; b
}
- J P" C' n$ r# S3 V
, c6 U$ h: b0 r# p# {3 Lint isOpr(char c)2 A3 D8 R8 g0 A( ?, U; [* `
{
K' N4 b2 v7 O# y( e if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')% u4 h0 `4 h9 H$ k, c$ g
return 0;
" j6 R: a2 Z* }4 e; ]+ S else
$ Y+ v$ X* e* N1 H3 Y! n$ }5 h7 z return 1;; Z. E8 {% {9 I, D/ Q
}
* Y# X a% h3 V/ S0 `3 ?
' K- w& L0 b2 B2 Dfloat operate(float x, char opr, float y)
7 R4 |, v5 ^0 Q+ S% D{* |" c+ I) j j/ t3 b
float result;, s8 d: [: _7 Y, i
switch (opr)9 ~6 r" `8 e/ l5 G8 X: l4 r
{
0 y4 j) W9 Y+ U e7 ~% c case '+':
" O0 k. a2 H$ { result = x + y;+ O* e5 m Q& ^8 s; e+ \
break;
6 Y1 l, f5 o: [& j; f1 x case '-':
. c! e5 i# y8 l1 _ result = x - y;
9 r8 S, r _, j$ g. K5 V break;% H/ ~" n, c8 u
case '*': * ^: E/ o" o8 D" ]
result = x * y;+ w! k8 v/ D4 y; |% }' e3 X
break;4 a3 r4 w) G; V: k& C. E
case '/':
& e7 \7 D0 a3 t" Q0 R; j+ `9 I if (y == 0)
, ~" @( }/ M7 b( i, V) h7 H {. M# @. `( L7 V* Q
printf("Divided by zero!\n");
& V( b3 g; r3 e9 s& w. C return 0;4 p8 p+ H( x) @! X1 O8 z. o
}" D' Z( o8 t& L; G0 ~% }1 L
else0 |8 e A" q$ _1 I
{
' `) I/ X8 U# ]. P result = x / y;8 `* O, C+ B* e! k
break;
/ Z$ P3 F: g) `# z }
$ C$ V& g4 l! a/ x0 c) y' g default: 6 C4 R3 T# t1 W5 p/ H+ T
printf("Bad Input.\n");
$ I( C5 `, ]5 \ return 0;
- n% ?2 y2 g* [- [! N }/ s; x& ]& ]. a. W
return result;$ k6 p1 \+ [+ ]/ n3 g- x
}
8 f- p5 Y( |3 J5 _% b, K" A6 N ~* j5 {4 l. Y
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/% p$ L6 m" ?1 h1 K
{+ s1 }* u1 I0 \1 v
Stack optr,opnd;! K9 t# w6 a% C! P9 k4 E
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;) a g1 F( ~4 p1 m+ U6 p
char c;
0 e% d" w6 a& X char buf[16];
( r3 J4 l! Y8 U int i=0;
0 k# _! n7 ^, B4 C# F$ A0 A 7 B/ X k* w4 B' W# u- L1 u$ u* t
InitStack(optr); /*用于寄存运算符*/, V* U$ u/ G( m
InitStack(opnd); /*用于寄存操作数和计算结果*/4 f. m. n2 w7 N' M
memset(buf,0,sizeof(buf));
. l9 b% w+ N% O% d( Y5 f3 N G 2 C# O. [1 ~! A" \
printf("Enter your expression:");
# h6 L+ k2 K3 O( r( ?6 W
/ d4 j6 |# s( l* R; ]! _ opr_in.ch='#';
' I7 f7 E2 u* P1 g/ h! h6 X Push(optr,opr_in); /*'#'入栈*/
{3 @, x0 Q& E# S- W' t. Z/ @ GetTop(optr,opr_top);
7 G5 V4 D5 E0 z1 J4 [ c=getchar();* ^5 L6 u/ C: S1 R9 |5 d# T$ S s
while(c!='='||opr_top.ch!='#')" X" k/ n0 e _
{
( A3 J6 m! T+ v( H! U4 V if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
7 G( B0 e+ Z- U% ~) ]/ L {
# _# X% s: Q* j f& k1 O buf=c;$ M$ j8 B8 q% I; z' ^
i++;
; v: h) u& x$ U2 _: X c=getchar();8 a$ w$ N+ V' ~
}
' \/ G' e4 Z0 F# h else /*是运算符*/
6 G* @* s2 |% l5 Y: x$ D# ~ {$ N7 U U1 w# T: u% m, W
buf='\0';
7 b5 \3 y( q" s6 ]3 p if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/( D* e% w% ]9 H& `& x9 l
{
( m- U' B4 P' x opn_in.data=(float)atof(buf);# c( [" T9 E# t6 Y
Push(opnd,opn_in);" X# }# W! j/ ~ Z7 Z! K+ G! X; U
printf("opnd入栈:[%f]\n",opn_in.data);
# y& y' ~$ ~7 {/ I1 K i=0;
" n0 M, J1 d; Z# l: u3 s4 d memset(buf,0,sizeof(buf));
; t9 v% g- K k8 W( |* s' g }
$ S* Q5 l+ Z/ w: d( D. p opr_in.ch=c;
1 l- u' G6 j. Z, k switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5 i" @. ~# ]8 P" v+ Q {3 @( G- `, A2 R' Y8 [0 j5 o
case '<': /*优先级小于栈顶结点,则运算符入栈*/
7 U/ t. T% U& I/ `0 b. Y Push(optr,opr_in);
+ }+ G4 X2 P; L" C8 u printf("optr入栈:[%c]\n",opr_in.ch);
( N+ F; j7 C9 E* {: C) Q c=getchar();
6 P; C ]- T( T, f; d break;5 m) n0 @- J3 G6 O4 N9 n
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
/ h. _- {$ ?/ M* v, J Pop(optr,e);
, K) } _8 J3 Q& D8 e$ o, e printf("optr出栈:去掉括号\n");
: G8 v3 w( |3 w$ i% L+ l c=getchar();# u6 t3 [. V' G* S1 Q. D7 h' W# ]- G
break;
4 ?* l& r3 m9 i! i3 ~* C# L( r8 A( @% q case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
* f& d0 V0 {$ n9 y4 V' b4 q Pop(optr,opr_t);) _8 B$ O; P1 c. a. J' A+ x
printf("optr出栈:[%c]\n",opr_t.ch);
5 S% \. S5 j- u! o if(Pop(opnd,b)<0)
t O5 M7 w0 u/ B3 R( k5 V; X+ h {" L/ P) Y7 l2 y7 x& ?1 f
printf("Bad Input!\n");- `( @. h- A$ d9 _1 {0 G
fflush(stdin);
3 c; ~$ F1 F6 P) k% | return -1;
/ E3 Z" {& B5 y% w! L. h, u }; |) r0 b3 {9 K* h+ q
printf("opnd出栈:[%f]\n",b.data);9 h4 |# h: o7 s9 d* A
if(Pop(opnd,a)<0)
! H' {& Y6 [) _* b2 M9 f* w j1 { {
2 l9 q! Z9 T: |& u printf("Bad Input!\n");: A Q G/ j I9 R% y) o4 B3 n
fflush(stdin);
) ^: B% ?7 s- N' U, I; y- P return -1;
4 T( U6 ?& m" w$ ~8 _& N }7 o; _' K8 f% z. ^! l
printf("opnd出栈:[%f]\n",a.data);- x r# z# I! I9 @
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
5 g4 [& A* ~) j% ~, N% o9 S# Y Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
/ V9 I9 p4 C) t& k printf("结果入栈:[%f]\n",opn_tmp.data);
3 i4 |" B8 v9 y! ^ break;
: I9 G; V: G9 _' }) z6 |6 m }$ `2 l& p( a% j9 a# L
}
' ?. @% G2 b# n$ }9 P GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
) V4 g; X( ]/ ]9 H2 u) i n }
$ R) m" }0 v9 ^& J1 V% ^: w& A GetTop(opnd,opn_tmp);. u! i$ X/ e, R( u
DestroyStack(optr);
b) _/ a: C/ Q Z9 P) j# r DestroyStack(opnd);0 ]0 r0 c: n! O) w* x7 C
return opn_tmp.data;
; a- S: {! V/ z( ^ n7 f}
8 z- n x; u' @; N9 f
: [+ A. J3 s' d, p2 e ]" \2 Mchar *killzero(char *res,float result)' I% | ^$ `9 r# l) h$ P
{
! }) T2 l9 y/ B' v; x int i; E( u3 f& N- Z: J- r5 P5 ^
4 Y! K3 H4 z4 i+ b% F8 G# x
sprintf(res,"%f",result);
: w1 W+ `& \2 a. U9 }- K3 a" n0 T i=(int)strlen(res)-1;& o: E4 I9 X* m/ G/ f, g
while(i&&res=='0'): u% K9 w1 g7 ^" f/ [3 ]- q
{: J8 n% T9 I9 g5 F, [, a
res='\0';; t6 ]/ ?2 S% N$ p- m# E$ w: B$ s
i--;4 b- @+ |! ?" p& y( z, ^
}
. J4 C+ e/ _$ P$ z4 y. J: C9 M% q if(res=='.')
2 S& ]1 l/ a; \0 \ w/ p, R; m res='\0';& q& x/ ^8 R: z4 g( G
return res;
9 u3 k+ o, V5 h* h/ Y2 c}% B" A0 _' v7 \5 S4 X6 B( y$ z6 ^
* X, q3 G4 l3 x
int main()" w- q, B$ J+ Q% d7 T$ @, z
{
7 ]% {4 g$ H5 N" R char ch;
+ C' t: D! `3 w) q) w; A char res[64];' ^# }3 O1 }) v Q& n
float result;
' L# a. N8 @! U( |3 g& G while(1)% [7 P, U& Z3 |+ m* \/ L* ]
{
/ B$ d# P' f9 C* S4 k result=compute();
. ?3 [+ L8 r* y: } printf("\nThe result is:%s\n",killzero(res,result));
5 G1 y2 k9 e* E( l3 i4 u" R8 @ printf("Do you want to continue(y/n)?:") ;
' q, z8 J+ n3 |3 n ch=getch();
! t: Y6 p0 u: c. ~6 f- Q6 @ putchar(ch);6 H8 M' { Z) D/ Q6 U9 b" q# i
if(ch=='n'||ch=='N'); E2 F: F+ q) \ e9 f: I3 E
break;1 ?: ^0 o+ f$ q5 C+ e7 R
else
- h! F8 h" {+ W( J) n' [- t system("cls");, U( M0 R0 p7 a# O1 l
}
$ v: j$ ]6 @$ Q return 0;% q( n* z9 U+ g, {2 R) P1 B4 s
}
6 k0 h9 t4 U2 q+ ]4 h: U0 t9 F, Q4 ]9 i% A1 ~+ O' w% g' u6 D# E
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|