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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.' v7 e& |1 I6 Q) Z
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=6 j5 b) l- f3 i4 |
/**************表达式计算器************/
" e4 O! L& C3 ~6 B$ W( V#include <stdio.h>
) f. h+ n b- G- W#include <stdlib.h>
/ A7 M2 z6 {3 D- q#include <string.h>
" a5 b! ~9 m: u7 |) h% R Q$ ]5 }3 q#include <conio.h>
$ a- P& m3 B }& x4 ?$ K#include <malloc.h>" i9 G g5 | A0 z3 W9 E" Q" J+ Z/ I
' v2 @7 z5 g8 r+ T6 H
#define STACK_SIZE 100
- o# b2 s4 _- r# c#define APPEND_SIZE 10
5 B1 I1 h4 m t. n& X7 J6 V% Y/ H) T
struct SNode{; m, g- s$ z$ v* a
float data; /*存放操作数或者计算结果*/( N8 {9 k" L9 r4 P: p
char ch; /*存放运算符*/
u) M$ B! d' }4 B};
; {) y/ c5 _! a1 j, w/ S' z" A" d" R9 y
struct Stack{
/ x% s1 G8 R- N; g3 Z- q, M SNode *top;
$ v- D4 D3 A; C8 K: d% i SNode *base;
! o. M, D5 m1 d" N% E int size;# v% h4 B* b( \1 H, Y
};
# Z4 D: @ T2 ^8 b& L9 w) q o- v K" K' e) q
/*栈操作函数*/
5 E2 a/ K: v& ~* @+ X5 Z9 p* C0 _int InitStack(Stack &S); /*创建栈*/! m, _( G, ]! c0 T7 K/ O+ _
int DestroyStack(Stack &S); /*销毁栈*/
- q- B- W2 L/ p" f" s: \2 z) Kint ClearStack(Stack &S); /*清空栈*/* C: K' m7 e1 C/ u
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
% n+ y+ O1 [# g+ _3 Uint Push(Stack &S,SNode e); /*将结点e压入栈*/
1 Y( t& f, {8 Pint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/1 c' @6 @) f+ a. R9 Q: `
r) b1 C% P) G# F; m/*表达式计算器相关函数*/
0 l/ |: ?1 G9 N, F+ v" @4 }6 |4 |6 schar get_precede(char s,char c); /*判断运算符s和c的优先级*/! a; Z; C0 t; A% j, ?
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
" y3 p7 q) z* }. N" L0 M% B+ k# K& ffloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/6 C* d- A2 ^. }+ X' K M) l7 z2 F
float compute(); /*表达式结算器主函数*/' J `! \5 j: G1 r
char *killzero(float result); /*去掉结果后面的0*/
1 m2 d( J& m! n3 o! {) H
! c7 r( x+ I W! H) M2 q4 a z% h8 E4 Rint InitStack(Stack &S)5 X) F1 F: B( w, B
{
* K7 w( x9 y1 p5 `' l S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));5 z* G# ^/ F" y6 d
if(S.base==NULL)8 H5 A! f5 K# m- A! H9 l$ h
{
. K6 P) D3 ^/ U8 ?9 T printf("动态分配内存失败!");# @9 o6 N" R7 r) U- k! z
return -1;
: |6 u" b# w4 C }
% U* T* L6 x9 |6 w* J: \ S.top=S.base;
* L! p4 d7 S, z S.size=STACK_SIZE;: Z: |4 u" |7 g% F5 v
return 0;; |& X4 D5 E0 @2 Q4 N* j; B d0 o5 P
}! R& ?1 n' c9 ]: v
3 n9 U m2 s4 r% q
int DestroyStack(Stack &S), I# b' y. w0 _, Q# j. M
{# u/ m5 E( Y' z( ]
free(S.base);
* s3 C! }) `& G2 t return 0;/ j, |5 l; [3 p, z2 D
}
8 [4 i* a7 k0 ~3 E# V+ n, ?+ @! V& t, i. k1 h2 q
int ClearStack(Stack &S)
+ @$ p+ W" }! f. X$ l{
' b S9 K% O% f5 V8 Q1 @ S.top=S.base;' X0 f4 _7 H9 S2 p/ u" \8 T
return 0;
* ?1 Q# T8 E' \. h2 N) [- ~}
5 S: t2 p7 K3 U$ |# d4 Z
; E: X( ~; m6 D* F6 |3 aint GetTop(Stack S,SNode &e)
/ Y3 d/ C5 G2 C m5 r6 z{
5 m, \, W, T, c+ m& z$ Y if(S.top==S.base)
) m* C* |4 k2 ? {
7 _. N' v3 ?4 u printf("栈以为空!");
! X* d8 l6 y9 i7 p9 E# _! M2 A return -1;
1 q6 V% h8 [4 ~9 b* V: T7 c }( a( U0 B3 p/ | J9 M: ]7 X) r
e=*(S.top-1);- |# L8 B# a, p& J% M6 j* ~
return 0;
" X' r2 N0 c9 L4 [$ w}
; Z" V9 g3 y# K& i L% A( X. ]$ t8 o5 A6 k: @' Y
int Push(Stack &S,SNode e)
; Z. k: d8 p3 e7 Y( X* j{5 |5 L2 E5 g" p+ L2 B
if(S.top-S.base>=S.size)
# s; v) L5 L" |: ~ {2 F' C7 I Q& T: J
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
8 m# U& O7 E2 Y4 L7 r; G( C if(S.base==NULL)! E6 h# N$ c) r3 x
{
% v! t( n4 O' C' V6 c+ o( M printf("动态分配内存失败!");
& ~+ r% l+ X- ?2 c4 l return -1;
! o5 e4 }7 n* h6 ]/ K }, L; [* E) t$ b, Q
S.top=S.base+S.size;: b6 h" i; y- l1 P6 D
S.size+=APPEND_SIZE;
: U* w( v$ D1 a% M0 @: H3 Q* S+ w$ V }
) _# u* [& Y' k- e *S.top=e;* L5 c! L* R5 N
S.top++;: J& p# U+ n5 z, ~; B" w3 Y
return 0;
0 n, R! V6 X* n/ g5 @% e}
, @5 v% J: n: d1 |2 Q H4 a ~0 }# u
int Pop(Stack &S,SNode &e)
* \9 Q9 y8 | _, z H' V{
! g! I. u8 k6 O R3 i if(S.top==S.base)) Q" ? j6 b7 |# T Z4 [2 G$ ?
{
6 |! n8 h+ w/ N3 G! m) H. h2 V printf("栈为空!");
% {7 t4 k; H( }# u% j/ A0 J return -1;! D5 W% W1 [8 b- \
}+ K M9 a; {5 l
e=*(S.top-1);
5 o9 E9 j- D. O& Z7 H- k1 K, | S.top--;
; I0 w: x% B/ O9 Z5 g# D& C5 U! \ return 0;1 x* n$ y* k' i9 F
}0 c! U5 ^ i b$ h; E. ]
/ f' e I) j2 }7 Lchar get_precede(char s,char c)
: z# h/ A4 y. v{
: |2 n5 n8 H2 T* k e1 S5 q switch(s)& J* @+ c) u$ d
{* B# W' @8 I$ o5 d9 C7 |
case '+': 5 M" r. d. m+ A' r
case '-':
?, ]6 }7 j$ H% `7 w: H) | if(c=='+'||c=='-') ~( W5 A7 D6 Q6 C$ K4 _% p0 Y; P* u9 F
return '>';
) g4 Y. X4 e6 h: {7 M8 u) [# z else if(c=='*'||c=='/')
+ R# ~# I0 |- M$ l0 j return '<';
I3 G) a8 l1 ]3 I else if(c=='(')
* c. q" L9 a8 U+ c return '<';
) M4 n$ J' f j% X# w else if(c==')'); ]; R7 Q: _) R: |: A
return '>';
6 e# f3 a( }2 p5 f; i9 X( ]4 t) } else
7 A1 N7 ?& b2 [' Q return '>';7 l8 |3 c5 V6 S+ q; y
case '*':
- b# Y% g- G1 C4 a. G case '/':
* { \" O8 }# Q4 d if(c=='+'||c=='-')
8 l$ k# i0 v& M; p2 H* t: p; b* F return '>';! \; p! ]' L D* K( N, L2 b U
else if(c=='*'||c=='/')
$ Z% L; }* o, a# D/ z8 c9 C return '>';
: ~) j0 z4 A& E6 _2 u/ Y- {. Y else if(c=='(')& s: P s- {' o# V Y @; _! s* p
return '<';
% u$ g# J) B8 r! L else if(c==')')
|, J4 _$ @: H1 Y9 Y5 F return '>';
9 e b9 t. d$ @: y5 F7 \, Y7 T else
I* @- X/ ?$ a5 B0 P return '>';. m7 c6 E( ?3 ]
case '(':
* x6 @4 E# g. r' W if(c=='+'||c=='-')
+ m7 T) |% k( F/ D' [ d V7 u return '<';
3 k% h8 S: i( _* a9 c$ { else if(c=='*'||c=='/')5 H; l7 B7 e3 m G" X
return '<';
! {* m& N+ q' y4 {' h else if(c=='(')
L# \$ j8 e! }# E- P1 C return '<';
" Y" c" s6 m5 @* A. Y% n/ X) n8 W else if(c==')')) S$ }( F! W& c9 K% c
return '=';
8 Z$ m3 P/ a# i; o5 W else
$ H J4 Q0 e9 G return 'E';
8 {9 P5 o( T5 U- P case ')':
. I8 f! s# j; ~ if(c=='+'||c=='-')
; G: m( Q9 t' s) O/ r return '>';8 `* f( _4 d: I# X M
else if(c=='*'||c=='/')
9 Y, H' W0 i5 U3 Z3 B1 M return '>';# `2 O* M- O! V9 B* [; A. D
else if(c=='(')6 W0 N% o& R$ I7 x( U6 A6 e" ^
return 'E';
' B# p7 L) a3 s1 i0 G- O6 y# ] else if(c==')')
4 z! ]' b3 L$ s return '>';
4 }, Z- W" d8 ?- N8 j8 D else
0 [7 m) i5 S! P4 {/ E5 r9 @* p$ V return '>';) o7 I. S9 K9 c8 b
case '#':
+ {: @1 G1 P) A2 L if(c=='+'||c=='-')3 N4 ~. i; m8 `) ?
return '<';& ]9 b. ], S: [
else if(c=='*'||c=='/')
, t& k. D0 y! X, ^1 t4 E6 f5 K return '<';
, Q6 e2 b- y4 J3 O* x% T* l else if(c=='(')) k4 i5 ~! C2 E, U( [ a. \
return '<';
' g4 E4 L, B8 T% \ ^# F2 @* L* O else if(c==')'); G9 H7 ?! _" L' ?! i3 P/ P; }
return 'E';4 j$ m& Q7 y3 @4 \- H
else
7 k3 }" O0 e% w6 @' u j return '=';
( c5 v+ n! Z6 G# Z: ^8 o) W8 c default:3 H, h# d2 _& y5 Y
break;
2 B6 v* Y8 H* o8 U }
2 c0 _, C9 j% J0 a& {+ u) D9 ~& b. o return 0;
6 \/ T) |7 E% l1 Z* u/ g}/ _/ U6 k( X. `2 R' A. z! J
9 J9 K8 _# L8 A% ? x2 s
int isOpr(char c)
3 }( t( S7 {/ x{
" O( l% N2 M& S9 ` if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
# _: u! k4 v& D/ S$ n return 0;0 x: x$ I t; Y3 n' A+ D* N" H4 E
else
% h% d+ ]! E7 ` return 1;* r, K) k) b: q/ _
}
7 U. W) j. q! Q9 i2 i' [( [8 V3 n: _
, e- F% G3 ]. L% e% H1 ofloat operate(float x, char opr, float y)
: F0 ?) Y4 \+ w{
; Y( h; B( n* I; U4 k H. j float result;
2 I! K7 B, r" K1 d. M switch (opr)
+ L/ d9 F8 O0 I- y; \; N {3 J$ Z( W. y" f" }, t* V
case '+':
: C5 S) R7 s" f: v- _4 {* _ result = x + y;5 g% z- n( A# B" }; Q3 D
break;0 K, a$ f$ E" d9 {& G. D" C
case '-':
2 ?( j* D8 N& a& r result = x - y;
0 `8 N7 L, t. S. x break;% I7 C( L9 I9 F/ {1 @8 W3 p; R* w
case '*': 6 O) y$ k/ C, j8 o+ G
result = x * y;
" [. J( x f) ^- m6 W# w4 N6 G break;
+ i5 F" {8 \# X' F8 k case '/': # @' l3 V, B7 T' C6 Q% T' e
if (y == 0)
( T r, |3 w; z& Y {
0 P: r2 ]6 U4 z* E# {6 J# @ printf("Divided by zero!\n");
# o) l1 v% B& E, F return 0;6 b! t: K9 I% C1 r
}
) x$ L9 o. f. i else
" |2 T3 q# I& c, T& ^6 n {" _) R; m6 U+ [; h6 Y$ J' @ G0 c0 m
result = x / y;
0 t/ I# @# ?0 V4 U# w3 z$ ] break;8 N; @4 B/ X2 V! u v
}
7 C4 R& {, q8 [* t! [$ P# Z. ]5 M default:
8 l1 Z3 x$ `4 t7 }4 Z) Y. o printf("Bad Input.\n");
( M' |" j. ]% ]7 T, O" G0 X! P return 0;& T' {0 m/ z6 G
}$ z& N# [7 h$ D
return result;
4 F& A, u& E( S* Q V}
* U5 m) V! V0 \$ ]' U
- N2 f, t7 t2 u1 w- Wfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/8 P8 j& V+ t9 h1 I. w- N
{; w) B; v" L' L+ G9 J5 k9 W
Stack optr,opnd;: W# R) z; y0 C$ i' u) c) T- U
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
# t. M/ y' G9 U char c;0 Z0 D/ ?2 d" n3 f4 d2 ?$ _
char buf[16];5 a$ X+ x7 E0 q0 o+ K
int i=0;, T! o7 j% N% i9 t( @# A% p! h
2 X6 T4 T Z. r InitStack(optr); /*用于寄存运算符*/: o7 K4 E- n' V
InitStack(opnd); /*用于寄存操作数和计算结果*/
% O% F# P3 g8 e8 I2 S& W9 V memset(buf,0,sizeof(buf));8 Z1 `/ W9 W- j/ q p
6 @# X6 T6 p* \9 D& O7 U* X
printf("Enter your expression:");
; V, F- x$ k: R" z; N$ v+ a + m7 A! Y( x# \- w
opr_in.ch='#';5 [3 u" ]5 K. J: e/ W* i" v! v
Push(optr,opr_in); /*'#'入栈*/3 ?& D5 {+ ^# }: N* G! ?' {! f
GetTop(optr,opr_top);" C( ?' ^( F2 y1 Y* m
c=getchar();
& {/ g) y0 I# V1 I2 Y while(c!='='||opr_top.ch!='#')
5 b7 G- T( D' R& m4 z: B {' ^. t! v, S9 }! T& ?6 t4 Z
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
p# c2 G% s2 Y$ e( [2 `( }5 z. I8 ] {0 Z. s0 i, p" e. e0 K7 c% V
buf=c;" q K3 ~* k9 p1 Y1 ~
i++;/ [% m( r, e5 p: G4 O
c=getchar();
3 T8 J# u8 L/ `) `+ Y' G. f* ~ }) H2 |% I; V2 V6 i
else /*是运算符*/- ~7 U D# {7 y& h' m0 f- R3 o( B4 b1 \
{* t* B! `5 B) R% I- ^) h# z" l
buf='\0';
# s8 N, q$ z& W) c if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3 v( K [9 x- C; g" U" f; `: b
{2 N2 M( y' P( @' {) {7 J
opn_in.data=(float)atof(buf);
8 Z! {' X0 X. a* X0 I$ }0 t Push(opnd,opn_in);
! }5 R$ p1 A+ y$ B. H! B2 t" @3 ~/ M printf("opnd入栈:[%f]\n",opn_in.data);: G& L4 t3 E; X- D1 t J4 J, i9 a
i=0;, O, K: P0 z1 e M, G5 N$ D3 P
memset(buf,0,sizeof(buf));
: B( K# O9 k; l } [' i4 l# Q# Y
opr_in.ch=c;7 F2 H6 c5 s9 V; w5 j
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/. U; O* ^5 `' w: k Y9 d
{6 T$ K. c2 b7 k" _- o
case '<': /*优先级小于栈顶结点,则运算符入栈*// U' U9 h7 J1 i, F: P
Push(optr,opr_in);
4 `# `( w9 s& j! W& m) k7 y printf("optr入栈:[%c]\n",opr_in.ch);- w2 ^6 e$ g& q
c=getchar();
1 c+ v/ N( O# F- _' H* L6 ?& f& n/ ~ break;
) [& s/ Z9 O' m, p: i case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
& ?- y3 O2 o- N) D8 W Pop(optr,e);' G4 H7 P% ~0 P0 E: _1 N8 Q
printf("optr出栈:去掉括号\n");, {! B* B0 D r) }/ v! P
c=getchar();
1 }/ c8 R) b3 e3 m* L% O break;( l: E, k% ]5 p/ o8 c1 u: U Q
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
4 }$ _, V# |2 L1 c! A2 h Pop(optr,opr_t);
4 i! l1 G+ ]. ] printf("optr出栈:[%c]\n",opr_t.ch);
6 h8 e2 B; q4 f( r2 N, g if(Pop(opnd,b)<0)! ^; [* H- G+ Y3 s% h# M& \9 i
{
* ^; B0 W, m- Y printf("Bad Input!\n");
, U- N/ v, c* i1 W, `5 L fflush(stdin);
% t) \% q9 E0 T% l3 Q return -1;
. f1 H7 u2 ~5 a) T( Z8 t }6 O1 \ t# X( e
printf("opnd出栈:[%f]\n",b.data);! F% m6 B* }5 y& ~ }) w( S' g
if(Pop(opnd,a)<0)( x1 b% e `' o1 h
{' |6 ?$ A' [& y6 E- r2 Z1 Q
printf("Bad Input!\n");
! G- A& R7 s6 J- M; y fflush(stdin);$ B% X: q4 O; v4 m' i
return -1;# l p5 r5 }. [) i; E! v- g6 v
}
- \, A7 _6 i7 o0 P, l printf("opnd出栈:[%f]\n",a.data);3 x. r* j) [, f( G0 K- V6 L
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/) P; C& g3 E/ ]3 l+ L
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/! J$ Y1 l5 V3 b, G7 n4 X7 i' ~& P
printf("结果入栈:[%f]\n",opn_tmp.data);
9 s& }8 X$ }# h, Z Q break;
9 a6 u3 Z8 m* D0 N8 P }
+ G+ I6 K& ]1 ~$ U; _$ l6 I& _+ t }- e+ M9 O' U; _+ Q
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 0 _' V! j2 O1 v
}+ U5 o& y/ I# {* ?
GetTop(opnd,opn_tmp);3 C! ^( ]2 k( E0 [
DestroyStack(optr);
) o: M3 O% _, n8 J9 t+ r5 Y DestroyStack(opnd);
/ \8 k! H. U# W j return opn_tmp.data;: |- v1 W# f( D$ r
}* J4 [: A6 r `9 Z* E* M4 q+ G
- w' |5 _! |+ u; A, {
char *killzero(char *res,float result)- R1 j7 {" _# Y- S6 D7 F, L/ g- V7 F% t
{
+ T& m) @9 p/ D$ |! ^ w" b int i;; ]- S! W+ A' {6 o& a
! s0 ?: _# @8 z1 e sprintf(res,"%f",result);
& N7 R- V; e! f, U i=(int)strlen(res)-1;
; D# m# m( G* o5 c! j4 h/ t while(i&&res=='0')
+ j x" B2 `0 o2 @$ Y {
5 z3 m: y+ E/ A& M2 C% l/ U res='\0';
* a. w& F# d' i! U( T! b- K i--;
1 y7 `2 ?7 c( z5 \# I a: Q }# f9 Z$ B! G$ E# l5 C! \
if(res=='.')
* M$ n$ ]6 I1 m* j2 s3 y: o; Q res='\0';
0 p# T% K0 o& ~9 B3 Z return res;
& i- e7 `. a# r5 b" ^8 h}, U3 |+ U% C' ?! M- N
0 R/ L) \* I- T+ \0 \% C
int main()0 N% c2 _" C" \" q
{0 K/ K0 U+ y4 J) e7 q" b
char ch;
4 K( M# J+ ?6 A& k! Y% ? P3 A char res[64]; b! K" b4 o g2 j, h I
float result;% e( T0 M- I( i/ K6 N3 |
while(1)
# e& q- l' q8 I- ^/ h5 i {
' [% O6 J5 X. Q; j result=compute();
, ?0 N8 g1 A9 t- ~; Q4 O printf("\nThe result is:%s\n",killzero(res,result));
+ ^" A9 g4 f2 L: D+ \3 J+ H+ I' l. K printf("Do you want to continue(y/n)?:") ;; A2 ~/ Y' A* v- e' S' N& p. E$ c, v
ch=getch();+ k* l+ Q8 }. X" z, I& S
putchar(ch);) [& k1 V! d0 G, X; a$ P) E3 x2 Z
if(ch=='n'||ch=='N')% u' Z3 g6 i6 [. E' R
break;
# l$ N4 T; R$ Q0 `3 ~) }( ? else! R. R7 O. p0 I( G/ e
system("cls");
$ p( |7 @6 `7 y2 d }& o6 S( q: I1 Y9 r3 v
return 0;) ~; e+ k }" D
}
$ O7 A' X" C/ s6 x1 g) y' J4 G- a% U1 V8 g: k, C
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|