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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
) G8 R- s& e0 X. C5 V程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
3 ~# a' F* Z, ?! L; \/**************表达式计算器************/* h K- X+ r* ~9 N: h( n
#include <stdio.h>& M E) K1 l- _# O
#include <stdlib.h>
}8 p) i1 p) z; ]* Q' m% J% N4 S' v) s2 ^#include <string.h>6 `& O+ g! a* J/ M2 H
#include <conio.h>* d9 F! X+ ?, T: |: E1 X4 t
#include <malloc.h>
6 L, F- g( Y8 F' [+ W; k! g9 D9 C6 F. r4 x# P& Z
#define STACK_SIZE 100+ Y( J& `4 L1 w' o
#define APPEND_SIZE 10
' Q% _5 V; f1 b6 o+ `
6 V1 A3 f& _. |struct SNode{, }+ P- w H+ U) t4 S
float data; /*存放操作数或者计算结果*/! U8 \, S: V- w# O& F) _' c& k
char ch; /*存放运算符*/8 D0 O1 P$ u* I) N/ {
};1 G- ^7 [% D) V+ X
. W4 \7 g3 I+ n0 c- [' n* x O
struct Stack{
7 L7 M9 k) H( K) [ Z SNode *top;1 l1 ?( O, b @. @. Z2 u, T
SNode *base;8 _ o1 t* p/ q9 P1 w! e& s2 h
int size;! N P" @( C# W4 J0 p
};
. j( ]. D$ J/ Y' Y4 y6 l
" z# X# L2 u! o( n. f/*栈操作函数*/
3 m- S3 o3 U) e- @* P0 n6 y$ ?- wint InitStack(Stack &S); /*创建栈*/6 G) T2 z7 {1 V1 U* V& E! ]
int DestroyStack(Stack &S); /*销毁栈*/! I6 B. N; z9 V% e& Q0 `
int ClearStack(Stack &S); /*清空栈*/
4 P- z- ^: U; i6 f) vint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
+ ~3 I- ?. E- D. m5 K& e* d/ G# {1 X6 Jint Push(Stack &S,SNode e); /*将结点e压入栈*/* b5 [9 k+ q& O1 V9 k
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/( t+ S0 }" ^, M- o2 y" R
( \+ t/ s) Z# l3 [8 f3 ?0 H& l
/*表达式计算器相关函数*/- a2 k9 e2 H) [2 M3 T$ o, o3 F7 Z
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
# B; Q$ A K; q: ^+ Pint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ j4 [0 R; j2 Y- K$ p
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/" ?" x$ @+ `6 C2 K% ^
float compute(); /*表达式结算器主函数*/7 n% P7 ~. P5 a( D2 c" m& |/ w
char *killzero(float result); /*去掉结果后面的0*/
7 v( _2 S$ F6 X# t9 ~8 Q/ N- t" D$ L/ Q9 C8 b! S
int InitStack(Stack &S)' s2 a# x+ t; ^5 S
{
( W/ G" A4 q1 L( p* Y1 l S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
9 Y L' D) F! L+ v# A8 v if(S.base==NULL)" m0 Q ?3 V5 P$ J2 T7 ^0 Q
{' {* X* S" _- Q1 ^! `6 S
printf("动态分配内存失败!");
: p! _* P! I, d. a; c( a/ f8 T1 B! d return -1;$ |# B2 u: u9 U H6 q3 L
}; V* C; D4 D2 n( P# k" c$ X
S.top=S.base;( ^6 | H, B+ q. ?) |6 \% o
S.size=STACK_SIZE;$ a" [$ D! W6 m2 L8 s3 z
return 0;
6 y3 ]6 w2 ]' d, U# s9 F* B* _ @}
, X' ]' @4 e1 r9 o y3 w4 O- w: W
1 a$ m( O$ s) k& Z; N" i5 Hint DestroyStack(Stack &S)0 i$ E: ]4 @; ?0 X2 o7 ]% g3 l: r$ ^
{
7 H# p8 A* ~( ^/ i" ^8 b free(S.base);" p+ a! d: \) ]) D) e: _& ]
return 0;4 M3 k' p: g j4 I5 z2 M
}
F6 v6 q# Y9 k# o3 y
/ s) T& Z, S& r6 u7 w' J3 h. w( yint ClearStack(Stack &S)
+ V- g) h; A" ]( A% \{) [0 T) e3 ?# g \( t
S.top=S.base;+ J5 E5 j" S+ x; M! e7 n
return 0;
" }' r# n* b3 k% U/ W- f( j6 H}! h9 R) D% w/ w/ c$ m1 W' j
0 N& o0 `- ^1 E) X- e, j2 D, P% O: `
int GetTop(Stack S,SNode &e)
5 C" Q$ Z! t1 B{ ?* y. D# R8 {# h- A0 Y9 P _
if(S.top==S.base)
! `9 X/ G3 S& L+ l' D; _' } {. {' V8 C6 e+ F
printf("栈以为空!");
8 g* r/ e7 \/ H( i; G2 m3 B% U return -1;
- j0 L; f" W' {. C! K# m }
" G _# c! s J/ @ e=*(S.top-1);1 G2 {2 L0 {% F
return 0;
9 w( _$ _3 _, Y# q j% }, s$ v' ?}
7 |. j; r/ n5 e+ [, X0 n; D& d. z: C% }. x, D2 ]9 S+ H; k' j
int Push(Stack &S,SNode e)
4 w: o, n" i2 N4 \( _{; g& @" j5 U; X" o9 _9 v |
if(S.top-S.base>=S.size)) b+ z( U! M/ b/ a( q! P. ~
{, I& ^% s( a# h, {: f
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));# @% o8 v6 q6 [% D- }: F; j9 a
if(S.base==NULL)
8 V5 z* o' m6 ] {4 I5 C" q- G, X N( N: a" h
printf("动态分配内存失败!");( D& ?2 `, O: y/ W: ]1 _
return -1;, O$ i* N9 ^% B* P4 P3 H7 m
}8 |. j% P- ?2 M3 W' J- M" `
S.top=S.base+S.size;
$ ?( u+ h. H; q: g! ~2 R S.size+=APPEND_SIZE;
! t5 Q$ p8 l: K& l% F3 t& Q }+ s1 W" L: P/ B! t& A1 s9 q
*S.top=e;: F l8 M6 p" n* v0 r& M+ q; F' H
S.top++;
' G2 X5 ]9 Y2 Z; D4 T- J return 0;. m" N; u. V0 v; e
}* p4 g9 j5 V: U6 B1 Q [$ K
$ B' R+ Z! X/ {) v
int Pop(Stack &S,SNode &e)
& S0 r. E+ X# E( p* Q{4 _# [- I, e9 z4 L% ~
if(S.top==S.base)$ z/ y) o" o: I) i6 B x1 _
{
$ ?1 V5 i& q. D6 V( `- y: u printf("栈为空!");# g/ f$ t* l# ~; M6 F* H
return -1;& k0 Y+ b: C3 o
}* {! y8 I% M a% ~$ [$ \- P4 J
e=*(S.top-1);
5 q2 v9 t( G9 s9 Q" k. ^& [: M S.top--;: c0 Y1 d, e; h l2 ]$ x' P J' n
return 0;5 R { d2 S. e" A
}
0 C3 `0 n7 s) n7 {+ o2 M* X9 J
1 M( L0 q+ a6 G d" ?( s, u: gchar get_precede(char s,char c)' G- b8 ^$ e% ^& Q4 g6 |6 t
{
$ u; n: s' I( {$ w% D7 u switch(s)5 b6 b6 V( f# _3 M9 l
{4 E7 ]5 g, p, X7 d
case '+': ) ?/ ^2 ?/ m8 Z" ^
case '-':- d4 [5 G. |' W; y2 y' l: |
if(c=='+'||c=='-')
$ X" M7 b/ |( i' O return '>';
5 b2 `7 j" A+ h& j, ^ else if(c=='*'||c=='/')
: s; \/ ^( s6 k8 D! {1 t return '<';
! S0 f8 T A9 `' e# V else if(c=='(')0 l: n$ U% U& p& p$ L+ R' H
return '<';* _; \) z/ l8 W, _! J
else if(c==')'). f9 H: w2 [7 l; D/ d. \
return '>';
! Q2 f7 x% s z else & Y" P! s2 T2 W( H: k& \
return '>';- B* T+ O- D$ Q
case '*':
6 F# p7 D" \' S# V! w/ z case '/':
8 J! q: u( P5 b- M7 D, k6 g if(c=='+'||c=='-')
3 M) z$ T7 b: w" j return '>';
0 [" e4 \5 w) j$ {: V else if(c=='*'||c=='/')
; Q$ ^7 z0 l+ K! h return '>';
9 D# ]0 t4 L; Z* Q else if(c=='(')
I: V4 D; B' I0 \; Z9 C0 S6 ]- p, ` return '<';& s4 {9 y. s8 r5 P2 T' r
else if(c==')')4 l, |& g4 z! o% _% g" z$ S0 Q
return '>';
0 E# y! ^& g! p6 M else% M" u( p# X: K- ]
return '>';% U6 [* p ~- w. M+ `; ?0 i
case '(':6 U3 `6 ~+ q3 A5 n
if(c=='+'||c=='-')
# u- ~0 b W$ }8 u1 t+ Q return '<';
1 ]' X& J% T/ `8 j4 M1 @ else if(c=='*'||c=='/') {( Z+ X3 F" Y6 O; ~5 g
return '<';
* R9 C' D7 Z5 \) j8 h7 K else if(c=='('): c% \, s' b% } h6 M. P0 d' a
return '<';, t6 _0 _7 E# [; g: x
else if(c==')')9 y, n+ y1 _7 }' a
return '=';
2 @; T# a5 O! h& D' R i) } U) G else- ~. W V: R- v4 t' v
return 'E';
0 B2 n' I y- a case ')':' i0 e0 M7 D7 l
if(c=='+'||c=='-')5 f3 a6 E& w Q2 l) @
return '>';0 Z: Z$ O% `, n" d/ M& F: d- {$ P
else if(c=='*'||c=='/')' `- K' ], [/ B; {
return '>';
+ \3 c. @. n2 j' M else if(c=='(') L# r ?4 a' U/ R7 Q$ s& i H) z: O
return 'E';$ ?- b5 x% t! F2 `
else if(c==')')
+ L+ u* f# t: Y' s. |, d% K: N return '>';" j. N; z9 o B5 L6 m' F
else
$ p2 |, w% H( Z return '>';
) J1 _5 ]" m7 l0 c. _ case '#':- w4 t9 a. V" { D6 q
if(c=='+'||c=='-')
# D& N/ Y* w: a! S ~ return '<';
6 |' u2 x( H; W$ C. ~ _5 T else if(c=='*'||c=='/')5 a: Q) ^1 l# U, L; X6 b
return '<';" P3 b' \9 h7 \9 j# k( L/ D2 H+ z
else if(c=='(')9 }8 a! _( a9 d* O& z
return '<';
6 {9 P, }5 E( w' e+ w9 O else if(c==')')
2 A% G' L" n. }- S7 J- w% ]# U) h return 'E';
/ \% t4 O! e0 b- u" H" | else/ x: ], m& r, m5 I
return '=';* m; h4 Y0 m5 x/ u/ o( k
default:
+ Y3 i# Q. U9 z" L) N3 d9 S break;
3 H0 n( X5 P5 N! C# P }
; O3 ]6 o3 ^; ?. l% H. |; I return 0;
; l5 \/ z. g8 _" x6 y8 V$ i! ]. G: J}6 W8 A" Z" W* c( P- [& _- a
: ], f) y+ B Z/ L
int isOpr(char c)
" F3 P3 l5 v9 F1 T5 y{2 g; N! w& A1 O- E) r
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
" D2 b* {% M$ T return 0;6 i; h2 s2 C5 R: Y7 F1 e
else ~* }4 s* p" k) ^
return 1;
* Y0 _* {, i1 |& Y3 B2 ~$ Z}
( m; H! ~; ^, a1 f+ b4 d$ o7 d$ d9 M
float operate(float x, char opr, float y)+ ~4 F4 U) G! t3 }
{, g8 `5 L6 @$ I8 ~8 a* U
float result;( c* N! P/ ^9 I, q5 ?2 B
switch (opr)
4 R( u" l' c1 E8 }) y {; l# F: {5 ]% O5 F7 j* o
case '+':
# e* S; v" N- B5 |) Q- [# Q result = x + y;
: R) I, j1 w+ W4 m break;
9 W! w$ ^; {" r. h2 Q$ z1 _! o* S( V case '-':
* W9 C; Q+ W! o7 R ^ J' ^ result = x - y;( V. F O9 q N. E
break;% J1 ?% s. y `
case '*': % p5 a) H: J% b
result = x * y;! H$ M* W7 j- f( E
break;; p2 d+ m$ j$ N8 l u
case '/': ; t* F* ~, A5 C4 ]5 u7 l
if (y == 0)
* y- n2 v G4 R {
; ?5 u3 U' J1 Q/ E1 T) c printf("Divided by zero!\n");
1 B# W8 H4 ]5 I& _% r return 0;: L* h& E/ I# {/ {. z
}
9 ]0 Y, R; W4 _6 ^ else
6 D% m. D) v* K5 ?$ Y9 V {1 [) B9 ]7 h* p0 A! \; \
result = x / y;
; l" c: l) N* q" @- ^; { break;
, g. |3 n( ]* [- Y }
* s- T% r- x8 w, a- X default:
+ C- U3 P# ^1 d printf("Bad Input.\n"); 1 A6 v/ i$ C' q! s0 j
return 0;# K7 e6 M8 M9 T! L2 Y
}2 N9 }0 k6 x0 x! x, n3 Q
return result;5 l6 H7 M: m6 g: r6 e
} $ U& K. d, S- @# H
* c- L. J) s! b. w* ^float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
* a4 q4 ^2 C% y7 Q+ o3 L! E{3 U+ e" z6 z9 W0 r* T
Stack optr,opnd;* G0 j* K* d8 O+ i" l3 L
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
( c! T" M+ t* [* E* a char c;
, G* W2 F$ M# O/ C char buf[16];* ~7 M8 K4 B5 n* w
int i=0;' k7 T3 \/ }6 }. @" h1 @/ p! t
+ I7 M3 o9 X ]$ j1 ~9 [ InitStack(optr); /*用于寄存运算符*/' q& W4 Y7 e' z4 @: Q0 k. G/ S
InitStack(opnd); /*用于寄存操作数和计算结果*/$ N4 R2 J) g" z( f+ J2 J' f9 N
memset(buf,0,sizeof(buf));, X6 x b: c/ p4 y" h+ @6 U
5 R( g5 ]$ ]/ ]( k8 v u! ^" k8 c printf("Enter your expression:");
2 V/ R+ u5 y, N2 b/ @& K& m; l " i1 ]1 W3 F1 u/ U, ?: o8 n
opr_in.ch='#';
' ~2 c4 ?4 { J" A5 R. A- K Push(optr,opr_in); /*'#'入栈*/
* P' W1 L1 ]9 A7 j1 r1 G0 d GetTop(optr,opr_top);% a4 B6 R0 a) _
c=getchar();
1 a, r4 L5 O6 U) d n% _ while(c!='='||opr_top.ch!='#')* I$ M) B6 N! l8 z
{
; Q9 o5 {6 U) | if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/3 o/ o& g' c( t' q7 \
{0 K; K" E$ Q. @% R: h, u' t
buf=c;
/ C4 b- v M' W: C% R( N, a/ \ i++;* H) z9 i1 R, D
c=getchar();
# O" [' t& G$ {! H2 p r+ Y5 K+ E$ d }
: l% m& Z a) p1 j% [ else /*是运算符*/7 _$ g8 q6 w5 L: N6 }3 W. R4 v: _, G
{$ r- l" v6 h- Y) V& W; ^
buf='\0';1 o( V* j0 z. W/ V2 m r1 C+ D0 a5 h
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/. u6 z. |; l$ K& e' z
{* l+ y# m) M; v% H B8 S) u9 h
opn_in.data=(float)atof(buf);+ A. ]9 r0 w5 J
Push(opnd,opn_in);
" e7 I! S/ O6 }+ x5 H6 v printf("opnd入栈:[%f]\n",opn_in.data);
2 s& \* s) G3 t; J- t i=0;2 s0 N1 H" u; o2 I# C5 D T% y) z
memset(buf,0,sizeof(buf));
: `7 |/ Z0 l$ ~2 c1 u3 T }
" @( A8 w! \. q$ `! E" h: t$ s5 Z opr_in.ch=c;! k5 l, p- D$ c5 P" E; y! v4 v% ]* v
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/2 v) m2 P8 k h: G" k
{- s- A. x" C8 e! Y x( D
case '<': /*优先级小于栈顶结点,则运算符入栈*/9 J. ?$ i9 {7 P5 D5 q! f
Push(optr,opr_in);
i/ e& D% s- Y- l printf("optr入栈:[%c]\n",opr_in.ch);4 U& ]! h; V6 x. H7 r
c=getchar();
: u! @: X8 x4 O! S. L4 w break;9 X; k6 |( z' }2 T4 j X
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/" O6 y' |% h c( Y O3 X9 H
Pop(optr,e);
' n- v" x# B% B- i* _0 q8 ^! ?; u8 C, V printf("optr出栈:去掉括号\n");
2 ~2 f" g) S/ i; P2 q( v c=getchar();/ H7 ^$ `! O/ J' e( L8 I
break; Y9 d/ t& z; t% G; S6 y
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6 o3 S2 X& v2 i4 u2 r0 o Pop(optr,opr_t);- ?, h7 m# C' ?% M# r
printf("optr出栈:[%c]\n",opr_t.ch);: |6 H) `: p. p% l' y, S
if(Pop(opnd,b)<0)
( I y/ o: c+ J1 K& h {
* h a5 W% P z7 n0 s9 ~ printf("Bad Input!\n");
0 a( @& V" O2 {6 ~+ |# m( J: e fflush(stdin);
' }4 ]3 @9 k2 ^ return -1;7 G2 ]5 N: f: s; |
}
7 O3 F: d2 k, n, C* J. ]2 U8 Z1 u printf("opnd出栈:[%f]\n",b.data);
1 M* _2 M+ {4 F if(Pop(opnd,a)<0)
I6 d. w$ u) i: T4 x% l- X, ` {
. ~. H# Y& _# t [ | printf("Bad Input!\n");
- K; { |: Z$ C fflush(stdin);
! i' N2 w( c! n6 W return -1;
, B/ r: i: V" q) n; H) ? }& U* T, i5 f. o* i: k, Q
printf("opnd出栈:[%f]\n",a.data);
! D: U, |% Y4 z/ P" N5 v, _ opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/$ x8 v- K& y. Q) T
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
/ v' M1 |+ M/ h! E printf("结果入栈:[%f]\n",opn_tmp.data);6 d' n; M! u- Q* ~4 @3 ?/ V E$ c
break;# ]7 g8 ^* h/ ]! h. C' Q
}
/ b& b; s3 R, p5 V: q5 G }
) R! ]( Z' I* Q" X3 ] GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ + D, z2 k7 q {* Q; @# s: e
}
0 O- @0 Q! O* Q8 A+ H0 b; d9 X2 @ GetTop(opnd,opn_tmp);% W0 }+ B8 j E9 {; \$ v3 {
DestroyStack(optr);4 V# c9 B4 ?2 P- M4 F* G
DestroyStack(opnd);
3 M- l" H( e6 a return opn_tmp.data;8 Q, x3 }1 B1 O6 R" } y; f0 N2 I
}
. O6 R1 l2 I2 W- h7 z7 |. j, o5 _) q) ]" _- c, B; T( D0 P
char *killzero(char *res,float result)0 b8 d% h' V, m8 R! c
{
/ s' } q8 }% F- ~& Z' t int i;' _9 |4 {7 J$ [* N3 m7 s
! _; N7 i/ D+ {% I9 A; n
sprintf(res,"%f",result);* E: \- n: {1 C' Q
i=(int)strlen(res)-1;1 N V+ `; s# }
while(i&&res=='0')8 ?2 z9 \ @( u1 S' U5 H j! N
{+ m4 g! ^5 F& @- ]5 ^% B
res='\0';! u% D7 R& h9 l+ K$ ^
i--;
0 |, A, y; W; m& e, `2 @' w }
7 r, M+ L% c/ U: r: n8 f* J+ [( `1 J if(res=='.')
% {5 _2 L9 `9 N" P2 R res='\0';
6 B$ u4 z, r; _1 \ return res;
E" q4 j7 k, {1 |; h}
5 A* ~) _3 b2 p! Y1 {8 s
d. f4 Q6 U: w) x6 ^' fint main()
! H X! _' R) s5 Q{
5 I% ?, Z: S) `. v char ch;, r* [ L( J# [+ Q( _, B! h/ p7 E
char res[64];
0 |9 y( a9 y( R, S$ ^ float result;
! L8 |+ @9 h" j; {' e% K/ q0 e while(1)! w4 }2 v) e0 |0 \3 h6 a7 M; C+ P j
{. @: ]+ T' S9 T w9 E& q4 t; |
result=compute();
2 n1 r- A! H* G! J" D printf("\nThe result is:%s\n",killzero(res,result));
0 g3 F' b6 q1 |1 B( S7 C. R9 A# q6 U printf("Do you want to continue(y/n)?:") ;
, n5 x1 Q+ V T* ` ch=getch();. s2 S- R: G% Z1 {' y9 n
putchar(ch);4 r% ?9 c1 Y: W
if(ch=='n'||ch=='N')3 s& p/ { ~3 I p7 t" j
break;
! |6 R" D. b" N T- t% J4 V else3 u$ n8 G( Y4 \- f) k* m& V8 ^- Z
system("cls");
% h1 H2 c5 v0 j9 }" H3 w1 @8 a; L }
6 z6 _& N/ t* n$ W8 z9 U' n4 H7 e return 0;
5 R" T* U& v0 A}" ]$ q" q- n9 R) S" S
`0 v: I1 K2 I6 T1 u$ N
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|