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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.3 o/ q* Q4 R4 |. x* w% X6 w8 m4 f
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
# e. P' S3 ~! r$ N/**************表达式计算器************/5 V9 A& O0 H. k5 s- q# I
#include <stdio.h>
8 Y3 S2 T! [% t5 x) I#include <stdlib.h>: L+ w0 K% A# w y2 b) S
#include <string.h>
: ~- c; z; B8 E, ~+ I1 T#include <conio.h>
6 A6 K) o2 I, q N" [#include <malloc.h>
% i' G: m8 K9 I/ c% g
5 G9 r7 A# j0 O' \0 I. J#define STACK_SIZE 1003 x6 {) m& x% z. c. w& B0 |8 A
#define APPEND_SIZE 108 w0 Z9 M7 \# I# W1 j) \. h+ x
* f/ z) \& \4 }9 ?. Kstruct SNode{5 E( I/ l3 Z/ y" Q `. J
float data; /*存放操作数或者计算结果*// g4 U( l/ s) Q" f0 K$ s8 r" M+ |
char ch; /*存放运算符*/
' r# _5 n& K& B$ a( k1 {5 E};
& g& K& A2 ^; u9 A3 ]$ ]$ s. n, L% \& ], f) b
struct Stack{
$ e5 K) ?; \. X# c SNode *top;
2 v$ c# c: b4 d$ G$ a# f$ T SNode *base;
5 ]! J; {) ]5 `0 J9 g f2 \& M1 E4 k2 M* ? int size;
1 f3 n3 g; f \$ V8 {1 O; F};
2 ^1 X- ?0 v$ r2 C1 g9 n0 ]' M9 w, h# l. T* b; J% {+ T' G$ W& w
/*栈操作函数*/" r9 `7 s( v/ T- [; |5 a* i
int InitStack(Stack &S); /*创建栈*/
" e3 _. x5 _4 s# ~5 ?5 }) Eint DestroyStack(Stack &S); /*销毁栈*/
_( j p3 i( l% P8 Z dint ClearStack(Stack &S); /*清空栈*/
/ t. r# X- w& O3 W' l; n% B% E% _int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
" k7 L2 f% l% i- ~. \; z' A& ^int Push(Stack &S,SNode e); /*将结点e压入栈*/
$ Q0 G& @: P' C" ^* J( o) z% S+ ?int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2 A i# G6 r8 @- X3 H4 R+ N
6 T0 i! u5 A' v% _* Q V/*表达式计算器相关函数*/
( c* U6 a3 ^* q% J4 xchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 g* K8 u3 c( [ N& u3 Tint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
& p/ z8 ^! ]( u! O- ^float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/6 H- `4 ]0 w. I8 s- V
float compute(); /*表达式结算器主函数*/% L; h/ ]- i6 N; d c+ v, A
char *killzero(float result); /*去掉结果后面的0*/ & ~3 a, m! d9 G; n1 p4 O- r/ Y2 c
. B' V; K4 n* [$ \int InitStack(Stack &S) s* ^- a& s& _* S0 V# ]
{; N- @$ U) K, D$ C4 t& R; l3 \; x4 g
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
* w4 C7 O8 `: g: }) l. z6 S if(S.base==NULL)3 D o/ _3 e- p
{
; t2 x! [7 g% A/ h" N) u ] printf("动态分配内存失败!");
* I2 G: I9 b9 I* w8 w return -1;
/ _) u7 j3 V/ R }
) [2 t. V& \' o1 X0 c S.top=S.base;
) b" ^2 [: k S* a- O: I/ C S.size=STACK_SIZE;
: Z5 _$ e* H' I5 N return 0;; r |$ G0 R9 Z M* J( a+ N; m; |
}
$ ]. D! z5 L7 Z# Q4 I! F, z$ ^; Y' X- q: g# p: e, I3 q
int DestroyStack(Stack &S)
7 K4 I$ d0 p* ^& C3 x{
0 s! Z7 D8 H0 g4 T2 J free(S.base);3 ^: W# o3 m. T) b) \% W
return 0;& O8 O4 L# J- Y9 O7 }; ]. L
}
% R) `, c% R: F0 P9 i8 W3 l
) `& o+ _/ B# L0 a4 ?$ S7 n+ A) oint ClearStack(Stack &S)
; q9 G( g! D5 U$ I' U, o: {3 {) j: X/ K{& X" Z) i# O5 P4 q% J$ U% a
S.top=S.base;* x- r9 a* n- I; t/ W% f
return 0;: u9 q4 i0 j+ M% P+ I
}* o$ M' R4 Y6 M7 a W' V |( y
& T! F, Z- A& r# P: P! b1 Z
int GetTop(Stack S,SNode &e)8 J" O! w6 X- _- `- F4 ]7 n+ u* y
{
$ [9 L: O6 I" y$ U& M; u2 s if(S.top==S.base)( f$ r* d; `( I5 v2 I
{
# e" I. {. \1 u7 q5 c2 v8 K printf("栈以为空!");
: l/ I" O T" x9 m4 b, m" P return -1;
5 ]) _0 _1 z& I: | }
c9 Y; J& w+ j& a! b$ Y9 Q e=*(S.top-1);
. g+ I% b' N* y _ return 0;, z4 \8 ?- u9 m/ E' ~
}8 t; S: D0 ]( c/ _
) ^3 |1 C6 b0 r5 i" W' r
int Push(Stack &S,SNode e)+ ^" Z& N! p) o3 v
{* C, o2 S2 r& ]$ \' c h$ S+ a2 b
if(S.top-S.base>=S.size)
. c/ F9 {; o+ Y3 T9 [ {
( n- y, H2 e( j c, U1 Z! m, _ S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));+ j+ L7 [$ B( Q
if(S.base==NULL)
1 X4 y- I4 N8 x* }( d {
9 h v e5 y2 V8 b printf("动态分配内存失败!");9 _" X" N% v8 _
return -1;
3 J( Z4 K- }( a; |- _ }
6 M, \* U! U" ] S.top=S.base+S.size;
4 G# K/ @- T7 i S.size+=APPEND_SIZE;
: r; F4 }) V$ q9 p4 \8 b! r/ H; Q1 V }6 p/ r3 R' _6 W
*S.top=e;0 L' D& L T5 J1 G
S.top++;3 l4 W7 i$ A, ]+ L* u' ~1 Q
return 0;8 H3 g) I" w+ f5 j
}% @6 s# }! y# Q3 v+ i% n7 b7 r8 `& s( \
) H X& w% U j/ b- g4 A8 L/ u
int Pop(Stack &S,SNode &e)
$ A$ x6 l( A; m) A4 N+ K4 i% f{, N4 T/ ?- m) P! {; b2 |
if(S.top==S.base)
7 U2 G6 \ t3 D ^( a* w8 k; a0 ~ {
C9 h! R! K* R5 c. z1 E4 D4 O! v a/ K4 \ printf("栈为空!");1 v% M! A- d" m0 J* p, a
return -1;, H7 H c6 |8 U) S
}
2 g3 K% r7 U. s2 K: A: l e=*(S.top-1);
2 P) M `9 T. N& E S.top--;
* t0 j7 w* ?1 F5 o2 Z return 0;
& T3 w8 R. S$ q5 }}7 ^ _" k8 H! t# j& @; x) O
/ ]0 [4 k" \% ~* F
char get_precede(char s,char c)
% \& c) I, H: C7 ]+ P. K. V/ r{" i) U% `! K7 B a5 i
switch(s)
) a4 A% b1 Z) A {
% i7 k) g0 _ O5 v9 b+ [1 Y' L case '+': . D3 [" ^8 w6 _7 ~
case '-':/ Q5 S( y* |0 S% |" L5 s
if(c=='+'||c=='-'); A" W& X* c* p; O* i* H
return '>';6 }3 ^7 w) k9 L
else if(c=='*'||c=='/')4 o! c/ K; D1 x
return '<';! w* o h2 g) ~0 W+ d2 z3 h
else if(c=='('); ?" r7 N* G4 s5 d# F9 z
return '<';3 I( i! ^6 x& |
else if(c==')')- N& L$ Z0 \# L
return '>';
7 Z/ n4 W, K4 Y4 O# w( e else
# N, V+ @* J/ R I( E( |/ E return '>'; H! X+ u. a M) C
case '*':
- r5 y# S$ W0 u4 } case '/':
! t" K; I2 m6 r if(c=='+'||c=='-')/ H* }" G1 R5 b, ?
return '>';. e- [; d% d/ O, l+ S6 r: g \
else if(c=='*'||c=='/')- b* L, w+ D# k% q
return '>';
+ g6 n, P( Y8 m else if(c=='(')
. u/ o- l; T9 E5 t9 f' D5 H' E return '<';
; c* w( {; ]- u else if(c==')')8 { p0 u4 M2 ]. G. U' M7 T& i& {9 t
return '>';
: f3 q0 A. l% p: r6 P/ Z else4 B$ k J- ]3 p$ h- s8 G" n
return '>';
4 ]. Y0 f6 }$ R case '(':8 z% c* b( F k! ?' r
if(c=='+'||c=='-')2 v4 y r) h" ^+ C, v- `
return '<';/ A- X% J/ A$ r/ Y6 D! g' L
else if(c=='*'||c=='/')
% C# D% c& c6 j: j return '<';: W2 j# F1 e# K }
else if(c=='(')
8 p1 m; j. U |+ l8 e return '<';
, f0 u! _1 @. l" E S, Y else if(c==')')
( \* y/ q$ S. Y' p0 D7 k return '=';
" X) S3 Y8 d" x) o6 F else4 e/ r: n; s& X- `
return 'E';
- P# x4 |' B: d case ')':* a& ~. ^" s* x. K5 x3 F
if(c=='+'||c=='-')% r: q; s. l: x+ N0 W
return '>';
8 x1 f$ o- `1 H$ I$ b else if(c=='*'||c=='/')
/ ]. \! X# D7 {- ] return '>';
& i/ U7 `" W' q& ~$ }) { else if(c=='(')$ Y+ t% V) x+ I0 \7 j, y- l' z$ E
return 'E';& n3 O. L; D0 G9 q' n- }* a0 A. ~
else if(c==')')+ L. c8 ^1 P5 [* z
return '>';9 o2 P; \2 f" g4 f: ~9 i
else
2 M2 h- ]* ^) F/ s- o3 Y4 m1 s return '>';2 e+ T8 t' \% Q
case '#':3 A+ o+ I' y. W( ?
if(c=='+'||c=='-')" N# I# g5 L7 j4 c. a: [2 y
return '<';4 k/ U0 W7 y0 E$ R0 e, U
else if(c=='*'||c=='/')
2 n. e% @6 ]' [: Z0 Y4 N V% Y5 H return '<';
0 @) J0 ~' [ I/ o7 H else if(c=='(')
. W: S# Y% V9 C$ c7 Y return '<';2 l0 o# P0 M7 R" u
else if(c==')')
5 u u5 f4 v1 t7 V4 p return 'E';' N' o+ K7 S$ d6 X" l
else
. r% `4 e3 ?# ^( Z4 g return '=';
! L% F1 s3 e" E5 I2 ? default:: F2 X' e) h$ b2 |
break;
: x$ ^( P( j2 u2 Z2 @ }+ `7 O( X! _. S! q& M
return 0; & O8 F9 `( \# M [* T7 @5 `9 L2 Q
}/ X; }9 ?# ? c2 a3 l6 s
5 r6 z% [: ~8 d( b3 M
int isOpr(char c)
) {% e7 G1 d$ A1 r- U7 o' }( ?{
/ M$ v, w* h$ A0 ] if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')4 H9 H% v- q: Z$ ^ V
return 0;* @0 W+ x F2 Z. Z1 M- Y @
else + v" T& J# X% J3 F
return 1;
% v0 Q1 |* c$ H% u/ J}: j$ U1 I- m a8 D' u2 x A4 I0 h6 z: `
7 e* g" u- x- D- Q, b
float operate(float x, char opr, float y)! I3 u9 V3 _, u: l
{, h: u( s3 H) W, K6 h# h G
float result;* T6 f( j& u9 B" c& g2 h8 z
switch (opr)6 C" x8 U" f5 t
{ r6 A; f4 Z& ]( z6 t6 d
case '+':
( \$ @% v; k4 s: L* }6 e result = x + y;
3 _; c8 |6 t3 u0 \+ E3 ]( E2 W$ K break;2 Z) B( M7 [# ^
case '-':
K6 A) e4 e$ w. I% }" J! ] result = x - y;
8 t, ^+ `/ O8 M break;
2 }" F$ R1 B$ |. o$ u- a" _ case '*': 6 G8 ^: L: Y' V; y0 d9 g) O
result = x * y;
$ C0 V% t1 D b/ u7 I break;
7 A& {5 [6 m. b+ f% S+ _' q case '/':
. @. h2 J2 W6 C& {& O if (y == 0)
0 Y- ]$ }8 T8 N9 @ t {8 C$ t- S, A6 a9 y5 } ~
printf("Divided by zero!\n");
. x T) u6 u7 Q) k7 V/ g1 J return 0;
' W$ O9 }# L7 G$ H: ^0 _& g }
. M; k8 a) x6 A0 M h else+ ~% j% x6 |3 r9 W0 m# l
{. @7 `; o' @+ p$ h9 C
result = x / y;, G) i# Q; v9 K, s3 C
break;
* H: z. M4 r7 L3 }" O }
: X, C0 M! ?: l5 w; r/ Y, | \ default: 2 c7 G1 ]$ F N5 h. h
printf("Bad Input.\n");
1 ?5 O3 Y+ d% Q) Q3 P! K return 0;
. {+ S/ { @. U: e$ b/ b }! t' K2 _' ?( R+ f+ i% [* c& w* q
return result;5 X# e+ J# U/ W) [
} 8 A/ J5 ^9 `7 {* c; R0 l" `7 N
' J1 l1 N# s$ e+ b7 _! e& r/ E. ffloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
" z$ G# E+ V: _% C9 e* {& T{& g/ O# [: B9 x+ \ E. o. C8 p
Stack optr,opnd;
% ?% w0 ~5 c$ \! u l0 L struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
! |( p5 ]3 J9 R3 ?8 h5 a7 ] char c;
) C. w; X4 @$ w! m2 `" P+ j char buf[16];
3 a: B4 W; p, x, R4 o$ J& L7 ? int i=0;
) r) l6 N* [8 f
x2 ^% ]- e6 M9 n- X x/ U6 R8 S1 | InitStack(optr); /*用于寄存运算符*/$ M2 b& K0 B9 V- s) w q; b) }! @5 r
InitStack(opnd); /*用于寄存操作数和计算结果*/
) B, A+ x% c, [% [, v memset(buf,0,sizeof(buf));2 _3 J" ]5 D( @3 |4 U. Z+ b7 A' V
$ V! B: X& |3 \- x) k
printf("Enter your expression:");
# a1 x9 B9 w7 D9 Q a6 x( h4 g& d) m# V2 w
opr_in.ch='#';
5 s. |' j7 B0 U. H& [' t- A Push(optr,opr_in); /*'#'入栈*/
2 D3 \; d" g) x3 S5 A& E7 L GetTop(optr,opr_top);
% _/ e$ K. ^ m2 y# W, y c=getchar();
& b% L" b) X3 @' ^4 ` while(c!='='||opr_top.ch!='#')& Y) j- D0 z+ K. {
{
- }2 Z6 k9 V6 V6 [ if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
, E4 C; W7 r9 C4 R% y3 j, ? ~ {
+ v0 k+ i4 C$ D# f& O* S buf=c; Q6 Y0 d) X" i
i++;% l$ K* V8 \" x' \
c=getchar();: J# j$ J/ R h8 @- A
}5 S/ s0 F& k k9 T8 d! n
else /*是运算符*/
0 [0 L- @* o! z2 S) \! U+ X. T {
2 a' F1 ?, u+ } buf='\0';
. l+ X: D) `$ B/ V, L" j8 d: q if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
. z. ^ l8 R( ]) y {9 Q1 m2 e' @, d7 G' F/ D
opn_in.data=(float)atof(buf);
) Q3 g+ s' m5 D. k1 B0 W Push(opnd,opn_in);2 ^- p/ y0 _: o, r
printf("opnd入栈:[%f]\n",opn_in.data);( ~6 X# `7 z' }4 M; t8 D3 g! S( \
i=0;
; X6 k( G6 w" W) V L k3 b memset(buf,0,sizeof(buf));
7 E. V* _% H. _; F- A4 I. t }- N) H" E& v1 X3 |
opr_in.ch=c;, l, I/ m S3 Y y! R
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/9 N! Z/ C6 _; s. t+ B5 F1 r9 o* K! r
{
" H1 _# ]) z0 V. F0 O6 M% z0 s case '<': /*优先级小于栈顶结点,则运算符入栈*/
: h+ y2 b& E% D. J Push(optr,opr_in);
2 k9 s, E [! [9 D printf("optr入栈:[%c]\n",opr_in.ch);" B) D: y- L r- h2 \6 ~: m5 X
c=getchar();9 T( C3 D, B( `! G) U4 |5 F
break;: x; c# I* N; s' W; R: O
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/' \& r( @. f: r8 m
Pop(optr,e);
" M+ K$ B+ k% k3 U# Y/ W# ^3 J printf("optr出栈:去掉括号\n");
# a, ]7 w3 ?) N+ u. ] c=getchar();
- |, |; c( I5 n' D* b# w3 ~ break;
8 B) p. ~$ ^3 b case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6 N: Z" p( a6 P Pop(optr,opr_t);, q! o$ a. _3 S) Z' Y: R6 T# [6 S
printf("optr出栈:[%c]\n",opr_t.ch);
% A8 d5 s/ z/ D# @ if(Pop(opnd,b)<0)
( I* S% F: i2 j; X& C {& H2 g5 h r, E) ^
printf("Bad Input!\n");
0 g: e' E8 i( D+ x8 v fflush(stdin);/ h2 K6 b" S5 _7 v& H0 D8 E2 F
return -1;$ N, @. \- r* w0 n2 `' U
}
/ ]' [- Q+ G: ]4 l1 v printf("opnd出栈:[%f]\n",b.data);" `, M4 V1 h* r! R& |6 V$ z9 n/ Z. E
if(Pop(opnd,a)<0)7 T/ e' p, e; ?9 R* G
{
" L+ { C/ |( s- k+ P printf("Bad Input!\n");
% f4 l7 T2 V0 W fflush(stdin);
; @, Y' M0 ]! S1 j return -1;
4 {; C% r4 S: k; \- y }; D$ ]8 G1 Z# v
printf("opnd出栈:[%f]\n",a.data);
* @7 C+ P" n9 H0 K v' _$ j/ ? opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/0 k; F& x' h+ J
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/. q! n9 m3 _( c/ W6 i( h7 p* ]) U
printf("结果入栈:[%f]\n",opn_tmp.data);
6 z6 T/ o# w Z/ v break;, B- x- K( _! v0 ?% x9 M( o; }
}
" K A/ d, h. S/ D' f& G, P }. H9 G* B: x# d; C6 D# S
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
0 e; @2 o% J8 _: L, F& ] }
. \/ I) H1 L) W) n- y% b3 W GetTop(opnd,opn_tmp);
0 A0 h# z1 J) P. H8 d9 } DestroyStack(optr);
: N8 l" \4 A9 ]4 f; m J% w DestroyStack(opnd);
& G1 C* o% X5 N" G% e* D* c0 Q return opn_tmp.data;- T; K9 t; J& i4 k S9 \
}) p( x- o# Q7 A' L+ p& G
5 e& L! g# v3 H' w! C P3 o
char *killzero(char *res,float result)7 g! {* R& v. d: n
{
+ d! o, _) l+ }% ^% |% b int i;
) _0 n! b0 T7 G! c- N* U8 @
+ O2 B: s% J) l' r4 c& P+ g9 |" k' D- Q sprintf(res,"%f",result);3 g8 f9 y1 G5 i. K0 B R
i=(int)strlen(res)-1;
. E; j& ?( ]0 L! ~4 F& |& I2 ]; | while(i&&res=='0')
+ u# d" J/ z4 `0 i0 K4 x; n {
2 n! n9 v$ H' }% B( [; y res='\0';1 O4 k' U3 V+ ~# C2 p
i--;# k ~7 Z, p+ \) Q
}7 e8 |' @; O, |8 m# j1 B
if(res=='.')
, Q0 A7 r: U0 c4 x0 H+ f$ j: V res='\0';
% a1 G4 Q$ u% Z) O3 z4 a8 g# e return res;3 }3 p& f+ P% I0 f1 q4 e5 b: x
}* v0 g2 {/ P# T" {6 @
& U, M% Y) {2 d6 A; J! m a
int main()+ I1 G5 L: O4 G; |! W" b c" y
{
c$ k% z# z2 b char ch;
2 g0 t0 J0 q! p8 o char res[64];
! N- E6 _: `$ u) _6 O float result;
* n. p2 c, `$ C { while(1)
) ]. ]$ p/ l( j { c. o& x1 C' f( O- c: L" B
result=compute();7 R5 V) t+ {+ ]4 g' O# Q6 M
printf("\nThe result is:%s\n",killzero(res,result));& U5 b3 L( G+ [2 @3 e
printf("Do you want to continue(y/n)?:") ;, _- D' ]9 I6 Y
ch=getch();9 X" `9 ^7 Z m. Q0 K- P8 o
putchar(ch);; y1 t: o- n9 i1 P0 h( E. S1 r8 |7 a
if(ch=='n'||ch=='N')# }- ^2 C! I% [* L$ h j: N1 Q
break;
* Q9 A7 Y' L" ~1 w else/ s$ B# l$ W/ Z& `$ S" P' p
system("cls");
. r. f. z% t2 Q: p$ ]- e }
" }$ Y6 |4 ~% L return 0;
* x, M3 z9 D/ U4 j+ h( ]. u* |4 |}% K g% h- c8 G
6 j7 J" v1 P- W: E) |
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|