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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
; P# n& i! z! e; P2 j& ~, _程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)= w4 p. T, K; K
/**************表达式计算器************/3 u: x+ g! `# n( |9 E
#include <stdio.h>. L% Y- ]8 K. x2 o- S. c8 J
#include <stdlib.h>
) m, n* h! ? A% D#include <string.h>8 `9 D# a/ i g2 P
#include <conio.h>$ H$ B' L; A2 \& d$ j2 S; C
#include <malloc.h>
* k; s0 W- ~& T7 }# y9 c
1 s7 m2 [* t2 s/ R- I4 Z$ ?#define STACK_SIZE 100
?* l% W* E5 L. U& O; g#define APPEND_SIZE 10* f! N6 z9 w) g
* B2 Q, E) i- Wstruct SNode{
9 @, n8 I5 _" }& _ float data; /*存放操作数或者计算结果*/
5 y7 f U) q! h0 X char ch; /*存放运算符*/3 ~7 G* W! ^6 v* z. b7 E
};! {6 @4 O: ]8 _+ C" Y9 N4 @. R
. `0 r/ v" ?5 R% ?: w. d! G
struct Stack{
' J' H3 w3 @! ~& R& y/ S SNode *top;
{& ~9 N, F0 n1 }& C SNode *base;
- g$ q; m/ {7 K( \) t7 l ? int size;
6 {* E2 R7 J% a2 k T};/ T! {+ \+ D+ s: r
! C* j$ Y- ^5 G: x6 m6 @" |% F/*栈操作函数*/
) K5 [" g+ v" b5 t- t+ k0 V' Gint InitStack(Stack &S); /*创建栈*/; [& R( P! C2 n( d7 y
int DestroyStack(Stack &S); /*销毁栈*/
% `) P3 ~( A6 W Pint ClearStack(Stack &S); /*清空栈*/
, p S! F0 c6 p* w2 g# Pint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/2 d' b' B5 f- I b0 k+ Q
int Push(Stack &S,SNode e); /*将结点e压入栈*/
# n& R6 @9 t+ V8 `, y; y. Dint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ H# z' B" C: [7 Y* v
" }2 ^% e4 O+ R+ f+ U
/*表达式计算器相关函数*/
7 n4 h. Z' r5 K9 A/ }& s0 D% F1 Ychar get_precede(char s,char c); /*判断运算符s和c的优先级*/
- G' t- o- R9 e: j3 _) N2 L8 Pint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
7 ]" F: L& B' g' `# t5 C' x' xfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
$ m- r5 i8 Z# N( K. gfloat compute(); /*表达式结算器主函数*/1 R( z9 E2 v# } r0 o; J
char *killzero(float result); /*去掉结果后面的0*/ ! |5 _% o$ {1 j4 f
& L1 F2 A8 d% d* Q6 Q, r
int InitStack(Stack &S)
6 C8 x: W" H/ w/ A{
+ E- S4 I$ ]- |; W3 D S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
/ d0 A) ] y, _/ \' a if(S.base==NULL)
1 l4 [! q9 B4 U4 z4 } {6 r4 v2 W! G$ s+ i& b
printf("动态分配内存失败!");0 J$ ^$ X; |9 I# _
return -1;' L4 X6 r3 W' l
}9 q4 \ |# E2 v- f- ]- Y U
S.top=S.base;
3 T1 x1 X% Q/ y1 w S.size=STACK_SIZE;2 N; p3 p8 \) R7 p( n4 D" N
return 0;8 s- h) { W+ c
}, P, g* P* t3 I, J/ i" m* k0 q
) M) z+ _! ?$ P$ g M. z+ ]
int DestroyStack(Stack &S)
- x& } h4 s9 o$ N7 i. A8 y# P2 b{ B7 @9 R. t. ^/ \! k
free(S.base);
& j1 K6 o0 \ r- _8 U6 y+ o return 0; @ ^5 o4 v; N" E8 ?
}5 X0 }- x5 l' I& ]
* V9 s% \" P# w$ B3 _int ClearStack(Stack &S)
- w1 X1 B" \. m( V9 X{
7 g% y6 I8 @. }4 m& } S.top=S.base;+ [- S/ M& `: W* w
return 0;
4 @9 n& z$ U3 `) f: w}
1 D3 S! ?0 ^9 o% b6 {/ ^3 x+ n( `' x
int GetTop(Stack S,SNode &e)
5 o5 k9 \* N' [" r+ Z- [* \! \9 F$ ?3 I{3 ^; O9 t$ I$ n# V, l. F( _: B
if(S.top==S.base)5 n/ N b8 L" T. L' W9 R# U
{0 c G; j2 g8 m3 G- [0 l2 w
printf("栈以为空!");
: g$ ^7 H5 F: n. z+ X6 z return -1;$ B# ~4 l1 ~4 O8 x, x, P
}
2 b+ \3 r; A6 L+ o% {& k V* _ e=*(S.top-1);6 f$ ?9 @7 o0 D. ^ o9 T
return 0;2 u; A4 R6 H3 j9 t& x L& R
}
, o& g% G t) Z* l, _0 b& }( ~$ D& u! ]) T. `* ]* g$ ^$ l
int Push(Stack &S,SNode e)
' s8 C, y; C4 p1 q2 x6 t{
. ?, S$ F1 `# H0 ?% y0 n/ a if(S.top-S.base>=S.size)
. n* N- N0 H; @ Y: P {
5 Q6 z' { |; ^6 u8 E0 @, l S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));2 I6 _7 }! s1 k. l8 \ C7 a3 e$ O
if(S.base==NULL)6 y& F- P9 V# H# T; K5 H+ b% e
{
' Z/ Z k$ U# G printf("动态分配内存失败!");- g6 H' \/ u* A
return -1;
; L9 r8 H! `2 m& l }% X% ?' O* E" W% j' R$ d' t* F v
S.top=S.base+S.size;8 n1 [8 S. S8 [
S.size+=APPEND_SIZE;& _$ `+ l2 G X+ j8 i4 I! N' D
}% T% }& {! P9 M' P
*S.top=e;7 L! g) w+ O0 r& o7 g
S.top++;8 c. v+ P( X! j3 k' A5 S! G
return 0;$ m2 B3 H& S) a) S+ c
}) D1 J4 p% i) F a
" L s7 D# t9 ?5 k
int Pop(Stack &S,SNode &e)- g8 d) E& e E; L. _- E/ ]) y
{
/ s! }3 V/ ]: e if(S.top==S.base)
# s H ~4 {) m1 u0 ` {* }; I: p, P3 U5 h1 o( c1 n
printf("栈为空!"); x& r4 u, \# {( p2 R9 c
return -1;
; l) o9 R* @/ x& C& R, b U( l }& P, b5 J: Q; S4 W3 ]# T! X" \8 j- L
e=*(S.top-1);
1 a0 e/ D# Q, @1 F, c S.top--;8 |9 } }; M' v1 j) f; C. y0 q
return 0;6 R% B* w* A8 F8 n
}+ _5 x. H/ E5 K) S
( i, t# |) }7 j0 B# y
char get_precede(char s,char c)' o. x2 ~2 d9 X0 M0 t# m
{9 ]& ]. u3 Q% Z' f
switch(s)4 m0 Y7 ?8 c5 e: J
{; Z/ J5 ^: }4 ~4 C/ W; J
case '+':
! G6 ]& d1 U; W! v/ b5 L case '-':
. g8 d0 F+ w" S. O' `9 [0 | if(c=='+'||c=='-')/ Y3 i5 S4 [/ o7 D: @: U7 H
return '>';
. G( `8 T# {% c) O else if(c=='*'||c=='/')9 R& W; B1 M" ]3 z$ o6 h
return '<';
: n" J T( z6 \- d* U% d else if(c=='(')8 ~% e, A: {6 h# s' `5 K8 p
return '<';5 |" o! {# r+ R7 W3 R; V
else if(c==')')9 @- ^/ @4 _$ q4 C
return '>';: J7 ^5 ~3 a/ [$ w+ ]; k
else
2 R- K# t3 o0 B9 m: E0 |" s return '>';
t' d4 n" }! k: c& g/ I! M case '*':
`- s& X) z8 q* T case '/':
8 k2 H1 b" q& H! L) Z4 l4 p if(c=='+'||c=='-') \( p, d5 U. A" S, S
return '>'; x3 A# `1 h3 L/ `- n% w& v! k! f
else if(c=='*'||c=='/')2 K) N' [/ |3 S) H8 _
return '>';: |$ J+ |# D( c3 Y6 Z
else if(c=='(')
, Z7 |! s9 ~0 d6 E return '<';6 x" q. m/ [8 S L, n2 F/ Q$ U1 Z
else if(c==')')
1 M5 Y1 Q: w" X4 r: s& M5 H return '>';- _/ V; k$ y" L, \' Q5 m2 F
else
* o9 j0 ]$ ^. {: n% @0 C# W return '>';* l; C. Q% A2 B! t9 h) A" N
case '(':6 f4 u; S3 X9 z# w! Q
if(c=='+'||c=='-') e6 @: P2 F4 q8 H" t
return '<';
7 Q, ]8 \! u% J; L else if(c=='*'||c=='/')1 q! p+ c; H; D6 N% o. d
return '<';
5 ]5 E/ Y( W+ a' T- e& V1 B else if(c=='(')5 X+ G7 Y+ b; y/ {3 p7 h, A" P
return '<';% \2 I% N8 n! e- q
else if(c==')'), x, O! v M6 v
return '=';
( A( T% B# K+ g# E& L5 ? else
- ?/ n5 c: Z1 J return 'E';
$ k7 V4 O: @, O3 v3 L case ')':
% r5 ]( U; Z- b }4 i3 G if(c=='+'||c=='-')% H3 [( R1 E/ n/ k7 v
return '>';
% X$ }) `, ~. L: x0 B else if(c=='*'||c=='/')
% @9 }# x" n9 @+ H2 ] return '>';
1 o( B" d9 ~2 F- i" t. u else if(c=='(')+ A" i' p: Y2 w) G. P# R1 v/ d/ x
return 'E';
( _7 g( L) Z' @1 Y- e" L8 m- p else if(c==')'), X y1 @' A! X7 V4 Q9 [! ^
return '>';
' R7 P, c+ h6 u+ t5 [1 b, s2 Y( I2 Z g else! g( z6 c' z, }- R4 `9 D. B# v
return '>';
# r2 i3 p# w3 Q5 q case '#':6 ?. H2 S& V; e- t( X: l- Y4 v' y
if(c=='+'||c=='-')' R" X7 j9 u0 i- L
return '<';/ {* V1 k, ?! w+ ?: i7 F
else if(c=='*'||c=='/')
: ~& P$ g5 { F7 }& e/ ]0 K return '<';
) U, S: `" O+ z else if(c=='(')2 B# g; ]0 i n
return '<';
+ r3 ]2 W, Q! Z' \ else if(c==')')( o5 ]3 ~- ?3 M3 R: R6 s
return 'E';
. ] n, `& U( A- G* L else
3 a/ D7 Y' k1 @; X B. i return '=';
, s! B& n/ W, e8 |; d4 C default:
: p: o, Q& l7 }6 H8 V break;& |9 Q& |; N8 d* N
}
6 R5 Z4 U D$ g2 R- L/ k return 0;
- T# j4 {+ Y/ f( z$ G7 G3 h}
; j% x* L: R' v6 ~
; @9 d/ c) b% {int isOpr(char c)1 D/ Y7 n0 B: C& \+ R3 ^
{
+ B! g. i, ^0 { if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
) }$ I, [/ S8 a) L1 c$ I; j2 ` return 0;
9 X2 s. b0 m. |# h3 W else
9 _; }7 m3 ^: z7 i8 ^* m return 1;% f3 j/ d; c9 M) {1 G2 X# A+ ~" j
}
$ t+ o1 I( n' E" y9 l- s* S2 j# K8 g- R' m
float operate(float x, char opr, float y), o; a- q4 H. N2 ]
{" a$ t5 B3 ?& x, F+ X
float result;5 N+ R N# o, o T' N" b( [. ~1 U+ P
switch (opr); q: }/ [! e1 `7 r
{2 u! M7 k& K- c, X |( V2 K
case '+': 1 j+ U# |, |6 j7 ^. u
result = x + y;/ t: i* W+ o& Q$ V* {
break;
/ [; p! K2 u, q/ w case '-':
' v4 {9 C' A. [) j# Z4 A/ P result = x - y;
4 R+ {( Z( m- b1 d7 E0 R: M break;: I- q& S' N* M/ g: w& E$ a
case '*': ' r; o" F9 |' _7 l5 A) I! \. X
result = x * y;
! A" u3 b8 U( y. [+ o2 K break;
6 u/ q" u9 E4 {6 h2 t: @) X% t case '/':
2 ^2 J$ V' L. u0 M" ^8 i if (y == 0)
7 _6 @0 W8 H* K+ @ j- q* g( j; N {
" ^/ B( Z. f* V9 f3 K printf("Divided by zero!\n");
& q! b1 h9 }0 I+ j% } return 0;( [, r6 _4 T( E$ h0 j
}
U& c2 a5 A9 \: i/ w else' \6 Z2 ?; I0 j7 [2 ? K
{
+ H% @3 @: S8 y0 e$ B5 O# S: Z L result = x / y;& j2 G! p, G8 ]/ Z. f/ [
break;
' ~, I; J* N1 Y, D. o }
1 H- f) z* Z$ q2 F/ s. j: o default: 1 m# K' l+ b3 {% {" r( K' e/ W
printf("Bad Input.\n");
5 z' |! \2 m/ c! n6 C0 d$ v3 w, h return 0;' Z' ?; \, u8 N3 G7 M8 P/ U
}8 C3 M- O) ^$ e! J h0 C( g" V
return result;& {1 t [& n$ ]: M) O/ b; e* o2 R+ u! U
} ; D! U& B4 Y1 E% \, z% N4 z
( Q- S6 |, O- h1 L9 b0 {
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/( q0 A# W/ T4 |) |
{! L! p X" f$ q" j* S' [( U
Stack optr,opnd;
- K9 L4 d6 q' c8 B5 v' F- Y struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
$ S M6 I% L' C' ? char c;' |2 c J1 X9 g* }5 `& d$ a: J' v3 n
char buf[16];) X7 y- ]) a9 [8 S# I0 L
int i=0;
8 L# M& K$ W* ~: `" `& U8 n " P# f2 `. V: x- d W) Q; D
InitStack(optr); /*用于寄存运算符*/
7 c5 A$ J X4 P3 h9 q, W$ W. q; q InitStack(opnd); /*用于寄存操作数和计算结果*/2 @/ p) E( w, Q1 J' E2 o# ]7 ]
memset(buf,0,sizeof(buf));
* E3 U: Y# X( F ! n! P n3 h) I6 B5 S
printf("Enter your expression:");+ x/ o+ G0 ?' K {
& p6 t' S% M+ j; }) ~ opr_in.ch='#';
a8 Q$ U2 ^' g Push(optr,opr_in); /*'#'入栈*/
5 z& j) i9 s4 o8 H. G& i- ^7 |) z GetTop(optr,opr_top);
9 a2 }' F5 j9 ~$ b( {4 w c=getchar();. S% d% C6 `$ M
while(c!='='||opr_top.ch!='#')2 i- B1 Z# L } y8 O
{
4 \7 _4 J( l9 X# r0 M+ N if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/6 i, j0 s! a: W
{. B* T9 e; u% U
buf=c;/ N! i4 @% N8 H8 r2 V; a
i++;/ m, L& Z& r/ `1 Y( {6 c& q% e8 V
c=getchar();
$ w3 ^+ T0 S! y, m/ c# F }
$ g5 a) p; |" P+ o: k4 | else /*是运算符*/
# N' L( P' B0 L( }) P {7 w: H- W5 e s- X
buf='\0';
- j+ a" u% | r, g if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
9 B" j- z$ R( r {. [) O# `9 B# h% I% D% _( {
opn_in.data=(float)atof(buf);1 K6 j* O- H5 e
Push(opnd,opn_in);
# e- }$ T w2 ]8 s5 n+ b printf("opnd入栈:[%f]\n",opn_in.data);7 {4 d. Q" L- o% Z( Q
i=0;
$ {: c1 w( V2 {; b1 x memset(buf,0,sizeof(buf));% c- |4 ~7 ?" y7 P4 O+ f
}2 C0 A7 n: B- \
opr_in.ch=c;& w) ^; d/ r/ e4 t& m5 [. q
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/1 F, P$ g' r4 A# a. x
{
. j1 t! z% h$ Z! ] case '<': /*优先级小于栈顶结点,则运算符入栈*// D' u% {: }) ]3 q u
Push(optr,opr_in);
' P& X7 I3 V- `4 F- N2 N6 M printf("optr入栈:[%c]\n",opr_in.ch);
1 H. m# {5 }$ D. T- G: q c=getchar();
6 x2 S. ]8 o; r% g2 \ O. j+ W break;
- Y- p# b, B1 m% L, ?! x case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/: C# \5 G6 E0 h( H# d' d
Pop(optr,e);
4 R6 F9 f- r& h" K printf("optr出栈:去掉括号\n");
0 x: @/ U- [, I: `4 r2 [4 ]7 q' M c=getchar();, O1 p6 g" G8 e5 ?1 V: \8 L! a
break;
: S" M' ]6 B1 m p! q6 S case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/9 {+ D. w9 X$ W" D3 D
Pop(optr,opr_t);" r; M. W1 A0 w, e, S! w2 K
printf("optr出栈:[%c]\n",opr_t.ch);
5 T k. X2 c: |% [' h( L if(Pop(opnd,b)<0)% U9 |( t- g; j% X
{( p/ e5 ?' {& l8 y0 V
printf("Bad Input!\n");" G+ ^( M) h3 U( I" K
fflush(stdin);1 `7 e' L! f7 j; X
return -1; g3 d8 t1 R) N& D: a; M
}
3 J2 A- y0 f. K2 y8 _4 M printf("opnd出栈:[%f]\n",b.data);
% V/ g5 L, w/ e' O4 w if(Pop(opnd,a)<0)6 I" R! g- n1 A- d+ Z" w
{8 R1 O( Q5 K& R [0 Y. q
printf("Bad Input!\n");
0 Y3 g4 ]5 R& U3 @$ d9 U fflush(stdin);9 p8 n3 j1 r5 H- M% Z' z& l
return -1;
& b* \4 R* l/ x1 e/ R. p }
+ d' D% y, |$ L; {$ @ printf("opnd出栈:[%f]\n",a.data);$ l/ e* r2 [+ N' s* F
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
8 P s+ O2 h5 P- t& c Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
: G4 R" v* D: f5 V2 Q; r! | printf("结果入栈:[%f]\n",opn_tmp.data);
! O& X1 T; Z6 z% U break;8 e5 g- s1 W* p
}
- k1 v9 m8 j g+ w9 @ }
. C3 }) O$ o0 C1 h8 Z GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
7 a% g! A( J5 B# u }
! d8 T, }3 j8 I# a/ k! u. t* b$ c GetTop(opnd,opn_tmp);
3 [, \4 Y5 [- R) ` DestroyStack(optr);
) z+ h) S; w) @7 b3 D2 i DestroyStack(opnd);
- @5 V( b2 g" D, c1 t- m& L return opn_tmp.data;8 W& y# E& ~7 X
}( R. d2 y5 L0 G8 ?; |8 V
% J' q" K& i. q) {4 nchar *killzero(char *res,float result)
9 w- ?4 e: |8 d; ~{. ~1 y9 G8 S' q t! S) _8 g' q2 I
int i;) I# H l, k1 w/ v- c6 a, o
) X4 h7 A6 i. a& N1 C: I+ R
sprintf(res,"%f",result);) n, s& ?9 }. C! ~; e$ A
i=(int)strlen(res)-1;
- {* x, B+ i! w! O: ]# O- n5 c! g& @8 { while(i&&res=='0')
' G# w" A. ~# ? {$ h' f9 x# _ q" O1 g- u
res='\0';) L* E) J, u; x7 B# r" N# W
i--;
i- P" l9 F. u8 L8 C% I* O }0 e0 f- }) I/ V0 C
if(res=='.')
: Q5 K% a3 i% C: @: e res='\0';
+ t2 V8 ?$ S& Z% A return res;
$ _( M3 p/ n! N1 D0 p: z}" C7 v* }" g, o O4 N
$ K) @7 V% x3 s+ k: I% ^int main()
) D) u6 Q: B F{$ O$ Q& f/ H/ C5 ~6 u; D, S
char ch;- C0 f% e2 u- H3 p
char res[64];% e$ Z! G O: O! X& i2 \4 Y
float result;' V& t1 \$ Y) t, a! @
while(1)
. J1 E( }' I: Z9 O {. D6 \" \8 w7 r( z& T2 c2 a& r
result=compute();
9 v+ m6 q+ o" w# C printf("\nThe result is:%s\n",killzero(res,result));1 M- o4 c- f2 Y/ u1 x. `
printf("Do you want to continue(y/n)?:") ;
' v _7 M/ w! D3 U* p% W ch=getch();( T% |* t/ s2 U! n( ~4 K
putchar(ch);+ ^( i2 z2 g0 d) a7 c
if(ch=='n'||ch=='N')
! V `/ G$ b& G3 n9 H break;
, _. z4 W8 n: j9 p else
5 ?' q9 K& y3 o& I2 ? system("cls");
7 `3 w. D% j" Z$ Q& v }
4 p y! D$ ^- B" I return 0;; f# Y% B# v9 S
}
9 d8 q6 E3 G9 l3 W7 t" q* E$ x
, o: z1 R& X! U! @[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|