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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
! B; u% e$ f L4 a程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=3 s0 B I7 ~0 e" O4 }
/**************表达式计算器************/
; l0 U# S$ W) `8 J#include <stdio.h>7 H2 v! i2 w' \9 }, v+ E
#include <stdlib.h>, S& c# ~# e& n' I) T
#include <string.h>1 N2 X# L$ r$ c! `
#include <conio.h> ?0 W7 l& F& z q) `
#include <malloc.h>
, u4 U2 m" g" S1 I$ P5 J0 E2 x% t/ Q% h
#define STACK_SIZE 100
* _/ O5 [+ U! R+ P: u: Y' \#define APPEND_SIZE 10
! Y. `7 u+ T% D3 |; A( M# {+ ~4 e: l% D. s$ V7 f
struct SNode{
% ]: l% X- o) i) ^ float data; /*存放操作数或者计算结果*/
+ O5 w& U1 _( E& W5 n, w9 ^* H char ch; /*存放运算符*/
e9 ]" W( z7 W) R' ~};
) c; o* a- @. a; _5 q" d8 z( @: R; d' I
struct Stack{
- R4 j) k4 R5 E J9 `1 X$ ` SNode *top;
% {3 J' h# y# Q4 X1 Q9 M6 [$ |! s SNode *base;8 F( i; G& E1 n. S: K0 X
int size;
/ g2 V; I( g( A4 w};
& x) V h2 W! L
) \' z% A* E% e. P2 S; O3 g/*栈操作函数*/- s# [6 z3 j) l! R
int InitStack(Stack &S); /*创建栈*/6 c: h! Z+ N' k n- o( ]9 x
int DestroyStack(Stack &S); /*销毁栈*/
1 ?$ Q: O. P, O1 e1 Y1 eint ClearStack(Stack &S); /*清空栈*/4 U% _1 J! a) t
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/% N3 m1 M6 _. T5 V+ l
int Push(Stack &S,SNode e); /*将结点e压入栈*/
( z, u8 ?) e3 ]' u E) X2 sint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
; T+ }! H6 a/ e; Y' D! J
F. E& R$ R5 h( q2 C4 h5 k5 v/*表达式计算器相关函数*/
; f5 F( `8 n. ~4 Pchar get_precede(char s,char c); /*判断运算符s和c的优先级*/, e) l$ i% T1 `8 e, ?
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/0 p8 `5 u s. q3 K4 m8 R, P
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/# |$ l& O2 \+ m+ Q* U! i
float compute(); /*表达式结算器主函数*/
+ ~8 y+ F% P" a& m, y0 h& pchar *killzero(float result); /*去掉结果后面的0*/
6 p9 C! D0 O9 g5 d7 ]
7 q1 s4 j2 z/ e0 gint InitStack(Stack &S)8 P$ Z$ m, I% I' _ l9 f2 q
{2 p- E) _9 n3 r+ j7 @5 O( ~$ k
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
7 N: P, j+ {$ j" p) W if(S.base==NULL)
) f9 ^$ H8 C$ i5 ~- w- P {: `/ ~, ^3 p M3 K$ S: ^
printf("动态分配内存失败!");
- v0 f& J2 D) G( l) g return -1;, ~: G6 o3 d% X
}& Z* y% S: O& E
S.top=S.base;$ b3 E' l$ u4 N1 r, r
S.size=STACK_SIZE;
' _! \( R0 x5 S: \3 z' G3 m return 0;
+ ]' n0 E1 Y: K) ~}
8 V5 g5 s* ~" _7 @/ N& J: X+ t) W+ o: p5 Y6 y
int DestroyStack(Stack &S)9 r; w1 O7 @3 \- _2 N7 w0 b: Q/ V
{! o! j+ F- S* b9 B8 D' L
free(S.base);! j9 J# q( p( n
return 0;+ W' V/ Z- a4 Q) e
}
2 {" ^' v8 n% R) C3 G2 ^& x- u2 f( p1 G' _
int ClearStack(Stack &S)
, c, P1 k7 w; _% U% {{
/ X! i0 O; v$ \ S.top=S.base;& I* a% t' d( z' H& ]+ c
return 0;& C3 Z: Q8 }( d+ @9 E! Z) V$ c
}& F8 l% }% T+ l" o2 N- G& x
- K/ ^2 _- w) p. m
int GetTop(Stack S,SNode &e)- ]1 o9 k( `4 J( Z$ i! Y3 J' s+ z
{
% ~8 K, c3 M9 k: m6 q3 H6 Z if(S.top==S.base)' o' {, Q# c) m
{
+ ]" E4 b- }* ^+ C0 }: e printf("栈以为空!");3 H0 u# u( ^, S
return -1;- }9 G# Y; V( W0 s7 P8 h
}
# T+ |: \% F1 V2 E* c) t% E" a e=*(S.top-1);2 @6 E: p8 u4 x
return 0;
) |, N4 v5 I+ D& B& \/ E0 w* V}; |/ ?3 z1 `. `& F1 Z" m
# u# r4 |/ N. [% y1 ~1 `7 q% z2 Nint Push(Stack &S,SNode e)
6 m9 y" L1 r+ j$ j{
: e! i; X) C* h& @5 o if(S.top-S.base>=S.size)9 S# F, H+ h- S/ A0 @% I+ H
{. ^: \7 [! O$ n x8 a) Q
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ P* c$ k& e/ o4 \3 y9 J
if(S.base==NULL)7 X- s5 N# p% O( r/ ?4 ^
{3 u1 y3 b. i) @( w% N9 M
printf("动态分配内存失败!");
1 N, h% t( h( I6 I return -1;, R& S# o, f. C& k" y: f7 O9 i v
}, @3 ?" o' c/ }+ i7 J
S.top=S.base+S.size;
% g. d d# h2 e- C- K( h S.size+=APPEND_SIZE;. h- u1 t5 U$ u, U+ b7 n
}) T8 _( A1 Z. ?+ w
*S.top=e;
+ x' V. J: X0 X& ^ S.top++;& I- M5 }) B* k. y" N2 U v
return 0;
' i& n1 U. v) `0 |2 n}
* E% s4 Z/ q N, ~$ H7 H
/ `9 R3 J, _* S3 p; d8 A4 Y lint Pop(Stack &S,SNode &e)
, D2 |% X% ]' T: y4 \{* y* t' M C1 j7 e3 g) B# Q$ B+ ^& p
if(S.top==S.base)! @1 B, a% p. G Y' A j
{/ R& n j C+ {' {+ S! O1 L1 Q) p
printf("栈为空!");% W: A8 L+ s& N3 {9 T, P' L
return -1;
7 {9 k! y1 b' h" t2 \ }) q' e7 c/ t+ r+ I/ p
e=*(S.top-1);
8 g! |' j% Y6 W# h+ j S.top--;* R# s" J, l" b/ I' e' `5 l/ S: K
return 0;
4 L4 x& k$ u8 ?+ C6 b}
% l9 o J+ h" C3 C) \3 z
0 ~5 V# Q/ K3 e# p6 [char get_precede(char s,char c)
" Q. x9 [& s2 y# Q: e( K{7 r: @* o! N+ O8 l: M3 Y( t; H) }2 F
switch(s)4 D. ^7 S& q& L2 B* N' j
{
) k/ k" O" T3 d, F case '+': , I- H5 q3 l. Z- v
case '-':
% o, c% m' h$ P* X0 ?1 M5 ] if(c=='+'||c=='-')
( p. ]9 k& D! w. Y; c' c3 B5 a return '>';
! [- ]1 }7 J6 h. N$ e3 J else if(c=='*'||c=='/')! r# | o. i1 k% Q# d: }+ m# ?
return '<';- b j9 h% F9 I6 C" x! |
else if(c=='(')
; i Y5 q; x% k+ N return '<';
6 A5 w. k) N, q; U4 |! | else if(c==')')% y' i+ Q, E- m: H/ W6 V4 N
return '>';
- W3 }( w+ {$ K. R3 k% |$ O& v' ` else % S, b8 t6 I3 p0 _+ w% M# h7 P
return '>';
8 ]2 w' i& |- J: X4 k6 X5 K/ z8 C case '*':
' T0 |" D9 L, a$ T& d4 Q2 v, r case '/':
{4 m$ P# p6 e x; _6 Z3 F if(c=='+'||c=='-')
4 D7 G+ g$ i( o2 B return '>';
; t+ i4 D' l0 ]& [7 F else if(c=='*'||c=='/')
- `" Q% ^' Q2 Z/ p% P$ O return '>';
/ [/ N' {- S. N( a e9 F4 [+ U7 E else if(c=='(')
) o6 t1 g! J0 i: I( r% M# z3 O return '<';
- b- I3 y5 U$ s! _ else if(c==')')7 k+ y3 f- L0 ]# g& I( N! C
return '>';6 l1 o- [0 }) l
else) k. F' t5 c/ Y
return '>';
# t0 }7 }. F9 a$ \ case '(':
* G6 D3 ^. V, p) K# a. a if(c=='+'||c=='-')
# m; R7 @ [* ?3 V9 ^ return '<';
( [; X e+ w! Y9 M. m$ C. Y7 x else if(c=='*'||c=='/')9 u! c1 s& W6 F' @$ I0 ?2 B9 P
return '<';
' y# c' _/ i1 l" a3 N else if(c=='(')
- i. Y" M2 p8 W" u' H return '<';
* ~4 T8 f5 e" x$ ]% D" o else if(c==')')
% _6 s! z( \* Q( A return '=';
8 X5 A3 I3 s1 b E0 Z7 \) z else! I2 ]7 c( [/ }
return 'E';1 S. k; n! Z: u! Y7 z/ _$ a5 g- c8 {3 b
case ')':
! p/ ?% F6 A7 r2 q" a if(c=='+'||c=='-')
4 Q# x" i) }( ?. Q: f h return '>';
6 X, Y6 k1 {; x* q- N# H else if(c=='*'||c=='/')
6 \. b( N1 m& K0 ?3 O6 V return '>';0 A' j0 S6 c' x$ P
else if(c=='(')
4 [0 |) l- f' s% {: |; K return 'E';9 B8 a! m& r2 |8 w6 @
else if(c==')')6 U5 q! z+ |0 w* M1 n
return '>';
6 ]7 G6 d, u; M0 j' c$ o else
* ]4 s w' X% O return '>';
* [% o& e9 c* A" U" U3 o$ o3 ~ case '#':
# ^ m" u& @3 i* M, `% k' X: r if(c=='+'||c=='-')
5 Y7 t V, E: N return '<';
V5 q, H0 ~7 c! \3 e else if(c=='*'||c=='/')
/ n/ l% A1 X/ a. i2 D' |2 W) K return '<';4 Q' L4 [9 }, M& Y3 S
else if(c=='(')1 [* X* C; b" z2 y6 W1 | M+ X3 }- n$ M
return '<';) u$ L' A) d, h
else if(c==')')+ Y: F$ S0 `; m0 D
return 'E';
8 j) l7 o. v( r& U- f else4 P; i9 |9 `" k1 Z% x$ r; S
return '=';/ Y" o# ]- O) m. W7 m& |+ ?
default:
" `; t. w/ ~6 m- a& i3 p# s break;
. t$ ]; T# {3 H2 q0 C4 J, K }- W0 }. e: o8 d+ X7 x1 l. }1 P4 E
return 0;
! r# d6 ^( s8 {& h8 y( B5 h7 K \}/ p$ q N: T$ K6 I {
0 q# Y. N& @. ]
int isOpr(char c)
0 {# w4 @% n5 `4 u& G% G{
: |. _# M9 m" o( v if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
. s _5 W0 @' K, [ return 0;
: |4 ?& } Q) {5 ?2 }$ v5 w else
& g# L2 _% c! q return 1;
) [3 V( B" d9 i a4 P}5 x: u- C$ }8 w# P% j# F2 _
7 T5 ^5 V* e3 j; A5 g
float operate(float x, char opr, float y)6 ~5 t8 v& Q, e: C
{" g; ^( V6 _1 U V, I2 Z
float result;
: P3 d; S# p( k0 o, {( `1 f switch (opr)
# e* f, ^7 }5 x: t+ n {/ `- u b6 b% V% b! @) v5 U& r
case '+': 3 }9 Q; p7 P* ~6 P1 r/ l. O f; C; R
result = x + y; e5 r, N, _6 N, @- `( [' D4 F3 V
break;* [) x: E. q% a2 u0 g0 V- ]' x
case '-': / ^* B2 C# q/ H* r0 }4 B
result = x - y;
. q- [7 J6 Q. h break;/ j' a7 I X$ I1 G; H6 ^3 {: h* S! t
case '*': . P0 v3 h* N% F6 O' f- \4 t
result = x * y;9 N" P) N; T; C& D: l0 _6 Y
break;
: j/ b9 b$ n: n) n2 n) X. a5 t8 i0 y1 {( E case '/':
/ B& F/ C' Z: c- G$ i if (y == 0): N M4 O: g, U3 ~% t
{
4 r/ @& ^- V; e, t3 t# e printf("Divided by zero!\n");
% }0 {! _% h2 C) ~4 G5 b( m return 0;/ u! ?) v& P8 S8 X* j$ X% Q
}* u8 f* z; [ l$ k6 B6 i
else
$ n1 t8 \% c" e% y! V- G {
5 T. j) m8 m6 i [( m result = x / y;
9 i% f& Y8 M6 B% s: f break;* ^& x6 T" J/ r; @8 Z8 B8 {
}, n: I m3 j1 C% R$ r; V
default:
1 {$ z8 C/ H; a; i printf("Bad Input.\n"); & w* o, x2 w! g2 `
return 0;
9 a# @3 m- K2 \" M! r# {6 j }/ A1 Q4 e% H6 ]: D
return result;
# P2 d' d" O: W} 3 Z3 f% P; z% U% c8 T
' P v9 i& F5 Q. e4 g; j8 t9 z
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 {! K4 C& H& A F& r{
& G o) N) r+ ` Stack optr,opnd;
: ?; J/ w N' Z% |" S" ~ struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;6 G% u/ t/ K* J9 ^. I
char c;" l3 m/ e- L3 G6 N: l# W
char buf[16];# C' I$ z" q( r
int i=0;
9 O/ N0 i" `) s' ]
4 ]+ D# Q5 |' m InitStack(optr); /*用于寄存运算符*/1 j Z* W! l5 s/ H" I
InitStack(opnd); /*用于寄存操作数和计算结果*/' y9 o6 P V+ m/ s4 |
memset(buf,0,sizeof(buf));
g) G3 }+ x/ w: u5 A. O; {( } ! h5 R* ~' ~; d- N$ r( ]4 U: B" d
printf("Enter your expression:");
) P: Z: C; E5 S2 B E# ~6 I- o 5 v1 D9 R1 w g8 @; e4 v
opr_in.ch='#';
$ U/ Y" L! c }6 P% b+ _( ~1 i Push(optr,opr_in); /*'#'入栈*/
& Y }! P( q2 [ S8 b' W! }+ u3 u4 | GetTop(optr,opr_top);
2 Y2 J5 a* R- _! W. l1 Y c=getchar();/ a! }. U4 F# W+ [9 a* C, T
while(c!='='||opr_top.ch!='#')
# H$ b+ k$ z# ~( q1 [5 v4 R+ o) M {
, N$ k; c4 Z$ C& x. [8 \% w. Y if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
: C9 y+ m* f2 f* }' j: I {
/ m$ B/ N. n- I4 _( ^ buf=c;
' U z) [! C+ s i++;
' h- X7 q4 ]7 X, P& @( O c=getchar();
; H) _$ [' Q0 p2 [4 {4 q6 ~, p }4 P" h. y/ e! ]; U
else /*是运算符*/- e" V, l# C" {9 B4 G# R; x
{3 e! j) T% [4 h
buf='\0'; F8 [# W/ P" m% m. v# D
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
6 Z/ C8 g: h% K {4 A& I( B+ [9 ~
opn_in.data=(float)atof(buf);
* u4 s$ r% N1 R: K# s3 j; x# { Push(opnd,opn_in);, S9 T" }, F% E; E& i# {- j; [
printf("opnd入栈:[%f]\n",opn_in.data);
' X) y- Z7 I* I8 Z8 ?2 [8 s i=0;2 q9 g$ W% p, {$ ~: d6 h) }2 N) t
memset(buf,0,sizeof(buf));9 i5 v9 N: x1 B; ?
}7 V3 }2 X) i+ C! R6 h) k/ N
opr_in.ch=c;
0 ~8 L, l/ j0 ^$ W, I F switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
& H4 L" N6 g" h, m- Y9 n. V \ {
; e5 U2 V; s/ N8 D; s) n+ D: H case '<': /*优先级小于栈顶结点,则运算符入栈*/4 | ^6 U: E9 [/ g
Push(optr,opr_in);
5 I! D) v! I1 S0 V printf("optr入栈:[%c]\n",opr_in.ch);0 V, T" A% `' F' _% e5 b, c
c=getchar();
: ?' Z1 W' W( ? break;! W8 E6 m- k$ i; B8 M" k$ x1 U) l* \
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
* G7 t' n; V+ `8 Z7 d$ U, z& w Pop(optr,e);
& A% K- |; M3 ~. I3 y: W) m+ X8 n printf("optr出栈:去掉括号\n");
& T+ t, R9 D! b5 T' V c=getchar();
( Q5 r% w! |4 U& ~ break;
8 F# O$ |5 ]6 J4 n5 g case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/: y6 Y' {/ @) p% ^# F
Pop(optr,opr_t);
! F( x/ C9 N3 {7 \0 h7 k printf("optr出栈:[%c]\n",opr_t.ch);
~; m" G3 w8 X8 E if(Pop(opnd,b)<0)
1 F0 Y5 C8 d% }6 R8 c {
/ P! X4 m) a3 w( e# E. Q X printf("Bad Input!\n");
5 K1 }! m6 W4 H% A2 F7 T2 ^ fflush(stdin);
# ^0 ^' S$ ^+ [ return -1;
5 l9 m3 h% K1 Q; Q& V2 @7 j }
) i8 c" g* }- |8 T2 }- x# _ printf("opnd出栈:[%f]\n",b.data);0 ]% `+ p7 M$ \0 H, b
if(Pop(opnd,a)<0). e2 R4 \% W6 o5 a; N7 Y
{
1 r" Z, L! m8 [) Z+ b printf("Bad Input!\n");* j7 O: N' L4 T z
fflush(stdin);5 V$ H$ M W: A, @. Z# S. [5 U" [! j
return -1;
( w) Z# i0 Z/ c }
) I: e/ N! p- P8 v, a5 t printf("opnd出栈:[%f]\n",a.data);$ a& L7 ^/ Q6 ]( b2 F7 ^
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
& A' }1 F1 \& o0 K Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; Q5 U5 |6 P. r7 E printf("结果入栈:[%f]\n",opn_tmp.data);* u+ n. o9 ^4 ~3 [2 q: ~# p4 j
break;
/ @( ]. e- ?. i }; ?: {8 N5 G. z4 a! N% `7 g" D9 z
}1 H, e& Z o1 D5 i7 p
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 3 M9 V: E+ z5 \3 E8 o7 r W, x1 q6 N
}
* ~0 E }1 P$ ]- Q: D: m% F* S GetTop(opnd,opn_tmp);
; Z( V- ^5 C' d' `0 _5 e% O DestroyStack(optr);9 _9 j" ~# \: X; ^, M7 p( g
DestroyStack(opnd);6 E" j+ w1 ?: ?. X3 |+ k
return opn_tmp.data;( C! S7 _( U6 {8 h% H
}
( ~% S/ Z, P6 [& X$ a5 j" P0 m7 T
char *killzero(char *res,float result)
$ z, v$ l7 v1 G, l- Z) i{
. w* O. o* |9 J% M9 H& c P int i;
, E9 U9 B, B2 S4 t# y- S# o( Y! ?* T$ \! |: P
sprintf(res,"%f",result);
7 M z0 G) @4 X U i=(int)strlen(res)-1;: x8 b. K* p% |
while(i&&res=='0')
3 D; o2 T( @; |( {7 ]2 x6 k+ ^ {) g$ ~7 i. c1 |4 A8 ~6 ?4 H6 W
res='\0';
; ~3 K9 v3 R7 w+ _5 _ i--;% g9 {4 u6 E! z/ j: z
}
# |. W: v: ^) B9 Q; V& a+ I if(res=='.')4 d7 t8 d& Q% t* |9 L: C
res='\0'; D. V* n. F, }0 Z6 T3 u; y! p0 G* h; v) O
return res;
; i$ X$ ]& Y* z1 w* F- H}
% K* T8 d9 @4 x' k% ?( o. ^0 R: ^$ L# b8 N' s0 ]8 c( x
int main(), u. P* A- D) S% C
{& q9 w8 c, }9 P" F9 i8 `0 a5 [+ |
char ch;- w$ }1 |! M& f; }
char res[64];9 ~, J6 v* p& c
float result;
3 V, i) e1 e6 H/ X" R7 w5 Q) I while(1): D m; c+ _/ _8 p9 ^2 {
{
6 V& W& A4 ]+ }8 ]3 Z, B" m6 E result=compute();) P) l$ l7 K- R: X! \4 j& X4 `
printf("\nThe result is:%s\n",killzero(res,result));
( L; `; r* M2 `, v printf("Do you want to continue(y/n)?:") ;' E7 i! O" @% a* Z% H
ch=getch();
6 q/ u+ l/ L5 ]4 J1 O1 z putchar(ch);- `* O5 |3 N [: ^6 ?
if(ch=='n'||ch=='N')) G6 {9 @$ F4 {% I: ^& f
break;9 v2 S8 W7 t; t" @
else
) y# q& t* @% a- m system("cls");6 r" W1 E+ p; q5 C% g) E
}
3 ]7 X0 k4 F8 t! R( c9 N9 |+ o return 0;1 w3 O B+ `" v2 ^. y/ N; u% O
}
4 s7 _7 j# p: ]" a. j' s, n c' g5 O% ~) y- b* I1 r0 k
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|