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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.$ O3 m9 b/ z, E* ~
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=5 l& F, p: |+ g' P4 @, J" U
/**************表达式计算器************/' L& G+ {5 @$ q2 }4 V
#include <stdio.h>6 F) c3 m3 w* m5 D3 ~8 B5 A6 [
#include <stdlib.h>
# ]1 M3 \4 f$ k/ u/ r2 K#include <string.h>
3 Q) N& Y: R s) R- a+ F#include <conio.h>
5 q4 Q2 w& G* o( ~% a#include <malloc.h>
$ k4 Q# A. z/ f2 o7 d( R9 p2 q5 M
#define STACK_SIZE 100
6 {6 \/ ?* h5 r. `) w6 o$ T7 V#define APPEND_SIZE 106 N7 N! t& i4 q
0 A) v3 e0 e P3 C: l7 |
struct SNode{+ Z% ~0 X2 ?" j g
float data; /*存放操作数或者计算结果*/
- s. V# |- D; D7 X% K! g. m char ch; /*存放运算符*/
& W, H1 m, y3 ^};! H( N7 X& B# L7 T* J
% [) |9 M% C' m$ K Q' U8 j4 ]
struct Stack{
# h2 h8 u" z/ E' p2 @ SNode *top;
4 U9 q, Z4 j, N1 p5 s( G, t SNode *base;
+ T* ^" J% x; `2 b int size;% \# j0 R; {$ E# ?0 ?" ]* {; c! {9 T
};+ \4 N# k6 }& R" t6 _
' q' L: U$ ?* t w' I/ |% h* Q+ \( D
/*栈操作函数*/& r3 Z1 }. r1 L4 v* B" `1 |
int InitStack(Stack &S); /*创建栈*/% b1 g& U% x7 T$ m/ [3 Y; @' S& o
int DestroyStack(Stack &S); /*销毁栈*/
% G. N1 k5 R" m' e4 W6 p5 p8 o: |int ClearStack(Stack &S); /*清空栈*/- w2 k% G/ d' H
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/: |( K. h/ }$ r9 U- M3 b) p
int Push(Stack &S,SNode e); /*将结点e压入栈*/" {, ?/ `( e1 x; [' P
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
, y% \8 B8 d2 i1 F/ v5 w+ m# R
) z2 m/ H& `6 o |, ~/*表达式计算器相关函数*/
. @+ J4 Y1 ^& Uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/6 m$ R$ t$ n* D" D7 ]
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/7 P! E- }6 p+ Q+ ?
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
# M8 @) n, D- B5 M1 K8 b0 hfloat compute(); /*表达式结算器主函数*/ q" ]: [" l& E7 r3 Y
char *killzero(float result); /*去掉结果后面的0*/
% j. z o7 ?' e& l
2 I. [7 C. y% a; c# P% H( Cint InitStack(Stack &S)
4 ^% [0 N U4 S% E9 W% j- |{
" a+ C) m. X1 S3 d' i5 S S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));3 Q) P; t2 ]2 @! o/ j6 @
if(S.base==NULL)
9 e5 w. @" `0 e {
# W$ ?6 o3 [* P& r printf("动态分配内存失败!");7 z. }1 l6 ]6 t, ^4 q- K- E
return -1;
4 |* N: s7 [; H4 ?, H- ?1 a; G }
4 N8 @0 m. [3 D& m' A S.top=S.base;3 J4 [: T. K2 t; ?. x- j
S.size=STACK_SIZE;
3 @0 x/ c, b2 M% h- |: m: L return 0;
0 [' ]( ]2 E0 h8 v. h}
9 O/ V! w% T' ]! }
9 t! P- m v* z6 Bint DestroyStack(Stack &S)
- K" R* I Z" O% s, z+ s; l# e, ]{$ ~' e3 z9 b( c+ X. a0 s |4 D; t/ g
free(S.base);$ l$ W1 Q. k, S1 S
return 0;
& g# [: _, ^3 q0 T/ ~4 B: K}$ \) V4 ?# a6 c$ w. g
1 E# a2 x: y7 H. \0 W- E2 d& `int ClearStack(Stack &S)
4 {. E' O- b- n! [{$ d _% w( A$ u" i6 w7 R- m
S.top=S.base;% B" h% k9 r$ z' S9 K# e
return 0;
. Q7 b6 {+ y; F1 v. B3 }' f}
1 k. u- \5 @# D! G- V2 n4 \) j8 e) d" a, X
int GetTop(Stack S,SNode &e)
2 s& h4 n1 U+ e. C1 a{( r( _. W+ {0 B1 P5 q* e, a
if(S.top==S.base)1 {& m* k9 s# s. d- p
{/ z& N/ E1 ?' S3 U( V1 }& j
printf("栈以为空!");6 x6 P& m" C7 K9 L) l3 O6 z8 e
return -1;. e0 ]! m. d* ^( Q0 {
}
( k* K* `9 J+ L! y e=*(S.top-1);
! V4 {$ y, I: [ return 0;' }$ I" [8 h. Y( W5 O7 o+ Z
}
1 V0 G5 G! U% K
! S- E; p% P' tint Push(Stack &S,SNode e) r7 [" x- l6 e6 X
{% c2 a+ r# W/ X
if(S.top-S.base>=S.size)! f4 u! s# D! ^3 E% }, X5 c
{
! T$ ^ t; ?! b" ? S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
8 l9 e/ L( m$ \ A8 R; }( R) \ if(S.base==NULL)8 j U) k4 s/ m( J
{* @1 s0 [; P+ ?# q
printf("动态分配内存失败!");4 L7 I9 o# D4 T) [2 B' x4 u8 I) d
return -1;
0 {* q# }5 d9 c7 D }' L f' r% ]! `6 W: T, e3 M- T/ u6 @
S.top=S.base+S.size;1 G: C' F9 O! e7 v5 T8 r
S.size+=APPEND_SIZE;
( [" K7 |3 x7 ^ }& s- v7 S$ r7 u2 d0 p
*S.top=e;' M2 E$ `9 S' O6 d5 [) P
S.top++;
8 z& S3 p* a) c2 n" O$ s return 0;! h! q+ x0 a. V6 W _- c
}$ K$ a5 g" L( ~/ o6 U! ?
/ C( A& m2 V% F' X. k/ ]3 V
int Pop(Stack &S,SNode &e)3 f( N7 x K7 `/ U
{( Z/ ]3 ?, c+ X3 ]: w1 V
if(S.top==S.base)
# C& ]' n, l( k) ` {4 }. t% N. D# J. q
printf("栈为空!");. Q: x& N$ C! J9 o3 Z
return -1;: q/ D% ~5 K+ k3 J6 i9 r" y! l
}
) X8 w6 U2 s" [ A e=*(S.top-1);0 f; Q# ^& \) r! N* j
S.top--;
7 I) ^7 X& [3 C" @4 `! Y return 0;
# C5 |/ Q, J! u$ \, u}
% X* G g. I4 X4 O1 g$ Z" i
6 O$ L3 J. C- f/ c* bchar get_precede(char s,char c)9 D0 [' n" X" j. {
{
* g3 u$ X% z; [3 E$ G7 l2 k switch(s)
% j! Z% ?! _, ?2 P+ A {% v+ R9 Z% S4 [& b+ t+ c
case '+': 6 M1 ^ i* t ?, ~1 [' y/ C
case '-':7 j8 G4 ~6 K: V4 N. }/ s2 b
if(c=='+'||c=='-')
0 e- G; p( H. V2 K1 P, Q5 t7 C return '>';
9 Y4 ^9 a9 E4 g M else if(c=='*'||c=='/')
; J' H, m: b- {) b3 I, y, a/ ` return '<';! H0 X0 w9 D7 V t2 g
else if(c=='(')5 r5 a0 g5 @8 N1 }8 ~1 [: t
return '<';
, q4 b7 l( Q% c2 H5 s0 E M4 E else if(c==')')
& s, B" k" ^# O; n9 a- k return '>';
6 w: V- H. O7 _& D) Z else * z% ~( e9 f) t3 ]* t3 D# u
return '>';+ _; C/ x, J0 p, l* U4 M
case '*':/ X/ p' J! Q# Z4 V& R
case '/':
6 B. X) i% S: j6 W if(c=='+'||c=='-'); H6 p! [+ K# O/ _; |4 F
return '>';" d8 d% l* ^6 r
else if(c=='*'||c=='/'): ` y* ~* P3 b$ f r
return '>';
% n" w$ Z7 \$ L else if(c=='(')5 P) I* b. F: e- C9 ?5 R1 J2 C
return '<';
2 j1 H9 ^8 m9 h3 R else if(c==')')* B0 V* h. N0 W4 M6 c% Y
return '>';
x y3 P# {) C% |, Q1 e else/ f' @; g# Z0 m
return '>';$ T- O" V: y' j7 s
case '(':
# u& H E6 Q8 O6 J/ V if(c=='+'||c=='-')
# {3 i0 S, D g5 \5 x return '<';
7 o) t1 O) e. o i! e else if(c=='*'||c=='/')
" q% n& v0 W7 G0 `4 V$ r return '<';
! c1 t1 M5 l0 }- g4 ] else if(c=='(')) L4 [1 p8 i0 X \
return '<';
$ T! e) Y% P5 R9 C3 i Q else if(c==')')
) k2 Z$ j! \4 q" l! ` return '=';
9 W0 A& `, R( Y" ~; r# S) b else* o% S: ?4 S2 H
return 'E';
1 j, @3 N! b- Z' `% y9 F) z+ q/ p case ')':. S. }; k( d! a
if(c=='+'||c=='-')
Z9 b& k! w+ w8 O return '>';" l8 Z/ p" p# W5 b
else if(c=='*'||c=='/')& q5 \- n% `* E
return '>';
4 r9 g7 j8 x: ^ else if(c=='(')* _3 V. W" [2 `
return 'E';
5 k7 N8 ?: l6 R else if(c==')')
+ _: x0 ]$ Y- ~1 |. N return '>';
- m( ]0 u8 x, U: o! M' B! u else6 Q n5 @" f9 J3 M+ D6 K& E1 G
return '>';2 e! q9 Z# p$ ~& L; v
case '#':
; Z* ~5 ?& R$ H h% _; o2 K if(c=='+'||c=='-')
& O: K! n& K. K/ { v X. y return '<';5 z: ~) w0 P+ w% a" j* Z$ d
else if(c=='*'||c=='/')
/ j/ F, o0 J, G; I1 q return '<';
+ |( t6 g8 z. Y else if(c=='(')
9 z; Z9 s+ f* [+ L; {) Q4 v/ S return '<';: H$ h: v$ y3 p+ ]* Z
else if(c==')')
7 \- C- i" w# _9 c4 y. S return 'E';
( Q0 G0 ]% w# n) I, b else7 Y. k- _9 [3 J$ Z
return '=';9 Z/ N3 G0 g- N" e# ?
default:" j9 B7 m, [! P8 b( ]
break;
* Y M N- z9 s+ Q/ b0 J0 \ }6 m5 x$ R" v" D& [* Q5 b8 p
return 0; + B2 P5 D6 \8 Y! s# R% C5 K
}1 @3 a+ z! p8 a8 x. W
+ E( H i. k+ j- F, l% ~% ~
int isOpr(char c)
% O# e t5 D- X; K) {5 B& s{2 T% e E9 k) w3 z( P
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')4 u5 p7 J) o8 @. ~6 o9 ]
return 0;
2 v/ w3 o$ @. D C6 _6 R5 a O! D# \ else
$ U3 N! d) Y' `1 }+ m0 ]/ E return 1;
- n) E) @& p2 T! k} U) j7 ?- N% }3 p; [ n
5 N) h: h. K D3 q) a) Afloat operate(float x, char opr, float y)
6 y+ c4 w& C5 T3 e4 I9 y- @{4 S( e0 M; r: K0 j
float result;1 s8 b! ]( D T/ j8 t! I0 j
switch (opr)
7 `3 n: |3 D. m: G2 r {3 W6 s6 b: |' ], f# w) j" q
case '+': 1 D! R) V; ^& x6 g+ I7 @, E
result = x + y;
% [, z. c( k( M9 r break;
q. G8 R/ N$ L/ T8 I case '-': 3 C9 E6 h% ~* E( |/ L2 Z
result = x - y;' W( B, C5 K, N
break;+ {3 [8 E8 l( f) ?& c2 Z8 X
case '*': 7 j- z7 l( B' l, W$ ~8 ?* ?
result = x * y;
/ {1 n; ?# |/ j0 l2 k4 `, n break;3 v1 z" E9 v+ o* `3 ^$ \
case '/': ' R% R# r3 {; }5 o2 S) v8 x8 s
if (y == 0)0 w9 w4 i& l* M2 ^3 v$ `
{1 n7 o7 v9 f6 {5 ]& H/ ?
printf("Divided by zero!\n");
" o/ R! K* @: w6 \( T7 X. S n return 0;: P, O$ D: @/ y7 I
}" o4 V. x/ I' b, F1 I0 Q' }
else
! M* M: A1 k4 k! V {& K A. x, ], M- _ {
result = x / y;; w. ` s, _. j; b6 |) N7 P/ ~& F
break;: A+ r9 I6 }' c. L: g/ |
}# |5 {4 i2 x$ q% _" T4 e
default:
+ e7 @* J1 h5 U7 Y% K9 N( Z printf("Bad Input.\n"); + H1 ?& C/ P6 Y% O( I2 i
return 0;
5 w, |! \2 [1 e1 E+ M }9 i v- B; c! x5 z
return result;0 g/ d1 i; p8 z# b8 y% i+ G, A/ S
} ' q& a _% w# n8 @. u" P" _4 Y
7 V7 H7 B/ ?/ d% ^; efloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
/ e) }! Y3 u/ Q) @. r. o{0 T5 [' ]0 W: E& @2 V6 ]) I# O) K" P
Stack optr,opnd;
0 K; H8 t: k+ J \9 V2 [ struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;+ z3 o: U5 J) ]8 [1 l0 J3 [6 h
char c;, T; n j4 Y% t# f+ j
char buf[16];
8 h, v0 X3 C8 Q int i=0;
# L+ X0 H; H9 l7 U9 \
+ k' U* H- `" p5 k1 [1 n InitStack(optr); /*用于寄存运算符*/
! Y+ s% C& G+ k! Q% C6 X% V5 ]9 q2 H InitStack(opnd); /*用于寄存操作数和计算结果*/
0 B& q; e1 K& C$ c) y8 n memset(buf,0,sizeof(buf)); C9 g/ {% W. v: @7 U8 g
4 g# h* ?6 U# K8 D( [' H1 r printf("Enter your expression:");* [& b$ u& _1 t& }& p& t
9 W3 p) a7 e; { K4 }6 l0 r opr_in.ch='#';, E/ l% l+ T) D' u
Push(optr,opr_in); /*'#'入栈*/
. p- k7 b/ Y+ M4 T+ K GetTop(optr,opr_top);0 W5 Y/ \/ r4 @" E, V" ]
c=getchar();
; x% k* D* ?4 o3 y- g3 d while(c!='='||opr_top.ch!='#')& `& N/ b4 l. F; _1 u9 E: B
{
6 q% z8 t3 H- h if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*// ]) ]* I" B/ ]" a& n5 I
{) }8 L# K; }$ X
buf=c;# J" S- G1 c d, X# P
i++;
$ s3 t# G2 k X! m4 t c=getchar();+ ?% E% h6 T# X2 k
}
- l5 ?( N7 O( P3 `0 q+ {" o# S else /*是运算符*/& H% q7 q$ Z2 t* q. M! n) {
{( p8 q* ?" |- |' V7 `0 z! I4 A& {, D
buf='\0';
7 Z7 y2 G0 m8 H6 @, @# L if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 J& q: y4 ? @+ r5 F$ [4 K0 k
{
: m& V \3 v# x opn_in.data=(float)atof(buf);
v" j* o/ e$ R5 u. l' H! s4 u Push(opnd,opn_in);
/ H! B; I) ]& a2 L* w" l% n' S printf("opnd入栈:[%f]\n",opn_in.data);
; F, `' u- O0 p3 Q7 ~3 j% Q1 Z: N i=0;: V G% G% m; @( A6 A- |- t. D
memset(buf,0,sizeof(buf));, ?0 l2 h [6 X2 N" o0 _
}
" v5 ]* U b1 P, f9 C3 v/ @ } opr_in.ch=c;1 H8 c* U4 }: J7 V- P' E
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
) U9 ^' [( n& A. n$ K# ?" } {
- W- A- Y3 X- D/ A! p9 P% X case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ Z$ a; u# S2 L7 n& u Push(optr,opr_in);
; a4 A* R$ y. f# P" g5 N: D printf("optr入栈:[%c]\n",opr_in.ch);
/ o; X7 B+ [5 p2 m c=getchar();
" \6 B2 _* R" X, @' |2 d+ n break;' b! O$ ^8 v: I9 W* \- Z2 W9 ^+ G* q
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
8 A4 j" n) q8 D1 y8 v5 F9 B Pop(optr,e); k5 q4 E: A5 w$ t _) k B
printf("optr出栈:去掉括号\n");" D1 h2 l1 U% A. j3 C# a' Q
c=getchar();
" w5 p3 {* S- y* ? break;
& I) _' e6 s3 u1 e f case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
5 @% T! `2 Y1 }# O1 ` Pop(optr,opr_t);
9 A# w9 S# _) W3 g+ |- m3 y" I4 k printf("optr出栈:[%c]\n",opr_t.ch);+ e9 p# R. O6 Y6 _- @; S& R
if(Pop(opnd,b)<0)& F F0 Z: E$ }; i% M$ v$ Z
{
. g$ [* [' Z( C! o O0 w printf("Bad Input!\n");( T+ F! a+ I+ ]; {& X* ^, S
fflush(stdin);
" _$ P7 c: ]% u5 k, U3 B return -1;, d L! s5 Y+ E
}8 ?' C. I/ I) Z' s1 H6 q: J; ~/ l8 f
printf("opnd出栈:[%f]\n",b.data);
M# r5 [/ F$ o if(Pop(opnd,a)<0)6 X" w" V( z" l( A b, u# M2 ~# o
{
8 M0 } x5 K1 x* `/ e. _, V printf("Bad Input!\n");; I- p4 h7 Y& P; ^0 O2 q4 `, i
fflush(stdin);
0 u7 H* u, Z# \% w3 a; ~9 n2 c return -1;
0 p. p2 |' [5 V# E) u2 ] }
) o/ s8 M/ R' _" | printf("opnd出栈:[%f]\n",a.data);( W$ P, ]% l! Y: v3 g9 \. z
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9 ?1 B# ?0 K+ v- U Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
U2 a; g, r3 g# U/ I( S printf("结果入栈:[%f]\n",opn_tmp.data);; v+ s$ X" x, c
break;
$ c( m/ Y- L- K5 V0 P' i) X }. c: [1 d9 T' @9 W& O
}
1 T7 y0 M9 L: {9 E; g6 V4 f GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 3 K$ N; A8 A+ Y) M6 S+ B& H
}0 l. T1 s y& v! ^% F! v1 {) ?+ ^
GetTop(opnd,opn_tmp);
# ?6 b) p$ o6 |) g f DestroyStack(optr);
: M) _2 o& l7 r8 J7 \$ S/ E( ` DestroyStack(opnd);
* [. N( Z4 i4 `. u4 y return opn_tmp.data;
# l; M4 W5 ]4 d6 P) D N}
. v6 H$ t' d% d* p$ D# ?# f
/ c5 H/ M G" P7 d; mchar *killzero(char *res,float result)
% v9 }' ~8 Z8 O" |1 }1 v _6 O/ W{
! ?1 X# \1 M* i7 V int i;
+ y m1 P( `5 H5 o$ _& o0 J/ ?
5 `& W2 n+ V" B! N+ P) P F sprintf(res,"%f",result);# O/ D5 k' }) Z' e. ~ V; I. H5 Y
i=(int)strlen(res)-1;
" u8 G0 ~+ `" R( p- p* ~0 _ while(i&&res=='0')3 T2 R+ A3 A4 v$ O5 [9 l4 b
{
6 Y4 J& F+ h6 Z* E0 A* v res='\0';" E- B+ ~1 @6 d
i--;$ t+ j7 M- y2 H! `9 ^4 R
}% O1 M, L2 |1 {1 b
if(res=='.')
2 A8 D& a/ S. S! m7 ^ res='\0';8 f) K9 F2 ^5 Z5 E5 q9 c) e
return res;
7 `3 [" |; H% d A4 Y' n- F}" V+ h% h1 ?7 p. s
9 s- t' E/ V1 m3 T6 A- e5 ^& J% I, }int main()
" ~+ I) \) m5 {& X{
- t* V, I+ W! U: r8 h5 l char ch;7 ~" C% E0 v4 T5 c3 H( C" j2 ]
char res[64];9 c4 z% C7 g1 r% ^' u2 {
float result;
) p5 Z ~: o4 p* |, _3 i* \5 E+ S' h while(1)/ R. W7 u( w [% f; V K
{5 o" D, } K: X, S2 t+ L
result=compute();
0 L8 C" L P$ e printf("\nThe result is:%s\n",killzero(res,result));
9 @0 A1 r" ?7 T1 n" }& q7 E+ { printf("Do you want to continue(y/n)?:") ;0 R4 G3 ~! k/ t2 i0 R
ch=getch();# @: g2 Q2 u% c. V. C
putchar(ch);
. S" K# e8 }. R7 s- d if(ch=='n'||ch=='N')- l4 s/ L8 k6 j) T/ G: X" \5 ] ^
break;* J- [" {- ]" N
else# N9 _% X7 |" E0 L" J! E. V9 c
system("cls");
$ L: `% ]# Q1 [% O+ }) V0 A$ `2 \ }8 J4 h4 E" Z" M. m, V( G
return 0;: C# D) w7 G8 O" {+ Y/ K
}
. f3 I* D; `2 D+ h& `5 g, g
9 o5 q# K$ U7 y, h2 T[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|