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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
! l+ Z4 W$ ?) W# \# e; Q: l程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)= t: d8 `5 ~8 \1 m3 u( \
/**************表达式计算器************/
, o9 J/ }6 s8 Y! ?/ w#include <stdio.h>
4 S9 ]% u+ C3 E* W#include <stdlib.h>& E/ X4 |: M( L+ v* Y' Z4 S& t
#include <string.h>5 _1 b+ l6 S3 B( @2 j
#include <conio.h>+ t( Z5 z9 _% l+ \
#include <malloc.h>
% b( |) v, i& R2 N
" `2 @+ K( ~, ?0 t. E#define STACK_SIZE 100
% f% B, V1 X7 U& Q+ u#define APPEND_SIZE 10
2 ]2 q. Q' A5 h! }' L
* M3 P3 }5 Y4 o# l Istruct SNode{; X7 P2 l3 y9 }6 M$ L# h9 ] f s, D
float data; /*存放操作数或者计算结果*/
1 X5 u/ H1 d. P- p0 ~: `/ | char ch; /*存放运算符*/6 x) ~- Q, g2 B: C: H
};
! B, g0 S; s* X% }; q* U7 s( i% D' D2 r2 ~# g
struct Stack{9 b2 M6 C. w2 a' N
SNode *top;/ \ a5 n& E- e- B. Q
SNode *base;* Z/ @5 z3 G4 _8 c6 z- M
int size;, U4 e- w% _1 Z6 K0 W+ c0 _
};
1 N- n* E# Y& K1 N8 h& B2 }! S+ b% o% L1 u; n
/*栈操作函数*/, i. E4 J5 W- t' E" {7 y
int InitStack(Stack &S); /*创建栈*/
$ w6 [* {/ ?- ? aint DestroyStack(Stack &S); /*销毁栈*/6 n; x) h c$ G/ O
int ClearStack(Stack &S); /*清空栈*/
) V, n6 N* Y- A5 Yint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
- B$ c7 \* ?2 |' I/ f/ U( wint Push(Stack &S,SNode e); /*将结点e压入栈*/
* ]; z' K" \) g6 p/ ~, q1 q7 Xint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ j6 E: }! u2 G- g
0 Y- \- _& Y# i) F+ C+ Z; a' y/*表达式计算器相关函数*/# ^9 |: f# Y4 }: Y. V- P% v
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
' e" G% f7 S0 @5 y& gint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/; K1 S$ L9 N" o0 v8 L9 T% [
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 H; n8 T- l8 _$ @ yfloat compute(); /*表达式结算器主函数*/& i7 B' Q6 T" l9 U6 e
char *killzero(float result); /*去掉结果后面的0*/
" z; V% J$ Z0 ]- v4 e$ V1 G5 i/ \8 a$ h! A) i, ? z, x) }
int InitStack(Stack &S)
/ x2 j. C8 Z7 T, Z{2 z: Y! |) r7 G- w/ K' i& t
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));- l' X% }0 N5 d' ]- z( t
if(S.base==NULL)
. N2 B X! M5 `, o a" S {
Q$ o8 ]3 o5 @8 q) `0 \6 C+ j printf("动态分配内存失败!");
# W8 L4 G, F4 w* l" _ p( l y5 w return -1;5 d* ?$ s& \ i& @, |# B/ u
}6 N. p3 [/ l% ]2 R
S.top=S.base;
; K" R) _# [1 Z S.size=STACK_SIZE;
' z2 f, G9 j6 I( O. b6 w3 z return 0;
6 A' [3 F7 p* Q* I5 y}
" {: Q& n* g. [' [. d: D( _2 K6 d& q F
int DestroyStack(Stack &S). s! ~( s& W& @2 I, F% z
{
" J0 ~: r" O- j1 I( \, g+ ~; F free(S.base);) ^) h( b( A7 K p3 X; C2 ~
return 0;7 ?6 m9 x4 X1 f2 \( G1 ]
}
& J- O1 Z4 k) S0 I7 w2 t% j5 T
4 N# b3 r( N+ j. n+ u; u" F2 Q- uint ClearStack(Stack &S)- v" {' L `) P. n! L
{" \4 k9 l, {( e# Z" u+ m; Z, N
S.top=S.base;
* z& w1 F0 W+ c+ c return 0;
8 ]5 d) {& b0 v& _} S% R4 m, X. P0 ^0 W
& r# t9 M) q: Y- \9 a! z4 T
int GetTop(Stack S,SNode &e)" P3 K! ^% f$ F$ D2 L3 I& K% @
{
7 Z( }5 `3 \; Z; Y if(S.top==S.base); Y3 D; D% Q- P) W* t* u
{
/ W% r; Z6 F& `$ M7 {/ Z printf("栈以为空!");
4 B7 u# Y, Y/ H; d2 V6 a return -1;2 f i5 J! n1 b' b' L
}* e4 }+ B7 z- W# z/ U# n! @
e=*(S.top-1);
& i; X) ?! N- M8 h" {7 \ return 0;
, z9 j3 c6 N: l1 i7 Z/ f9 O N7 Q}
' y* g& x$ p$ i
+ I, C' b, B& R1 p" Mint Push(Stack &S,SNode e)' r. K0 K( p4 K
{9 _/ _4 \9 n6 S3 M+ s7 O1 O
if(S.top-S.base>=S.size)
, @" ~5 b7 T; c' s- J {
$ v3 e* a; Z6 k. Y- ` S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); m' ^8 n j* \4 f6 U t# Y
if(S.base==NULL)+ S" b# b" Q4 h- f9 L+ ? a# p% e
{
- B* z% k7 b+ L$ v" }2 Z' ] printf("动态分配内存失败!"); i% m4 p* a0 J8 k- _
return -1;! a9 ]3 `( @% r
}% ^" b$ N5 S! n6 w
S.top=S.base+S.size;. L8 e0 y/ U9 ?# Z. r, F
S.size+=APPEND_SIZE;
" O0 G; K7 e: f4 [ }
2 ?) U- g; l( S# L& y4 |1 ? *S.top=e;
0 O: x/ L2 f" p( G S.top++;
! x+ z) B+ G' s* L4 K) V( `+ [ return 0;0 [7 f8 `3 b5 D- Q; y2 f z8 d
}) K3 f$ |, a4 X
, X: V( [# ?" w, X8 x
int Pop(Stack &S,SNode &e)
+ t! }/ `3 D- Z1 p7 q{
0 Y+ [' H) e9 E$ x if(S.top==S.base): U- u' {! T( `9 b& R' R
{3 z; r* g* l8 Y4 q; v( M
printf("栈为空!");
5 p8 i) V( k; l( Y3 C Z return -1;
4 ?; i* o5 c$ P4 H8 v% M$ Z4 v }
{$ }: F: a& } e=*(S.top-1);
& K y }; |: ^; I8 F( m6 u S.top--;
! a/ A9 f% \" m- Q9 g! p" ?3 Z" i return 0;
; w/ M8 J2 A* n% J& L: _7 r- ~}
9 Y* Z; b; S3 f( |& G) M. M2 T' `
char get_precede(char s,char c)! r+ w* P" [2 Y" ~$ ?# i, t
{
M1 ], T( N, z1 Q4 ?: O& B switch(s)* D' }$ A6 A2 q8 Z4 k( g4 Z
{, U; J$ `0 ]7 j9 Q' ?
case '+': ( q2 m ~9 u6 a; R9 z
case '-':" G7 ` q" i, J1 {/ \
if(c=='+'||c=='-')
& P, t' d1 O7 n+ E8 H2 R, C return '>';2 q$ f6 V5 R& ?; k3 H' L
else if(c=='*'||c=='/')
( M8 L1 K" b& }: w" E4 [9 K return '<';
9 s& d& q" a4 l) m. ?% P& \ else if(c=='(')2 l. ^9 k8 h7 L1 i. X. Z! t2 w
return '<';
5 d8 _( K0 A) f& P k; z0 E else if(c==')')
% n) R* [5 A/ |. e% [ return '>';* {7 W) j( V/ V! x: v5 E7 u
else
6 W/ L9 V1 Q, d# J: R, q return '>';
' e: i; `$ x1 @+ k' \3 d8 q N case '*':
8 @ D; D6 h" i. c9 {% T case '/':
K" N4 O& t4 m1 y& i) W if(c=='+'||c=='-') K, p$ Y+ E k4 P9 o5 v1 v
return '>';
8 \% V' v) B }' v! u- \ else if(c=='*'||c=='/')$ Q2 L& C3 A3 i. A F% _- ]
return '>';' y6 E. O/ L. ?0 I& T
else if(c=='(')
; t) H8 O" j3 Z" X return '<';% R6 q3 G3 h) P6 k8 G$ x1 `
else if(c==')')% C4 H4 v) o$ @2 T( L
return '>';
3 E* t7 b# D. {% `" s9 o0 X else
% A) S S' j v return '>';
! x' ?5 I( i' a case '(':
9 }" P% A' A' Y A, Y3 { if(c=='+'||c=='-')
( g0 f2 W. ]( _3 L; M1 |, @ return '<';1 Z( T, }( c* H+ V* \8 y7 [" N
else if(c=='*'||c=='/')+ q' A( U. N5 ?4 D2 b8 R1 R% t
return '<';! ?2 T5 J+ f; Y8 E0 W' R
else if(c=='(')
9 g% E5 P9 _- P* M0 Y- l! |6 h return '<';8 H7 g( w% F! |0 ?1 h; J8 O: n
else if(c==')'). [: Y6 ~# f! Z6 g
return '=';: F C1 S5 ?2 Z( g x& m
else
9 U, a& c' {+ r* n5 t2 ] return 'E';
. t. V' o* D" C case ')':
: H6 S5 R; [& ^6 K if(c=='+'||c=='-')% a h) D- @ J
return '>';. B# D0 s/ C( Q- e
else if(c=='*'||c=='/'); w+ H% e1 A( L# Y
return '>';
; A9 \3 ~ \0 T% u else if(c=='(')
/ `/ J/ a& R& O+ Z$ H; X return 'E';, S. a$ `5 m, r
else if(c==')') `) q+ m' d- h0 p8 [4 g9 N! U
return '>';
7 Z/ p; s/ `% h2 Z0 t/ t else& a% h4 T6 \# r: t6 d
return '>';, ^) j; W2 F$ Z# D- ]
case '#':: n7 l' ^# w& Y
if(c=='+'||c=='-')1 P7 M- _& E7 f4 p. |( v! |/ w: w
return '<';
5 I8 Z5 r; B3 x* e# L* W# U else if(c=='*'||c=='/')
! b. A8 z3 Z5 A0 ` return '<';( Y4 r4 W: G, R1 t' M8 i4 C: S7 g
else if(c=='('): O# {; A N& a- g T' Z
return '<';! G! o/ o9 D; m9 Z5 O H% \7 @
else if(c==')')$ l% w+ m* z! w. p5 p$ A
return 'E';
/ R& v q7 s& x else3 q3 V. ^9 ^: P$ T `3 Q( W
return '=';3 d1 o/ T; U; n6 K" s
default:
% ~+ {# F- }- F break;
, C1 Q! P9 e" R e4 J2 P7 V# e }+ S: s1 }" z9 m$ P! t
return 0;
$ A; X3 P n7 g$ @, A}
" F, v4 j8 y* S3 V( l, V, n& _$ `3 K; M' L. V; n& c2 @4 m
int isOpr(char c)
* i1 W% n# V( Z9 O4 i% @0 i# [1 n+ e{1 g0 a0 Z- C" c5 [! S
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 i) s+ p+ x. J1 R
return 0;# G4 |+ Q A" w' f% A
else ( ?' {8 d! a/ b6 B) u5 b
return 1;+ N7 v X. B3 Q6 ]4 p( k
}
3 V) Z$ F3 q# l7 O5 d% j; V: S( @* x) l/ d
float operate(float x, char opr, float y)4 n% J4 C/ T1 ^: P' p8 d0 O6 k" O
{8 G: {4 ]1 Y: r; H% {
float result;& U# @+ t. j: u$ E
switch (opr)' O5 t4 X/ A$ v/ l8 P5 d! m- i9 ^
{
& a4 ^( l: U3 W& P case '+':
) Y+ L0 d5 Y& E& o8 H7 F5 \# e6 M result = x + y;4 x D0 s6 p K7 M
break;
% w- ^' h3 A: A8 C# l case '-': . Z& q6 t' H4 w/ j
result = x - y;
" J0 g; F; I! q' a! G break;
5 A; i+ \" U& N4 ^: T5 u case '*': 9 K [4 v! w. [1 Y( M
result = x * y;
- A) ~; M1 ?( { b5 g7 y' W, p" I break;
$ o1 N3 O" L4 ^0 M case '/':
* E" |8 Z7 u# y4 z if (y == 0)! m* Q8 N9 d7 U7 k# L: I
{% H+ p( X! r% ?/ h7 L! W9 x4 Q0 Y
printf("Divided by zero!\n");0 W' z0 F" O8 X) q' u, D
return 0;$ g- f6 Q a! p' L8 g: j
}2 r% U- o- R* O. J
else" d; m8 c" w8 T* _
{1 }4 w3 V1 E( n" i/ A
result = x / y;
( o( s9 H; I5 d0 @. k# q2 d break;# V5 a0 w0 F9 L- t" H' c. B
} g# \- ?% G! b+ {/ Z; S! i& a
default:
$ w/ Z) k1 `4 L& }. z! ~ printf("Bad Input.\n");
. @* f8 f Y9 X7 A0 B: D return 0;
9 F1 J# w& V1 O8 P6 z* ^6 |7 S* ` }2 X P4 p0 F# w- u
return result;. |* f4 ^/ L- |; \$ h3 w
}
$ X8 l+ ~* J l6 H) r/ \4 p( g! ?& R9 m3 p+ `
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/' W3 ?8 y) N* s' D ?! e" X
{
0 ^$ m& q4 B9 u$ U$ p6 U Stack optr,opnd;+ C2 d% F" A0 J/ R4 R
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
. A' V) h( r' a- ]0 y$ O$ j char c;; G; y) T/ f# ]2 _. z W
char buf[16];
" ]% c% @! ?. R5 U3 t, X% X( |- l+ r9 r' Q int i=0;: i6 J: ^. l5 r Q' \, R0 X" L$ S
; K: e/ a# y$ @
InitStack(optr); /*用于寄存运算符*/, `6 M" W Y) M# Z
InitStack(opnd); /*用于寄存操作数和计算结果*/# P. v3 z8 F' F! h6 S1 W
memset(buf,0,sizeof(buf));" m9 [7 q0 |+ U3 C3 J- M' r
& M# Q# i3 L( z& o+ T
printf("Enter your expression:");: Q/ w7 R$ K# ~7 o2 m! L
& `8 q9 O" {( L
opr_in.ch='#';/ X; |9 l( j0 s
Push(optr,opr_in); /*'#'入栈*/4 Q) J9 ]5 m) x! a* w
GetTop(optr,opr_top);
1 I. ^; I0 f) I1 a- Y% f c=getchar();0 P6 N9 S- U6 [4 y3 y- |
while(c!='='||opr_top.ch!='#'), n) m+ }8 Y4 p& N
{% d5 k% ^- {$ G
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/) Z2 F, N& W4 q4 {3 y Q- y) ]
{
, B$ G& D9 V/ u, G7 \ buf=c;$ G, [+ d4 B6 ^% y7 x# R6 @3 w7 g
i++;% ~- z6 Z$ W- j/ e
c=getchar();/ v$ E2 x5 x! P
}7 ]9 \( z& c8 {, ?- t# w, N6 C# t
else /*是运算符*/
' J6 X$ N# {1 ~' S1 j0 t& m {
* z! S/ @5 _. b; O buf='\0';2 T" G; ^9 [* K" }
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/- w1 y: j; T5 Q l7 |6 C
{
4 Q9 l$ J2 S6 {6 G" V6 H opn_in.data=(float)atof(buf);
$ W8 v. ]9 r7 v: A Push(opnd,opn_in);2 T ~; r6 g, m( m( c
printf("opnd入栈:[%f]\n",opn_in.data);$ P! U2 H7 D; i' r
i=0;
' _7 }$ S. M* [" l8 s memset(buf,0,sizeof(buf));& T2 o; t4 G$ }! c
}
% l, y* W* T/ }7 a2 S8 Z5 [* p7 { opr_in.ch=c;* f, |/ B7 F, s: V0 \- \* T
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/; t" A6 K" E4 u, ?5 f
{
9 E+ n+ {3 I, I case '<': /*优先级小于栈顶结点,则运算符入栈*/5 H+ {2 m: R F* @! u
Push(optr,opr_in);
; {1 i, S& e# i# j5 ~3 R printf("optr入栈:[%c]\n",opr_in.ch);
7 c3 P4 }( A+ r+ a8 }" s- @0 m1 p" { c=getchar();0 V: q& w6 p8 y
break;; r8 M, V9 z& J2 x4 s9 G* l4 _: b
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/7 @7 ? W: s6 o
Pop(optr,e);
7 |) \, a7 J) q$ X, S printf("optr出栈:去掉括号\n");7 n' r+ u: q9 m1 g
c=getchar();
, [7 a( S: e* }, ?6 n/ ^, A break;
9 x0 w* b9 A5 v+ ]: D case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/+ R% h2 _5 b$ i5 _( O
Pop(optr,opr_t);
3 ~3 U' s4 d1 A0 p- }7 I3 q$ K: v. D/ Q printf("optr出栈:[%c]\n",opr_t.ch);
. {' N' c3 D q0 i8 W0 d& D if(Pop(opnd,b)<0)4 s6 U7 R7 P) w5 r. o; O$ `
{
0 x5 Z/ L0 N# a printf("Bad Input!\n");
6 }& F/ L. M0 N3 N& E4 e3 \ fflush(stdin);& u6 r' s4 M' p2 ^( g, H
return -1;
u0 h' ^, s( F- S }/ ?7 x0 f# \, L8 ^7 f9 ^
printf("opnd出栈:[%f]\n",b.data);
3 y/ \) |5 f# ~) x5 a$ q if(Pop(opnd,a)<0)$ l! f- H# p% z
{
0 A- A& |9 \9 X( w& p1 j printf("Bad Input!\n");
6 z; M8 N# ?- j& t fflush(stdin);
( ]. M# s2 Q; o1 U return -1;$ s5 O8 {7 }7 m+ s
}
3 A0 h& R, [- h; { printf("opnd出栈:[%f]\n",a.data);
9 ^! ~( l4 q) B2 Z; C W( d opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/4 K9 b, A! G/ q. O
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
& g5 G' }4 J0 L0 ] printf("结果入栈:[%f]\n",opn_tmp.data); a4 ] X/ c) S3 |6 g: w
break;
! `. V$ v7 r4 p6 ` }+ f, m9 K2 D# O) Z% }* s: [
}
2 }' {3 Z) b4 H1 b+ f! G# R GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ q# S5 {! d* h3 Y% _ C
}0 ?8 J& v+ W; c& R; X- v0 ]1 |
GetTop(opnd,opn_tmp);
* t- w5 `3 G: A% q- W0 P$ f! N. N DestroyStack(optr);
9 Y% f: l" j; K2 E: ^9 Y DestroyStack(opnd);
3 r% R# q) }7 T2 K; |0 o9 q return opn_tmp.data;5 D- D+ |0 i/ A6 O& n( F4 ~8 q6 R$ D
}9 A3 f9 m4 v p1 m, u
7 q: s8 H0 Z0 _4 p3 l" I3 ?
char *killzero(char *res,float result)
: e5 T- ^3 ?& g# \{
! A! s- n3 b; j* W+ Y- f6 _% w int i;, z/ ~ r: a8 i9 N) Y
6 P6 q" s% u/ L* M- p+ {+ ]+ b sprintf(res,"%f",result);
* h: @: J; g ? i=(int)strlen(res)-1;
8 c8 L4 a1 d0 ~" _ while(i&&res=='0')
9 p. [ O6 i: ?* V {- J7 I) E8 Q" P
res='\0';
; h, f3 P, d" r! m, C. [6 Y; a8 c i--;
! A1 ~2 b; N8 n& T8 \ }" e h; F" _- b8 o6 o
if(res=='.')
~' K+ |* t8 G9 o: @/ g res='\0';
Q/ f- E& l8 X9 W7 w3 ]7 j return res;
8 U- m0 ]1 S, q2 i; g9 Z( R}: [& R/ k" e9 u2 J) z, n0 z6 O/ i
; I) u% u! o1 V' j
int main()
8 p% f9 D8 K5 J8 @- G4 U{
3 E4 ~& i& ]! }) d char ch;
. F3 I! A! b' B8 [ char res[64];
: q, k1 U$ A0 C/ b. R float result;
: L' T' D7 q8 O0 Y0 Y" F( \7 D8 A while(1)3 y2 V+ b; Q2 W, U; O
{6 m6 B$ l- Y6 m
result=compute();
* f# l' p" t! ]- O: P# N printf("\nThe result is:%s\n",killzero(res,result));( ^ r3 @/ F. U; g
printf("Do you want to continue(y/n)?:") ;6 M. z: S9 O% k& V6 l
ch=getch();4 Z! V/ s+ s8 h# E( ?
putchar(ch);
. {! V0 a) `) g, O- `/ C- q if(ch=='n'||ch=='N')' s. l# W. @" ]" G9 l
break;) d5 h, D* c6 `- r# q
else* {9 s) Y/ w7 P6 D, B& e
system("cls");
" j, z" l2 \0 A9 p! x* L$ D }
5 k! F0 v: E0 V+ ] }9 g2 M5 o return 0;
# f( I6 E( Q/ i, E- g; n}
f; Q0 _ T& ^# g. f' X6 A2 w/ T! v4 Q
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|