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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.2 w8 G" @' P5 i
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=: g" I ~9 l# @% B3 k
/**************表达式计算器************// e+ t$ h3 Y8 \0 \, }5 T
#include <stdio.h>5 Y1 v6 b4 v! j d8 P& T
#include <stdlib.h>) R5 @, c1 T: Y/ K
#include <string.h>
j& c& O, T$ s+ k+ W ~( I2 }- R#include <conio.h>7 [8 d9 b7 \6 O" Z. E# t) Y
#include <malloc.h>
6 r+ Z* q. B& o9 ?# ]9 a$ k6 k( h) W9 Q" y8 `0 b
#define STACK_SIZE 100. F6 H1 b- w- |
#define APPEND_SIZE 10
% T* i8 d1 r+ s5 |
. M! V- X; E- q/ ~; O6 Q2 W3 ?struct SNode{! f) x v/ g6 t3 |/ ]
float data; /*存放操作数或者计算结果*/6 F' k8 b4 z1 R V; H+ k
char ch; /*存放运算符*// ?7 D( m) }& z3 T
};/ T, T6 F- \/ n( B! Y: q
5 T9 a$ B7 s% O/ dstruct Stack{
3 @3 ~- L. p( v7 G" L: H4 a4 | SNode *top;
9 J: T, C! x' J. z$ Z9 K% n SNode *base;6 D% P9 t5 D' `7 v0 ?
int size;/ D; H( q/ D6 O/ t
};
$ |$ c2 f* _9 N, B1 W" T) o
" a7 o# p8 n4 k0 M/*栈操作函数*/7 s& B5 `, ~1 E! U7 X
int InitStack(Stack &S); /*创建栈*/
" k) |- S' \9 l' w3 @, A5 G. Mint DestroyStack(Stack &S); /*销毁栈*/
1 \' b4 ~( M5 l+ R2 d. j, wint ClearStack(Stack &S); /*清空栈*/2 g. k8 p: Z9 a" j) j, t" ?1 _
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/! _/ g3 v1 V3 S( O% H# Y
int Push(Stack &S,SNode e); /*将结点e压入栈*/
* U) C& K3 `3 eint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/+ Z. u/ Q7 h- a0 @$ d) ]; ~
' F( l' \3 |" U) }1 |6 j/*表达式计算器相关函数*/) a' }1 c: D! A0 g" s- P
char get_precede(char s,char c); /*判断运算符s和c的优先级*/& U" k% a: {6 R! ^' Y0 w# O
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
V# }) ~5 I# r+ D7 f Nfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/' o: K* n: {2 i3 T, a; g. u' A
float compute(); /*表达式结算器主函数*/! E" q+ b) H. u5 O; d, t" j& Y
char *killzero(float result); /*去掉结果后面的0*/ - t" h" q+ \- M6 ?
@& x$ G$ l% [ Pint InitStack(Stack &S)
& L1 K; H' u* q' d( p{' _1 X+ ~- d! ^/ A/ D' K" [: `
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
& |' K6 z) Z" h Y3 i if(S.base==NULL)3 K4 v5 n! T! z4 M# Y! I
{/ c5 f- b+ D1 q% s; u
printf("动态分配内存失败!");% A! f% q: N: E9 M8 i* Y
return -1;* c; I1 |$ @3 A+ T. w
}
2 w& N) c: ?* ~4 { S.top=S.base;
0 H% r! [7 r' z q2 N' M S.size=STACK_SIZE;
3 g* o g, E8 J9 C. d7 j* r) T' h) s return 0;
) w& ]* e- f, ^/ t}
3 O! h/ _( r1 w6 e4 i5 ?1 k& W. `- R7 a7 W- I
int DestroyStack(Stack &S)
K |/ g; _! d" y{
, U2 E _, }/ x: J, v+ n free(S.base);
4 L4 j8 z$ _- C6 Y return 0;( c) Z! g' L$ J) r
}' K* X2 A, `# i) Q$ R# `
2 q( Z5 ~7 w9 p# r( ^/ e- _( eint ClearStack(Stack &S)# j6 d* q; E! y- ?5 I
{+ _6 X, H# \* L
S.top=S.base;
+ z6 M& O* t& W! D return 0;1 h" }1 X. c: @% y X( T) Z* q% `, t
}
( F% i( H- f g7 T2 P3 y: z4 X, b5 N" Z B
int GetTop(Stack S,SNode &e)3 O: J* S2 N/ y3 V3 }( V) w4 s
{, ~4 Z) J' \7 p6 H$ z
if(S.top==S.base)2 v3 R& }( E5 O
{# R# Y% D& [% ^( W3 E; u
printf("栈以为空!");
3 l: C) e& T% _' z return -1;
$ y8 ]$ E. Y1 Q( D G0 k/ @/ J }
& K" s3 |% U2 }- M8 Y9 U& S* [- x: i e=*(S.top-1);
* ^! f; t Y6 z5 u, d; Q& B a return 0;
, |3 O2 d/ s6 h2 F* p) ~}
( y6 B- m+ H& @8 T! M ~
* t* q6 j/ \3 Yint Push(Stack &S,SNode e)
3 R; k* q- N( l( H- | c{- y+ T: |0 ~: e, T
if(S.top-S.base>=S.size)
5 x6 M" y) \- l& Y {5 X s. Q" y V6 }+ U
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
* _5 @8 f; |* i% h* N) \8 r9 p if(S.base==NULL)
6 T% n( k& b9 y2 F; a' _2 o$ K5 V7 B {
2 g) d; I, G1 n printf("动态分配内存失败!");
% Z: R+ L( S) _ E0 E# r+ X( P$ z return -1;
& q5 \" P( m; e/ M/ F' r }
6 H7 B1 D5 o% M& X S.top=S.base+S.size;: O/ O! X& Q3 R! m4 K' f0 \4 A
S.size+=APPEND_SIZE;
1 ^* _, b' h$ l$ ]8 L$ L }8 P5 B/ J9 G0 X/ ~: v' c
*S.top=e;% C$ l( W! M* m! w
S.top++;
9 A8 {6 B3 z! O( j9 x) F return 0;: Z# k2 _' J n" N) ?
}! o( [4 c f8 Q3 I
r# c" n7 s* w
int Pop(Stack &S,SNode &e)
. K3 C; {3 K7 V" ]0 X8 x* B8 r* `{
! Q# S+ ~5 m8 z, F% H8 x7 M if(S.top==S.base). J4 s$ t8 S/ `7 q1 q
{/ S, B9 c8 ], o7 h1 J
printf("栈为空!");8 P z% Y+ A8 K
return -1;
+ q( b" }9 c7 p }5 h1 C7 I; q) n4 Z% y2 g
e=*(S.top-1);
6 s- t7 Y2 E# R# r& | S.top--;
# X9 u( W& r" C7 p6 L- n! q# R return 0;, S. O) \, u( D! `, b8 ?
}! ]) F1 V+ v n& E0 ~4 i3 [
5 f6 S) }, O+ z3 S" w( F
char get_precede(char s,char c)" u* B* \& k: q1 j- q4 H; b. d2 @
{; `% R8 s4 u# K- q; Q" ^+ q0 W# h4 W
switch(s)
! H9 X1 _% d7 O2 n( c {
; i# U5 a* u Y case '+':
0 [) U; r3 f( c case '-':$ p6 L* S1 p. T; b5 M" O, |" K$ q: `
if(c=='+'||c=='-')' d" _. C. E- b/ i# }
return '>';
3 c# w" A7 S/ s else if(c=='*'||c=='/')( U% ]$ D l- ]. U+ V( Z$ ^1 d/ W
return '<'; A6 j& \' v, n$ m. `; z8 i
else if(c=='(')
3 W' d5 v+ J: E+ U; }+ F return '<';( ^# s; I3 R: q
else if(c==')')
, o) L4 X- P; _: m" | return '>';
" r- Z" W" J3 T else 8 G- M v; z8 P0 Y7 o! N7 {
return '>'; d! w, y% r, h4 J5 Y
case '*':, g4 L9 g8 s1 n
case '/':: K1 U' c1 O- X$ x: {
if(c=='+'||c=='-')
$ ~7 n; {0 k* |1 x% j, ^% Z return '>';
* m' U- l$ T& H% [2 P2 N) S! ^) V else if(c=='*'||c=='/')
7 G9 Y6 i' L8 Q, y4 s2 I return '>';
+ w" K# _/ J# I5 {. V3 t/ Z else if(c=='(')2 L' l6 H8 b; M
return '<';4 \7 [" L' ?% h K, {
else if(c==')')
$ p) a% o" u O! b9 ]( T) f return '>';2 Q8 U9 h1 S0 B9 T5 c* H
else. K+ t+ s* c! l9 j+ H/ b' T
return '>';
- c) F2 Y+ {* o5 ] t case '(':
5 [6 y6 U: z2 h* _% G if(c=='+'||c=='-'), _% B5 o$ c( |
return '<';
7 G D" i6 j% J2 w% ^* J else if(c=='*'||c=='/')7 r$ I8 W9 B, l: Q# P
return '<';
: @0 h# i6 n3 s/ S' y6 u% O else if(c=='(')2 O4 s# `' G5 K. \* m4 N
return '<';
% t$ J: f9 D$ _9 [ else if(c==')')
. `, H1 G( O: R4 Q; v& Y return '=';
, f2 x9 }" E8 I2 f' x7 b else) ]" Q; b+ H! [4 v8 p4 u
return 'E';
6 Q4 V2 Q/ K% n case ')':1 ^% ^7 \3 o. K& |9 e
if(c=='+'||c=='-')7 z4 e8 e& q, w0 w9 [
return '>';
1 I9 ]! w1 q! q% C; b else if(c=='*'||c=='/')7 I+ [: G) {: Z7 {& C
return '>';
' {% Z, S% r! ~& x6 t# a) P else if(c=='(')
U5 u! a- S& {, q+ D return 'E';. A0 O6 `% q! M. m
else if(c==')')
* u6 i/ R2 i1 o f return '>';' q; E# w* O; ?3 U" S x5 b# i
else3 v. ?5 D* x# D9 P0 N5 N9 V
return '>';0 {% E5 `$ v5 w# V Z4 t
case '#':
1 ~" G9 @: k( g; H6 u- c if(c=='+'||c=='-')
+ v8 H# M, q, Y return '<';
6 C, {% G. H; e else if(c=='*'||c=='/')
8 {! C0 u9 \- \; b: U. ~7 w return '<';1 T# j X- Z% X& S: b% `1 l7 ^% v
else if(c=='(')
9 F9 w6 K: s' {0 O5 T5 m9 R return '<';
' j: ?/ j' u' g1 v. R$ l else if(c==')')
; i5 r/ X* I& H& m# ^" T6 w return 'E';1 |' w( B/ K% t5 f. a
else7 p# j4 _8 u8 R+ t: c1 J2 Z
return '=';+ b3 B8 m+ f# B" ]! h% v5 Q8 ]
default:
A5 d" A1 G$ U7 I8 i break;
" W( m4 D& j( `) ~) l0 D. ~ }. z% d: d: V, r% `& b4 z
return 0; + l$ Z! J) S3 p8 Y- C. @! Z
}/ t1 u1 ?; M1 j* x
7 A2 m- l4 [5 B+ h
int isOpr(char c)
+ A5 {& O3 P0 ^! W' W, ~{
2 [. @' D, y, Z& i1 Z6 r! ` if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') T( l7 s' W; {
return 0;
7 r. F9 z# i: Z$ r' Z else
: F, m$ J8 e& A# q) z return 1;( q6 X l8 L/ ]/ B* P Q
}9 s( c% B) m8 R& Y9 A; k
% l6 W `$ _3 A$ B( `7 Z! Z% q- R' ^float operate(float x, char opr, float y)& h" h% l7 ?9 p
{
6 i* e, W; F9 G" b, \6 R5 i4 ~ float result;1 d. a! j9 [4 M
switch (opr)
+ D% c0 V5 p4 C7 L# I( T+ w {% W2 a# ?. c& X
case '+': # Y. e1 x% ~& R% A h; A
result = x + y;( S, j4 P; E5 [/ k
break;- Y( s+ N- {4 h! r9 W3 ^
case '-':
% u, C' T6 H* x5 w7 T8 Z result = x - y;
+ \: j8 x! N+ H8 I) T. H$ I u7 E: a break;
/ O; M2 [( G% K" G7 d: X case '*':
" l# [- B3 I0 N0 N3 x result = x * y;' ]1 L5 T; ^* w' A/ |5 J$ t
break;
/ q v& C! U6 z# I& m3 \* H( [6 V case '/': " Z" y4 ?$ x o) d; s
if (y == 0)3 x. e d4 s, T- k& ?4 A- w
{
) @7 v8 k$ n" P {4 j printf("Divided by zero!\n");
1 u, j: [4 `+ I- j return 0;
) l$ w0 @" l5 P }* ] b5 x6 v, a7 C" G% x+ Q
else
2 s% d! |! [5 S4 ? {, V0 q7 n( p% G/ v8 D
result = x / y;
4 X7 k- o8 a L! }) y- }& v break;
# k" m# k1 v% d: t. d# x } _ g" t' U7 Q
default:
* d" h( H3 ?1 y8 B/ W3 N7 `9 ? printf("Bad Input.\n");
+ j- w/ N6 d9 ]* g2 m( l return 0; i+ p) B! T3 F
}1 ~/ W |# f/ m8 c7 x
return result;
1 _1 Y( O8 @4 [3 A1 i}
& ^: K3 ]/ P8 K/ O/ o2 ]$ z% X
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/. h; m4 A2 i3 ^1 z7 x" A- k" r" j
{$ P5 [4 n( a$ P* `
Stack optr,opnd;
0 B* P i" C* W$ A7 y% g) a3 t struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;' S8 L4 K! C, c
char c;
: Z- L1 L7 Z( v* M char buf[16];1 i$ |+ p, r' p% s7 M1 G- [' ^
int i=0;
) Q3 ?! t4 x$ Y5 v0 Y0 `
/ \0 a+ [: ~! m: W( r; I5 e InitStack(optr); /*用于寄存运算符*/
3 O1 Q7 A, R5 O# a' z' F+ J* F( o InitStack(opnd); /*用于寄存操作数和计算结果*/
- r4 z e6 l8 @4 ^: o$ r8 ~+ e memset(buf,0,sizeof(buf));
, k+ ^0 K' I8 J$ M4 S
* I% ~; U* n R6 w printf("Enter your expression:");: p* A, m' x2 X. }! u w/ |
7 O/ a* \" B. Q% R3 x( J5 y opr_in.ch='#';
# e8 p) R5 C! l, S6 c Push(optr,opr_in); /*'#'入栈*/
# i& Z1 S2 R- O- ^" {; i GetTop(optr,opr_top);3 R1 B6 Z, }( k
c=getchar();
f) o" p- f# ]: L& j- z while(c!='='||opr_top.ch!='#')+ k! {1 t. O3 o; T( y0 u+ O
{
2 m+ u& R5 Q7 g7 b4 I! V if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ _( m- c; f. ?, s6 N) s. K0 m! ` {
9 f; R1 N2 g. N' z! u8 k2 j buf=c;$ q5 O0 E; }0 B3 f8 L& ?
i++;
& d8 K8 x2 `1 M7 ]' H1 I c=getchar();( V* S n: F6 F8 s
}
& n [0 E2 j* s" @& L( K. A3 B: E else /*是运算符*/$ \2 [2 `8 I W
{; ]+ Q$ K- W5 d$ e; \8 t
buf='\0';
, S! h& S: w8 z0 N q2 \+ O if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
; `- T+ o- ?: N: ^2 |, W9 d) @3 H {
: t* K# O& u& H# A' ^0 f: J4 k, ~ opn_in.data=(float)atof(buf);
. y1 R$ G! `" t x& N Push(opnd,opn_in);
' Z! i0 y8 u+ F' A' J$ D( V, o printf("opnd入栈:[%f]\n",opn_in.data);
0 {, y2 f, \- M% \( X: _ i=0;
( s/ B4 u V% }, j. O! p memset(buf,0,sizeof(buf));
2 o# d% a! l7 o; w* T& s" B }+ f l" A9 w) h* N& j
opr_in.ch=c;$ J( z% A, Z! s
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1 u% }/ Y# s. t% N: Y. ~ {& P! o( ?: Z) S1 N
case '<': /*优先级小于栈顶结点,则运算符入栈*/5 p+ {- D2 z! M1 s- ^7 N5 g5 b
Push(optr,opr_in);# o) s: _6 y( Q8 q8 Q+ ]* l% K5 g+ ~) T
printf("optr入栈:[%c]\n",opr_in.ch);
; \; ?1 ?) Z7 M0 \6 e c=getchar();
( F9 D/ |6 Z. r( M5 b break;
# c3 Q6 \' y& n. q case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/2 f: ^) W1 e% i; f: d( [
Pop(optr,e);# K" U( t) y9 p
printf("optr出栈:去掉括号\n");7 h3 G/ y4 y1 E& `, V
c=getchar();4 c2 I3 ^& R9 z9 |% b/ G1 u0 p
break;( N8 d5 D/ L3 d/ }) m4 Y
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
- W: V4 t/ X7 t Pop(optr,opr_t);5 D3 @" w' S$ r, ^% d
printf("optr出栈:[%c]\n",opr_t.ch);/ S! k: N; U$ K5 Q- `
if(Pop(opnd,b)<0)
! q) J5 }1 x; p" l {
. }7 i( I) @: E) ^. p5 ^1 Z printf("Bad Input!\n");. I: p ]+ D7 ?4 w B, z
fflush(stdin);1 u0 D/ M' D3 f2 M
return -1;3 E0 q- U6 \* ]& `
}
0 u6 J6 V9 _4 Q9 C7 S# x printf("opnd出栈:[%f]\n",b.data);
+ H( j1 K0 Z8 \ [ if(Pop(opnd,a)<0)' y) U4 L- b$ t5 Y/ \
{
" e6 r/ k5 i( S! v. Q( I printf("Bad Input!\n");" l' D+ W) X; _% g. {1 v
fflush(stdin);
1 a$ B+ [ Z/ e) R: z return -1; f3 n( ~0 \- w) Q+ O5 ^
}! b& W) P6 B- ^+ \1 u6 e: l
printf("opnd出栈:[%f]\n",a.data);9 y; T: k R) c, i
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
+ X4 I% A0 U9 ?" | Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/4 Y% ^ u3 w& ^% v# q6 D
printf("结果入栈:[%f]\n",opn_tmp.data);
2 R, i1 V3 g+ T. \! Z; U* U8 I break;
5 B5 X) i1 o$ K } L! p; u, S6 n/ b( x8 }6 Q4 V
}
+ J, C1 a8 R& C% x( g0 Q GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
8 X/ p( O! j6 J* j. ^2 e( B }
; A }' V4 X* \ GetTop(opnd,opn_tmp);
- V6 r0 w( J& n2 F4 X! k DestroyStack(optr);
' \ H: e( }1 \) x# e DestroyStack(opnd);9 i' f& }) d. u
return opn_tmp.data;
) i' a0 e* @0 ~}
/ t" j9 J5 Y# A6 \0 ] {# _5 o8 ]6 }/ M6 z$ Z, o0 M
char *killzero(char *res,float result)
4 n2 g% Z2 e) u6 ?6 G2 M{$ ~; B- k2 a9 _* g' ~
int i;
M x6 j5 n# \) X
; T5 _& V3 |9 T: j2 P! @ sprintf(res,"%f",result);6 i# v A3 B1 x$ A' q3 z# {' M& F
i=(int)strlen(res)-1;
" \1 }4 f( Y3 Q& s) z5 w2 p while(i&&res=='0')3 }6 M# m5 v% m2 Y
{' p( u8 ^; V+ u% ?
res='\0';
5 z% C* D; Z: x6 T7 e. C i--;
2 x3 N; B3 q# c/ C }
" t2 p- S: K/ w3 t2 x% p! O0 M! r7 E if(res=='.')1 M. @9 h# I+ D+ j6 I, J
res='\0';
1 Q! P E2 v( d return res;: W5 K: ?; ~# T; R/ |
}% }( t& W: c0 ]9 E) L2 P
, q% u( L I% ~" g2 r" `( C2 kint main()
6 o; y0 C. ^; A0 [: v) _{
1 S; R& P4 O. z+ p' `9 D char ch;
. G0 i7 F. N+ U H# M char res[64];
. r5 l% u: x% F- P float result;
8 _4 b {# b. I while(1)! T; g# v6 [6 y6 }
{" J8 ?1 U0 ]! J7 E( d
result=compute();& R1 @% M2 E" m, D
printf("\nThe result is:%s\n",killzero(res,result));: S* C Q5 S, J8 X
printf("Do you want to continue(y/n)?:") ;) d" x, V0 j3 Z: L, v
ch=getch();7 k! I0 g3 Y1 y; v( u- [+ _
putchar(ch);
2 M. o2 E# k6 [! g8 ]7 V+ Z if(ch=='n'||ch=='N')
9 }) d0 C5 a6 J4 n3 |% r8 z) S break;8 y5 T, F$ i5 P. @& @* y
else( U m+ S3 F5 x
system("cls");
7 I( h: U h7 P8 I }
" c1 ^8 y6 b2 } {1 c% E return 0;
; t8 }$ g9 h9 r" B7 y5 W" _}2 k/ Z {+ `: a! Q
0 H6 A5 k: J4 ^ c! \/ Q[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|