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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
7 k9 [7 R- H6 ^1 B. D& m: P7 |- e程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! v2 u# K5 y8 u$ O+ v/**************表达式计算器************/3 \% F7 y/ `1 K. d
#include <stdio.h>
. U! k9 n% G3 b1 |+ F" k6 x5 ^#include <stdlib.h>
9 w7 d( Q& \/ Q; m#include <string.h> c- u/ t. A! o# u+ z
#include <conio.h>; w' i( h' v! ~7 K! I. F6 A
#include <malloc.h>
8 M. W* t2 r o8 |8 B. K; W) j. Q! _; K/ `" d/ p
#define STACK_SIZE 100( K! X/ L# B, f$ t1 ?8 g i
#define APPEND_SIZE 104 z8 [: x) o5 E/ A/ u& g) g
3 J. d* [# k# X# ?# W4 s) D6 z/ M
struct SNode{- b0 P5 P" I. b6 F
float data; /*存放操作数或者计算结果*/: P0 E! j3 J$ b
char ch; /*存放运算符*/* r. m0 \3 K! t& n* |! A7 d
};: J% e, k" `0 e, a) m# R1 `
: E, @+ O8 e0 f* ~; m$ @
struct Stack{7 ?2 _- z$ m% z1 W6 I
SNode *top;
+ O/ |: c2 n/ ]6 A5 k- O, \: B SNode *base;
( P4 L: g. [7 D2 K int size;
3 W v' a" L, x- H4 A};
" u' y" @8 Z% N+ [" R
6 R. s4 P5 U8 c! Z# P/*栈操作函数*/+ D) I4 M2 ^$ {" b; F
int InitStack(Stack &S); /*创建栈*/
. \. S b& c, eint DestroyStack(Stack &S); /*销毁栈*/
6 y O$ f/ X! I5 R8 C9 cint ClearStack(Stack &S); /*清空栈*/1 n. d; D" _3 b/ `
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
+ h3 G& H, T, n2 Qint Push(Stack &S,SNode e); /*将结点e压入栈*/- f" |. u2 H' U# V4 E
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/; {* Y. o7 E. R" `
) i* `- ~# y; i3 b# A# T
/*表达式计算器相关函数*/
6 I4 ]. A, j, T6 K$ B6 Z7 Schar get_precede(char s,char c); /*判断运算符s和c的优先级*/; d3 q' f3 y' T9 E
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/6 ~' z5 U( y1 r7 _ Y
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
7 ?8 A( l: C! t, Rfloat compute(); /*表达式结算器主函数*/0 z9 X4 J' |( V1 Y Q( V$ L& z { D# D
char *killzero(float result); /*去掉结果后面的0*/
9 B3 v, i, ?7 [7 ^6 }% Q) O% x9 z* D, m `" n5 |' l! ?
int InitStack(Stack &S)* E1 N5 z( K; r% O- b. ]7 \
{
; h9 s$ j" D4 l( g( ?6 l! Q S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));( Y8 M2 x; ?8 a Y
if(S.base==NULL)8 W5 o T- ^% U; Z# A3 D
{- a+ K# ~: A0 N1 m
printf("动态分配内存失败!");& W# n) \' E2 [! Z
return -1;4 w" k0 D9 w8 `; K" H
}
: Y; ]& n0 ~1 J( T: H S.top=S.base;
# @8 _4 k: |! G& J f* F# U9 u S.size=STACK_SIZE; R4 J$ F. L, e# }
return 0;
; |9 p( w6 N7 q+ _+ B3 L# S}) P8 |7 f1 V8 l
8 C: k- H2 i. T* M s; k' F1 ?int DestroyStack(Stack &S). |! }+ w- j+ R
{" q. ?+ h7 i! f" b
free(S.base);
3 W+ ]( R- o* Y0 Z. f# X1 P return 0;
# O( U8 N& [. G5 @0 U}
$ K! D' q) t$ I; D" }% q5 @' g, t; g L& h5 M- S& a% Y
int ClearStack(Stack &S)
; j2 i9 G3 M7 P! p8 S1 u3 n{+ e# q( ~: g9 e8 l1 s
S.top=S.base;! U; R5 R6 P9 R1 E% }' C
return 0;. y& \ Z6 c' t, n6 w) ?
}
. x5 Z7 t/ _) w* ^0 Y& q+ C* m3 h
+ H( f. w/ q5 f; P0 g9 G' Xint GetTop(Stack S,SNode &e)
, q( N, P4 b+ _4 D* z{
/ ` z7 M5 q3 N2 F$ p/ v if(S.top==S.base)
* o4 f; K# c7 D. Y% b9 E# y$ D H { p1 z5 A4 l- v% O- B
printf("栈以为空!");4 n! Q, B% `5 p3 E+ d/ u7 w
return -1;
$ z" ^8 _$ Z$ |5 w& E5 m }
: ~$ A2 r: Q" L0 r* |* U e=*(S.top-1);
/ ^* E1 g6 d7 Y7 @# p return 0;
$ r$ Q) F$ F: R' v9 E+ i}
. B* h' v4 w# y
% a* E& y* B9 t9 E _3 n" }int Push(Stack &S,SNode e)
* z4 T- ?7 k" i{8 x) e/ c5 N: F
if(S.top-S.base>=S.size)
+ E+ X" i' j& e' Q/ @$ ~( j" S {/ j) M# x& E B, i( M3 c5 w
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
! t) N% o) i2 D3 p4 r' _ if(S.base==NULL)
+ |5 E& _) D' k0 I {
]" J" O D# r* W printf("动态分配内存失败!");
/ K# ^5 ]3 W1 [3 t return -1;# g5 g; S& c" K6 Z
}7 O& a+ {% c) e* p
S.top=S.base+S.size;
, ^7 `. \1 R! |$ ^9 }. Q1 h. B* g S.size+=APPEND_SIZE;
9 c+ L9 M/ `/ s$ O4 V }
, ?$ H: A# s4 |* W) B) q# Q" W7 l *S.top=e;
9 n1 g) _" a8 @$ e6 _* D S.top++;, m4 C3 L) b3 ]+ o
return 0;
4 X" z7 y+ u& X7 \6 j}( D7 d6 I+ w4 @4 Z
: c7 b7 r/ c: K- p6 C3 `2 s" ]: H* tint Pop(Stack &S,SNode &e)- t2 @, J, L: y. U7 l, x1 V
{6 e: K+ _# s( k0 c2 _2 y' C5 ]+ E
if(S.top==S.base)# q+ _4 N# J( f% k8 K V
{
* k3 x3 G% S+ T printf("栈为空!");
7 a, D) v- \! n. R return -1;
& ?' q8 e3 ]# D, U* P }
+ H# t) L8 z9 A% W$ U- b0 r e=*(S.top-1);& ?1 O$ j2 [) Z8 t
S.top--;
. k3 J: J: m. B/ p4 j4 W F6 @ return 0;
! v9 u3 f( U# o9 P}
3 S6 u- {& C* P3 `# a5 L: X; g) ^, e ?# l, m/ w: ?' p z
char get_precede(char s,char c), B# W4 w3 X2 j+ V Y1 [! q
{3 p( N% W; R' t! @% u+ D
switch(s)4 b* Z/ Y. d% |' e; r
{& l0 K7 n( S7 e0 m( P6 I
case '+': 6 P; |( v, y1 V
case '-':
5 u, m8 p' g: V& q7 ?/ B6 } if(c=='+'||c=='-') O3 Z7 Y! X+ u* i1 N
return '>';
* B% Y, N+ O8 n. p else if(c=='*'||c=='/')/ C* M6 ~) ~ [& H- U
return '<';
: D9 J5 u$ }) {* u" v, k2 e else if(c=='(')8 l+ ^ O8 s# U3 P5 w$ Y9 N6 Y7 `
return '<';4 l# z2 l) U0 p6 O( ~
else if(c==')')- @5 a( E7 N* {* `
return '>';' b# g% v6 B( B$ }& ^: i! J8 [
else
3 b' X: o, S7 k% u1 } a, U return '>';8 s5 `" j; ?9 q: l
case '*':6 A" ^6 Q, T4 c
case '/':
% {8 U! [9 f$ v# p; R- L/ Y P if(c=='+'||c=='-')
1 L* h K/ f9 r# Y% f4 l/ }. C7 N4 e; y4 X return '>';, e4 }/ v% y8 \" {% x& Y
else if(c=='*'||c=='/')
1 K F* I1 }& ~9 b$ @ return '>';
1 O: T& [" n1 Q6 g6 P; x: @- ` else if(c=='(')& T' S7 D" l! L' `# T! o! W
return '<';. i! [3 }- Q* F) R5 Z% n
else if(c==')')
* n6 A2 t+ S: |* ]# I return '>';. I0 Y% T# Q1 g5 x' t! s5 P
else
' g3 Z8 ^6 V! x+ _' P return '>';
: A6 l' Q" l/ [( M, S- k case '(':5 \5 ]- n& R( s! ~9 o3 @& {
if(c=='+'||c=='-')
2 b$ Q9 i* q+ C return '<';
# |. {- g4 u) w) q% m8 z1 _, Z else if(c=='*'||c=='/')
s7 t o3 d- P! @0 d return '<';' V( U, w- o. j3 o1 ~
else if(c=='(')
: Q9 f; v x9 |/ l5 H8 Z& X return '<';
9 V6 M3 g- `# X, |1 k: {/ \* g# e else if(c==')')# v% \' K! w6 ` b6 O6 U
return '=';
* w& u4 c7 o {1 |! _* `4 u* ? else
8 R% J, r6 M6 S% }* U( k# U return 'E';- C; m' L/ O) Q2 {4 R O5 M
case ')':3 y8 ]6 Y3 n k! k' Z9 ^
if(c=='+'||c=='-')
& P w+ k7 z$ f7 G L1 h# I7 o return '>';
+ j3 q8 o" r( \2 H+ Z9 a/ S5 Q. X else if(c=='*'||c=='/')& I- f$ E% |0 g9 m4 ~
return '>';
7 N$ P: {+ F) p% @; l! x else if(c=='(')" A- K5 C" K+ C @! Z' f; t7 Z
return 'E';1 B& j. x* x6 L) r5 w% q
else if(c==')')0 k5 A( u% _( D8 n1 X# R
return '>';
8 s- U5 |+ ?% y2 @* Q) p. L else# D2 s! S- w7 N- k" h u
return '>';7 }( |. [2 N8 `+ a0 t
case '#':: X) A% ]# O- Y. x6 Q7 n
if(c=='+'||c=='-')7 Z! `1 I( [; v
return '<';+ g) V, W8 `+ a4 U0 S
else if(c=='*'||c=='/')
/ G6 o' O1 u- V0 B9 j( e" ^7 f return '<';/ c! Z: t/ C$ V$ N( k. f: M
else if(c=='(')
9 q7 v1 a3 P% q# `8 T" W1 u return '<';
0 J0 f* q0 {2 L6 e' p6 f( M6 J k else if(c==')')
' T: L. b$ c, u& w J return 'E';% ~) P0 d# ~9 ^* K
else: ~6 b/ m, y( p' Z/ f# E9 L
return '=';
, L( W3 n4 t$ Q% q default:
+ g* x9 q1 Z; _1 @ break;
L* L7 z) W! o& L8 M }; B3 f+ H. a' \$ {, l
return 0; f" ]% {, w- J) J3 i9 `
}* A1 A4 p5 M! p
" o/ A O& o4 b
int isOpr(char c)' X1 _) A6 u! i. Y
{/ l- s) v* ~1 ]6 b$ ?
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='). \- l A& @ J
return 0;
" T- d9 x4 F0 s) W; f5 G. j5 e) M else
3 d" S7 c' w8 u X" u return 1;0 l0 q2 [* J5 p& N
}
( h1 S" f- }: e% _. q% ~8 }/ P! t0 t- R9 P- g; ]
float operate(float x, char opr, float y)
( S% c/ @% ^( L$ E- p{0 V, n9 S' i0 C& r/ g; u
float result;
- z, }/ b8 t; [$ d5 P switch (opr)
& J2 i( [, A! }) p; G- l5 c {2 ^/ c" B+ V+ D" f
case '+': # k* K0 a7 A" Q2 g) a4 V
result = x + y;
0 T+ f& H0 u% X" B' N( s, N break;% L0 d# m$ q7 P8 c, W. J
case '-': ' F/ @7 c& V, s. W) I* G( b1 ]/ b
result = x - y;
3 H6 F, E4 ~( H4 |6 i6 c break;
( m+ @5 r3 s" P9 L case '*': # `6 T* _" L& P2 F
result = x * y;
* X% O: k% M: R break;" V! n# T6 y, N# f* p
case '/':
+ M5 d' [ y3 j F* [ if (y == 0)8 O1 q1 {( i9 r
{
0 @# s8 E$ j# [1 W printf("Divided by zero!\n");3 H/ Y$ x: {) J% o
return 0;
9 ^( N0 V# ^' K# @* D8 f' C. j8 _ }. h, o* C2 I) f: i B8 n, E
else2 n" r2 a8 Z" ]9 f& `# B
{
( h# q) }" m! ^ result = x / y;. l$ L' a- r ^9 @- b2 G0 U
break;% t, p; g) M! _ L2 N. ?
}
, Q7 Z1 h) s- a5 e default:
: P, N6 s1 e, I$ @ printf("Bad Input.\n");
5 K- [; q! z2 W1 S$ b return 0;
4 i+ G9 z' a" o& v5 R9 A/ g. X }0 K U% y! Z; c! `
return result;' `/ H2 Q0 [! ~; `9 P
}
; q Z- R3 V7 w/ A! w4 K9 J$ r8 A+ Z7 j% j3 C& V; w2 U
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
) N5 N) Q5 e7 l{
+ o( R4 ^0 O7 [" g Stack optr,opnd;( X6 @% M6 n: J7 E4 {" u
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;" \/ T4 i! d3 \- Y4 ~# t
char c;6 `' p0 w. B, G
char buf[16];: l0 C6 [* G/ T6 N
int i=0;
0 V& X. v! G- j( T: R 1 j% I! p4 U, f* u
InitStack(optr); /*用于寄存运算符*/
_) P& }! H! \ InitStack(opnd); /*用于寄存操作数和计算结果*/+ l! g! K# Y7 i8 e4 n6 L7 ~
memset(buf,0,sizeof(buf));
( g; J# e6 L$ ]8 d
$ P) [. E M+ Y+ K- j printf("Enter your expression:");1 {0 c7 C9 E5 q/ R
7 @- B9 T, R4 L' @
opr_in.ch='#';
/ U6 ?$ n7 O1 k) p) j+ _2 z Push(optr,opr_in); /*'#'入栈*/# d2 S0 R; C" Z
GetTop(optr,opr_top);8 @6 n% ]' l& Y9 m9 R4 W4 M, S: b
c=getchar();
3 J) _4 t# [1 Y0 f6 I while(c!='='||opr_top.ch!='#')) Z5 m' Q# O- z2 J: m5 h
{
5 B$ J- e* N2 q$ [2 d if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/) y6 ~+ V2 v. }* _( J) z! X
{* k; C+ v) }* ]) U9 P1 J& e
buf=c;
* y9 g d0 [, f4 a i++;
/ B+ V' F" u/ g, ?& T4 a c=getchar();
* Q9 U9 ^( M% J9 j$ ? }
7 u B7 ?( z. l: A0 c9 w else /*是运算符*/
% J" S8 G: y3 p/ e& L {( Z% {' j+ T; T
buf='\0';5 E7 ~( ^% ~! n# K: c a2 r0 i7 R1 O
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
0 g3 i' A* S; A; w2 \ {
$ j' A$ I5 T/ C9 W% X& [2 Y |2 j opn_in.data=(float)atof(buf);
o6 l. r/ O- P Push(opnd,opn_in);
* d9 L7 r# Y7 `& H2 I/ R printf("opnd入栈:[%f]\n",opn_in.data);
' N: V- u5 d) R; ~8 D i=0;8 ?0 y( f) n. B) C& d5 k1 D
memset(buf,0,sizeof(buf));
z+ p$ m8 j- Z; c. K8 @9 o }
1 _4 O+ {9 _, F2 W: s Q opr_in.ch=c;
& b; D. r7 T5 d z& `( o8 v switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/& z/ Y# A; G2 X) y! [1 E2 P
{
+ p( D0 h+ Y4 ^' c ]! ^+ z case '<': /*优先级小于栈顶结点,则运算符入栈*/
+ b* d7 ^5 E4 x Push(optr,opr_in);
- d$ m( Q4 X2 Z3 X( G) u2 G printf("optr入栈:[%c]\n",opr_in.ch);0 e9 X) `) J: J; R
c=getchar();3 s, A3 S$ N3 B5 G* s
break;' c* s" E. \) S1 I7 |1 l+ }
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: I3 z% G( y8 R- Y: y x' m Pop(optr,e);. C$ v$ U* x4 ?- g! q6 W5 I2 Y, @) X
printf("optr出栈:去掉括号\n");6 B7 T& [4 G2 Z& E! n5 _
c=getchar();1 X" r/ K/ p" ~! G5 c% p- o. s2 o: n/ p
break;
{0 v9 j% u* G* I! P4 Q- d, x case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/6 v& ?- F/ r2 O; _
Pop(optr,opr_t);
; t( B0 b) }6 E. | j printf("optr出栈:[%c]\n",opr_t.ch);* T/ k" y2 [( ~. J
if(Pop(opnd,b)<0)
% f( `7 ^! S, t3 q, |/ G {/ E! G# P4 p4 f E
printf("Bad Input!\n");
6 i* Y2 q A, y' Z fflush(stdin);
+ e5 q- K& M# o' p3 Z) V return -1;6 y; p* f. {1 s6 |+ a& c
}. ^2 ~% b* W" C1 k
printf("opnd出栈:[%f]\n",b.data);5 ?8 Z0 f% @) m/ c( G. a0 Z) G
if(Pop(opnd,a)<0)
4 f! G( m) R1 u0 l {
! o0 y4 L; c( O) G6 h2 R7 Z2 O printf("Bad Input!\n");
( S# J& z+ w% n8 W' C fflush(stdin);
, a: |' V' L2 U3 H0 m! f return -1;8 O! Q) [1 b4 n6 m" L: n1 @; Q
}- W H) x4 n, m$ ^. v
printf("opnd出栈:[%f]\n",a.data);8 v; p6 j; G" ?- L i _/ |/ m2 E
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9 V+ `1 _# G' T' q2 j! S, J- \ Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*// y8 }6 p8 T* [# p
printf("结果入栈:[%f]\n",opn_tmp.data);
3 @' E9 ?* x& N6 M O break;
. N4 f" }- o. v7 [: o) \/ m6 J }
/ ]" S! c- _& j# I }- x! k2 }8 l: D: T0 ~2 Q
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
9 s2 g. b% N3 t% V0 d9 v2 d }5 L) M, y& E6 b7 R( m
GetTop(opnd,opn_tmp);
( K" E7 ~, C5 t/ Y; I: r DestroyStack(optr);
" h+ e: ^ [6 [4 N2 B( U, J9 `; p$ t DestroyStack(opnd);) t1 W6 U# m- p9 j/ ~, t5 Z
return opn_tmp.data; t& ?- m3 f+ L/ m
}
' }" A. Z ~ b/ {
, V5 s. O+ ?: L* D2 K. gchar *killzero(char *res,float result), u4 l5 n9 M+ _. _7 a+ u
{. j1 l, b' v5 e
int i;
9 j% q& f5 u4 ^
1 F8 K, Z$ M1 [2 n sprintf(res,"%f",result);
) M5 P# v/ c- c: y9 X1 ? D i=(int)strlen(res)-1;. W* i: e: F& z% s F1 \5 @
while(i&&res=='0')
/ C/ c# [$ J8 B) h% Q. E! I {9 N( y' N8 B/ c+ X9 E. ^
res='\0';
( ?/ \5 N% E) ?3 L+ q. ]0 Q$ K, {' B. Q i--;+ }1 ?8 E5 h4 @2 ^
}) D H" Z4 Z: U5 [9 K; r1 e* k) q1 c' O
if(res=='.')- _' S% L: c6 \3 ]( K0 Z- G
res='\0';
- J9 X/ H- R: H% X. d/ U& `3 w return res;
2 _" B* c5 W6 }}5 f+ e) y: c& z0 i5 I, q
6 }+ P4 Q% k! Jint main()
1 L' L2 _# {; v* w* j+ F0 T8 O" W{
! z: [" c: E' i8 {* {, ` char ch;
* B- g/ `7 y0 S1 ^ V char res[64];+ @2 k: O- w; i5 I/ @2 E
float result;
0 y( A [0 k( W3 s- p! w while(1). {2 {: f5 t r
{* t' E0 b) ?/ t/ M0 j" B' |( }
result=compute();
$ S& [6 a$ Y9 F$ n y" [5 x/ h printf("\nThe result is:%s\n",killzero(res,result));
8 {1 w# J6 v z% M2 m" L/ ]5 H printf("Do you want to continue(y/n)?:") ;
6 y' b( X" F9 S4 p7 ] ch=getch();% T% e+ h6 |6 q2 d2 O( \
putchar(ch);# P/ O" C9 B0 s& g$ N
if(ch=='n'||ch=='N')0 c) h% L3 M" H* {
break;
! b) J+ i7 ?: G+ p) b. N- C else$ T8 L# x& S, Q2 t
system("cls");/ X% q% A9 i( _3 [
}
5 O( t: _; O; f return 0;
: I( t. U; Z" b9 K: Q" A+ f3 z! D}) ]5 P; A) b" D& R8 X
% c4 _" M9 [* J1 U T
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|