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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.2 \- t( U8 N/ g9 e# r! M
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
5 p( |& [& [+ { F* |( e/**************表达式计算器************/4 [0 s0 ~7 P7 N# s5 y1 ?( ?
#include <stdio.h>* H7 @; j. Y. L% U
#include <stdlib.h>
7 L+ h" @! |2 g& \$ D& R#include <string.h>
" a- D/ y1 `; p) T#include <conio.h>8 @! J: Z8 F8 p! w4 t
#include <malloc.h>
- h) H! Q1 p+ g$ m t/ Q; a2 n
6 w( r% {8 L' Z4 Z#define STACK_SIZE 100: @* U. D v! N0 [6 {- o5 x4 @
#define APPEND_SIZE 10& B0 I: a8 P% r
6 Z. T* u8 [7 C$ istruct SNode{
; i% k( J( G( U float data; /*存放操作数或者计算结果*/. W; A; W$ `$ a2 u* z6 c1 m
char ch; /*存放运算符*/, ] ]4 X. }6 |5 o7 _
};
1 m6 J* M+ m. ~1 I/ T
0 J5 f: f' O: C# Z! V9 istruct Stack{ a+ O0 M, I4 D2 K' b2 C
SNode *top;0 `, {) b! q) }2 S% H
SNode *base;) z" P6 \0 e5 ]. e5 S' y
int size;& |4 M/ Y5 c" U2 ]0 T) q$ I9 @6 K6 Z, ^* D
};9 Q: t6 o2 Q) n, g
! B7 | t3 C) Y6 l$ l D. A/*栈操作函数*/& ~" E/ W0 t- r4 i' r
int InitStack(Stack &S); /*创建栈*/5 l1 h" |5 d; I6 w. U
int DestroyStack(Stack &S); /*销毁栈*/
+ ]3 i( [$ q- ?+ Hint ClearStack(Stack &S); /*清空栈*// z+ \ a4 H6 f7 Y% j$ T5 O
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
9 ?) [% i$ j5 l# S8 v" @, W$ M9 lint Push(Stack &S,SNode e); /*将结点e压入栈*/# V% c! G6 n2 P! D
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ I# K" G$ z0 v
3 J$ M3 H L' I0 D4 z6 X c& g. B- W/*表达式计算器相关函数*/ I7 O5 a3 b& Y
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
: o) o$ ^" k: _int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
8 T1 L* U7 q. \7 Vfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 Z# K6 X$ \+ P) i1 |9 e* i9 sfloat compute(); /*表达式结算器主函数*/
9 r, t+ q! y, B8 C% ~char *killzero(float result); /*去掉结果后面的0*/
# V; E; Y3 [5 t3 a, J8 `/ V( f9 [+ f% X! l. v/ P
int InitStack(Stack &S)
- a4 m }; ?, ]. p6 R5 p/ A{( }' M& V+ B# a% v" ~ p( Y9 u5 R
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));( i( A' ?0 _ Z
if(S.base==NULL)4 b+ `4 o" K X- ]5 N( O
{
8 C& U2 J; t6 F* J printf("动态分配内存失败!");$ {' v3 d; W, Y3 W) ?
return -1;
) ^$ r9 Y: n0 I5 G- ? }8 p3 W/ N, g. w& R" ?* q! O
S.top=S.base;) _. z& c* G* y; r- g9 g
S.size=STACK_SIZE;. a) g0 P- U, K7 e
return 0;
: P# n: l8 F8 l, ~) @8 i1 V+ T2 E}
4 X/ {/ _* S' d1 C* S( P* {% P9 U N
int DestroyStack(Stack &S): b5 Y/ p; |; g5 T3 ?) A( q
{
. m: B) Z. S4 @$ w) L) |: V free(S.base);
6 n5 @" C G$ r return 0; T( C& }, L6 `, Y! q0 x: j
}
- j; n$ R1 I# {+ H( K
, }' Y, |2 y Vint ClearStack(Stack &S)
3 N5 Y" X1 |5 U{: N4 N; ]( Q8 b+ ^9 h
S.top=S.base;
( f4 {7 ^& [3 O. v$ S) R0 |% S return 0;4 w# I! @; h4 T& n% l& m4 y
}
5 z. [" I- v" V7 X
$ V9 S ?7 A. x- Qint GetTop(Stack S,SNode &e); `8 H- Q. H5 m* J5 `
{
& w1 L/ t. K8 X if(S.top==S.base)
% s, C4 x5 L) B% Y8 G. ^" A" v {6 `1 [. k2 b. z+ r' |) O
printf("栈以为空!");
9 l0 G) c. Y" U return -1;
" b( Q4 C4 O* x }
+ W2 l% F% t: r" G( s1 O# }. x% a e=*(S.top-1);
. O$ o/ D, V8 s# E, a3 K9 _ return 0;
' c0 Y3 g6 h7 i8 Z}
- k2 Q: n$ e5 F& I* v+ @" C' x' f/ v3 V3 t. i
int Push(Stack &S,SNode e)( B9 w" q- S: |. ~- h6 z2 w
{
/ C/ k! m3 X6 I6 W" j if(S.top-S.base>=S.size)0 x7 g3 H! f& k$ O
{
* h4 B+ r; x5 a" ` S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
# _$ o: d5 t5 f. Z& V4 Y0 W if(S.base==NULL)# T) B2 ]6 e1 n" a4 O% y8 n; P: v
{5 @7 N7 o. H1 ] V2 V8 y7 U4 O0 l
printf("动态分配内存失败!");
8 Y1 c' L0 N" b return -1;2 s S9 G# ?3 s9 e6 y$ w
}
. A6 Z2 x. U. V* w* L S.top=S.base+S.size;/ W: s1 R% P. L- v9 I
S.size+=APPEND_SIZE;
- a7 J; h/ e' i, x, g6 ~ }; L$ A5 Y" `) j z- w+ p1 y" t
*S.top=e;
) Z9 `' w* B% n& K3 t; \2 g X S.top++;
* w8 ]) n( q; u; I# R" ~/ z- ] return 0;/ i0 ?8 q z$ D
}
, A% C. H# N" J) r, o( `2 {3 \& j, r! o1 K: V/ S- x9 _; r% A
int Pop(Stack &S,SNode &e)& K$ E+ ^; a" b( m+ K
{# i6 r( o% H' P% N0 o
if(S.top==S.base)$ o/ j2 K( u# Q
{6 w$ Q% Q2 G S7 v' V' W8 s% {
printf("栈为空!");
/ r& P6 f: b. j+ _) n$ F return -1;
, U7 B/ N0 P: K! w$ v4 @ }; r+ w2 k! ~) v) V$ N
e=*(S.top-1);
/ Q! Q! G- y) ]' p* G S.top--;
* U" d5 [# ^7 M( N9 ?- [$ c# r: |) }2 K return 0;
X1 M* M9 ?! m O2 _) r. Q/ I# ?}
$ H- y, b0 c: P+ w* G9 ^1 r; G* V* r0 t
char get_precede(char s,char c)
9 p) |0 a$ s% w0 {5 I# `{
% _; T! u9 S& R: X$ u& i5 l switch(s) J: i' H2 `0 H3 p
{ _( @- G- K; f2 g3 a
case '+':
6 x: c5 d4 }# N) O0 A case '-':- T6 M4 i1 B+ X1 n& U% W' o4 `/ q
if(c=='+'||c=='-')- A% ?* D/ ^, b8 \$ Q6 \ N0 |
return '>';
& F2 K+ {; I* ]" x5 e' e else if(c=='*'||c=='/')4 u* Q/ B+ A0 w
return '<';
5 z0 T/ J; W9 E r$ G$ d0 e else if(c=='(')% G" S6 }! h8 q" F/ [. U
return '<';4 B4 l9 ~- v5 G. O
else if(c==')')/ e9 T9 C! ^5 G! k5 f+ T
return '>';6 g) X% u4 _# S5 F# [5 f# L5 g
else
. s% F0 | L$ T0 Q) j& B. t return '>';# B: O; ]' |/ y2 G$ K! G3 n5 _
case '*':4 h% ~0 h( k# u
case '/':8 o: C1 h' r- u4 U/ H4 ~
if(c=='+'||c=='-')
" E+ @/ `3 r; t" Y! |" S# g return '>';
/ H( b7 ^; a; G else if(c=='*'||c=='/')# i9 A9 n& |" f
return '>';
1 t- z8 R- E1 a- U else if(c=='(')
+ X- Y; K/ F; f: _' A# ^% ?0 `8 a return '<';1 A- V/ p- B. E
else if(c==')')0 t. t( s, ?( P& w F1 k
return '>';
# i" A: f K+ [# Z+ G$ ] else2 K3 n5 [4 R9 n
return '>';& W0 @/ W- O% _5 K6 R! w
case '(':* N% }$ ~$ s: p0 _3 I* t* @" e
if(c=='+'||c=='-')
0 b2 A* B# \( h return '<';+ N# X" f. G5 F- Y
else if(c=='*'||c=='/')
, c4 ~7 M( f" S( A7 Q! f$ | return '<';
5 _5 W7 h1 _ w4 K* B) o7 v else if(c=='(')
$ \! y% o2 W5 t6 m ^! ? return '<';' C* g; l3 S2 o1 V, h
else if(c==')')0 K3 p( [9 E. o6 A+ `% G, u- N3 Z
return '=';6 h! X# A2 v3 L& S* d& X/ Y3 r; s
else
5 m- }( q3 F* m1 ~ return 'E';, f/ M; G2 W+ |3 Y# \! T
case ')':
9 s1 X: H- ^0 V8 J& i* C. } if(c=='+'||c=='-')! `( P+ V9 I1 x
return '>';% C5 h2 u& m7 _% C: n) n) u( t
else if(c=='*'||c=='/')
3 ~! _1 i1 O5 B0 z- h+ p" r return '>';
- c8 l! ]# W6 I* t6 u& I4 g U else if(c=='(')
% c2 j4 X, l5 p return 'E';
, Y1 c* ^+ `9 T& F) w% L else if(c==')')$ ]. S( P5 B. [: B8 B" {( r- x
return '>';
) ?7 `* Z5 q( Y6 ^' N else& } D: f7 p. A
return '>';, x, L, @: `& B- G- p x& d
case '#':% l9 r4 v) _: w1 }2 \$ p
if(c=='+'||c=='-')
0 d; E* D! q5 P- z: Z8 e. u5 O7 |' f7 o return '<';
7 R( q8 e+ \. c! I else if(c=='*'||c=='/')" Z0 Y; v; V$ \
return '<';
6 c, h4 ?8 F9 Q& P- C9 P$ O else if(c=='(')
$ v( @, V# W6 T+ S# l7 [; U, h% l! o return '<';. @* c% T. m3 \8 y1 ]
else if(c==')')
; l& m9 R% x# U# ? O8 f: n return 'E';' ^/ }9 H' K0 M: L7 Y
else
( S( T0 ]! ?! c) O return '=';* f+ F3 o+ e; u4 s; D
default:
, E, X1 I% A+ V3 k break;
; Y1 u1 w; x/ k }
4 J7 q' y+ C) [* d* T, i return 0;
6 e. P. Y9 J6 C1 t2 ?$ [, g}
0 D( F* T8 ]5 K( d' X" T4 n/ g& o2 `& Q7 ]+ l' y! s [% M
int isOpr(char c)
- m3 H; p; M; S6 `7 |1 F6 G1 v{2 e p( _( b& p( C
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='). D, T+ {# n1 S- X6 h0 O
return 0;
3 P1 D5 I! x# [% ?+ z( o" @ else
& c4 C( C, H% V# {' i- j return 1;
8 S E" K* ~$ ^8 Y. c* K/ Q' u* f8 w( z}
: j3 \5 z% b2 j; X
$ T) e& v2 N, @float operate(float x, char opr, float y)
7 F, J% j& s8 C- F9 T" r% x{# h: E4 a- Q! |! W, Y
float result;
( B) @% {, i+ z+ D- k6 j switch (opr)$ ^3 e$ O$ d: P* v& H# m
{% I4 `! u8 `5 W: _+ \& ^
case '+':
/ O2 w9 V* M& s result = x + y;) y: ], k$ l/ C% o
break;
8 w( k5 m; J* k' E6 y case '-':
" K8 F9 Y# P# Q result = x - y;
" G" i+ p5 B, D2 g break;. K" _+ |- W2 Z* ?9 a7 q7 b
case '*':
9 P$ N) K7 N8 l4 {; a, U result = x * y;$ K8 l8 ]: Y( w9 K, g9 S
break;
7 a3 ^* T$ W. W1 Q& _& J case '/':
# T* B7 `( r& d# q if (y == 0)6 t) l! f! S# _" Z3 Q
{
* p: j% ]) s" C' p1 F; D printf("Divided by zero!\n");
; ?" `, Y" c6 m+ R, A( Z return 0;
; a+ [& q. `' v% ]5 f" G0 P }' G3 P3 S, W% _3 s5 X
else
: H' v+ ^; ]: g+ s {7 E0 t( U+ l2 E: B
result = x / y;. y! t( ~0 r) v) k: b
break;
4 S. U0 b. W9 e5 A8 t }# q F6 ^2 u" z0 ^
default:
" K4 |% b( D6 x# m% C" ~ printf("Bad Input.\n");
. A ?- ^6 d) m1 v+ K return 0;6 ?8 c3 T* w* R9 V0 z3 r# f# x
}5 g1 c) I2 n$ Z2 w. q. [3 j$ `
return result;
/ F+ G7 B# Z" k) [) x6 \0 B( i} 3 s' ^# S/ S) J
" b+ Z0 O- ]- G- h
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/" V2 c0 V* X- \5 }7 W; w; X
{; X- ~% }* {: n
Stack optr,opnd;
7 h" S l, f% i5 r& O, I- z. g struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;0 X3 A) g* a/ u+ m
char c;8 f6 z' Q, n! k
char buf[16];# Q ?$ u4 S3 U2 |% J- U
int i=0;
W3 i/ W+ H& M A& L4 Q 2 w0 U: K. z% E2 k- ?; X
InitStack(optr); /*用于寄存运算符*/
^% o7 i" |0 } InitStack(opnd); /*用于寄存操作数和计算结果*/
5 F0 C8 P( K) y. L8 \5 f memset(buf,0,sizeof(buf));& f n+ V+ f* D1 p
' U& g" ^; _. k& Z- _3 H* W6 [+ R printf("Enter your expression:");
* Q& n5 C, ?0 B! F- C4 {; Q* w
, Z: x: s2 \2 O, y. B; B opr_in.ch='#';* }2 B* ~+ x4 _( F
Push(optr,opr_in); /*'#'入栈*/
# P, Q9 x8 k' A5 Y# W7 L( E3 K GetTop(optr,opr_top);
% ?) |6 S* G0 w& a& G9 m7 Q c=getchar();
& E+ ]/ a1 l3 h while(c!='='||opr_top.ch!='#')" L$ `1 A' D0 {! L
{, K) `9 R n0 K# d# u# O6 t$ }3 N
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
2 B0 U: f0 J) g0 E0 [; L {( X% R1 n+ f4 g+ i+ j# o
buf=c;8 y' K2 U" M6 a- v1 o6 |
i++;
5 J" W9 t2 m( d& r c=getchar();
; }. S0 X; G# p& K) C0 [" V }
, Y' N' {. h ~# T; d else /*是运算符*/
& \1 @% }, b3 y: H# I0 h {
/ ]8 _ h! q; p4 H% k& T) I buf='\0';* s3 i' {/ W2 F4 m# S- Y% k
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/* _. A; L/ y1 e! m5 {1 c
{
/ v w' I; J3 m5 X G opn_in.data=(float)atof(buf);4 x- E6 p( n! [' p& ~
Push(opnd,opn_in);& Z2 U2 I5 P2 `7 n f$ t9 G
printf("opnd入栈:[%f]\n",opn_in.data);
/ i g6 C% N* d i=0;
6 z- v% A3 e# i3 _5 W7 I, ]" t& N memset(buf,0,sizeof(buf));
$ r2 z" q2 Z/ v" F- D0 f }
1 b! g" Y* c$ w* F& p5 d, F opr_in.ch=c;
9 ~; w8 ], z2 k switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5 N' J. e" Y" A3 o {
2 _8 l, Z+ ]# q7 f* e& @ case '<': /*优先级小于栈顶结点,则运算符入栈*/
7 g' | l, J+ M' {. G5 v Push(optr,opr_in);
8 ?. W5 B' h8 _. {0 | printf("optr入栈:[%c]\n",opr_in.ch);
$ H/ i" Q/ d, q& o! S9 I" [ c=getchar();) Q- [7 @9 w7 Y0 i
break;
" l$ K9 c5 M, R% a0 \, X case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: p7 x7 g9 f4 o7 n4 u1 b6 o2 [ Pop(optr,e);
B* h: F$ U! o printf("optr出栈:去掉括号\n");
. p0 d$ B& ?1 [6 |. W* k5 P c=getchar();- |! c' n0 r+ A* {
break;; H4 m# p. n. K* u5 C
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
" [. J* O+ l$ { Pop(optr,opr_t);. `7 a9 L+ P. ?/ x
printf("optr出栈:[%c]\n",opr_t.ch);
8 W( B8 E3 i$ @( c: k if(Pop(opnd,b)<0)3 O1 r) J9 o2 l2 n. I
{' |7 \7 K! g+ z& Y4 K
printf("Bad Input!\n");
' P3 g) E* c: M: S5 X4 A% ~; F2 y' ^ fflush(stdin);! |3 G' l" [0 E! K. K# W
return -1;! p! h S; P% K6 a
}
9 E- A8 c& q+ Q4 \% ~7 [ printf("opnd出栈:[%f]\n",b.data);5 J- H$ A7 K' w9 t( K' [# g
if(Pop(opnd,a)<0)
3 y) A- }$ x( ~/ N6 q* ]8 S T {" ~1 e7 \+ f9 z( r! r1 U: @
printf("Bad Input!\n");
+ c: Q6 N9 k* J* q$ U7 P+ e fflush(stdin);
- r8 a0 ^5 N' m4 ~2 Y3 A W# U& j return -1;
1 X1 l! }2 `9 S0 B2 b! A }0 k: P4 J1 |6 t4 z
printf("opnd出栈:[%f]\n",a.data);8 P2 g4 X) w2 m$ R3 e) A
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
4 K; O5 i7 N7 s Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
% J5 ?. }. l* i+ p" W, s printf("结果入栈:[%f]\n",opn_tmp.data);
! Y. q E! [. C break;/ d- ?- F( @, E3 t% h9 d
}; c6 ~9 x" E2 x3 i6 I" d& b8 D% J
}
* a8 t- T! b+ l) T GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ( h; \$ z# [8 U- R' w8 j1 I
}
/ ^6 {) U4 P/ ~. @# _) G GetTop(opnd,opn_tmp);, D1 E4 _! c& B4 Q" A
DestroyStack(optr);
9 Q0 }' ~% H; e DestroyStack(opnd);
+ K& {3 |8 a- `+ t& K return opn_tmp.data;0 E/ {5 S7 x% D1 H9 [
}1 j& w( r7 _+ R C' T& I$ Z
7 e, N) ?9 E$ C1 I5 U) _' Y$ x
char *killzero(char *res,float result)
; ?1 D% o) P2 w. \; U9 M' f{9 e ?$ ]3 _$ [3 E$ E! f
int i;
. p5 S" T5 y% W8 d9 R- z
& u4 T8 j, m4 F: q4 b: W1 n sprintf(res,"%f",result);1 M. x1 H a% c/ g3 z: \- ~ z
i=(int)strlen(res)-1;. M+ D5 f! X( e
while(i&&res=='0')
8 f+ N6 @# w0 G7 I0 [8 z {
0 o2 [% t+ {8 N9 H d; c9 O$ c res='\0';( f* g1 ?! J; S, J
i--;! s) B, i8 i8 w" ~3 f
}+ y! i5 G1 e% s
if(res=='.')
( y! H6 J; K6 `) P' h4 Z) k res='\0';4 o' ~# _1 x* p; {$ t( ]4 \
return res;+ h' k' v. j9 S/ b1 V, c* F% r3 V
}
2 v" w4 T0 Z" o- P
: E- \# q" O' Y/ |7 Fint main()
# J1 Z! F1 ~7 V{
# i; D9 |! a( J1 `& U# Y char ch;
4 I% x3 s5 R* E( {: I char res[64];
* B; o4 U" r: T4 f7 A, F! x float result;! A2 ]. U6 ~9 n* E. P
while(1)1 A4 |: ^2 c( j' }3 w# @
{
' U# \9 Z' r2 @) C3 {1 h7 Q result=compute();
: J- q2 X) Y* D+ t printf("\nThe result is:%s\n",killzero(res,result));
- u3 H) S. h2 W printf("Do you want to continue(y/n)?:") ;7 i9 P# T6 e2 A- v
ch=getch(); t7 L" Q* \5 P. M1 m
putchar(ch);9 R5 v5 B3 \7 t- I3 F* X2 A" L! E
if(ch=='n'||ch=='N'). \! C, X' ]; f9 l3 S% h4 r: r) M
break;
$ c n4 \' ]1 Y D; u# n p else
% | k# }# B# ~) ~7 X5 e system("cls");
/ {! }; v# u3 N% {8 M; L+ ` }
: @( D6 C, Q1 W6 p, V! f! v+ k return 0;/ k7 g$ D' c, Z+ |% `
}# d6 J$ D5 ~" |( h' q: P& r, Z
% J* N; t0 w* l8 N" W0 ?
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|