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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.% o( y$ p" V6 Y% z& u. o
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=! n- I: K2 |9 q( j9 S3 J$ k2 U. l
/**************表达式计算器************/7 d5 Q3 D) R r6 ?! I
#include <stdio.h>
+ X& Q# [" v2 S- q#include <stdlib.h>" Y2 T; H; }* V
#include <string.h>
) R8 t5 ^" i! T/ @$ E; K _#include <conio.h>- Y- O. U) F" u! C+ |$ a
#include <malloc.h>" J, D5 h6 D0 y* l. s5 {0 r
( a. {6 \/ p& c4 {% y! D @. o#define STACK_SIZE 100; X N7 x/ Q- d: k, n* p A+ ?
#define APPEND_SIZE 10& p/ [9 C4 U _7 ]
7 M8 u: T, D! V4 _
struct SNode{& g0 U2 X2 S: M& }& X/ i
float data; /*存放操作数或者计算结果*/7 E0 E6 g% Y$ O V: t
char ch; /*存放运算符*/# z y7 a6 e( ` ~9 r6 }0 O
};
) N2 @0 r! v* f5 E5 }" U# U6 D9 U) p; [$ R
struct Stack{4 f. q$ \3 z! C* ]; {' {/ i
SNode *top;, ~4 z& B& n" M$ A- q4 C
SNode *base;& y6 S3 ? o; t9 O: z8 C d( y
int size;
7 U) U/ d8 P% J};/ ~$ S+ F. C \$ d! h: `, H) {7 H, H
9 s$ T# E. E; ]' a+ u+ N" A2 [
/*栈操作函数*// A3 J7 ?- u% Z, N! O3 ]
int InitStack(Stack &S); /*创建栈*/
- Z$ T0 g- G ?! M4 ?$ Uint DestroyStack(Stack &S); /*销毁栈*/) e) E' o3 s0 m2 A9 e; d, O: M
int ClearStack(Stack &S); /*清空栈*/
7 a0 F0 |+ i' I* \# {6 U dint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
! z# `* a' F: [: u/ Iint Push(Stack &S,SNode e); /*将结点e压入栈*/2 G3 t+ @6 c8 O! C
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
- ]: L5 k/ E0 C. h# Y
' B/ a' k4 b8 q: o0 i/*表达式计算器相关函数*/
7 G, R/ L' h2 S5 F' \char get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 t; b# R+ ?" t' W! Yint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
: k0 h/ p/ }4 s [; E" cfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/6 n3 B, k; ]+ h8 b
float compute(); /*表达式结算器主函数*/
. X8 @1 @) q2 l# b4 X0 ychar *killzero(float result); /*去掉结果后面的0*/
9 k, d0 o: Q/ ^( `
/ q5 V3 a1 E; c$ P% N/ Gint InitStack(Stack &S)0 `5 j" r) E& |$ ] b0 }
{
: C+ Y4 {2 ~; y S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
$ t4 I- _& x+ d if(S.base==NULL)
# @$ v- f; f9 z6 d {
( f. Q, H9 J& U3 F; e& Z) B printf("动态分配内存失败!");
9 C+ u/ F# i' s# c return -1;% I9 S, @/ v/ T) r4 m4 P
}* i+ j. e3 @3 d* f) Q# C% e5 E; l
S.top=S.base;4 ^2 `* o! Y0 h" U! k- @
S.size=STACK_SIZE;
$ q7 X0 A& V6 q( c& h0 P1 w1 Y$ `! c: M return 0;
) w% ^$ }) _4 I5 ^}
# M. q4 F; c! u- B) m9 `! y; _7 W3 V/ F% X# l- k% U- P
int DestroyStack(Stack &S)
* l! y; E" K& J- _{
" ~7 M* q% \3 S4 u0 X1 j free(S.base);
1 W- f" J: O/ G0 J- a: Y( Y) p return 0;+ l; _' \/ e) V( h3 ^$ |" c
}
" s4 }/ Y- n6 K5 J' ]
: ^, x; c/ W' C% a1 @) C- V" ~int ClearStack(Stack &S)5 }+ Y! j1 u8 o2 i) K! l
{, F4 W$ L$ N/ J. _: n( }
S.top=S.base;' C6 {6 V" ~" Q4 ~" K
return 0;
+ U( t, b4 g# U' `' J! \, N}
& N2 k \ K# \1 @6 x
6 m2 V3 M" r' r/ ^3 Nint GetTop(Stack S,SNode &e)
3 Q3 J5 _0 [# X{
0 C, X) J r; t. \: @# D# \- ~ if(S.top==S.base)# K9 M! l' d5 m8 M
{
: N/ H( H+ y6 N; C4 O printf("栈以为空!");
% V3 {* k8 A9 F6 ?! f return -1;
' u9 u- G$ m ]5 m8 N/ L }
7 i& c0 U- F, H e=*(S.top-1);
/ C2 V: z; F9 c0 C% j, ` return 0;
7 Y6 ^1 G+ o) B4 K}/ h; p3 e# y2 j$ o
0 j: ?% U5 ?/ q7 U7 Gint Push(Stack &S,SNode e)
: E% @: @; S5 Y{
2 A2 z$ l; v: z& Y: c if(S.top-S.base>=S.size)
7 l" J% p: I M4 Q# D {
2 R0 W4 Q; n7 o" K6 a# s S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));1 A% f% @9 p$ k# s8 r% K b
if(S.base==NULL)
8 F) ~# ?/ s. Z8 ~ {( {# G8 F8 H" V% D: D8 B
printf("动态分配内存失败!");- u" l8 i) L+ C: }1 ]% _* Y
return -1;2 O& E0 b6 e% b& D/ V& }- C% ?
}
% v* S+ E5 n2 m. v S.top=S.base+S.size;3 J# h. `$ V: l( P* u9 v
S.size+=APPEND_SIZE;
/ z( Y$ {' ^" r: L# N8 P& p5 J }
3 B$ w _# {3 g) g4 }/ }3 g# M *S.top=e;% v; O+ z( D l: B! y3 x
S.top++;
1 U, |$ f) r. P! F/ j( j5 J return 0;2 U8 K6 n- g% p9 ?4 j
}; M5 f8 `; a- C7 ?" ^; \
0 a" ?$ ^, f, }0 ~int Pop(Stack &S,SNode &e)0 z) s% e8 u: v
{
( H9 T! E% H0 p1 c3 J/ |! O if(S.top==S.base)( @6 Z9 i( P# m, e; s' T2 ?
{0 m, w9 r- j9 m9 l' I+ P+ q: a
printf("栈为空!");( q' h" M! a" d* f" C o- ~
return -1;3 Q- l% R; J6 m3 Y
}5 A7 \: }' W2 M( ^& J! M- a
e=*(S.top-1);
* E/ v% |, o' \- b7 ]/ r S.top--;- C5 v0 Q; p8 h6 R* T; ?! B3 S
return 0;
' A$ ?; R4 R2 p" q9 ~}
7 x1 d; R! V* H1 R; h: E' b* v' B2 f) H& z3 O$ I, b& X* ]
char get_precede(char s,char c)
, w" ^& Z0 ~9 ]' H{ p, v: q. J. y1 J- _- x) Q* g
switch(s)
8 x6 u) p2 G# o7 v) R4 C& e! X {
9 b O5 X& }- Q2 i; Z) G* x case '+':
8 m1 z- P. _& }' c6 _2 A+ w: ^ case '-':
3 ^! I& M! L, H, P. s4 E7 b9 F if(c=='+'||c=='-')
- q% Y5 u0 ^" i; ]$ M' F2 b return '>';
$ r( r1 Q- E$ Q else if(c=='*'||c=='/')
& k8 _ ^( [6 d! E) T: X return '<';- c7 l+ q+ O, ]6 [ M1 i
else if(c=='(')" E9 V9 m i$ n, ^
return '<';
. J, } v' c1 Z* a- w else if(c==')')4 M6 p% |* B2 y/ Q
return '>';
) Q. U0 L5 M k u5 J. N else
. }2 [# D' P; h$ U return '>';& H- j. A" `3 @( d4 Z+ i
case '*':+ W. ~, I" T, P2 c' ^
case '/':9 w- J# d& k. a
if(c=='+'||c=='-')
. k+ Y4 t! M' h. q8 \ return '>';- ^. t. t( a9 X) Y3 S: {: a
else if(c=='*'||c=='/')+ ]6 ?" j2 f) w% L3 l; O
return '>';" {0 o# X9 q% c1 L" l) _$ S
else if(c=='(')
# L& h; b& f$ b return '<';
$ s: \+ Q' @+ G/ v) i else if(c==')')/ ?! J8 N% N( t
return '>';- I& f) k" a8 I; K6 O, x! n( q
else
# I) R4 ^+ {( T/ T. h return '>';
+ I% Z0 ~; D! J0 N* k4 Y case '(':; j8 O. I$ }: n3 R, e6 a0 ?
if(c=='+'||c=='-'); \+ L" W( R' h Q+ [5 ]. r! q
return '<';7 D5 O8 O: b) B$ {# X5 T% }
else if(c=='*'||c=='/'), d* p( P3 h6 o! [0 K! B
return '<';4 ~9 l: K0 t2 Q8 b( w' e; L4 \; i1 W
else if(c=='(')/ C6 l5 V3 c% |! T0 p
return '<';
( L# j1 c& F8 { else if(c==')')
; y- A5 }& u0 F/ X8 m3 } return '=';
" S. O2 t! l8 U9 R e else
5 ~. r' ?: q7 c return 'E';# i& D2 Q8 p6 g W7 ], }
case ')':3 w. S- y2 h( ^; h2 ~/ T' V% y$ a4 z
if(c=='+'||c=='-')
; F! A4 d9 w1 {2 t& [/ j/ o return '>';
+ o4 I- f u6 [4 F- D; c& y0 X else if(c=='*'||c=='/')* h& l) }' C; `5 q, I% j/ k; z
return '>';. w6 Q8 }0 ]9 [5 h( Y7 [( h3 o* \
else if(c=='(')
4 ^2 y# Y: p5 E2 ^/ n return 'E';
9 V/ }6 \2 Z" j7 ~% e7 P0 W+ i else if(c==')')! J2 c3 V: D; d7 ?
return '>';
; `/ k5 X! q; e' E( Y3 z else
7 s+ A ?0 @4 n return '>';
9 G5 ~" b; }* ^ case '#':
0 O. l( v' c1 [) h if(c=='+'||c=='-')
' }! I V$ O. h( x return '<';
: @' P# R+ V6 d, Z& Z& `/ M else if(c=='*'||c=='/')
' S( k7 I I) h+ A2 }& s v5 s return '<';0 v0 a1 z7 S+ v, L: e g2 \% W
else if(c=='(')
; _6 z3 j3 m! m6 @" K+ I return '<';
2 l$ c4 A5 y0 p0 @& J7 i else if(c==')')
7 {7 k9 s0 j( n; J7 P! N8 O( X9 P return 'E';
# T/ @. k6 B+ I( Q$ u% o else8 |& ^/ Z$ N: C( r3 R5 G, D- {
return '=';3 ]* A) A" T5 _% O" S* t. f7 ~+ _& [
default:
% U: t8 B1 F; w* ?( u% _ break;
9 K5 k# R! g: u1 C& P' [6 O }4 |) n& l# z G
return 0;
) H5 g9 i/ Z! o3 v; M% m" V' M}& n2 T) {& ^/ L! [ K: e H
, N% v7 |9 u+ I) Z9 E* Y0 H+ p/ oint isOpr(char c)
& S4 S! \8 l: A4 j+ r{+ s9 Y' s# U* E" a
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
+ T8 L: `, f. w* }: [, I5 B9 S return 0;
6 O8 O1 D/ U+ T3 ]# J \5 Y else 5 ]* @1 G$ ~- e0 }4 E5 S( N
return 1;
. i" ?+ ^/ E" ?}& s a; ]3 f8 t8 K; w# s' \, A6 e
' r4 k5 w9 p1 b* \6 Hfloat operate(float x, char opr, float y)
* x1 i! B) q m0 m& ^ k$ [{
; |6 W; ]+ ?4 N# i( e4 I d5 J$ s2 k float result;5 J1 j8 X- n7 r6 _1 ]4 C3 K
switch (opr)
1 i! `8 a( a9 M! a; d5 ]0 D/ l {
" T5 G' U3 l3 ~& j4 {# m3 o case '+': ( E7 \/ U) F- g( Y2 x1 Y
result = x + y;& y1 {) ^- u: h! }/ i+ v% B9 w9 o
break;
+ ?$ `% n# {$ h- `, r case '-': 8 J3 j$ v2 M/ \
result = x - y;/ C7 {! p8 f4 j, i# m
break;
7 I: l% {5 `6 b, m. [$ d) a case '*': 4 l; E% P J' \5 y7 c0 t" Y
result = x * y;
" U& o/ `& E- B9 v9 @% E break;/ ~2 o8 r7 a7 r, f1 R) V9 D C5 S
case '/':
8 m" f/ T$ G, }1 `: E if (y == 0)
( h9 n7 y: S$ ?# I g; ?2 B {
: I7 W2 X& G! v- O printf("Divided by zero!\n");
7 v* i) e; K3 C* f/ E, X" A, g return 0;
/ B6 y0 N, V& \$ x4 A7 c {, u }( _' [, d: M8 {
else
|6 r6 N3 p; {# J2 z) L& R {
+ K9 n: K4 @# x8 ]) j# Q result = x / y;
4 g' L$ K& Y5 y l2 ^ break;8 ^# Z+ C% O$ q3 j, R
}
/ ~# I* W" |6 X2 V default:
1 h# O; B8 V. y: L& `5 H9 A' \- e printf("Bad Input.\n");
- i% o' |$ }' Q0 L, p, r4 a return 0;; w) t- n, z7 b2 C" I3 H+ S
}
& r1 J- d1 S) [5 m. L2 n- c1 [ return result;2 n4 F: {- t( S1 r7 b9 W/ {; a
} * \3 j7 g! N1 I$ H0 U4 |
2 `) I! a: t. d4 T2 M2 K: T, kfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
* _) B( w* O( C/ `; X{: C$ a5 s$ y4 o; n. u* A/ G4 H
Stack optr,opnd;- x5 G8 m8 |) }2 m2 d5 P+ G, k) }
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;1 t4 q# G! ], K! O- m" P1 C
char c;1 E6 Q+ A6 R2 ?. Q @ W. s S: m
char buf[16];6 v& ? A: s! j9 t
int i=0;
c: X1 U* u* x1 a) j$ d* X: f) h + A* }4 m: C3 p4 e& S* q% [6 S
InitStack(optr); /*用于寄存运算符*/
3 W1 F* K! K" r1 v! V9 l InitStack(opnd); /*用于寄存操作数和计算结果*/+ g+ L! M# Z& n- R* I- [# d I
memset(buf,0,sizeof(buf));
1 @* G4 r- Q: v, Q . f6 l' g2 q% E$ l% N) p& y, ~
printf("Enter your expression:");
3 x5 @; v+ b i) V' [8 v
* v% ]. m8 Q! T opr_in.ch='#';0 `2 i9 L! T1 K; ~' {. {/ J
Push(optr,opr_in); /*'#'入栈*/
: ~0 M9 M( `! m6 {7 O6 r' W2 M" F GetTop(optr,opr_top);# {& U: Q5 H0 E- ~) ]/ Y
c=getchar();
! ~/ k1 Q0 o! L1 e ^ while(c!='='||opr_top.ch!='#')+ B* |5 a. J7 J6 J4 }0 ]
{. a; S( e% w+ H6 E' l; J
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/) y+ _. [, m. K: F% H/ S0 v. i9 D
{
4 m# G. t) K6 \7 ^; a buf=c;
/ G. C Q2 }* O& C) N i++;4 P) |& Y% C1 V( r
c=getchar();
7 j8 h8 R( [1 n& s }
& p* @: j _1 y! ]! h* ] else /*是运算符*/
& g! r# S, _* W& A. M {
$ ]1 x* @- w0 F buf='\0';+ y0 h4 W8 T. N7 M& a
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/, n l/ t8 e/ z+ g+ y
{
: A+ V! d+ d X7 P opn_in.data=(float)atof(buf);0 T: B) @. f; h0 b
Push(opnd,opn_in);1 ]* F$ l1 `3 L% q' l
printf("opnd入栈:[%f]\n",opn_in.data);8 y, i2 I7 y/ D1 A. ^# u
i=0;
" t( P7 [7 ]* }$ r5 x6 u memset(buf,0,sizeof(buf));9 \# ^+ P% M: e1 O6 H& I
}
2 c& r8 i* K- k3 t opr_in.ch=c;1 |9 ]: x+ _1 B+ x, A
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/0 S( y% M: E0 @1 U& _
{ ` n i' d8 N! {0 R
case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ [( d( g5 h3 o% t( ~ a0 t& s# y Push(optr,opr_in);
* r& j( F7 v: j( [# z1 K; H printf("optr入栈:[%c]\n",opr_in.ch);6 Z" O2 W+ ~; H/ w3 |3 h5 R+ \
c=getchar();
+ k; B$ Q, S, c, l break;; Z6 a0 m' a+ T- {
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1 g6 L/ O; g, E9 X Pop(optr,e);( B0 |' e h2 D$ r _' J5 [* D
printf("optr出栈:去掉括号\n");
) Q/ ?2 T5 v2 E# T5 N9 h c=getchar();- m% }/ E. K8 ?+ m* R
break;3 O( \6 p+ D0 f7 J# Z1 c& F
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/& L# f) a) y: [
Pop(optr,opr_t);" C$ U1 H* p6 Y
printf("optr出栈:[%c]\n",opr_t.ch);: Y) Q. o4 ?3 x: q# v
if(Pop(opnd,b)<0)5 W5 y: k0 _, Z( Q
{0 w% Y9 |7 L) E1 J0 G6 A
printf("Bad Input!\n");5 W7 \: A5 f+ C
fflush(stdin);
5 e1 n) p) m% { return -1;
- X0 R$ c( x4 G; y' S }
+ x, I+ K1 h! \. v% {+ y# ^ printf("opnd出栈:[%f]\n",b.data);
; [& Q/ l. c# e: `7 L" r if(Pop(opnd,a)<0)4 m3 c. s# d# T
{7 X& b" \: \4 d ?0 H
printf("Bad Input!\n");$ u- h7 a. a7 Y9 ^* [" N5 [- o3 n
fflush(stdin);& F. |/ C M# c3 _3 h4 q p4 F
return -1;
' d' Q. s; c" s; [9 u }) d2 L* m% L: }5 ~( S4 N
printf("opnd出栈:[%f]\n",a.data);
1 e0 Q3 }1 O/ E" Z0 l# k5 {1 l4 A opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
* k0 g9 n# p; R, k Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
! }+ l) F, e/ y! W printf("结果入栈:[%f]\n",opn_tmp.data);
* `% W9 q4 O+ L& F7 p break;
8 `" l( M) ?" j7 r }
r4 R) W/ h4 q0 I. Q }
! W8 [; z5 |6 E' A, ? GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 6 w4 k2 ]# r0 H5 m
}6 o3 r c% L- {1 l( b; l& S& T
GetTop(opnd,opn_tmp);
. D4 }$ G$ L# t9 i( ^6 j7 } DestroyStack(optr);) D. Z. y0 V9 V/ L. M
DestroyStack(opnd);
' \; n- ?- w: a( |. r: B2 M% S0 g return opn_tmp.data; c, G3 j) \. }: V( F/ N% d+ C
}
2 X# ?8 I0 U2 o4 R4 e. @0 h M
/ \0 H% h' c* z' gchar *killzero(char *res,float result)
/ n2 m- d" S) r1 f{
* B: d# m* h4 [ int i;9 x+ T. r. h" V2 c7 L' f
- ]' f7 p# s$ o/ X% { sprintf(res,"%f",result);& {; F. ^0 f/ s; z- }. K' C! A4 b
i=(int)strlen(res)-1;
8 \+ Z8 f4 K' v* H. Z' Q! E) l while(i&&res=='0')
8 q0 H( P/ D' g) t9 e6 T {
# A9 F' Z+ o& Y2 E3 Y' N3 x2 G res='\0';
* i% }/ C0 I% k. A( N' `" B7 Q i--;
* b2 M- f/ }2 a. m- F }
& \) |. \7 s" [+ ] if(res=='.')9 o7 D) h* E9 @; t0 t. L- U% h
res='\0';8 u$ r9 X2 _5 B7 B! M: d
return res;
, J! w+ ~ z+ S% G* ~1 p}
0 G- K. g( H2 p3 U( A$ y% L
5 w, m# p8 @% Y% o& K& ~* W" pint main()
, h, [1 J1 ~. N. C{
8 U/ r: k& E8 f1 J" q char ch;
) y) C8 l1 r# P3 U% Y char res[64];
* x: f% P0 r3 H float result;
. b6 f9 p5 k# I9 T% D! z while(1)8 M1 ~) N) p! E$ V
{
1 _! c( G8 [1 {2 A" {2 J result=compute();
2 {/ E3 ^* m9 i, J& [4 | printf("\nThe result is:%s\n",killzero(res,result));3 [( h$ r/ ]+ j3 t& S V" G
printf("Do you want to continue(y/n)?:") ;
: W# T; _6 U# Z1 z8 a' V; o ch=getch();
( p% r9 V1 J. h$ @* J) l putchar(ch);3 n4 t% F% I+ X( _
if(ch=='n'||ch=='N')
y. b* M' A" Q) { break;* y) Z O6 R% J3 {4 P0 f2 Q( N
else
: Q/ {( Z# m2 _! \2 B) E system("cls");/ C; L% {9 u1 _9 ?4 u6 c, `
}
A4 f9 Z) n3 c# f* |% s) G return 0;
; T) X R7 h% S; T" L& o9 E}
+ t" o/ ?& k! O7 v; H9 E$ u
( b. H- s8 Y: u- ^ L4 K[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|