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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.0 k2 d3 v! O$ I+ J! V+ S
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
+ ^: G; x x) Z( b0 h/**************表达式计算器************/
/ o5 Q) ?) l: s8 ^#include <stdio.h>* g' D- j+ F5 g
#include <stdlib.h>
* g6 ?, W- {" [#include <string.h>
4 ?3 M9 ^' U1 s; n8 k#include <conio.h>( l* q" I% Z! N; j& n- g% o7 E# `
#include <malloc.h># g& [3 ^" }% _, J- p+ g
, Z5 o$ A6 ^/ }1 u" Z) ~- r' f: @#define STACK_SIZE 1000 Q* Q* N/ r$ q
#define APPEND_SIZE 10
) c0 n1 B+ ~! ?8 u6 x% `1 `& u! z0 ^6 p- Z# A3 I' I! E, e V
struct SNode{3 w8 Z2 e# C* o
float data; /*存放操作数或者计算结果*/# a. g: A/ m$ s/ |
char ch; /*存放运算符*/
; H! p& ]2 J [- Y};" r0 H( Z, h7 v! t5 G
; V9 `6 q) _( u; \3 E2 Tstruct Stack{! Z7 Q9 a/ o3 ~6 `% u! b& ^' J
SNode *top;9 f7 E" j) W9 i0 I
SNode *base;
, {: N# l) {/ q* X3 D int size;2 D" v" c; ?$ T% {
};
0 O# Y7 b# s: J
9 m2 D8 [* D# t3 Q" y: j) ]" A/*栈操作函数*/
8 d7 c" Y- j$ }; kint InitStack(Stack &S); /*创建栈*/
2 l, R+ h0 o' s5 q7 B9 u% ^int DestroyStack(Stack &S); /*销毁栈*/
q J" r" d. }3 S! O( nint ClearStack(Stack &S); /*清空栈*/
# C& t: [9 n8 ]6 g$ F5 Nint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
1 [ J) e% ]2 K& l8 z( Xint Push(Stack &S,SNode e); /*将结点e压入栈*/
* M, j* e) X7 y& ?- B* S! X) xint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
+ C& Z/ f! p9 c" c2 J2 B
# A4 z8 h+ y7 D% K$ P( A/ r! i; v/*表达式计算器相关函数*/3 w# R7 E5 r/ [2 K9 T
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
/ B3 t' W: P: C% t4 L7 A. E7 tint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
# P7 k* k, |1 u/ l/ D' e+ nfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/. F. s5 i8 W. H$ e& m
float compute(); /*表达式结算器主函数*/
g7 x# v) F9 h+ T, {char *killzero(float result); /*去掉结果后面的0*/
1 Z! S @( X# @% O/ ?- m6 v. N) y
int InitStack(Stack &S)
+ I5 h3 q9 Z( _6 O* f{/ v- p0 b; D: p! Y
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+ P2 m- E7 H0 b
if(S.base==NULL)" M8 b- k9 Z* i o9 @) @9 B
{
- T# k- j7 Z' K/ L( Q% T printf("动态分配内存失败!");
- V/ W2 r: T. r" o return -1;# @3 W: `8 O2 @: T
}
9 \# G0 s" _7 C S.top=S.base;. u2 z, x. G j) w4 A$ i: z3 \
S.size=STACK_SIZE;
$ e5 m1 Y7 s* Q# K, h3 O r+ W return 0;! v7 n1 w( f; }
}( J$ o# T* c4 R. u6 H
0 L; E5 b( u# M& @6 R2 m2 aint DestroyStack(Stack &S)
( P% f8 h6 ^; @, P4 r" [{
. n( m5 [6 R2 U6 a w; o free(S.base);
: X1 P7 p5 ]% ^5 e# U" I! A9 G return 0;
* S" l# @1 H2 F}
" n/ Q& q' w/ r9 B9 C% N" D6 {* V$ P& d5 x: f" y$ {5 Z
int ClearStack(Stack &S)
: \5 m+ H$ n: F; r; x+ t" F{! `$ ?0 P) x1 `. Z6 q
S.top=S.base;8 f& { n8 f E% n, y( s
return 0;% `6 K! R# r A- [
}
, v* g1 N2 W' A+ S* G$ b7 o* L/ s
int GetTop(Stack S,SNode &e)& j7 s+ U6 [9 d8 k8 H
{
. S# @" [4 z J3 ` if(S.top==S.base)* S8 n1 l3 q5 V% u, L$ v
{( R* o$ A: M6 Z9 v5 M
printf("栈以为空!");, B' V% j! j, ?' n8 [& w, U! i
return -1;
% T I" }4 I; O% [/ z# O+ l2 `' N$ x$ S }# S* E; ]* n. N: R
e=*(S.top-1);% O- K1 T' e9 f: v# C
return 0;
! ^8 Z3 p _5 X# L$ D5 r0 \}/ w, F3 W2 e+ t- k7 N* G
* N; u8 R# l* A' g( e' m8 Bint Push(Stack &S,SNode e)! y6 @* p0 A/ @3 p5 {
{
$ Y" V# X( g! e2 c s if(S.top-S.base>=S.size)
' M' j3 U& U7 k- |$ v1 T X w {
: B; a% D1 j+ x- ?8 ^) g S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) D0 A0 j3 j# e s% g: B$ b) h if(S.base==NULL)* W+ C0 `, O+ L5 F
{( f4 \# U+ g2 J/ I8 j
printf("动态分配内存失败!");- Q/ D3 h3 H0 O& G3 X
return -1;' r4 c5 g9 n% l* a, a3 i. f$ B
}- F# Q( g9 R. \, e H
S.top=S.base+S.size;. F* ?+ I6 b% v
S.size+=APPEND_SIZE;, ]! ]) ~4 w7 N+ `3 t
}4 q, [2 W" e$ a6 a* ~
*S.top=e;
) ~; @2 J6 N) \+ ` S.top++;
0 S" K b- H+ q0 ]! e return 0;6 C& {0 W& H8 I8 E, h5 E8 O
}
% I2 N) S; ^" k& ~6 y# R
0 t2 d7 C9 f9 y( Yint Pop(Stack &S,SNode &e)" P# u, [: I" K6 C8 z8 o" A3 f6 c
{
; H# J- c: t0 \& J$ a$ e% V( B' j if(S.top==S.base)
+ ^, E2 z0 m# ?- M3 x {% `: Y( A' d1 e4 r; i
printf("栈为空!");7 s$ s" K6 M+ Y4 [+ Z1 P" A
return -1;
6 v' [' Z% U* D }
6 L# y: z2 K8 T5 T6 g e=*(S.top-1);
3 C- a" E( F1 Z/ G S.top--;
5 J# ~. m% G9 w! i return 0;6 K/ B) y: Y6 ~
}
& d1 n8 }1 D% M# J* m
4 r# s( b# z; e! V7 E nchar get_precede(char s,char c)2 p* C9 Y# `) f& v; U3 b
{6 s& f. F( B: D! F
switch(s)2 }( L' y n- r9 k3 J4 k
{
( O5 B' n5 x0 K# J case '+':
' b; c6 i! H- J; H8 Q: w6 e case '-':- h, T9 s7 O& B- m" q8 [
if(c=='+'||c=='-')' s1 _% t6 o4 Q1 h1 X. |! d
return '>';, ?5 `) x! q [
else if(c=='*'||c=='/')0 [5 f6 j8 x0 K& c( n" F7 d
return '<';
x4 ]; v$ T( o3 L else if(c=='(')0 m* U( L Y$ a$ E/ K5 R! _7 v7 O
return '<';
9 `" ?5 H7 O7 w else if(c==')')3 b4 J* z( d0 u; J; V& U; } k' _
return '>';" _+ M2 @: ^- k O. A
else ) C+ F; Y8 g% Q3 v" n( f6 @1 m
return '>';& V7 P2 r# M5 K& z! f9 e; l
case '*':: E: C5 U5 ?/ o; T1 ^3 N" Z, h
case '/':% a7 |( G. e2 d5 ]; Q0 q
if(c=='+'||c=='-')( k' j1 {& G# R7 {" @1 P9 V+ L4 m
return '>';
: P9 j( O0 D/ t ~ f else if(c=='*'||c=='/')6 Y4 \* A! p+ V: Z
return '>';: @5 l, ?& R4 K- V( E' } T
else if(c=='(')5 E9 L; z& U/ O8 k
return '<';
) K$ H$ M" d1 n else if(c==')')
! Q$ X2 s& k: J% j( a return '>';" Y# P9 B5 u: x3 k% J6 Q: v
else2 I. _/ M* ~2 e& u
return '>';
0 e- R2 Q: {0 r1 ]# y' A+ ~ case '(':' n" k2 S5 G5 c1 ^
if(c=='+'||c=='-')& x3 M' h% O) U" n
return '<';
4 {$ [8 M [2 X4 \9 e else if(c=='*'||c=='/')1 N0 O! c$ t, ~) f, `, O" r
return '<';3 ^4 ^3 P* S R3 b6 K- N
else if(c=='(')
- \; P/ u1 O& l, @) ]+ u2 O return '<';
) E& ~- a' P! w( a! { else if(c==')')& G# `9 l. q# M; l) F5 v) |, m' [
return '=';
- c/ c) }, c2 D% a1 ?- y else5 H/ s3 C# `7 S! i- k/ Z
return 'E';' S$ [- O6 a' n9 b& K
case ')':0 U; B2 ]2 H' ~! \
if(c=='+'||c=='-')& T1 Z6 q2 [# k) s- e
return '>';
" Z7 w/ S8 v4 ^! A' b/ a- h else if(c=='*'||c=='/')
N, ~/ l$ \* B return '>';
" c5 \# |" q2 z# Y! C else if(c=='(')9 }- K% A$ F" v* E0 V/ F3 {
return 'E';% E/ i: L4 ]7 J
else if(c==')')2 Q2 U) W' g# h: G* E
return '>';
" A% ?* O) N2 L: T+ |! [; S5 W else# D" T, o2 ], e/ M4 ?( l) ]; y
return '>';
1 B; U5 v* Z! i6 P case '#':
% u- V+ y* @' f, Z: C! y if(c=='+'||c=='-'), Z F) Y, q$ O7 ]6 y
return '<';
2 n+ z! P; I5 u4 J0 {. T8 k else if(c=='*'||c=='/')
9 J& ]! G; v& ~( F return '<';8 q$ Z* c+ b% r
else if(c=='(')
4 _" h: X& c2 I$ f9 L3 g return '<';: y6 l* s% s: @! R4 J
else if(c==')')
K1 H* P" H5 Z$ Q$ i2 Q return 'E';
1 j' L8 c& O/ d# m- Z: `- ^% g# W else
0 O" H, e7 ^. n' d% w9 B return '=';
( k3 o; B0 f7 M# T8 ` Z2 |& J default:
! L6 q* l0 z9 ~& K' ~" k5 N( y# A' g! C break;
8 F4 T7 @8 _/ A3 g }& r# X; X v( {. y
return 0; 2 a' G k* T: r U7 i
}/ ?% S8 w( d0 h$ L4 o4 E) c
" x8 X. w0 z8 _' @# |, O/ N
int isOpr(char c)' V5 b9 I: o, s! q4 X% ~0 q
{8 C5 ~! R6 N6 O$ a9 J
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')4 ] x+ F0 B7 J5 J5 z I$ a
return 0; X4 q6 o5 i) \% ]0 ^# U
else
9 W0 S: y6 B( p return 1;
- L% t$ Z! e5 J}; [. d6 h% z& X
0 f6 \+ C/ L4 R! q6 S. B% g
float operate(float x, char opr, float y)
) U- X+ G0 _# v{
; Y9 w& [- Y5 l; R* u0 d$ C h float result;
F$ u1 a/ b" g0 C( I switch (opr): o# k& r c0 V8 @* z
{
9 X4 B: Y9 k2 m7 l: O5 p case '+': 1 {' l+ X$ w. N: D- } {0 }1 w! j
result = x + y;0 K' q+ u% x! |! K3 K! {1 U
break;
2 P! I( N& f* b/ j) y. y8 v case '-':
$ N. F: Q7 r+ z# Y% b result = x - y;
r4 m1 P1 H+ Y1 q break;
0 D" r: a; s$ J( Q$ P6 Q! g case '*': & c& u5 H8 A _0 t/ H
result = x * y;. _, v3 f7 @; X3 J; o
break;' ]# P4 |) Z2 i) z+ Z4 d7 f. K, c5 S
case '/':
, d! R6 J9 r2 e4 P" K& s if (y == 0)$ c/ ^. v1 Y) {* b3 g/ O
{
+ D. v& O$ E9 Z6 a! v printf("Divided by zero!\n");, n7 `& f+ N; Z# A h
return 0; |/ i1 Z- v* @* [
}" v5 r9 P# N+ i. N
else
6 {7 N4 \8 t `- U. m: c {
. r; M$ b( H. p/ a: s- t* O result = x / y;
7 {$ ~- g2 `! y' Q# Q' N, r7 J5 J2 J break; d- A' [; z, P& Q4 H
}2 @, B1 ]8 t8 z' C( U9 i# `
default:
- \8 |- U: ?; m( L printf("Bad Input.\n");
2 c9 C% h9 ` T9 b return 0;4 B& U1 ~) V" W' { C7 B* S
}/ w! N1 `& U) p
return result;% _* o, O: O8 p, }! j$ m
}
" O7 t2 K( G* z
$ ~1 k+ M3 _- ?2 f; Dfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/( k( R5 o. _. X/ {
{) |4 ?! L* g! K' e$ D0 A* K$ e
Stack optr,opnd;
* H& M4 W3 _# J9 [" v A9 j; X! ~ struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
F! G. O2 w- e) O char c;
& D% T, S i/ S, s# I0 m* \( a char buf[16];. v. Y8 f) r( L$ q1 I2 }
int i=0;: f, x# q) }: l& c' J- y3 Z) l
" x' P" u8 e, ?$ Z
InitStack(optr); /*用于寄存运算符*/
`. g( }. I4 a2 i InitStack(opnd); /*用于寄存操作数和计算结果*/
1 E x0 h$ h/ ^1 i memset(buf,0,sizeof(buf));/ U$ Y6 T% ^3 m
7 I: m4 ?; `. e# k' z) n8 U printf("Enter your expression:");+ d; p- H0 K; X( a3 s( y5 q
* {" r$ e0 c4 l
opr_in.ch='#';
- K* {6 N/ D) J* @7 [- w R Push(optr,opr_in); /*'#'入栈*/7 Z* z [% a7 Z
GetTop(optr,opr_top);
! L+ Y- }6 _6 y c=getchar();" u, V+ O- y8 l+ H! p5 S4 U' X: l: F
while(c!='='||opr_top.ch!='#')
+ `1 ^7 i# o5 \ {
% V* i" U! _9 \- R* l if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ M2 _4 W/ H4 h" P( [& I {. K/ g6 S7 p* }2 p( }; F
buf=c;4 v7 P g8 z9 t5 M5 X1 a& R# G! G$ U
i++;
5 l- t- ~ V0 t0 M: j& Q c=getchar();8 @# G5 q1 x7 d. ]
}/ L k1 P2 C8 t& |7 a2 s7 j
else /*是运算符*/
3 R/ K& `8 o" ~' F7 F- ? O3 Z' [2 q3 ] {
0 U' y0 h! ^6 m# W: l5 F buf='\0';
- _( T, S/ g; w( a4 k7 k if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
" `! {( |$ k- @' d7 O" b {; j# j1 x) x0 Z' b1 b
opn_in.data=(float)atof(buf);
6 _) V( a# ]" ]4 ]" t% l Push(opnd,opn_in);% }- F( O0 u8 c
printf("opnd入栈:[%f]\n",opn_in.data);
- S, m+ E7 Z8 b2 m i=0;( c' I! f" Y, [' M
memset(buf,0,sizeof(buf));
u* K' G% V# H. V$ X) t, _ }
T5 V* c; L& L: Q7 x0 |9 l opr_in.ch=c;; n3 I# F- X8 d6 R( W4 M$ b
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
% u" U k7 j" U E; f1 G) k+ F3 U9 W {) h9 l( p# B+ {1 T/ h/ y, c
case '<': /*优先级小于栈顶结点,则运算符入栈*/& M; D8 v# }# U+ Y7 Y* K) z
Push(optr,opr_in);
- b! D2 m4 y! t" D- I printf("optr入栈:[%c]\n",opr_in.ch);" {) k# n' w/ i7 p% g
c=getchar();
* H) P1 L7 |3 h" z0 e7 m break;, z( c% C' }4 s7 u' H: O
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/% o( O% b8 @ c7 Q4 T% M1 L
Pop(optr,e);
1 ^4 q5 H+ L, X+ q/ y l printf("optr出栈:去掉括号\n");
0 S& h# A+ V% }2 N( D c=getchar();
( [# ]+ j' D* _3 ? break;
/ Z1 t0 L$ O0 N& o) g8 S case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/4 n3 F1 @ g3 B
Pop(optr,opr_t);, a3 @; h M/ |# S9 \+ V
printf("optr出栈:[%c]\n",opr_t.ch);% Z! k% @- K% o$ I6 n
if(Pop(opnd,b)<0), }1 n; T/ _2 X* z. Z3 r
{& ?; _7 N! y9 a% c1 Y
printf("Bad Input!\n");8 S6 w. T) ~( |$ ]
fflush(stdin);
3 T; W. t( ~0 U1 P return -1;' V6 A' Q: ]$ k* Y- @, |, |
}
h8 _# w0 k$ f4 ?- \# f printf("opnd出栈:[%f]\n",b.data);) X3 i. |, g3 a& E# S8 O
if(Pop(opnd,a)<0)$ M; e$ V' N8 I( Y* t
{
" A1 C! u5 F/ v" a- F0 _ printf("Bad Input!\n");
+ | t1 q7 P# T) y' q5 J fflush(stdin);( W4 w' ]: u" D3 j% N2 m! E3 @
return -1;+ M' i) A1 A+ s. E' J, w
}7 s! c1 g& u$ C: f
printf("opnd出栈:[%f]\n",a.data);
- p, z* m# o8 e( H% P opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
/ d2 i. I3 e# N Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
' Q2 E% s7 ~7 ^, |. E5 y printf("结果入栈:[%f]\n",opn_tmp.data);! [/ _% R' Z0 z/ E) A) C" n9 g
break;
8 M( B0 K/ E' R: d: e2 N& }' s }& R7 k6 [. D% y+ Z7 O5 n+ a
}
7 ~9 t- {) C% o" g9 J# X0 { GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
5 n; b, M9 ]) Q2 m5 d& Z) _/ t }
2 J3 e7 T- B0 o$ O GetTop(opnd,opn_tmp);# h0 ^% b& s: |
DestroyStack(optr);. H% g* E+ d* e
DestroyStack(opnd);& @" `' A& B1 y/ C; T6 @/ U
return opn_tmp.data;
* x# E, f( P* p' A, P3 D5 i8 g& t}
, J2 a6 u# M9 M! i1 u2 H
# P& L9 g: T( X- c7 }char *killzero(char *res,float result)$ l* T& x) x- j) n l. u
{
- d3 e$ f5 N3 g8 J2 Z3 D5 v- B& L int i;2 i4 ?* Q' ?# B2 a& P- p7 f" e
2 z9 [* E: x- j" o4 j. G2 e" V7 b
sprintf(res,"%f",result);! ^2 C' \* S6 Y( a# L
i=(int)strlen(res)-1;
6 [9 w7 |; ^# k. J while(i&&res=='0')
( U4 H/ v6 \3 ]3 F E2 Y {
0 }; z" p; {% q M( f& [ res='\0';: Z; \9 y4 d' j# ~/ Y
i--;( W8 ] z) S1 |: V A$ G
}& j. |* D1 [- h
if(res=='.')6 C) Z s' w+ Q* M# F+ c
res='\0';6 G# n T7 u( a4 o6 W
return res;7 o9 c8 R' V1 p# V7 ~. Y0 e3 A8 y$ _
}
V: B$ [% _" J9 C: I
0 q0 u- m5 |* s3 @int main(). @1 s/ ^. z( p+ V) M$ N
{
0 Q, Y0 Y' B, d8 R4 f char ch;
! N% j/ m* A* h7 @+ v char res[64];3 T j+ u/ x# ]* {. D+ V
float result;
8 Z( X- X( q* W+ S' l A while(1)
/ s: \+ ^% z2 O9 j {* y4 p- {; b/ \- r6 d( T3 w2 B
result=compute();
* d+ k% a f0 O0 X' l4 e! q$ } printf("\nThe result is:%s\n",killzero(res,result));
! Q5 }; O! P" k printf("Do you want to continue(y/n)?:") ;
- j n( t( x8 d* H! i ch=getch();1 S4 V3 Z: }9 a; [9 ~# r
putchar(ch);
f# Z3 o9 L i( H+ ^ _ if(ch=='n'||ch=='N')
4 {5 M5 Z8 b1 p break;" ^ B( ~" J! j
else
, b4 a8 v, y, `$ d w7 g system("cls");' y- h/ z5 i+ \' m8 k3 Z
}
# l" Q% F/ b, q2 T4 e- q return 0;4 }. x6 i$ A# l9 K8 |. U
} ~ U5 K$ U! J g6 s
) e6 R' f2 E4 U, j3 T6 S
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|