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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
* B0 N+ y' }8 }3 P4 U; q程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=; |* B, h) w6 T
/**************表达式计算器************/
1 P& V* q: F0 _3 f#include <stdio.h>8 h- D* ]4 B' J9 A) k( {
#include <stdlib.h> X6 @3 C+ \4 H9 w. c4 f7 A7 T
#include <string.h>- x4 V. _! L6 q3 i5 c8 z
#include <conio.h>8 m* G: ]* I8 Y2 R+ {
#include <malloc.h>6 K; O. ~4 X" [4 g" E) r
- E6 e4 S% _/ ] n
#define STACK_SIZE 1000 X, H% m8 ^' D i( ^
#define APPEND_SIZE 10; d, O8 N: H8 U8 `5 u
3 s; h% F6 i x6 f2 c9 ystruct SNode{" Z' C& s0 S" c+ N4 n, y9 g
float data; /*存放操作数或者计算结果*/4 k2 J$ Y2 Q5 v( ^7 H
char ch; /*存放运算符*/( Z! E7 F) W6 Y' A
};
" w3 v. ^# q' Q
' y5 ~; f- }8 i Jstruct Stack{
) J1 N5 z0 e+ S! I. @) _$ I SNode *top;
$ b+ _8 [/ f5 X1 K# D' Z( a4 i SNode *base;3 H* M: h( `! i" Z" i; V0 I1 H
int size;0 D* W! p# s' Y, \% T2 @ q# O" o
};3 f9 H1 `( p3 k4 w! P
! x2 h* U W! t/ `
/*栈操作函数*/
& w$ s) n: S" c E4 bint InitStack(Stack &S); /*创建栈*/$ G; Q% L0 N; R& `
int DestroyStack(Stack &S); /*销毁栈*/, q/ U+ A2 R/ z; o1 d
int ClearStack(Stack &S); /*清空栈*/( M0 N/ X: [8 ]3 F* C
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/+ G2 f- u8 L6 h0 p5 n
int Push(Stack &S,SNode e); /*将结点e压入栈*/& p$ n6 h( K+ `+ M+ G% W
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/& I. f) [$ {' \
% }' z- m i' E2 | t! e7 z$ V/*表达式计算器相关函数*/+ H5 v r8 A; x. _$ h) x
char get_precede(char s,char c); /*判断运算符s和c的优先级*/8 {- f2 [2 b* [
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
3 [* l7 Z9 w. I% A( i efloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/) i( e5 d7 D, R) {0 \* S, r
float compute(); /*表达式结算器主函数*/5 ~# M& F6 v7 X2 ^. B1 ?
char *killzero(float result); /*去掉结果后面的0*/ " S$ v% {5 \: {) [# Y6 m
# m5 P2 B8 h& l/ _* {9 Q
int InitStack(Stack &S)
' J1 c/ z: C' `/ R$ e/ e% f5 f{6 u9 k6 q1 P2 N" D3 X, l1 z9 G+ y% N
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));1 U a3 K! _% ]$ C
if(S.base==NULL)
' d( D7 ~9 [. j/ [' B- U) ` {7 N, U# K2 x; @/ v6 ~1 H
printf("动态分配内存失败!");+ y& U& o8 o; |, A) U( D9 n
return -1;
5 A9 I( i3 a; F: O }! m' e" g% e7 \$ q, ? k( W
S.top=S.base;
. e0 D* e; G1 {& z S.size=STACK_SIZE;
0 t d+ J& G) P' a' V, E return 0;
& x5 ]' e1 P/ a- q L, s( U}" ?0 b" I$ |" d. C
. M/ c& w; i9 P1 H
int DestroyStack(Stack &S)
9 \) S; O' `: C4 b{
8 W9 U! V6 R3 Q4 W) t. A, c+ V0 Y' H free(S.base);. d0 @: i! X. z0 t g
return 0;% u( g- n7 t, {0 R* H
}' H4 h, [" B$ j
* z9 P4 ]! W+ G# L, i H
int ClearStack(Stack &S)+ s" b: V \* T% M% d
{
/ @) u/ `3 s( G; o8 ^3 ^ S.top=S.base;
9 U8 {( O, n# m9 v* x! Y+ O2 S return 0;, E6 B& c- ?( ^& e# Z2 x
}
8 _0 i [0 S( c
, C5 L9 s' s# T% |: X+ M+ |int GetTop(Stack S,SNode &e)- V% |" j5 s8 Y2 Q- x
{' O6 g+ L; y5 b( q& ^+ R ?9 M
if(S.top==S.base)
. l0 @2 S- y, }% X$ ~7 c {. i& B& F. {4 z1 b% A0 T
printf("栈以为空!");
( h% _' i/ A: S6 T& x return -1;
3 p; }: k/ e( {& ^" h }
; `" d" t1 c: i9 v4 O+ }9 C e=*(S.top-1);5 D7 J0 e2 y0 ~/ ~- e
return 0;
3 x$ y) Z' {" U$ J; F5 Z/ A}
{5 c& i% I& O2 g
) ~% o. ~' t, n4 P* J9 d1 G( qint Push(Stack &S,SNode e)
" e4 ?' i# S# G; H0 o6 [{
# i0 z0 _' W( z) k! }1 I! i if(S.top-S.base>=S.size)
1 q( w4 N0 J3 J {! X2 `3 y1 {( r! @8 [; r& q# }
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));# e0 y1 q/ P2 _- f
if(S.base==NULL). n; k: F- v7 ~
{
2 b5 O7 w2 ~8 ]5 t% ~2 r0 H printf("动态分配内存失败!");0 G& @2 b' Q# @7 \! ^
return -1;
! D3 ^3 N: j. a. i3 s5 f }
- I) E1 \, x: Y" J4 x; y S.top=S.base+S.size;: t7 U, g- I" _2 c- S" \
S.size+=APPEND_SIZE;, C; L G, P& S1 }/ D
}6 ^9 [7 x' x# }0 J W1 a3 w
*S.top=e;
6 X/ k3 r1 ]' I+ R% J! x' i" P S.top++;) l" N3 s; P; K6 J5 ]3 _/ b5 `
return 0;: `1 V/ Y, X6 |0 z
}* q. R' T+ W' u6 Z& d
! ?6 u2 @, @6 R# u( l8 B5 d2 O: s
int Pop(Stack &S,SNode &e)
' \5 ?' R) v" a: s{8 n8 U( a, B/ g j$ B! J; ^8 c r
if(S.top==S.base)
" ~( g7 C. N5 k1 n+ T {9 ^2 C4 k& J! p# I s# v
printf("栈为空!");5 A% n f, K- R; [# F: s) y0 ?# |
return -1;
9 K1 X* Z- d' E$ H }% H2 O; {, C4 F9 i8 a! [
e=*(S.top-1);$ V, ~1 d! m' v0 B
S.top--;. \9 _$ {% A- t. ?8 r
return 0;
. p" F$ h# w* Q9 Y+ n3 d9 E: Q}. ^" \: c9 u9 T) I% L. X+ v7 g1 ?
1 s4 z1 i' a( p2 h) kchar get_precede(char s,char c)
5 N& H( s, V5 I. T+ c/ C* p' N{
) t( g. W* @. C. Z" K9 N switch(s)
2 t3 ^6 T2 t2 P {3 Y( n4 I4 e4 p5 ~9 g
case '+': ' L1 t: }; e/ [1 m1 B: F0 q
case '-':- O- v' Q3 F3 S
if(c=='+'||c=='-')8 X7 H- o0 n; `, L: j
return '>';: j6 m. v& G8 ^6 o
else if(c=='*'||c=='/')6 E. B; g- S6 H ~3 u8 W
return '<';! U& t6 f! {+ k8 j/ J+ t& v) ?. G
else if(c=='(')) c: k+ a9 I& d! O) I+ F8 g
return '<';2 [" v* ?1 \# [- E" o, e, _3 O
else if(c==')')
+ i7 W9 ^ y5 i" {! n$ f, C return '>';
; D4 L7 W2 Q$ |3 `/ l! Q4 a0 L9 \2 o else + J3 Z' E9 V& {
return '>';; |; s" z v5 k [9 z4 F& B
case '*':5 s Q/ `) B0 x: f4 n
case '/':
/ f+ W) f: M; |: p if(c=='+'||c=='-')
: J0 z, f* L4 P' F! {/ y return '>';
% V3 X' ~1 M2 H5 {" b& @) { else if(c=='*'||c=='/')5 j/ ~ |0 `9 j% a
return '>';
' F1 S; E9 Z5 S, A( S else if(c=='(')
* B4 v2 J* g2 j! v9 V- q return '<';' ]9 a' M4 s- I" `7 l2 n; x
else if(c==')')
, B! v( `+ y$ V# P% `/ Q e1 _# c return '>';
% ~; p+ Z/ t1 E h% W' o9 X) S9 _ else4 _' P( T& x8 H. m
return '>';
" S- U1 Y4 ]2 Y. U, M' K case '(':3 X6 t4 o0 i: l- V1 Y0 l; ~
if(c=='+'||c=='-')
) d# m) h: J; m0 R, D return '<';0 g: e9 m" H! M a
else if(c=='*'||c=='/')
9 w2 q4 x, j" A& R$ P) v return '<';
/ J& F/ { M5 p* Y& } else if(c=='(')4 j) J8 _3 B' a% m
return '<';
& @* U& V7 \( C# ~3 r% ^ else if(c==')')+ d5 q1 W7 p' o; r; U
return '=';
; |2 H+ L0 v. `- h4 r% H8 h else
" q; x4 ~, q8 b+ n$ U& q return 'E';) c. j9 p/ ?& y5 H) _- ?" v& H
case ')':
6 Y' ^" f X9 `7 k if(c=='+'||c=='-')& T S/ d( I) o$ w; q
return '>';
/ b+ }1 v) B1 | else if(c=='*'||c=='/')0 m# f5 c# C7 @+ Q& p6 G
return '>';9 o9 m. B2 p" ^, G0 U9 f9 P
else if(c=='(')- k$ v' s( g: c4 i; c9 h
return 'E';6 M( M7 z0 k% k8 ]
else if(c==')')# c6 u- i" l6 T" \4 T7 l
return '>';, C* Z8 c5 K9 B3 W
else/ O- n% A- H, I, u; U
return '>';9 `- ^1 R' C/ }* q% a- Y; t5 h5 J
case '#':9 r- H* w# G9 O6 N m$ v2 _, W; G
if(c=='+'||c=='-')
9 i) ]9 z" q! M: ^/ e6 v+ s return '<';5 B! n& l! Q( y
else if(c=='*'||c=='/')
3 L6 C$ r# J: D L1 N return '<';# m" `0 \; I2 l6 p) s4 J
else if(c=='(')
1 W" g& _6 y( i0 ] i1 a return '<';8 Y8 D2 I9 F0 i; X# ^8 }; O1 ^
else if(c==')') W- G& X5 s1 p# y7 S) B
return 'E';2 k+ q5 @2 m' u" ]/ j- b. d
else5 L- T8 g! A5 L: I* r
return '=';
9 o9 Z: E5 r) P1 _! T0 D default:$ L& J. r |* }1 V2 ?" G
break;/ k1 q' G1 y! w
}
/ g& N! R( c7 {. @& H y return 0;
8 Z2 _6 v4 a" a8 o0 i/ G}0 s! \+ Y* Q; M ?# u
3 x9 z" o% G4 c( R: hint isOpr(char c)
n P' e+ x- W' V) l8 r{
8 s4 w* N3 h* c9 w4 k U if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')6 \7 W# h: G: }4 j/ j
return 0; J; v( M$ B4 `
else
+ I9 \% T6 K4 ]! m return 1;6 G/ e2 B/ @9 r4 w/ b6 `8 N5 U! R
}
9 d) F3 t+ e3 |& J( E6 u C) Q
float operate(float x, char opr, float y)
/ E+ |- `& O' I3 g1 I{4 u# ]. A/ U$ m3 b
float result;
+ C8 w6 q! w9 t; q; I switch (opr)
) i0 d- H; v+ ?. {3 M; w! L {& {4 h7 M; l7 E( P7 }- s
case '+':
) I* l9 ?3 C; O9 L! i, Z! b result = x + y;
* ^/ a! D) a5 h5 D5 g6 c) `3 n break;
8 V# h5 n+ w9 ~ case '-': & U9 O4 T/ P/ d! F8 e
result = x - y;
! Q" d# e2 W7 ~3 `* c break;% t5 c ^) `! h' B
case '*': ' T/ R; [3 f' \4 q4 y. N
result = x * y; l1 Z. g8 [6 i6 i
break;6 f) G+ @7 m j, Y. R
case '/': 0 N( x" M0 A6 Y; @# B$ c' _7 C
if (y == 0)
Y1 Z: H# V& A" B {
3 A* B; Y; u* j, G printf("Divided by zero!\n");
7 ?- N; E& u( @6 q# ?3 G return 0;
+ }( d5 i4 t& f+ r7 ~7 s }
: x1 m! s$ E: _ else; C# H+ f6 a" \0 T* z! u7 M
{7 f8 {, i e8 C C/ v3 Y& C! v
result = x / y;4 Y- t& y( ]3 O' P t
break;
2 {3 M9 e: v" m$ u9 n( O5 B }; z. Y6 A3 |% I% }
default: # _4 E2 [8 R& \5 ~
printf("Bad Input.\n"); ' ]: K# Q6 A, {; s
return 0;4 z1 b/ `; I W" H# `' T
}% o" G; R& i& W0 R& h
return result;
/ g1 V3 N3 {0 l3 q}
8 g, ^) l/ y9 `" ^4 I$ A* c4 j3 c8 ~3 T* D( s3 h
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/( @ t9 ~ j3 T2 H3 h4 P! O
{
2 }0 J/ x% T* O( z- y Stack optr,opnd; R1 y7 [1 |0 M% j1 s" r5 [
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;- H, w- h4 ~0 m" N/ S# C' S# H( k2 C6 E
char c;
) `1 N4 w- X Y* Q char buf[16];0 n& r2 l1 e0 G3 u. t9 S) F8 W3 K) l
int i=0;. s( d/ J# a5 b5 ~# ?& ~2 \
7 Q/ N5 [% E1 m5 N( W InitStack(optr); /*用于寄存运算符*/
, s) s. {( A1 t: l5 s* @1 k InitStack(opnd); /*用于寄存操作数和计算结果*/
2 x" g' Q& {, G, u memset(buf,0,sizeof(buf));
" W. X' C2 A) A- [
8 @4 {* U" m% z; Q7 @& T printf("Enter your expression:");
1 A' F7 `! Y# h9 P! p5 A2 X- N ; ?; I" N/ f" b. Z; B( _) a5 `0 o# n
opr_in.ch='#';
4 g* w1 a6 K$ V% R8 q- N Push(optr,opr_in); /*'#'入栈*/6 ? w- V$ O6 j4 F
GetTop(optr,opr_top);
' j2 I2 U& Q, d& a2 w3 {7 e* F c=getchar();
. X" d2 {( ^9 `3 N while(c!='='||opr_top.ch!='#'). N3 a" q' n" ~7 U1 E2 b, r
{. G- @: p @, t% X$ j, I2 _
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/. t3 V F! \* S0 x/ s" v
{) r/ \# V/ g! U" F5 ]
buf=c;* H u0 n, ~- F4 U. @0 x
i++;
6 |3 l3 ^- l9 O3 |) T c=getchar();9 ]) o* Z5 N1 D" B6 C- G0 R
}
8 s& S% x& O2 R, b, T o+ m% v else /*是运算符*/, d% ?; A& ]% [5 l/ K5 o; }$ I
{: h* e6 b" H) u- P: u4 l, v
buf='\0';2 O2 k6 v# ^$ e+ m
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
5 S% j: ]" ` R- e& h2 v2 X3 Z2 | {' U3 S+ O1 g% @8 Z- j$ p
opn_in.data=(float)atof(buf);
+ }) V# r; Y8 @- v E/ c Push(opnd,opn_in);
+ h5 e3 l3 E+ [( D& W, A printf("opnd入栈:[%f]\n",opn_in.data);
1 W6 j5 N+ f' v) z6 U2 h- l i=0;
, {$ D3 b# C7 P8 F; L$ {/ j _ memset(buf,0,sizeof(buf));" J% @6 R5 C# k! W& U
}4 y r9 R/ B6 v8 G( U
opr_in.ch=c;
) }; `+ |* X- M/ H! S0 s0 @2 Y switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/( X' _! v3 I8 e, H
{
/ D5 s# n: I! T- @9 x, ], E case '<': /*优先级小于栈顶结点,则运算符入栈*/% g T* i3 x' ?0 K) z; d
Push(optr,opr_in);' T: O6 Q$ U+ b3 x. f" Z, c& o: S; e
printf("optr入栈:[%c]\n",opr_in.ch);
6 B0 E, p# Q5 N% r7 [ c=getchar();
' H6 p& f! u5 j8 u: n! c break;
& }! ~% m( }1 t! o4 ^; A! G% g case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/5 J$ |4 m! D+ ?% t6 J4 \9 E5 Z) {
Pop(optr,e);
3 O$ _7 a/ u5 x7 n printf("optr出栈:去掉括号\n");
4 [0 x# D3 v m3 F& m3 o$ a c=getchar();
/ U( f0 K# K7 Q- o break;# r# Y; s4 s* U: F' t( S
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*// z" r( j, ~1 m; O" t
Pop(optr,opr_t);
2 ~' R2 G9 j& O0 W- o C6 K printf("optr出栈:[%c]\n",opr_t.ch);
6 L/ R4 J0 o `9 I if(Pop(opnd,b)<0)
1 y# }( M- a/ D8 G: M {2 s+ e" c2 i6 O- T m
printf("Bad Input!\n");1 @, _ S- `% u
fflush(stdin);- E& J0 a+ E! C7 @7 x, L
return -1;( a% G1 Q0 C7 b! x
}
' d0 q) `* N4 L9 C$ B6 l9 c printf("opnd出栈:[%f]\n",b.data);$ m* k6 r. e8 u% J+ f' J. h Q7 e
if(Pop(opnd,a)<0), ?- x% |3 E1 m" j& t+ N# ^% l
{6 W2 S7 x) @1 a( ~/ e; W
printf("Bad Input!\n");
5 A6 {& V2 ?, ]$ y$ s1 B4 S fflush(stdin);
; }, c7 v0 L o! |! y return -1;1 m) m# C* f: s; t7 ^8 J
}0 N2 d! m, v7 A) y( Y a. l6 W5 T" j& ~
printf("opnd出栈:[%f]\n",a.data);
' B) `9 b: U* K4 W W opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/- T$ g! d: p2 B$ c6 z% Z3 r+ a
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
0 u2 d& U% N7 q2 V printf("结果入栈:[%f]\n",opn_tmp.data);) I" l0 Q6 m% M+ u, J
break;
) h1 w- r" v2 \1 U e: ? }
# Y) d& b" W. q7 C4 u% Q }: ~: ?7 R% R& d4 V8 t- r" {
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 7 D4 F7 q" {) ?1 w& L
}
' A1 f$ \+ R$ {$ ] @8 S GetTop(opnd,opn_tmp);
' f- p( ^& i( N2 A/ Q; s DestroyStack(optr);# i' M- _ R! i1 |$ p. |3 E: S
DestroyStack(opnd);
8 w% z/ u' w0 _ return opn_tmp.data;/ A* u) h+ p* X; y0 z
}
% c9 E, u/ c/ }, S. B4 h1 G! d
, t& h, v: w, J2 h) b& ^' r Gchar *killzero(char *res,float result)" B/ Z9 J# t ^% A
{4 s, X0 w5 L: z7 v9 u: h8 ^
int i;
6 d3 a2 ]* p4 N5 t0 J' {1 L6 \
4 N- D( ~/ {& b+ b0 h1 X* i sprintf(res,"%f",result);
5 D, n1 C6 F7 U$ J+ Y7 u i=(int)strlen(res)-1;2 c( p0 M& i# P% v+ ^8 O
while(i&&res=='0')
+ c% L0 u3 z6 u0 r( M$ D3 w {/ g( W7 O8 U5 V v) ~
res='\0';
8 W$ ^( h$ o$ A# A i--;
2 x8 `" q O1 D+ ? }* H+ b8 _* b$ p! {& g
if(res=='.')
& H m2 T! |" {! C8 @$ Z5 v# @4 ^! | res='\0';/ A1 e# K2 G+ n* O
return res;5 F# ~& y- f" X; p2 X
}( c' X5 V7 Q1 w& b$ Q9 P6 B
) o: \- V* \( e% E3 v
int main()
' Q2 _# J' R( |' r! c) z{
4 M- E3 s& g. i( o char ch;- p$ g9 x) u$ r) O1 L' M$ S
char res[64];
% _, X# y0 `. s% L( V float result;
* E$ J! ~. [ E: H while(1): @) m) T& A" N' x$ _( G
{
, z) ^6 j# T! {" Z5 E2 l6 w4 `5 { result=compute();
9 B" N" F7 Y; d7 E+ @( P printf("\nThe result is:%s\n",killzero(res,result));
$ t; B6 h9 j' z' q printf("Do you want to continue(y/n)?:") ;
/ [. }6 E9 g9 j, d1 {! J. @ ch=getch();( _# }6 b" w* c0 R' _! I
putchar(ch);# | r, }9 c: d* ?% F
if(ch=='n'||ch=='N')7 M/ n. z8 e+ M: h) b% p6 U, @
break;, |0 O# a" k& |% C0 W$ D2 g
else
- v8 X. V8 T t* q7 s system("cls");
' u! B2 o) Q2 M { z }; n/ b z8 b- N3 T C7 R8 T
return 0;. [2 X1 x4 N! L, M3 W5 e5 n9 q
}
: h8 a4 r4 V1 M9 r! I4 @
& T$ ]; X6 D4 d1 t[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|