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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6 N* Y0 ^& Z7 ?0 F) X
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=# a) ~, o, y& @6 m: f( [
/**************表达式计算器************// d+ m9 X! n* r9 X# x( V9 Z. r5 \
#include <stdio.h>
9 U" ^2 K5 ~, i2 {& c7 d: h* f#include <stdlib.h>
: ~& ~8 r3 s7 J5 I! a$ D" _#include <string.h>. Y$ ?! w- n& l7 U* ?
#include <conio.h>1 B2 P7 C+ Q/ O y/ ?' ?, t
#include <malloc.h>4 p( X" }1 d' x9 x
$ G- L0 g9 D6 P6 E
#define STACK_SIZE 100
; \: P( Y( g3 h#define APPEND_SIZE 10
3 u6 q- p# h2 j G4 i7 T0 k
8 F" @4 K; j, k1 Fstruct SNode{
* A+ s( }7 B& U# P float data; /*存放操作数或者计算结果*/
: x8 l, x* f- `* O2 w char ch; /*存放运算符*/( `$ D2 @8 {8 `; e( ^+ \/ ~
};8 I1 ^4 I& X' g+ z* w; d
& h* Y7 l8 f" cstruct Stack{- Z; o+ \7 p; k" G
SNode *top;0 d. e. ]# r5 q/ W
SNode *base;
' }/ V' d$ s/ {) W* j int size;
1 ]; B& m, |3 r5 h};
. x( p8 ^( m7 Q8 `0 o9 j% l; {! {! J# K0 [
/*栈操作函数*/
. Y4 c! J% Q @/ V6 a* j: V) c. ]/ Iint InitStack(Stack &S); /*创建栈*/
# J2 ~+ D8 \$ F# f, m- u! bint DestroyStack(Stack &S); /*销毁栈*/
+ d) k/ @- q# B: z' `, S- Rint ClearStack(Stack &S); /*清空栈*/
8 [) t0 `0 C6 B3 j6 ?6 f8 q8 eint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
2 S8 K7 D" [, X, B* K' r& o0 Yint Push(Stack &S,SNode e); /*将结点e压入栈*/" Z2 Y% H% U. p& T. M% r# H7 v
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/6 H9 d9 }- ~! F8 `+ H d
+ l2 U7 Q8 F0 d- j/*表达式计算器相关函数*/) F7 f5 l3 J: h2 ?& Q. ?+ l# e& M
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
- ?! `. X, O' Y6 X( T) @- Gint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
* s3 P2 D( k3 T% l3 i9 r% x% `# a/ Ifloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
/ [% S" J' ^3 u% Mfloat compute(); /*表达式结算器主函数*/) n& k% s7 u, I$ o' d
char *killzero(float result); /*去掉结果后面的0*/
8 t: K* C7 I6 C; ~8 p+ c6 C3 y( J% ~+ l' c
int InitStack(Stack &S)
# v4 }. Y+ w* c3 E{' \6 Q7 W# d0 q. y- h
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));7 R2 l- u u0 w
if(S.base==NULL): T( J( g' r5 i: k# L$ g
{
1 z- m, A- A: s5 w4 E printf("动态分配内存失败!");
" B3 U" t C$ J$ g- A8 ~; t+ K% m return -1; h8 ?# A& \5 D
}
4 M# x9 V" P9 q1 {8 I0 }9 s0 Q S.top=S.base;
& ?* `% P" P# J3 G( M S.size=STACK_SIZE;+ s8 H |7 s8 V, N0 F
return 0;1 Z7 X' e* q: s9 b
}3 b* R" l2 j0 D$ U
2 a# a' ^7 ~. l: Q
int DestroyStack(Stack &S). x" E1 V- g7 {) i% h
{* B4 H$ k1 s0 {* [
free(S.base);% E) z' E- }2 G1 H1 E
return 0;
, W6 a; {' n7 d) a. B$ U' T+ B}
- W* q$ n! T8 ~ t3 F- w6 `5 y2 n y A. [( C7 N& E1 _
int ClearStack(Stack &S)
1 D, H& U: ?( u2 ^' ^3 z9 X{
* p" R% X9 C" N6 h$ i3 Q' K; w S.top=S.base;
- `* U7 l; ^6 _2 H" F# D O+ ~* E return 0;
' C& A9 ?! J2 S4 o' b4 `}
* g6 o$ K9 j% m: t6 }. _9 g& B4 W6 a$ h+ m
int GetTop(Stack S,SNode &e)" u+ ~* h8 P4 c9 m: o$ F) v) U
{$ S4 Z# F. O; e
if(S.top==S.base)
, J7 u# H& s; p M {+ H: p. M/ G. c, t, r
printf("栈以为空!");$ |0 |3 P( q; U6 W
return -1;9 q) V, L8 A: f: I7 k
}+ k0 E6 G6 D7 w: C) h& D3 v" l% ~; e
e=*(S.top-1);8 B2 e5 @# i5 M8 D4 y
return 0;
+ A4 d2 T8 {' x2 P. k3 u z7 U) m. J}& J/ w9 c F3 j6 }
- X9 A: X: y ^, D: Qint Push(Stack &S,SNode e)
$ v' J2 r# W, |9 k& y{
' d# Y4 k! h8 r2 m if(S.top-S.base>=S.size)
( E/ y) C# Q* @1 X' w+ n {. f; z- n+ L- M$ s1 \4 x; m4 R
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
5 @) X) @6 e) K- E) B# q# \2 ^ if(S.base==NULL)
! H2 E( B( U5 ^+ B; i9 ^1 J" Z {% A6 A% v- L$ Y4 K9 n
printf("动态分配内存失败!");
6 x. u2 R7 }+ J9 L return -1;& u: D6 d3 J( d: D% i. f) o
}
L$ h" N* C2 ~3 f' G2 F; f' N S.top=S.base+S.size;
- \; a) x4 h& l4 ]7 S3 e S.size+=APPEND_SIZE;
" M1 ]) D9 i6 S) t) U9 d0 t& ] }
6 A3 W, ]3 d* ]3 k2 N0 u *S.top=e;
( ^. E5 T& B R* ^7 j: e8 D* L S.top++;: `, f. q' ^( v) s- O4 Q
return 0;
) p1 e9 s N% e; j L}
+ V" }7 p. B2 l7 i! I1 J1 ~1 S( U5 ?$ ]3 X
int Pop(Stack &S,SNode &e)
% V+ a$ Y! t5 R6 v$ Q1 r{
& D d8 ]9 e' v" { ? if(S.top==S.base)
$ J# G$ o$ p5 z# Z8 f- y7 K+ m& t# C {! Y* G; n6 e+ v, \$ O
printf("栈为空!");
1 @0 t+ N5 @" O5 }) [ return -1;
2 w' {+ q; f# D' x# H. }3 C }; O& j# _8 \( K
e=*(S.top-1);9 m$ {' i; w" X5 O% Q l5 e8 N
S.top--;
6 T; {# Y1 Z" ` return 0;
; K5 @; H1 W+ G0 h! h; e$ c}
& j* _0 N7 b8 T& M+ z4 I: [1 i- `8 X4 w- p! z2 J0 Q- c
char get_precede(char s,char c)
% b+ i3 I& f4 k$ m1 u- a" k1 a{
& x: m' b$ M- U& K5 ]2 e switch(s)
0 ]; L! ]+ ~& E6 D8 s {
2 S6 Y) `( Z9 t% X2 K" c case '+':
' }, C+ p$ N. i- x: Z case '-':
$ t# m6 B& K( Q) |: w+ @0 }# t if(c=='+'||c=='-')
. v. c, n9 n: K return '>'; J/ J8 s. }$ {' ?! z& ?
else if(c=='*'||c=='/')8 M: a+ B e+ E! @
return '<';
8 n" ?: P5 Z: Q' [ else if(c=='(')5 A0 ]/ [6 J- x* K
return '<';; Q5 o: O: t- s+ Y! [
else if(c==')')
" a: o! k! d/ \. E" Y5 `) T return '>';
6 |) S. v7 c4 c else , G" R+ C0 L1 ^
return '>';
) [- K/ }7 c( K, V# g case '*':1 `6 a# ^; f8 p* ]- Y" @
case '/':% ^+ p6 s7 ?* b8 D7 Y5 K
if(c=='+'||c=='-')
5 b, g! A4 G. D0 G1 I. e5 n return '>';0 [' N! D6 |, n+ p5 V
else if(c=='*'||c=='/')
* H% e4 W5 G% F0 ~( J' c9 A return '>';6 h g) ]. ~% k, Q
else if(c=='(')
8 S( l4 s1 L3 f1 ~9 W6 b2 a2 D* P4 V return '<';
9 d/ K4 B5 P% q else if(c==')')
5 ^- i5 ]$ F. ]* `, S& `2 } return '>';% J, C* X5 _$ r" D5 t# m
else
9 i+ u }8 h7 P7 V return '>';
) C+ l( O. v3 { case '(':
6 R& L" K8 S- c/ S0 C( _ if(c=='+'||c=='-')
) i4 C( u! h2 d5 P/ _- s return '<';/ H* V; s5 E6 M+ j
else if(c=='*'||c=='/')
7 N) Y; ?, c9 u3 x( s: U return '<';( |9 X+ K1 t# j4 v& c
else if(c=='('), c' x1 ?- ?" K; ^/ Q" r. j4 K
return '<';! B1 J! v1 x8 i3 z/ g
else if(c==')')" m2 s: @0 e' D) u4 ?2 X
return '=';! @/ x! W& L& s3 m1 e# ]9 a
else
9 O6 ]* K& P+ ]% |2 I; d; C return 'E';
' M8 t1 S, l: s8 q2 ^8 x case ')':
6 _$ }% R$ Q$ W* [: V if(c=='+'||c=='-')
% @2 D0 k9 X# B/ h, _/ N return '>';7 j; M2 ^9 @1 ?7 K- R# T n
else if(c=='*'||c=='/')
4 ~' {7 D0 K1 S, Y# V% H return '>';9 ?7 [) z- w. r7 Y" S# s* B
else if(c=='(')& D, u+ B& V0 U& v: |6 l
return 'E';
" c4 {7 e) z- _4 ^ else if(c==')')
/ c% D3 [. P, @" C+ t$ G return '>';
( R5 E7 r/ j5 X6 W$ p else5 h0 z2 [) C, E3 V: }' I: B
return '>';, Q& H8 y G1 ?
case '#':, ], _ D, v9 i+ h
if(c=='+'||c=='-'), t, J6 H* p* M, D
return '<';
3 q7 a9 N( f3 y1 Z; w' s* S7 G3 e5 b else if(c=='*'||c=='/'). X$ @( ^9 T9 ~
return '<'; o, o8 ~7 M- T, n
else if(c=='(')
- l9 i G: \" I" L return '<';4 y: V6 e4 C$ y. i
else if(c==')')$ Y! ~4 a, j* \. i2 \4 ^8 J
return 'E';
! A c! u* S: [. V: c& L$ L else! k" _3 L8 {2 D2 ~; p3 W
return '=';
' Y, c, G) k4 M6 [ default:4 V5 v: s: b9 ^
break;
; A4 e' T% d2 ]' [ }
1 N1 U6 S6 N$ H0 Z/ D* a2 n$ |1 O return 0;
) C+ g4 w; h4 b) ^}8 @) ^% u7 o' z5 Y# h
. Q" ~* n5 \# S( A) S: T
int isOpr(char c)
, Q" y0 _$ T# v" U& }{
* K+ D6 I' ^4 }7 f3 p/ g- v" n if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
. w# o3 W/ |5 F+ F# t# R return 0;
& b& w; q- u8 k8 z else 6 L( Q5 m# S) o7 v3 ]
return 1;; J p9 V& }2 ?$ l/ }. R
} M! F# T3 N# X( g
2 I' T) o" i( V3 O$ Pfloat operate(float x, char opr, float y)- _) o2 r& W' W% w
{+ ]6 M0 h$ N: J2 j0 Y4 c
float result;9 w+ [7 I0 X) Y( _7 U+ s1 F
switch (opr)$ \" c; M" X# L3 l& h
{
7 Q4 \1 c7 l' }2 g8 S: n F case '+': 9 U. C# U/ X( k0 h8 Z/ @
result = x + y;' k" y/ g% d; O' P* S8 K* e
break;8 F1 S, c( a: ~. e8 n3 g; S+ l/ n
case '-':
/ }$ Q* b- O# D result = x - y;6 j; }% b; ^: ~& o
break;
; I1 t, B5 G9 A" e! T& v; Y case '*':
% r$ X: m2 N$ Q result = x * y;4 T- a3 |9 E+ T3 N c/ z
break;
3 F2 s8 E g8 G6 E, O" R" o% x case '/':
+ m9 W" g) o8 ^9 M7 C if (y == 0), x/ W: @) p j
{ C4 p4 {" \& j2 D' D# ] z1 U" Z
printf("Divided by zero!\n");- R& [: h$ I$ w
return 0;
3 p8 B% |3 j( _. h" { }
5 O+ s" r( u9 {1 E' o* T% Y } else
1 @* F# f5 D+ S6 ^9 f {
7 b) k5 A/ W( w3 l0 S B% ~# { result = x / y;- T- v( { r; I/ f" ^5 q
break;7 i7 E9 P4 U$ E- F+ z: P/ D* d
}
( }4 G" s7 ?. o$ ?. O$ F! N default: , a R0 U( J: Y! S5 m( z4 V
printf("Bad Input.\n");
" V r* @* D& z3 i return 0;
, ^+ J7 ^4 F6 k9 n }) G( ]3 j4 n4 Y
return result;1 r) I5 h0 @8 B1 z
}
+ V1 H$ w. J" m9 h
# g5 p) V" s6 `) g' P8 T0 ]float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 y* b4 s5 E9 G6 g/ R{
5 Y# i* r& \6 a9 y, { ` Stack optr,opnd;
/ I1 e# b; c4 W struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;( u! c: y) R ]9 j1 m
char c;: h- f; j- D! H" Z( o, T
char buf[16];
- G; Y; s9 }" Y. }. Q# l int i=0;( Z! C' N: p, D! U% Y; E* ~& O- \' b
( A# a& l/ c# @
InitStack(optr); /*用于寄存运算符*/
% b5 L0 c$ C# D4 `: A7 a, ^ InitStack(opnd); /*用于寄存操作数和计算结果*/
; F2 a* I$ ^1 |! ]7 w memset(buf,0,sizeof(buf));
; ]% Y8 [! D0 E. o% n7 O" G 7 |% L! R! y+ u$ e: k
printf("Enter your expression:");
R/ m) X6 C* C# k " P4 m8 v' Z7 E) @* }
opr_in.ch='#';4 e5 D( K; _3 N
Push(optr,opr_in); /*'#'入栈*/6 Q7 n1 C" F( l. I) r P/ f( @: y' Z
GetTop(optr,opr_top);; T1 f$ n# `) g% t
c=getchar();8 D9 r* k7 L/ p+ p4 t+ \
while(c!='='||opr_top.ch!='#')
# |- G( o4 k& i; l( U' c9 k" y; O" X {4 ?) k! h; \( a4 H( {; h# z
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/, m; U, B* B% ]. r
{( g% F7 F$ ?' f: [" b
buf=c;$ h7 |7 [# ^- A4 D
i++;
. F8 h& D8 i5 m8 X) Y c=getchar();
7 o9 _3 ?) e8 v }
7 ]" M0 `( G1 Q9 u: o else /*是运算符*/
3 d8 s+ e0 u5 V2 Z% u {4 P8 R8 X0 a5 ?
buf='\0';
( P Q- d: f' x; u( H" z9 [% ] if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
. L1 D; H& e3 ?! {, j) e; {, @( t {
8 s0 d2 o) T6 ^4 {# y- g5 w opn_in.data=(float)atof(buf);
& S) d; F4 w" t5 H+ O5 N; e! g1 C Push(opnd,opn_in);& B5 r4 z1 b5 Q+ k; q7 A
printf("opnd入栈:[%f]\n",opn_in.data);
2 \" r% ^. V% b3 f; i$ ? i=0;
% W: m; A* _) c$ _4 O u memset(buf,0,sizeof(buf));
% t9 U. s+ R% [ }
* p& t2 t9 q a, a- l opr_in.ch=c;
r3 i) W$ K' x switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
m, w) R9 L: R5 q {
7 X) R, D7 ?# o# a5 z& q case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ }" u; c- z' L9 e" Q Push(optr,opr_in);
: _( O6 E! D0 }) h printf("optr入栈:[%c]\n",opr_in.ch);
& j: O8 S* \, _9 j c=getchar();
& o8 l! S; Y; Y6 X; K break;* B# y) f4 p9 H( o4 ]9 k+ i
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 G. k& p" J, z! Z) F5 X0 q
Pop(optr,e);
6 W$ ~3 r% m: _3 ~8 z. i8 v printf("optr出栈:去掉括号\n");' H3 a$ Y2 K5 e3 C
c=getchar();) e o5 [5 ^* L' ~7 v
break;2 D7 g9 F# o5 y. l* C' u5 F9 ~
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*// c v; S6 S/ Q) @3 p
Pop(optr,opr_t);- ]) t+ W# w$ E/ V) a
printf("optr出栈:[%c]\n",opr_t.ch);
7 C* u/ z8 C( u8 h9 b7 T( B if(Pop(opnd,b)<0)
% M3 w" z( g- B' [ {
5 f+ Q u, w0 ?2 o) V printf("Bad Input!\n");
: q# u5 _3 B) F8 c/ S3 L fflush(stdin);
1 f V; I1 Y8 Y; R1 L5 t- @% j return -1;
0 i2 ]" B( a3 I8 j. ^2 I( j9 E8 g6 p }; k8 O1 i e% B. C
printf("opnd出栈:[%f]\n",b.data);
0 @4 N3 ?3 _8 y3 C; j2 R if(Pop(opnd,a)<0)1 J l. e! c6 R6 M) `0 t
{
: y2 h/ y5 O# r) ]* o. U! d9 E& G printf("Bad Input!\n"); F |" m9 {8 P0 B( i% j
fflush(stdin);, Y' {" J! l5 R3 g! ?$ F
return -1;
( @' X. I+ z6 a# T; ?* S7 z, M }
7 @7 m) v0 q$ I% e printf("opnd出栈:[%f]\n",a.data);
) C: _! Z$ m0 g7 K/ A- x opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/# v6 K* T2 g" Y
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/5 V3 V( Z& B9 F
printf("结果入栈:[%f]\n",opn_tmp.data);9 {3 l/ p' u! Z J3 c& K! o, \
break;) m& u; c# u3 u1 o. Y7 v
}
( n/ ~- t- s, X2 R, u }
* t. t+ h- x# q/ P' ~( n. o$ l: w GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
) q/ w, N) J3 D7 J4 S) M$ B }9 c( i2 e; G$ v
GetTop(opnd,opn_tmp);
% R n% G/ S6 m6 H4 m* w" G DestroyStack(optr);0 U: }$ j, ^7 v5 R: N% u, w6 c
DestroyStack(opnd);
2 [$ E: }# g( ?- ]% N; d return opn_tmp.data;
: U. i3 h, c# d& M0 {$ e}! }' m% v' G' S; q) D' X
8 _& n8 Z* g. J, b
char *killzero(char *res,float result)" x) K# \6 v4 a3 I d6 m
{
5 V( w3 n" e+ v' G) t8 y int i;
; u- Z9 r7 q/ U2 y
( E9 b( o2 o! E6 J sprintf(res,"%f",result);
2 p, d2 b g, S# J5 _ i=(int)strlen(res)-1;
4 I0 o w4 d+ ~ while(i&&res=='0')+ Q$ ?! ~* A! r1 p$ c+ u2 H
{" r% D) Y# h# f3 Y$ V# {
res='\0';2 N% H, M; [% p/ n- e% J- ]
i--;5 Q- f8 Z( T' F, k6 f
}2 V* d9 A6 p% \4 t
if(res=='.')
; r Q: \ f: G2 L- A { res='\0';
K- L3 K3 b4 v/ Q return res;6 K. O% [, F, B1 W) O. { F
}
, ^9 c1 U& i' [* Y: Q2 U0 T6 h* @4 S8 l5 ]5 G X! M
int main()# {9 N4 K% H5 e* F4 W* p4 ] S
{3 A/ j5 Q' O4 G5 `$ f
char ch;
& i/ c3 W8 n- ?9 T9 y3 y+ O8 p char res[64];
& g7 g2 Z3 `9 x1 B float result;
& @4 x4 G3 k: {, D i. W# @2 Z: r1 B8 x while(1)
8 D- I/ `) g; d) B {0 h+ J' d( _ C/ ?& o" h, @- @
result=compute();
. c. G. _ p% {: g3 a printf("\nThe result is:%s\n",killzero(res,result));
# f9 p: h: F/ y printf("Do you want to continue(y/n)?:") ;/ e2 v- p4 P+ b1 i/ E" G
ch=getch();0 {# @1 t+ r) k0 V
putchar(ch);) l9 L8 |- U/ F( x7 Q
if(ch=='n'||ch=='N')# X" ^& z% W I2 y2 A5 I7 T
break;
6 U6 I4 a! i) U else8 U3 D$ C1 x% a3 x* z* y1 `0 t) x3 S# ?
system("cls"); G2 y4 z5 F U$ R
}
4 J( K# ]3 @: g! w" U, k: O return 0;- z1 y( S* t: r' E( M
}
' W; |" |1 H: K
3 j$ A4 v* z" e8 O2 g[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|