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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.' t) U! F/ U [4 p! a( i7 p: Z- M, ~( x
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=$ \* E+ ]8 B5 H. l* {
/**************表达式计算器************/
8 \5 b2 U, @$ D#include <stdio.h>
" H( q/ {( m2 r1 G1 v#include <stdlib.h>
. T& m. e) I0 M3 _5 E#include <string.h>
$ |1 C8 O' p/ g$ K#include <conio.h>
7 Q( l' m; k+ ?# D* s#include <malloc.h>. {: H$ D2 `" [
: [2 f B+ }3 y2 D1 e#define STACK_SIZE 100
+ @ x4 [! A6 G# _3 H#define APPEND_SIZE 10
q) P; C% V. c6 D7 N/ Z( O) j( |5 S) `' V6 q) p( d: y
struct SNode{
* f: M( X- v# A0 i, A2 I float data; /*存放操作数或者计算结果*/
' `4 \4 ]7 C' a! S3 n3 a char ch; /*存放运算符*/; u9 [/ t- u3 `# ?
};+ u5 @6 S5 n2 M7 `0 D
! r! W4 w5 M( W( H" f6 `
struct Stack{
- N/ r$ ^. N& z& j. M2 W o3 w" D SNode *top;( |: o3 D. l9 R8 H' K, F; N
SNode *base;
5 _! C/ g. @9 n. Q/ ]# L int size;1 x9 r' ?# \. W. [/ q6 K- [/ w+ i
};
7 {: \5 b6 C# i( {: U. O* r8 E% b. [5 D* d7 R
/*栈操作函数*/
& P9 S- J" R# V5 ~int InitStack(Stack &S); /*创建栈*/
! b9 e; K( c2 a( I+ S) {int DestroyStack(Stack &S); /*销毁栈*/( j5 T- N+ G: B1 [4 f; p
int ClearStack(Stack &S); /*清空栈*/, f: `1 `* N" h' K: l" L
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 \) {/ O" J+ D( iint Push(Stack &S,SNode e); /*将结点e压入栈*/
* i* I( T! }8 h- `4 aint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
( t- a8 d$ h0 z9 U" f4 Z- u( Q! O
/ n" w3 X( o# m% E- v( I/*表达式计算器相关函数*/
' s h3 L8 `8 e% S: wchar get_precede(char s,char c); /*判断运算符s和c的优先级*/! V+ A6 ]. {: O: G( I9 d& l! q; ^
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/9 V b( G z+ A; u- m8 @& b
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
0 _( [% }' u* S; Z/ L7 gfloat compute(); /*表达式结算器主函数*/
2 F5 B& F: D+ m0 f/ nchar *killzero(float result); /*去掉结果后面的0*/ 1 s7 d# Z1 s2 s4 y, _# W( J
# i& y. L1 g, r/ G0 E* G
int InitStack(Stack &S)9 E. b F" Z+ o1 `7 |0 T) w
{
5 \6 C% l( @/ Y. t S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));2 L5 H; |; S9 @( w
if(S.base==NULL)
6 G. h6 s5 _; `# [8 u, K {! \6 z1 `* P. F( D6 |
printf("动态分配内存失败!");& i' N+ @& d! S1 y# k- C' H7 D
return -1;6 V1 a( ~+ i2 E! N0 b& T+ E
}
1 U- u$ B. D9 |! |0 L S.top=S.base;
" L, Q% _+ S! n5 M' @- h O S.size=STACK_SIZE;2 S! [, [1 T3 w$ C# s) k
return 0;# X$ n% |3 N6 x$ B: p! t5 h
}
|+ L U8 x) o7 h" A, Q' L: P& y" _4 ~& B- o) h* Q6 d7 W& q
int DestroyStack(Stack &S)
5 F( a) k/ R- o5 c* Y9 i" s{* r9 `+ [ ]7 G' I( M; g
free(S.base);4 @# ]$ ]- I! C8 \" o+ B
return 0;" F/ G# c2 p* ^0 z- z; \
}2 e, o6 `( x7 e5 v
/ p' |# A y" v7 uint ClearStack(Stack &S)# R& l$ S7 x- L0 u9 ?( S3 Z/ a
{
2 l% k. X( B* d! Z3 O6 R S.top=S.base;
5 }9 ^4 }* O% L6 l return 0;
, _- W* `. t, ?/ n4 d9 c! w5 f- I}( F3 M E9 V* ]7 }2 P
" y! F' B5 t* G, @) E! n9 I8 P
int GetTop(Stack S,SNode &e)
9 c8 J% C5 S( N! J{
0 t) W5 a; q; y+ @+ T: w if(S.top==S.base)9 S( n5 [: O2 n( u: I9 {4 i; B
{
# N+ e" v) j2 V z" Z( g# Z printf("栈以为空!");4 V% r; ], S: c5 K5 b9 F- J
return -1;9 z* G+ I( C9 m9 h, S
}+ K% H N' a4 e2 Y1 E) l6 z6 E
e=*(S.top-1);
% D2 T& Y& ?" O4 p4 F return 0;
7 y+ {$ P% C. {/ a7 k1 W}$ t6 d( g/ ]5 p$ v/ U
" w+ W# l. m1 K' t
int Push(Stack &S,SNode e)1 N% i3 c1 w- e: F# w1 f" c
{0 G! B* s* g9 I5 L# K+ d
if(S.top-S.base>=S.size): H$ a$ ~9 g6 A7 z2 T7 Y" R
{# x3 ~( {: l% a' X: I- `9 [! Z
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) C3 V' Z; v0 C if(S.base==NULL)
# K/ T3 b( ~. p$ W# w1 n% H {
9 N3 q2 I: s, v; w3 { printf("动态分配内存失败!");9 ^; w8 Q2 Q- M$ W/ ?$ C `7 s
return -1;; {' }" v2 G9 \, w
}8 ?: a: L) l( u) c! ~4 i; S
S.top=S.base+S.size;
1 A+ C; n8 k# @0 \# e S.size+=APPEND_SIZE;
1 k ~! R' V9 {5 k9 i }
5 o, n) }- E" j: H3 a3 p; e *S.top=e;
$ ]: d) j# ?) Y+ e S.top++;
' T3 W1 i% l6 F2 w0 o- I& |3 N return 0;: D' U) x9 Z4 ?( ?) H
}. @, ~7 a" f3 N Z6 Z& W n; g
: h' S1 D; P5 F! F
int Pop(Stack &S,SNode &e)/ m) S# A" J/ S0 A% ^) }
{
. K+ K+ @: Z: _! Q$ ^8 B# {$ q if(S.top==S.base)
$ @% r/ R, f a, B {6 [$ l, Y5 U# G3 I
printf("栈为空!");1 l, U5 e8 C1 ~9 i
return -1;
9 C* O" k/ R% C% y. T6 o2 }0 ~ }
* u7 N" E4 `7 L; B e=*(S.top-1);
) w2 ]( }5 M2 L, l S.top--;% W! W" \( h" u% V# Q! G7 [, }; d
return 0;5 B' z1 Z7 ]! \0 J& q
}
7 f0 d0 D2 X) U! J& m( w; x/ |% v6 v4 X# x3 F
char get_precede(char s,char c)
; A$ M: B! B; c0 O) [6 m{
3 `6 v3 b H& L' a4 R switch(s)$ O1 R7 J+ V2 G7 e$ C2 d
{
# e0 b: {' H4 }: f case '+':
K5 g! h8 d: t/ E' L case '-':: `$ w9 a3 O* w4 S7 D8 u3 O3 o! ?* r
if(c=='+'||c=='-')
/ I) @1 H+ M, A$ R9 n5 b. Y return '>';
! h$ ?8 u% z" b. f) ` else if(c=='*'||c=='/')9 x* r( v& U+ O: `' @' U) |
return '<';! ]9 h! y4 t* b- o
else if(c=='(')
6 x. g p0 A w2 e8 n: v$ @0 ? return '<';
8 s. S* n. J* w9 } else if(c==')')
/ D8 d0 U c [4 H8 y1 [ T3 j0 I return '>';
! `( v! _6 m& }& ` else
) H9 B( O7 P( _3 k! F! P return '>';' ^- a; a' n1 z) H; K7 r
case '*':, q1 [$ X* t) a8 z1 h) D
case '/':
7 B( C4 i4 _9 e4 ]/ e if(c=='+'||c=='-')
' E+ r. }$ r$ r E2 @ return '>';9 z: Y2 q$ S2 P1 U; `) F# P
else if(c=='*'||c=='/')
( \- [' Z5 c! q' ^( P! O" |& C return '>';
0 c4 J9 M. g; u. p% u q2 J! ]$ A1 c else if(c=='(')
5 G; F& s- P7 j3 }6 d return '<'; z! i- h# Z- K* ]+ g/ z
else if(c==')')- ?/ M5 L, K- l1 E) T
return '>';% y- c0 @9 [+ n5 p7 B
else
R) R) a: h7 \& \! f- U return '>';- B$ L4 _6 [9 K4 B
case '(':
# M: Z$ |2 H2 v. N9 v s if(c=='+'||c=='-')4 p+ d6 y9 I7 ?' b
return '<';1 k7 y; u6 F- J# x7 z" g3 z5 m* {
else if(c=='*'||c=='/')
& ?0 D' {1 }1 G" L6 c return '<';
+ ^# G, @; o1 P. p else if(c=='(')
2 _0 Q: G* W6 H# k; U0 t5 e3 \8 | return '<';; s% R+ q& p7 C2 B" q/ ^& N
else if(c==')')7 y9 s& ~$ |+ _/ Z' {" A. Q1 |
return '=';
: e% @. K0 L; H5 e t# [$ X else
1 e2 t" @0 I$ }' \8 X1 ? return 'E';
8 N3 \# Z: B1 {, Z+ ]# o2 Q& u# m case ')':
) I m$ }) i% u Q if(c=='+'||c=='-')
8 L5 _' M1 L/ A! w6 P; ^ return '>';* A) F/ \3 K' r, n1 ]1 k6 [
else if(c=='*'||c=='/')
{1 q( Y3 ]0 }9 @ return '>';
4 N0 |0 P" u- H% X else if(c=='(')
- G& | R5 w) a; s return 'E';
: {% x ~( f y5 s: r else if(c==')')6 h9 y3 X( q2 s; n; P) z. o0 |
return '>';. T" \* o3 e; i9 W; f
else- G I7 N9 s. T; M* n# |
return '>';3 N) ~5 X5 t$ E O6 w
case '#':. w$ `( a1 F: o% G s, i
if(c=='+'||c=='-')7 t- s S) V( O$ f7 i
return '<';
6 C: R* T: H2 y$ r else if(c=='*'||c=='/')/ k: q, t: h5 y0 `: s/ t
return '<';% X9 Y& S% k- n$ J9 @2 b
else if(c=='(')
6 S3 K# o! n' P3 C return '<';
! k# x) Q) S* |$ U0 u% o else if(c==')')9 W4 @4 v& i" }, K
return 'E';, O" d- k. ^( _5 }7 U( q, K
else* x2 j" k9 F* f" Y% ~
return '=';
6 p& W0 W2 g- h, E default:
9 e3 g# |- ^( ]% U* l break;
; @: U! p4 }4 f& u5 T0 g( U! t }
3 a0 z) L" Y6 w* I5 T2 @ c return 0;
+ c& u5 M( \( Y2 a7 R, L. m- h" ~}/ _0 e3 P( h! L, l
, C9 U t- v1 y6 R3 Jint isOpr(char c)2 b) t! C1 n9 d+ ?
{
q. {. O: U, p d9 l. A if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
. l# J7 m. {# {! N: h/ H+ p return 0;5 d. w* ]2 T7 ]% c- G& F9 p" E. M
else 6 E( G! B+ \6 O' J4 u( J
return 1;; b9 u! b3 \. ~# T4 D" v8 I
}
, ]6 j% _- U! [( S8 j& o7 x$ L" E1 A3 ~. G. v! s1 ~ t: p
float operate(float x, char opr, float y)6 b, O; y: Z* @
{. S* ^' g' w0 W1 P3 u
float result;
; D+ M9 [6 j0 B switch (opr)
# x1 c; J' T& J1 [ {6 X% g4 m4 U N7 g5 w
case '+': , g8 O( i! N" I* f
result = x + y;0 @- Q& r4 C, N0 Z/ w
break;
5 B; n# e+ R- {, M6 B case '-': * G/ b: a3 E; e- n/ }( `- N
result = x - y;
$ r2 F3 V- h! W. v break;
1 h Y% h6 B0 b) g/ P0 N5 Q case '*':
+ G& ]1 n; | j. I result = x * y;
0 x9 ^" B( D/ u. |8 _ break;, T' @$ V" T5 L
case '/':
. ?, k* J( I6 P: c" V- I if (y == 0)5 C% {# d' w: u, X2 W, c# K
{8 _ Y. f$ r. F$ U5 H1 u
printf("Divided by zero!\n");
. N, w$ @" N: f2 a' ^& C! l return 0;4 O9 E1 k6 C2 B4 e
}
n; Z. B; l8 T/ E. N! A+ l; ^ else+ @3 C( {& j: S: c
{5 p- r! H: D: l6 s( ^' j* h5 A2 Z/ p
result = x / y;
4 V! n2 @+ `" Y3 y! k1 r break;2 J5 [# d: O+ h, Y
}
4 ^& \1 ^7 e# p. W, s9 | default:
! Y0 G6 `" i: J4 [ printf("Bad Input.\n"); ' q2 s. {6 R E$ z. r3 S, t
return 0;
? |2 U. g( ]* w. B0 k5 {4 u }7 l( n( X4 O; B; C4 G
return result;
. b+ z' j$ W0 x, y}
) ^9 c7 M6 g' [% w2 O, c5 O' H( \: I D4 W" X& U$ U0 Q5 M
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/7 P2 E4 Z$ Y) V
{9 R5 f" _3 X1 Z b1 C ^
Stack optr,opnd;
N0 b, {! G+ n* |& v8 f, l; v struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;8 V T8 t7 v& G) A' n/ u& l
char c;
R% ~8 j8 m9 p' G& w4 Q, t y+ a% c char buf[16];
j. V+ N& u' w! S$ V int i=0;+ N' U8 C& J+ L& t! U3 G/ W
' u+ G, v1 y' B InitStack(optr); /*用于寄存运算符*/
- H) k( O; s# f% H; b InitStack(opnd); /*用于寄存操作数和计算结果*/! g% b# j; f7 h' {3 f9 ~. J
memset(buf,0,sizeof(buf));
+ L ?% e* _* T4 k, ]0 l5 _% S6 }+ a v
1 d0 p4 R7 o& l; x$ x9 r8 o. z/ V! | printf("Enter your expression:");$ x" T3 t: @8 _# h/ l& _
. x- B+ s& O# B2 l( p opr_in.ch='#';/ W1 {! y# \& M' R
Push(optr,opr_in); /*'#'入栈*/
5 j* q; e0 h( f( N7 R GetTop(optr,opr_top);
! n$ h/ S1 M5 n c=getchar();0 U% o: F0 C1 w
while(c!='='||opr_top.ch!='#')
& t8 ]6 z- ]8 A$ n8 ?0 p {( f) a9 }- g" x, E) d% Y8 v
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
8 _" [/ H3 k0 n4 O. S, }* s. O {& P* T9 I: z4 b& y& I# g
buf=c;
% X- v" z/ l" b) h- j i++;
! t' M8 ~7 X( b; X2 j' W c=getchar();1 |/ `% g" j9 r$ S2 V& X# Y
}9 g# o. a. C$ ?/ K2 u8 F
else /*是运算符*/
: ]; {5 w( n* l1 D; G6 t4 w9 J0 T {
* l! |6 R7 x4 | buf='\0';
2 F& q8 _: F2 D) ~) t2 [$ q4 Q if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
3 V4 s9 z* ?* H9 ]9 D$ D' y/ H {; }2 u$ j9 f. Q( z& q; m5 k
opn_in.data=(float)atof(buf);' b, m! a" q3 P0 J1 D4 s* e
Push(opnd,opn_in);9 O7 @1 H2 {) ~
printf("opnd入栈:[%f]\n",opn_in.data);
$ C8 L t( f( u. H8 @% f i=0;
, {9 r, i. L; |% h0 ]% i( p) g memset(buf,0,sizeof(buf));( l8 f7 {9 f( X
}
4 L+ ^0 E: \# @/ |, x( f0 F opr_in.ch=c;3 n, S! d/ H1 H7 e
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/; V# a; h& W$ h
{. ]+ C+ K) t( P8 S g$ D; T
case '<': /*优先级小于栈顶结点,则运算符入栈*/$ M: O4 m7 I- n* S* p
Push(optr,opr_in);
; g y( D, f5 v" s. P printf("optr入栈:[%c]\n",opr_in.ch);
* R/ C4 N% ]1 K$ G c=getchar();- y: K8 Y g! q2 d* y
break;/ ]3 k# V: H9 l6 r
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/; _0 l0 P1 a: c: T1 Q2 F
Pop(optr,e);& z" G" _- I( Y2 q) C
printf("optr出栈:去掉括号\n");; d) g" y* q5 ?6 k5 |' C
c=getchar();% |" g, G+ _2 Y4 K* u: V' w+ S
break;2 {7 b @2 B, A( R8 Z
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
. M( A0 N* p9 t) J+ Q! y Pop(optr,opr_t);" b) ~; \' k- G Y
printf("optr出栈:[%c]\n",opr_t.ch);
5 I ~$ |9 Q0 T/ ]! C6 R6 s) ]. D if(Pop(opnd,b)<0) a/ Y! E9 ?7 q# H! {
{, T# Q/ T9 i9 I( |
printf("Bad Input!\n");
6 X. Y* J" a" k) F1 ]* s: S* n0 s fflush(stdin);8 ^5 s$ x! y1 U# O, a( N
return -1;
1 l: O: F; t$ h9 n+ @ }
9 s# h) k; A" ]5 \- [# n- Y6 P printf("opnd出栈:[%f]\n",b.data);
; i+ r: @$ _2 a+ `4 \. ? if(Pop(opnd,a)<0)9 f* X) S% v+ O, c6 f, H' w0 e
{4 x7 a- Q8 g- A
printf("Bad Input!\n");
# E3 b2 d9 |+ z; y( \+ { fflush(stdin);
/ J3 f* \/ G' q4 \! X- B" f. x+ O return -1;8 j/ y, K0 w) q) z( }( L
}: h" G5 f! H5 L z% q5 }
printf("opnd出栈:[%f]\n",a.data);
0 Y8 x$ [) ~& J3 ]3 G opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*// E3 O9 |2 {% @0 ~' H
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
+ [! @( ?7 u. O! g3 j2 a" n! u7 K3 ^ printf("结果入栈:[%f]\n",opn_tmp.data);& p* V5 O4 c1 ~ s' ]
break;/ G7 b( Z0 j0 _, q2 r, z+ D6 p, T
}9 P5 l+ g% C5 _" |; o
}
9 q% x& B, m# V GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
( `! Q0 d5 v7 |0 O9 B# F* L, M B }; c3 N" B- G4 R
GetTop(opnd,opn_tmp);9 D, c8 `7 n+ _$ ` l |9 Q
DestroyStack(optr);8 O, o* ~( W/ x( c9 a8 b6 e2 c
DestroyStack(opnd);) M' F4 I: D5 y9 i- ~3 ~8 X1 k& j
return opn_tmp.data;
+ q4 Y7 K j( ~}
, j" D' g7 e9 \* ] b' y* d
/ J0 ?" v7 s7 n/ L' o) Zchar *killzero(char *res,float result)
F$ m. X* M2 h2 d' Q# O{
# V2 j5 n) l3 V4 R7 t0 I1 V% w int i;
( Q/ {/ }& Q, u( V8 ~- V7 Q$ u p# Q3 S) W j/ J
sprintf(res,"%f",result);0 \/ ]& T0 J6 g! G7 C
i=(int)strlen(res)-1;
2 C @" W G7 @' Q. f while(i&&res=='0')
% W; T1 z3 }6 Z3 r. B+ P7 \. p {
; `0 N) y( g5 r/ }; H$ @2 J! e# w& m res='\0';, ~& y2 P4 O. |1 O6 B7 A8 V/ Z
i--;
' E8 {7 ?! W4 \4 n! Z$ e }
: ^( E" d2 M5 S5 c J+ H$ u if(res=='.')7 R3 }4 C! }; _' [, B% W ^
res='\0';3 j5 z" ~" f$ X7 u, G& f. [
return res;; _3 s3 r8 u' K( {- d; I5 H+ G
}. o# G- K) N( u0 u- g, y0 o
) F, x8 Q7 N; T
int main()
c1 v( d# X" h7 P{0 @% X9 j, h2 t
char ch;
}& i( U5 U* {! p2 w0 {2 g char res[64];
; r& p D6 L: L" u& B9 g float result;1 O9 d: P( B& U9 s; V
while(1)6 w, T. Q4 g& n
{
3 ]3 F! i. W+ W! t/ K- q result=compute();: M3 K7 o2 ~2 l' V1 f8 t, D* x# }, }
printf("\nThe result is:%s\n",killzero(res,result));8 f& O: P1 `1 d6 h6 ]# {7 e
printf("Do you want to continue(y/n)?:") ;
$ N& W8 T/ z# m0 G8 P2 ~$ \1 ]! ^ ch=getch();- X# g9 Z' V8 B, c2 u
putchar(ch);7 t/ N9 N$ i }! O
if(ch=='n'||ch=='N'). V2 x B* Y: I* f- _1 r
break; w. c$ ?1 j( h% w9 i9 G8 a3 v3 [
else( E% z! t/ A+ s0 m' z
system("cls");& K, `8 X1 Z( y+ X$ \
}) d' ?1 @0 }% {0 k8 V1 p8 J
return 0;
2 o+ `- _) r8 y6 j5 j8 [}
. g8 K! f3 r7 t
7 P `6 N o9 j: H3 T/ H[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|