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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.! T9 K# O2 i$ {, V: K3 o- ^0 }
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=+ g2 K$ m9 q3 Z- d
/**************表达式计算器************/
: l& e. j. ~/ J7 ?+ s2 E#include <stdio.h>
0 {; f4 B. k+ W$ y% U! Y0 M#include <stdlib.h>% F0 h6 T4 C" \3 e3 f" W: l
#include <string.h>! k+ |2 B y/ r% x: {" n
#include <conio.h>
. x4 O) Z5 G$ o#include <malloc.h>
, k& w8 _6 l. x2 ?# G+ s- N& y2 [, ^/ v( D0 l& r! ~- [" e- L
#define STACK_SIZE 100; l1 a9 s k" J# ]8 S1 {2 H
#define APPEND_SIZE 10& \7 q& r7 W# Q6 N
; Y6 X" h- j K8 d. O3 w `
struct SNode{7 x" E( W. P* G& N' G
float data; /*存放操作数或者计算结果*/
1 z5 R1 t6 H+ z- Z% ? char ch; /*存放运算符*/8 B" O8 H$ t! d; J0 ]
};
, v6 _$ c0 t4 { m7 b2 G2 D2 s% J
struct Stack{
5 I+ Q! R& u& k& t( j SNode *top;
+ m3 F' ]) K( `: A% {- \ SNode *base;$ p; V9 w, y8 p$ g0 U
int size;
8 G+ e7 f. C# ?2 I};
. U/ D# j$ s% j) u. ?! M+ w: G# R8 H) e. W( y
/*栈操作函数*/
% v/ k1 ~" C5 T4 x4 \2 ]int InitStack(Stack &S); /*创建栈*/
% p. L4 _9 I# {: @% g! u* o! Xint DestroyStack(Stack &S); /*销毁栈*/, H- m' Z e& t, @
int ClearStack(Stack &S); /*清空栈*/
, c# V# G/ h% u) r8 |5 pint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
. Z" v: p% J# c; [% o! {int Push(Stack &S,SNode e); /*将结点e压入栈*/
) X! Z# ]" x5 U0 l+ w, pint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/- e; u d6 G8 Z3 L# E2 T T
2 u7 L& p6 O+ g
/*表达式计算器相关函数*/
* W2 e+ j$ ?/ @, I pchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
( o0 A: s1 H8 M3 v" V# _ M& Vint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
4 g; }2 e3 V( P! \$ A h6 b: wfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/& M& s! p! p+ w! r3 E( h
float compute(); /*表达式结算器主函数*/6 X& S) S9 R4 r2 k$ V) c j
char *killzero(float result); /*去掉结果后面的0*/
7 I, n" d6 f% r+ y6 L/ I: W0 x7 ?0 x5 n* o/ x% }/ V
int InitStack(Stack &S)
) B; R- d' p; L: z; F$ L{$ a/ P( d+ i7 Z; e% ~3 C8 T' z6 F
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
T* Q2 R# J/ C0 P( g% V7 y; o if(S.base==NULL)5 A+ O( @ m f1 N1 V1 y
{7 V1 n$ t2 g! y9 Z
printf("动态分配内存失败!");
+ c$ n4 w6 }3 E6 ]) z( } return -1;
3 A) `* Z6 I$ X* m' R0 w }( _& l0 L6 ^. y, P: ~+ J, Y& L
S.top=S.base;7 z8 }' }. a6 l8 z" E0 F
S.size=STACK_SIZE;0 n6 O4 m$ p$ U" \5 `
return 0;
: I: W+ {2 \# h: t% {}
' c. R3 R1 x* w5 e" W# u f. p$ a6 V" F, @0 u; ~8 N! E" X
int DestroyStack(Stack &S)
7 M& ^) r% [1 g/ F4 z/ K$ h; y% W{8 q. G$ Z5 T3 q. ]
free(S.base);# z! ~; q6 a+ \: O* x3 B. o
return 0;0 O7 ]" A$ J0 {7 Y$ X! o
}
4 b. Q/ h5 E+ e$ A; U& s" u: W+ M& m
7 X. y3 V8 Q& @3 G/ Oint ClearStack(Stack &S)
$ U# Y- ~; ]/ V) f{
* i5 u3 L- H( F0 p8 _; }; S S.top=S.base;
5 m1 X ^* K3 r" r7 l: A. P return 0;
7 Z$ m' B# }) ^}3 E- J. v2 f2 B3 `: R
, I8 z8 u2 V/ E. V$ i* D* r
int GetTop(Stack S,SNode &e)$ p2 z3 ~3 `# n! p, E
{
5 d* N6 h g) ~" ^ if(S.top==S.base)6 {( k; K0 U( ^7 q8 c# g" u3 s, \: {
{
# W" `& Q) p" L1 }; y printf("栈以为空!");
* i4 Q/ D' G- W0 k5 Z2 V return -1;, p3 w8 E2 @' o* |
}9 _" T7 Z3 S/ I9 | p" x
e=*(S.top-1);
- U" z! M$ w( M- l R$ R' w return 0;2 u0 K# X$ Y: E6 t* ^
}
0 M" T# u7 m' ~# b# C3 `2 |; r
' J. C: l# I+ iint Push(Stack &S,SNode e)' J! S3 W5 @2 I5 e
{
# O; z5 G3 h* i2 q- t8 ], {+ u if(S.top-S.base>=S.size)2 r( M& r; N- N% T
{
8 H( a4 K' t1 `' y. j: U4 ? S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));$ D+ I! F" e' c1 S0 V% s
if(S.base==NULL)
9 \" K9 ?& m8 i: @ {2 u1 t9 w; L' v* P# t! i# O( ~
printf("动态分配内存失败!");5 K w& `: a7 |- a" J/ u
return -1;
2 K9 f( d/ W7 d* r- ~; q }. R. o: A% M0 z, ^0 l
S.top=S.base+S.size;
, ]+ \- M! E, T( x+ E8 o S.size+=APPEND_SIZE;% K" Q: o+ h2 U6 _ f
}, @ t4 ~/ b/ `1 ]0 U" s Y
*S.top=e;
, G- y5 V, U' W. \' v S.top++;
( a1 I/ [+ K A2 S return 0;# L( T0 S, X! V# \6 x0 J/ ]
}( Z* H* M6 k; t' ~2 Q) m" Z
- Q, \" E- `+ Y+ j! q' Gint Pop(Stack &S,SNode &e) F4 K1 [3 a3 w5 I2 g A
{* o* s) o4 v6 v; T9 N* P6 U
if(S.top==S.base)
) Q% D) |$ {6 M: r% Z5 _6 D {% L' h3 |% T/ s+ m
printf("栈为空!"); c- `( Q1 W2 S- C8 \# _9 C( F- o
return -1;
# \6 U- j: e% g' G H }! Q" W* C$ B0 |6 Y4 y
e=*(S.top-1);
# a. \: G9 z' U d0 c7 { S.top--;
6 n9 E6 Q- e/ _( k( _3 G return 0;) _" {$ d' [& {2 g: B& i4 a
}
# u3 L& e0 k" g' W; ?$ E' {9 K" M# @9 G
char get_precede(char s,char c)2 {. F$ G, z# X* U" M
{- {3 j6 X# h+ ~8 d3 W) i
switch(s)
1 `0 X3 x+ F% K: ] @* ~9 H6 q {& h e/ F! E% b# p1 @6 X+ G; y s
case '+':
0 |9 W. H7 k9 m, @. X' z( O4 L case '-':$ H0 L; f1 D1 t! m
if(c=='+'||c=='-')
0 ^% _0 F2 M3 r. D Y: g% L2 s return '>';, O, h) S* h. H: w7 A
else if(c=='*'||c=='/'): W5 n L" _# x0 G. ?
return '<';8 U. N1 B! P a$ f2 O
else if(c=='(')" L6 t! Z) {6 z4 _8 Y: W
return '<';9 d6 {- N9 U4 K& G) X1 V4 }1 k- |
else if(c==')')
$ J+ c. I: h' O9 H2 {. g' @% a return '>';# w% }% y# `8 T7 v$ j0 b0 K9 p
else
4 c* @+ O8 k1 _9 w* A: F0 r/ S v return '>';
. D# h2 ~$ ?5 P' o; @" M case '*':2 |6 [" p4 S0 K& @& W
case '/': y$ y6 B8 _8 W3 C$ g3 M
if(c=='+'||c=='-')7 F; _' `0 u# h
return '>';
9 ]7 U5 t B6 B0 b% G7 O else if(c=='*'||c=='/')
! P* s2 i5 G- h return '>';
. }2 B, r0 E# h# | else if(c=='(')
8 O0 j& T7 w0 B! j- z return '<';
# z) g5 x& j7 n$ {. l4 ~ else if(c==')')
- _5 v& m3 A2 z- R. J* n% \ return '>';
9 \6 X5 f" T0 ^: U* G; r8 R else
0 {2 W+ J+ V+ w; [4 ?( X J3 [. [ return '>';
$ T! ^1 ]% Q; P0 R' j$ h/ B1 s+ u+ c" C case '(':) J- M5 e6 z# p; T
if(c=='+'||c=='-'); [% C+ [$ z: F2 [3 {% d( d
return '<'; _6 u6 [6 w0 F- N9 F) L3 X
else if(c=='*'||c=='/')5 ?! |$ s7 d6 `7 q! u
return '<';
4 S" B) |( a4 @9 s4 |! e else if(c=='(')
0 Z! m' q6 N5 R( m7 y6 Z return '<';
1 ~2 _+ m' M) O9 ?: Z4 ?0 ~# [) w else if(c==')')2 X$ F( A2 S ^- E* f# ]3 U* D) C
return '=';
8 V6 @& ] ]: O' I2 K$ w- f$ W1 I; b else
8 G7 k( t3 p7 }) U return 'E';
3 K9 j- ]0 w! \ case ')':+ F. W. K' t; Q" k) M) A3 a
if(c=='+'||c=='-')
# r# P/ p0 k' \3 Q: M return '>';
- E: @ b& L$ j4 {4 k else if(c=='*'||c=='/')
4 a" G. A' @; [' \4 f& n return '>';' h& m: s, s/ p2 M! T
else if(c=='(')
4 F0 J$ d: N( p3 E2 g/ l return 'E';: _0 i# t* S' f3 n; R
else if(c==')')
, j: G9 E/ J. Q% {% a) t, W# K return '>';$ j6 R& a: R; u8 D) R
else0 B* d3 y+ r/ ^' y! a3 Q
return '>';: ?+ G7 C% D+ K q, h
case '#':
1 |; b1 \6 B& P: m if(c=='+'||c=='-')
c4 v2 |6 \1 k return '<'; [$ P" x, s6 e; O( w. `% ~
else if(c=='*'||c=='/')+ f8 B/ Z4 t' h/ K& q% |; d$ ]
return '<';* c( `- \! @( {" g, Y5 z
else if(c=='(')
% y/ i) ~) m$ S7 }5 L return '<';
1 y: Q2 l/ j6 m else if(c==')')
Y( w+ K. m' X' i/ q! Q/ u return 'E';
9 G# {1 r# f0 _. r. k5 N else/ Z$ s3 o! { a2 X+ b: v& d
return '=';/ {* A/ ?% a8 ^' Q% b8 s. I6 Z$ v( v
default:
/ r* G- j9 u, A( F* _4 `+ b break;
8 p" U5 x# p+ |* m) H }* G1 Z7 S+ b6 [ n4 u- ^/ I2 v3 K& S
return 0; , O) g+ I+ Z$ U
}' L v6 Z* h( r. Y
! U) |; w/ W/ h) C6 H: U: Q5 {int isOpr(char c)7 h) ^3 C) j$ ~# t# M3 i
{& N5 E8 N+ }; g2 K1 T+ @
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 A T) D; n( {3 U2 F1 A, ` return 0;
6 }! h" ?2 t6 u9 ^6 n# I else
* z J r3 M2 ?/ M% ]# O return 1;
. O2 s3 k$ h( W \( W} G$ M0 K" t* [. e
6 w0 E o& k* V8 v- u, ?& U/ ffloat operate(float x, char opr, float y); X t# \: ]/ R
{# Q1 E% W: Z/ j; V. p0 a0 c
float result;: V! k9 o: F- R9 Y
switch (opr)) Q) f! h0 V5 @) T- X2 n
{
8 S! C- C6 {( g! O case '+': 0 y( J, U: R9 u1 g, ~
result = x + y;
4 p& k% L0 V* L" N& t break;
6 m: {# K. Q4 Y# Y. d' d" F case '-': # o; H2 u$ j$ F+ t7 A* y: @
result = x - y;
3 L$ J/ W) q* E break;9 C7 N- D' I; q7 K, c" z
case '*':
" A8 g, o4 t0 Y' z; s0 ^ result = x * y;( B1 `1 w) f- j% v" o# \% h e
break;1 H0 ?% n; n! B' M2 V1 y
case '/': - c2 F" b( K/ b7 o' w/ k
if (y == 0)# f0 Y* P7 C4 e& Z% X" X0 T
{
3 X4 N1 A/ A2 m$ P4 h/ s printf("Divided by zero!\n");) U) U, U6 N% V$ q
return 0;
8 w" m: q+ p2 ` }
9 k: G4 i# n) z! o! x [ else5 n9 P( z5 U/ A0 g+ U+ d
{
* v. {/ T5 A9 ^" Z result = x / y;
0 k/ X8 A0 m P" @7 ^ break; z7 D, m+ `$ ^3 \: t3 T/ ]+ F
}
6 c' s3 _ Q! ~; [! a default:
+ G& a6 D1 ` d1 w4 o printf("Bad Input.\n"); N5 `, P0 L0 ^1 u" f+ n6 U
return 0;% L% I5 i& A7 V' z
}+ T3 A/ G$ u, C+ W* H1 ]) @
return result;! j% D, j) z, U# @5 Z
}
" k8 t8 C" a4 `# X
+ y% }. C* f" @% X$ e. Zfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/$ c, c6 j5 R$ G$ B
{
2 y2 q1 G: A0 f& {* T Stack optr,opnd;! Q/ c0 P% }4 v
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
7 |# ?1 M" S* `. Y char c;4 l( ]! G- e- M% h
char buf[16];
* t, Z0 V( x7 R# t+ y) J int i=0;( A7 T% j9 ]& E! M9 _5 P
8 ]% P% O# T: r. j InitStack(optr); /*用于寄存运算符*/
+ T6 r. f. ]$ D7 O InitStack(opnd); /*用于寄存操作数和计算结果*/
8 R5 k7 w. P/ o memset(buf,0,sizeof(buf));
" J( i$ n7 y( V5 T$ m, A$ ?& N% p 8 F; q$ y9 S& Z5 x/ M
printf("Enter your expression:");
3 _& R, q8 } W
" j4 _ f0 J7 d! B* @) K( g) h3 K+ Z2 ~ opr_in.ch='#';" J8 g1 Z- ~4 B' f/ }
Push(optr,opr_in); /*'#'入栈*/1 y7 N, ?; v$ ~8 s. R
GetTop(optr,opr_top);5 f W ^! J* I3 L8 {" K- |/ M
c=getchar();
' m3 G2 w7 W4 m' ~ while(c!='='||opr_top.ch!='#')
" G! i6 v& F$ E, c# i9 A {
7 P4 P/ e) ]3 [4 @& y if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
7 m3 a, g; C& v( m, C G" e2 ~ |' j {! `4 {$ j3 n$ S' }2 q
buf=c;
& W, V- e% |3 @3 w3 v" J* ^8 V i++;: K$ d4 ?/ w, \. H
c=getchar();7 C& `( e! E" O: J7 T- \0 Z
}( i0 O4 S1 u$ L( m, a9 S% _) B1 H
else /*是运算符*/# Z" {8 K! } h7 ]0 W. v
{
) I: G2 q- s6 U& a2 t' m( { buf='\0';
) c6 R6 W. r5 W4 S4 ]! \ if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/& P$ A$ H# C2 ~& Z
{1 l& r8 M" S% M! S
opn_in.data=(float)atof(buf);
1 U7 w. U( b: M0 F& Y u2 M Push(opnd,opn_in);
/ G, P7 n$ h3 j+ J' Y9 B8 u9 n1 G printf("opnd入栈:[%f]\n",opn_in.data);
3 T; i; V- {) |# s+ G/ D i=0;' a: B2 i `: v7 \
memset(buf,0,sizeof(buf));
8 J$ D K7 H" A5 L. g5 S }
) c/ V! s0 B! l& S0 N5 i2 Z opr_in.ch=c;
7 P, Y! E" H$ x# ^) G9 X/ O switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
* R- ^& v3 v1 p# r1 @; I {
& E9 x) _% \5 ^$ R% ?& p7 m case '<': /*优先级小于栈顶结点,则运算符入栈*/
: S! A5 @' ]& G' X6 O3 U1 W Push(optr,opr_in);
, c! O$ Z6 ^* R- `1 f printf("optr入栈:[%c]\n",opr_in.ch);+ F7 ]. c, ?% q# x8 _0 }! B* p" c
c=getchar();* {9 ^, r' }+ M7 v* r
break;
4 ^7 |2 V6 G, ~ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/1 I, n( P1 p. P
Pop(optr,e);. i1 y- o) X3 d0 t
printf("optr出栈:去掉括号\n");4 E2 i) Z) X$ }$ g' t
c=getchar();% w; X' E" P ?% q8 R$ g) k! a8 q, b
break;6 W( a, y: F7 q+ ?7 [
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/; T. O, ~0 A* K8 F4 V
Pop(optr,opr_t);4 ?! T% `* c4 s9 t! _7 r
printf("optr出栈:[%c]\n",opr_t.ch);4 ^# ]; ]$ R z$ j4 i+ r
if(Pop(opnd,b)<0)
8 Q4 S1 X3 j. O! ?2 f {) H9 F4 N; E; Z) M# d& l/ X- ?
printf("Bad Input!\n");5 V6 q. L# @0 y: Q9 f
fflush(stdin);1 O5 [+ Q3 D/ l- C! k% {
return -1;5 X9 y R6 u* k @
} n) n0 I6 N |
printf("opnd出栈:[%f]\n",b.data);5 L) s/ ]9 ]: _6 n& M' Y
if(Pop(opnd,a)<0), ]2 G& `& U$ b. o4 ^
{
. ~/ Q, b+ O% Y, P3 e printf("Bad Input!\n");& \5 `' ]# B1 e* {/ K# y+ c$ I2 d
fflush(stdin);+ R" w+ y- q1 O; t3 G3 k% Z
return -1;9 U* M+ ^. p+ ]
}
: b* @$ _+ ?; A% Q printf("opnd出栈:[%f]\n",a.data);
! N' S- Y# m. w' }; s opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/7 _! i- J) e- ^4 P
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/5 M" w+ K0 \- S4 L& Z7 ]& r/ j
printf("结果入栈:[%f]\n",opn_tmp.data);
$ [1 Q1 x7 t% K& T break;/ x' `$ j0 |% O7 P5 @: d9 _$ y
} H+ \( @. `# @6 z/ q7 M% S
}
1 D( H0 o: o* c. h9 C6 z3 E$ ~( V GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
( L0 ?+ L4 Z5 \" J5 ~- Y }. O0 l8 J. O A: Q1 J! b! V
GetTop(opnd,opn_tmp);
~. W4 k4 V! Y( F DestroyStack(optr);
) @) S! ], {7 g! e/ U3 C/ t DestroyStack(opnd);" D8 C9 u) b2 G! p0 s" |& b
return opn_tmp.data;
- \" R" Q: m7 P5 @. B7 A}
( ^5 `8 g( Q+ _0 t( m" A2 s( O# {! f u5 c/ K
char *killzero(char *res,float result)
* [+ i: W& Z! H" z4 ]8 j{
( R# h; @, d1 N: f$ ? int i;
* u$ c- {+ p5 G) j' ^, W' X
* g! \( N4 q: @2 } sprintf(res,"%f",result);
2 u7 d% @2 {) P+ |. M( N i=(int)strlen(res)-1;
: C2 D/ f& n. Y8 b/ Y8 B. U% ` while(i&&res=='0')
# l1 {3 F* t. b7 ^ {# o* {% }: M5 n4 @: Y; b3 Q
res='\0';
5 W9 D* O: ~3 j2 l4 r5 d: f i--;* ?: x8 ?. ?3 i
}; D3 Z# S' `; K" R p4 d' v
if(res=='.')# A* Y2 ~& Z# `( M
res='\0';
: n: a" m" I' q" ?; o" Y! J. A return res;! q: b2 G9 w9 G* Z8 P
} A% o! g: _' E$ U& { ]
5 I. s" A+ B2 }: x* w0 p0 d9 Z
int main()+ \4 ^ v/ k7 Y* A7 _+ P% X$ C
{
6 u z* T5 N3 K) b! y char ch;) H' `/ V1 i4 l5 O [
char res[64];6 C7 _% p$ }$ w( \
float result;. G2 Q" s! C8 ]) i Z
while(1)
: L: e( M* Z5 Q ^- P. w7 J# i {
) ~: y% j0 @' Z' s& D result=compute();6 J7 Y7 D2 @: Y$ `) W( `
printf("\nThe result is:%s\n",killzero(res,result));
8 L4 S2 A1 j! t! y- F printf("Do you want to continue(y/n)?:") ;$ n+ Y; R' q. |
ch=getch();; Z# J) ?' S& H6 R* Y# E( s9 v
putchar(ch);
) V8 o# s5 R( [" ^ if(ch=='n'||ch=='N'): t4 S; D5 ]* Q+ z. e6 c5 h/ V
break;/ ]. j/ V0 ?. _
else3 c- B( S H9 n- N6 `- ]% _) q$ E9 l
system("cls");
& |# B" i% d, C }
7 U0 m+ `) Z8 q; w* b: B% ?9 X* W return 0;
; g0 M2 o& P5 H& b+ ~ [}
0 H) d7 n+ w9 g# p! A, }' l( z/ ~1 n+ X# \6 K& L7 m4 x
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|