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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.# i7 B7 h$ {' `' E
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=0 K3 g" [4 J6 J; V7 W0 Y5 q0 J
/**************表达式计算器************/
0 Z' P! x+ S8 Z f#include <stdio.h>
% y3 w$ `8 @ m1 z1 [! f# A#include <stdlib.h>- C3 z2 p! j. F, M
#include <string.h>
2 r, z* D' n* M, d4 ?4 b7 m#include <conio.h>
6 f% a' F3 v }) D. [6 ^$ A#include <malloc.h>1 T0 t( \' K. C5 M6 K# r
4 q9 }6 d: F Y z/ H' p$ n#define STACK_SIZE 1000 b0 ]1 k' `+ c3 U% c
#define APPEND_SIZE 10# p t9 t$ ^# N6 V/ H' \% ~: Z3 j
' _, s+ Z$ ~* E1 U9 z( [struct SNode{
2 ]* }0 I2 K" W5 {8 p4 F2 O float data; /*存放操作数或者计算结果*/
5 V7 ]: g! T! N3 a% x' Y0 O char ch; /*存放运算符*/- U: g5 g; Z& C: O( i: k
};
) z7 N, O+ e, w2 q
' t' s, C0 V; [; O$ @3 xstruct Stack{
* q$ {( H4 ?! ~( D SNode *top;4 c# E7 l3 K0 |/ K6 G. O
SNode *base;
1 z8 e |1 h! ^. i int size;9 U8 Y9 B7 {. t$ T8 A# t! ]5 H
};, g! ~ n) O( ]0 c. P
- Z- f1 }+ p$ |+ k v z/*栈操作函数*/3 k% B- m9 |/ s' {
int InitStack(Stack &S); /*创建栈*/
% [8 Z: `7 n4 K& F5 Oint DestroyStack(Stack &S); /*销毁栈*/4 {& a! J. s+ ]8 h0 L+ B9 O2 x
int ClearStack(Stack &S); /*清空栈*/
* K# w' \ a0 r. ]- C6 jint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
: o5 @: D5 a( e) Gint Push(Stack &S,SNode e); /*将结点e压入栈*/
9 b& l7 h `. C- ?0 H! l$ E# w8 Uint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
! ], O& i L/ A; I2 m+ ~( n5 e
- D6 O9 x0 ^. c$ o/*表达式计算器相关函数*/! L' L4 K* k$ y7 u' @7 E9 s
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
1 U9 E4 s: H6 @0 E# _! N0 Gint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
, H5 N* F3 p$ e2 Y) ~0 i* M4 H9 Mfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
) H9 l, ^- o( [4 g; P' Kfloat compute(); /*表达式结算器主函数*/
6 x8 X- g/ r$ Cchar *killzero(float result); /*去掉结果后面的0*/ 6 n, G9 k$ [0 p+ r
4 \# x4 t. j& ?% {9 T/ W/ xint InitStack(Stack &S)0 i, q3 B5 R3 H! p; j z. s
{" g* a! Y8 q* A3 L. j! z* r
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));, @6 H/ M% X) l. N# w" G# [
if(S.base==NULL), i4 n8 M* t& t
{/ h& {' T; P- L
printf("动态分配内存失败!");' g% N- F) u0 M* q- g8 V# b0 B
return -1;5 {8 m4 }- |% o9 O; S2 I
}
6 t: U8 S R7 E" a. J0 h S.top=S.base;
$ S9 s" r; m2 ^& h8 ]9 r; u$ X S.size=STACK_SIZE;
4 @( P, f9 r: g$ A+ Z return 0;8 v" G' h$ B1 R) j( \
}. V6 R g, v1 @9 p2 O% x
! x. j, T) z! g. fint DestroyStack(Stack &S)
, f; Y; o0 A i3 M{
% ~$ l$ J9 K* H' G7 i3 g' d free(S.base);/ J c) O6 l- N
return 0;0 c1 O; a: a# d; l9 D6 u7 @: I) m
} h. F: K4 ?# _: m! d$ J
7 a: U. p1 d2 V! g# G. nint ClearStack(Stack &S)
! E0 y& ^7 C3 A{ a, S; P) C [# Z, y
S.top=S.base;8 e* e( C8 T8 F' |, M$ I1 H
return 0;
4 W& Q& q- F; g! Z2 h {: {1 `}$ Z2 u8 x% ] M% Z+ `/ v
& @) o4 b$ c4 s
int GetTop(Stack S,SNode &e)
7 ]0 g4 q1 G, \3 m; a{
; M' `2 t2 f, D9 P/ ~1 W if(S.top==S.base)! X. L- m; |, S3 l
{
( r' I. q* r$ ?: O% f printf("栈以为空!");
# P. A9 F& D$ n. } M! D+ d4 T return -1;
- ^. e: A' K1 E- i3 m }( E& m% R. Y6 |# o/ i" S
e=*(S.top-1);
6 D6 k5 g' ~$ Y: P. ] return 0;
' N: t& i# T/ q) ]5 n7 I/ Q}
7 q; j: V5 a8 o5 |8 D% q7 r9 Q& p% v0 h; ^, q. w
int Push(Stack &S,SNode e)
% P& [+ d3 d5 K* G" S9 r4 h) M{8 {- a) C+ [5 ~+ |
if(S.top-S.base>=S.size)
) S8 F" g& l" L {! j9 N- G0 u: M0 `# `5 ], P
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
w% v* W6 s# E& v* d0 b if(S.base==NULL)+ ]. y; u( u# G" B4 `
{
# l' ` N3 \% s# Y7 N printf("动态分配内存失败!");' i2 `( C. O6 N: ~' M
return -1;7 E$ a( R7 G4 |4 }% L/ u0 g
}
. ~9 `4 Z9 [6 ?7 w! {" |) ` S.top=S.base+S.size;; v" t! ?# i6 S' e* D( O
S.size+=APPEND_SIZE;) J4 p5 q( Y4 M
}& O, m& L) P, e! Q" M V" J0 S4 q2 }
*S.top=e;/ { x' h4 T% M0 x/ L
S.top++;; J0 g$ W. Z" E4 Z! V! C
return 0;
. I P; q! w/ B8 C4 d! c2 d- B}
6 a3 T- c; s" N6 l0 G
' ^* G% {. u7 X8 F( I# y6 V) c; uint Pop(Stack &S,SNode &e)
: M( J0 f$ Y9 ?/ s) ]{" v; {- K; p( Q2 T/ O4 |
if(S.top==S.base)
6 h0 U% |3 k4 d8 R- i8 n$ f# Z {
' a; Q: {. ^! u printf("栈为空!");# r( a2 a* ~& ]+ \
return -1; r0 c2 \7 K* ?7 @1 q
}; K1 W3 D: A& v; X7 y' D7 U% J( i
e=*(S.top-1);
; m; \3 s, s, @8 s# |( ~ S.top--;
" P M# b2 s& N! {- | return 0;) {0 ]! n/ u1 t2 N
}
' T% y" e3 o) I; w
: B8 ^% L, \- nchar get_precede(char s,char c)
_7 I8 N: P* k{
7 _$ x9 ]5 S+ c1 g5 O+ | switch(s)
: z1 I5 p- F% H1 J9 e& _3 y) `1 ` {
" X9 d- j0 f- n% [( k! |2 ]( U case '+':
2 r& B+ w- L( c. J5 A& f- | case '-':" W1 U W6 X M! S+ P
if(c=='+'||c=='-') l/ B# ?# K( r% a2 i
return '>';
! O! I( ~ T) j7 T+ a6 C# i8 H else if(c=='*'||c=='/')/ a1 }" R0 ?3 \' Z
return '<';3 b/ ?6 p" }1 g3 F
else if(c=='(')
5 I% x; y a2 K3 y' L return '<';
* C7 [8 k. O( A4 m0 ?" D4 K else if(c==')')5 u" t: R7 j! q# D# v8 \1 S" |
return '>';6 X4 U3 O9 C9 B4 a2 i
else 8 t' C i/ f2 v( |4 R7 U- H
return '>';
: S; Y w j n: G# c case '*':3 y0 p$ T/ h$ U+ Y1 l
case '/':. f2 I, s, M- D3 Y
if(c=='+'||c=='-')( w9 ~5 ]& L: ]1 U6 _
return '>';6 | G5 E/ s3 ^" F" h4 n2 q4 Q5 W
else if(c=='*'||c=='/')
- Y" B- E. T- f, ~9 d return '>';
! T" ~- R x5 b2 r; K) C else if(c=='(')7 v0 @ x5 O; w# B" ?9 ^3 C' ^
return '<';
; M% {, R) s P5 ^' j3 @ else if(c==')')% J- h- I" r- n4 |" Q
return '>';8 D+ i: ?8 L6 L* d2 Y4 v9 w9 @
else; Z6 S- ^6 C+ C. H; |# |: m
return '>';+ ]: a9 |9 @ t( i) X; Y A1 M
case '(':6 h4 v, [9 S9 s/ ]* d
if(c=='+'||c=='-')
( q$ s5 t: \: {, R) x7 ~ return '<';
1 S. e! k. }' J5 i8 N" W! B* n else if(c=='*'||c=='/')( l0 e! Q9 r5 y _
return '<';- e5 t4 v9 @, e. A4 l; v/ V3 ~0 y
else if(c=='(')
3 `- G, [, {! E _: Y$ A return '<';1 ]$ A9 ]7 Z: `
else if(c==')')- @. X: H: w+ K w
return '=';
8 a5 @6 ]" o& b" N, W# b else; A" `2 n# D, @8 R) U. @5 m) b
return 'E';2 D* K8 T0 z8 s* w& G( Q0 c# T
case ')':
. l& E" Y" X& p4 Y/ a" R7 |% n if(c=='+'||c=='-')5 [. h7 s0 H* ~; H, A6 V
return '>';' ^$ J' Y, u0 i* N
else if(c=='*'||c=='/')9 q' e1 f" e4 V' v% H
return '>';& c. q( G/ U5 |: G
else if(c=='(')
8 K- L! a9 X0 \+ D( T" X2 L( @ k return 'E';
7 I& k, g; m- w: z% F7 n else if(c==')'). d7 i) B! E5 P5 h4 e( g$ W
return '>';
b# Q* V8 j' o2 f; Q) C1 l) V8 \ else- h V) S: @0 o, V% i+ }/ f' i5 O
return '>';
* g& C' X: C; u4 \! v' K case '#':
! `8 o" I/ G5 e5 U( ~ if(c=='+'||c=='-')
. b7 c; ?" a0 z$ `+ U( C+ L# t return '<';
. C& p' S: O% G! T6 Y+ O# E. i else if(c=='*'||c=='/')" t3 \; v) Z+ n7 [0 A
return '<';
X$ ]4 z3 C/ b; l, j/ }3 y else if(c=='(')1 B( F) a/ \- ?4 I
return '<';
p7 L s0 [* S: a& O else if(c==')')
% s) T p: T% g6 z' w return 'E';
2 h$ g5 L0 X& G4 q5 g! c else
! T8 |( G, ^$ \: k# { return '=';
5 b- e) N) S5 ]% L0 O default:
+ q( c) E; E/ u/ Z# Z1 M break;
1 K, M9 Q, z' Z }5 v5 u0 S# S: J3 {" f x
return 0;
7 }. \( _ V0 i6 o, | ?0 ^}. D7 d0 Y! |& V
" `" G8 m1 N2 X$ {6 Nint isOpr(char c)+ q$ i1 I! W7 s( |3 u
{
$ f6 [2 F8 d0 s( K; {/ E) S R8 u if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
5 M: H* {3 E6 J1 o" J return 0;7 V4 r3 e) V) f- M0 ^# P( x
else
# P# d! u w1 j# V/ U; v! B; ^ return 1;
3 r E6 U/ L7 j" i+ a}2 r3 \ e: y' a/ o( m) u
3 O$ L8 g. u% v- M7 X X* G" ?) jfloat operate(float x, char opr, float y)
( F" }/ a9 ]! v6 S4 s{
: q) `3 O" c# `; j float result;6 n* w7 S7 m9 m5 K; b% h1 ^" }
switch (opr)9 E: T. Y5 J' l+ v3 x
{
: }# ?& R: q5 \9 V; R; o case '+':
! u3 W' P. U6 ^. L5 r ] result = x + y;: y% l/ _; a9 U1 [1 D* \- O7 K
break;
: a j9 @1 J0 n( q$ b& k+ l2 @3 E1 ^/ f case '-':
3 e" t6 M) v& s6 `1 e: Q9 i result = x - y;, x Z R' z2 I( K, O6 N1 v
break;
/ [5 @4 d1 ^* Y# @6 K case '*':
' G- f7 D/ }4 P+ L& j# L result = x * y;
7 B' D+ ?/ E% s; Q& _! V$ R break;& |8 J( N" E" P9 |
case '/':
7 I3 ~; l' [* ?" t/ J+ |" a2 { if (y == 0)
* r4 f: l4 `+ |9 A {
P* N( [3 l- O. A3 l printf("Divided by zero!\n");
5 g% c! Y# B1 N; T/ l5 m7 G return 0;, B6 l1 h0 a) E9 U
}
! P+ i# Q2 w. A else# [& {$ E7 k/ a. I1 j0 t
{! y2 c8 Q; B7 [/ g' o
result = x / y;
1 ^. F' a$ U4 K. i( m8 { break;% t- W8 t- I, T% }: \. Z t4 x
}$ Q/ m$ z& G- ?& {6 b3 ]/ K
default:
" y6 x/ W$ m6 f, r: l7 S printf("Bad Input.\n"); 3 c- g2 l& \( I( o# A& W6 h
return 0;
9 _ c& _ R; R2 w6 | [5 X! y }
+ O+ I3 b; d3 l return result;2 v. E2 w; o: T! S# d1 L7 w
} 8 |# D5 ], Q( r1 Y# ^; n
8 e# F: h9 v) o/ N6 T
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/, x5 d% z! W$ o: ]
{
U# p0 q# L) G7 e Stack optr,opnd;
/ @; w% S! z% s. G" B$ Q4 h struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;- T. p" _6 J" t ^* h( \- e
char c;( p+ ^) d8 a. f
char buf[16];
3 \. Q. F+ N; s- K$ V$ J int i=0;
9 V# I" ~* U" [. O! T7 d5 v
7 ?. N" I" T$ H( {, l InitStack(optr); /*用于寄存运算符*/1 B, _" o z! F
InitStack(opnd); /*用于寄存操作数和计算结果*/9 \( _0 w6 c( b7 O+ K) Y
memset(buf,0,sizeof(buf));
/ Y, B8 @9 ~5 E% _: K0 I 1 `; @# d1 V2 g$ \
printf("Enter your expression:");+ p0 n# y" W6 i* N. T; Z' A
8 D |8 V7 B: v! k8 J opr_in.ch='#';
% c v, l! q0 y! ]. o Push(optr,opr_in); /*'#'入栈*/
( e. Q, @7 v7 v, k+ O GetTop(optr,opr_top);0 P, l M/ l. g; g) H
c=getchar();
) O& {3 D7 {! B. f while(c!='='||opr_top.ch!='#')
2 ^2 x1 f1 m0 t, n. q/ H7 P0 j9 A {
& X. G, O+ M/ c* f2 j if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ I* x" m- \0 I; S' c$ ] {
) }+ s* P. y6 t, A+ T buf=c;
2 l" c) @2 D7 f; {" R5 d i++;
8 }4 g+ `) X% i3 v: o c=getchar();
& K4 l: t' C0 D) e( j } j. H; t+ a3 P& c
else /*是运算符*/
+ B9 x" \7 e# X {
8 i2 Y' u5 ?% U3 f$ \- U3 D& I buf='\0';! q9 U1 M+ t" u1 n5 J% _1 P' F7 K0 ^
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8 d: _% `) z5 I5 R {0 C" D9 t; A+ o7 O. ~6 g( P& M# x+ z3 t
opn_in.data=(float)atof(buf);7 S4 j/ Z& X8 v* |; P% X& {
Push(opnd,opn_in);
! v. h' C* {! m# N printf("opnd入栈:[%f]\n",opn_in.data); G5 J# K! `+ t% R4 y t1 Z* Z0 P
i=0;
4 q9 J; {" }/ Y3 [ memset(buf,0,sizeof(buf));
3 O* Y/ V. t9 p$ w2 J/ o }6 h. b2 M) t0 K* J6 O
opr_in.ch=c;- X9 _0 A, _6 y( X8 E+ I/ s7 Z/ h$ d
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*// N: ]" p' h& o8 T: l+ }# f
{( F5 x( l2 Y( X3 @
case '<': /*优先级小于栈顶结点,则运算符入栈*/* f% k( |: q+ s/ Q/ `! U
Push(optr,opr_in);
: B' C4 _7 D5 }# I printf("optr入栈:[%c]\n",opr_in.ch);4 U# _# r' k3 }0 _3 u
c=getchar();
$ l+ a6 P* n8 }) A* T- C; }0 y break;
& p& ]4 v) l. x# c7 v case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
4 O5 t; w8 a z5 Z1 l+ Y" {: U7 { Pop(optr,e);2 _8 I2 C6 T% [7 p6 h( t" E
printf("optr出栈:去掉括号\n");$ n& X$ {* T1 D/ \
c=getchar();
# l9 ~+ z& X- o( v8 r/ b break;$ O) O7 x/ p/ X* N( J
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
3 H4 G# s7 [1 i9 y6 | l Pop(optr,opr_t);
/ T) K4 O; |9 j5 i3 ~9 M printf("optr出栈:[%c]\n",opr_t.ch);
1 ]- E$ S! R2 D: U3 s' d& M if(Pop(opnd,b)<0)
6 J& v) r) e( M' r {, F! h S1 V; Y$ ?/ f
printf("Bad Input!\n");. R% U q5 @# z0 S8 n% E
fflush(stdin);
# R+ c. l6 k$ ?# O2 o8 l/ v9 L2 h return -1;
6 F. Q5 |- s) _+ C& f& I z }
" H% ^! P# ?' u v8 C8 _* e printf("opnd出栈:[%f]\n",b.data);
5 l8 s; N) v% L- A7 ?& t/ R. a& e if(Pop(opnd,a)<0)
/ \' Q* h' a. o9 A3 h {
1 e% J8 p! X# e- I) h printf("Bad Input!\n");
; R& R; i7 p3 _& M) ^ fflush(stdin);
( M, M0 w& K* Y0 ^7 } return -1;
* A9 `: s) O: e9 p) K5 M }
8 j5 c- i3 ~) w) B3 e8 I printf("opnd出栈:[%f]\n",a.data);9 n4 L% C8 m" c2 b
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/& f7 ]$ ~& A7 D' [* |9 v$ R# z
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
- [6 J5 j# B' X# ^9 H3 k printf("结果入栈:[%f]\n",opn_tmp.data);3 _- S7 P. E1 c8 _8 ]3 s( N7 Z
break;
Q; O% d6 x7 h0 C }% W/ q8 G, C9 J8 a
}
) @- \4 |3 @+ c, Y GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
, L+ C9 O: R# N: Z; q7 C }% y3 i3 ~. F* n' o
GetTop(opnd,opn_tmp);
# k: a1 T$ d( z+ X) U DestroyStack(optr);
# y0 o' _- m, P7 o DestroyStack(opnd);
8 }; j! e2 L, e8 Q5 i4 A return opn_tmp.data;, u- x6 l# G. K3 I
}2 u- b8 h% q0 v2 U
0 D+ j( E( C+ T0 ^ U5 ichar *killzero(char *res,float result)" j+ ?+ r7 q' t) h- q+ F6 B
{+ U& D2 |* l F
int i;& g6 k- N+ {( W) R: x8 X+ }
/ a/ f- E% i) k
sprintf(res,"%f",result);+ l' a: J( ^! k% a, J" Y7 B
i=(int)strlen(res)-1;& k7 x. ?& W0 _+ o; @8 w2 E; }" t
while(i&&res=='0')
; |9 E5 y0 T+ R7 |& H2 q {
6 ^7 K$ a; t1 T9 U res='\0';4 g( L( h3 i+ J- U7 ]1 h0 o9 t
i--;4 |' D+ |# j5 J. k8 M
}
3 z" x) q B- Q7 s# N9 {' d( E2 f if(res=='.')
+ @, f) C3 h$ D! W: C( F# z res='\0';0 b; u2 A& r" n1 K4 D5 D8 s4 c4 o
return res;
3 _* O, s% p+ u4 F}% R; b) L5 g" X3 q! [& {
; g2 w2 x; P; F5 K+ s+ V6 f
int main()
" E. j6 r4 U7 _{8 X2 a/ Q3 K6 e0 w* v( a! B
char ch;
* }5 Y# F+ K, r char res[64]; f& f- ^6 e+ w: w! W# x% ?) e
float result;9 ]3 P) A; g" [2 S, v- [# G. b: d# x
while(1)- o \' O$ d& i2 n6 U" @
{
# Z) v8 d6 D7 R% p result=compute(); b6 Y( G8 z8 ~/ I |
printf("\nThe result is:%s\n",killzero(res,result));
; a/ h# ^0 M2 V' Q6 [# j printf("Do you want to continue(y/n)?:") ;, P# X o) j. S5 d( _+ s9 Y- w: Q
ch=getch();$ `3 y& g9 V6 E: r' Q
putchar(ch);
+ [: S+ l" U; P: p6 }. l if(ch=='n'||ch=='N')2 }& g% f: U4 M* \% i
break;) B! q/ y! I" \: n1 O7 k
else
: t- Z: X1 x8 Z! i0 y5 G system("cls");8 g! n1 k( f5 f8 d
}8 \; |) q: Z0 F) L, ~1 ^
return 0;/ Y3 Z! e/ t7 `+ `8 P* n4 O6 K
}
6 ?$ y% n9 {+ H' X# c! U# M/ |+ j1 _' l& e+ v
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|