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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.* S# M/ \* P! u) H6 g% R2 r. O' f
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
1 _2 [& N8 e( C6 q1 w8 O/**************表达式计算器************/, {. ~0 C" ^! P" K; Q1 X z+ s
#include <stdio.h>
: \2 f( _2 d# R9 X#include <stdlib.h>& |% s: `9 Q( t( @$ |; g, F
#include <string.h>( z/ v9 F! L0 X$ c5 Z
#include <conio.h>
6 m9 `9 B5 A p# p5 x# [2 V#include <malloc.h>! ~. T* C5 n+ F. s
/ J' ?. o6 T( p#define STACK_SIZE 100
' }; z3 p8 M% v2 X/ Y- T: E" Z#define APPEND_SIZE 10, }5 z- j& d4 S; c: o$ a
. L' V3 F9 C' x- K @! cstruct SNode{
% D( B3 G& S$ W% [; G float data; /*存放操作数或者计算结果*/
! H7 Q. }0 ?8 j; ^; ? char ch; /*存放运算符*/8 l! r: W, }# v/ }' ^8 g9 N
};: O/ l* h; l! \) D
/ E" V; j8 V: o' c1 W& Bstruct Stack{
2 ]7 s1 _9 G4 ^" L0 B$ m: ~. _( a SNode *top;) i( E+ c! Q( W
SNode *base;3 p$ ^$ `; Z5 T, F% n
int size;8 Z: |8 {: ^* F
};
( s2 c7 z6 y5 b
+ h7 L! w0 F" I5 v; |# j/*栈操作函数*/
; F3 f$ l$ k% x" O, oint InitStack(Stack &S); /*创建栈*/
. l( {3 m# a! M/ Bint DestroyStack(Stack &S); /*销毁栈*/( d( R, H4 ]; m7 l
int ClearStack(Stack &S); /*清空栈*/+ G5 P0 s" K, {1 A; {9 h9 W, {
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
; s0 y) F n# Y. z# | e( \int Push(Stack &S,SNode e); /*将结点e压入栈*/2 T. _8 v: @) c. r6 a$ C
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/& X, y" z2 F2 ~6 {# @
5 V$ y3 [" L6 C: M& @2 A! S) E. u( U/*表达式计算器相关函数*/
5 x+ i" f9 T) U+ n* pchar get_precede(char s,char c); /*判断运算符s和c的优先级*/& N7 ]+ L4 `4 l& ~. p
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/, i7 i$ C8 t; ^' g
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/. E4 D# N3 m6 b c# j6 S
float compute(); /*表达式结算器主函数*/
- T2 E+ V: z$ \char *killzero(float result); /*去掉结果后面的0*/
# _" [+ w' n: M0 M' E
3 s9 O( i4 `! xint InitStack(Stack &S)
8 p. N1 Q& x. q) h+ Q{
5 Q9 \, \' z2 f' \9 I0 S4 k S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
7 N; t7 D, p Z* f) T H' G" G if(S.base==NULL)
7 R# R2 R' D; q4 x0 O7 Y {7 c8 {) p) r2 D* M& S3 g8 x
printf("动态分配内存失败!");* t7 ?# E2 v" V' \. X
return -1;+ l0 {# X' q- a. e
}0 J* k, p* R* j0 W2 c7 ~
S.top=S.base;
! H% ]5 l+ m) Q+ o% [, s S.size=STACK_SIZE;
. F5 ~6 r# ~1 [2 p2 Z9 H return 0;
: ]% P+ w% v% Z( [! G# G}
# r1 h8 s2 F) ?( R- f
" `! q: O" S b" p. E4 p" B2 Lint DestroyStack(Stack &S)8 C n# c0 C" z5 q4 z
{
. g% h7 [ R, S free(S.base);
; ` B4 k$ T8 G% g) u return 0;7 J. `6 V3 g3 P/ H8 y0 `2 e$ O# \* K0 c
}
0 R/ o( K& C3 c( ~ A/ M
7 |6 E; \0 H$ Q$ \int ClearStack(Stack &S)5 h; O! }5 E" z: l; w
{
2 a+ x1 m- J1 y5 x S.top=S.base;0 J' @9 J; D: b k+ r: @; Z. O
return 0;
$ K- v. _+ g3 b8 M$ N5 o" {1 N}
O6 _# r- \1 z) I0 H
0 K) `: b) j# H4 R% hint GetTop(Stack S,SNode &e)
/ N t0 T. W$ q% \$ v3 W0 K+ w{
+ M( A- q1 |. \: i" R if(S.top==S.base): E+ h6 w+ ^5 p; W4 Q
{
, C2 A' \+ W' ?6 I7 G! M printf("栈以为空!");6 ^) k2 h; O6 k
return -1;
1 K j- g6 h. t- V6 F. p1 Q }
8 m* t) `: H* ]6 ~ e=*(S.top-1);/ j- K- o3 H! C
return 0;3 l+ W5 V* z1 X; k5 H, h( N
}9 {* g5 P( z* ?8 |) a3 X+ X
& c% z, q& r. u/ j4 `# V8 rint Push(Stack &S,SNode e)
2 {$ H0 z, H3 ~$ d5 S1 c{
2 P/ h* ~5 X# _: ?& Q" A/ Y if(S.top-S.base>=S.size)
i" t6 J+ y m, D+ A {
6 |) J4 v# v$ _7 D S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));" f& g! y" J0 O4 e
if(S.base==NULL)
$ |# B& ~% k2 q- |4 U {
8 o+ x( u; V4 F- A5 y+ j8 ?/ Z& ^' p9 X printf("动态分配内存失败!");
0 z/ e' h9 {# d) f return -1;
$ t6 F! N- f% j4 g }4 H! v$ a8 O9 J
S.top=S.base+S.size;
* H) f7 ?7 [5 Z0 Z5 b2 H% u7 q5 A S.size+=APPEND_SIZE;
/ ^' T- F* _, w5 |8 U+ p7 }7 | }
8 E# ?) b1 }% @# Q% i *S.top=e;
/ O4 G% {+ F7 s S.top++;% w3 y4 z" H" B3 \3 K! e
return 0;
$ a, C; w0 r) Q9 @}. G3 H: N# D; F! s7 L2 T
& G: {% c L$ W$ M9 a9 q
int Pop(Stack &S,SNode &e) v4 z. y8 @: E9 |
{: M: G" ?0 r* F% [
if(S.top==S.base)
" g- m0 d0 w' l3 A% c {
4 }) H" ?! J- ~7 t printf("栈为空!");
0 b5 j) [- j9 y8 I, j return -1;8 J8 T' y/ x3 X
}
1 [$ D$ V0 Y' d) t( G# u e=*(S.top-1);
3 T5 m6 P# m" d* h5 C6 e1 v S.top--;
9 ^+ ]2 {( `3 F! w% @2 k" A return 0;
, p, K1 B( z2 |5 {( ~$ X$ G0 p}% w) {9 u, | \$ ~
3 N! E0 E% R7 h% x" l( [9 f4 pchar get_precede(char s,char c)+ j% f. f- X' \% ~- t' p9 x$ `
{0 f- G! F! O; H: c; o- G m
switch(s)
G& [4 _7 W! [ {
$ Z9 l0 R3 Q+ p2 n0 W, b case '+':
. b9 _) p3 w3 i6 Z( }& [4 j case '-':
0 v1 B4 V+ T+ B4 \& N! g if(c=='+'||c=='-')
( J G# {# s3 s8 v( M, T8 p return '>';; P) @- q. ~8 Y+ y
else if(c=='*'||c=='/')4 c" R) J2 g: P+ q6 } }6 V" o
return '<';
0 N* Q- G. d2 t7 x$ U7 L else if(c=='(')) l6 J- J3 m: l2 a# P3 a
return '<';4 u0 \) _) _2 V4 G1 e: M9 ^
else if(c==')')
6 j1 l4 y* {$ F; z return '>';$ @9 R- ]- E& h- P% e! q: `; K
else
/ n6 a& J$ F1 M# ~4 m& e) | return '>';7 K: [1 T) s6 Y c
case '*':
5 Q9 {; d) `4 t5 c case '/':
; T# U% e3 R; S: r2 B if(c=='+'||c=='-')4 `) v4 Q, J2 X' |* d5 t0 N* F' a
return '>';, p" e( ?, w# y* @$ y* q
else if(c=='*'||c=='/')
, o3 M+ C7 _8 |6 ]. k: [/ Y6 ? return '>';# B' D3 W' a. ]4 V% c* M
else if(c=='(')
; r' R$ l% P* a- C return '<';" W* F0 i! ^% b {
else if(c==')')
- }4 p5 Q! s9 b4 ]" \ return '>';
# E0 F- M8 S- t7 x g5 ] else
& h' z: ]7 m+ H" H! W/ U' U/ \ return '>';
5 @+ A4 P1 g( ~8 R case '(':# P! g A2 j4 }$ G& n" c8 r& n/ r
if(c=='+'||c=='-')
1 F5 R7 {/ z* W9 @: H- d return '<';
7 `# e; j% d o5 J% }4 i else if(c=='*'||c=='/')
( S* b, m2 }9 a( d1 Y/ z. m) q return '<';- U- Z, o0 Q, ?5 a5 U% F3 y% _
else if(c=='('); i; q I& M2 G0 ]5 a3 L
return '<';
& W+ P, }2 G* m) w, d" E5 `: }2 J* B else if(c==')')
7 G E# u* ?1 K* s return '=';
$ Q0 ~4 `% l) ]" [9 ] E) F else$ n( N) \1 Z& |
return 'E';
! b% x2 V% x5 K case ')':
! Z# V8 H! U) V+ S2 S- Z/ i9 n if(c=='+'||c=='-')
G, D# G/ y( ^) I9 w! J8 \ return '>';
, x) j" o2 l" X) k2 L else if(c=='*'||c=='/')
6 e( Z0 b6 s/ c0 B2 z return '>';4 B9 p9 Y* o. E( u1 W/ L0 X: N
else if(c=='(')6 |2 [: w0 A9 ` S3 j
return 'E';
. @; \) r2 x1 T9 {/ m, o else if(c==')')1 \/ \; ]* y9 u7 V( x& n! P1 A o
return '>';
+ I# A: {( _+ K! r else! A' q6 O! t) Q& ]& Y
return '>';
: Q! } o6 k7 H2 s# U1 h case '#':; }7 _( o% m4 ~% T$ W
if(c=='+'||c=='-')! m% |9 O$ J. g7 h( B- h
return '<';
) Y/ }, u& Z5 i# t2 o! U, G else if(c=='*'||c=='/')6 x# E" i- R7 u' F
return '<';, _: W1 o+ q4 a8 D
else if(c=='(')
! [0 O& B' ^, ~* C# Z6 J, }& l/ h return '<';
" S* y% i' K6 c& `+ Z2 ~% C else if(c==')')4 ^. v) a& j" U
return 'E';
1 ~) A; b' b7 y. A. } else
7 s6 c% v. g) f# A& N5 m return '=';
& ]* l$ L7 D2 e4 Z default:
( V7 B! s z* c3 @ break;+ D/ y# F& l6 h: n3 v1 ~3 Y" g9 C
}0 Q5 i' J' f# [9 t! [2 n
return 0;
4 c9 Z# A) ?4 w}
! }4 a+ J/ j3 {% _
: O. r7 c+ G% O6 mint isOpr(char c)
: k0 t9 `4 ^7 \0 H# V8 O/ c2 J0 L( w{
7 ]/ e& ]3 m( g, N6 l | if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2 `$ u! B5 d8 e/ Q$ U
return 0;0 x' O, W( \# R* u1 h, K1 y# V. e% s1 k
else
& n* O0 H. m; x1 a return 1;
6 ]) [' a* B9 Y/ L}6 _) _. P9 Z' l* Y$ w
~1 s! A; Z- u0 u" hfloat operate(float x, char opr, float y)8 O2 y, M e3 ^$ S
{
7 u$ `! j" U# F- x, @; p! h0 i float result;) u! a( y7 _5 h
switch (opr): {3 G( ~" k# G& P/ o
{6 o6 [ p/ T8 g5 M( w
case '+':
- y7 o$ {9 \1 w! S. z9 ?/ z result = x + y;+ w: y& v/ D% Z! [2 U2 X7 d1 g
break;
5 `; J) d8 C; @* d; e" f5 O8 b case '-':
0 |+ y; s/ l9 I/ ~- T% G2 j' c result = x - y;
1 `2 z* w) ?" Q) w4 p break;% j" Y {& w/ k
case '*': 9 k* d7 m0 k& s
result = x * y; R# q$ `* G$ ^+ B
break;
" E9 K" j: [- O; }* E+ s case '/':
% D. a* W. t: ~) `0 m; @3 ^ if (y == 0)7 ?4 N& x0 M3 t3 L# l5 O1 f. O" Z
{
a: U7 j0 Z0 \. z, i2 P7 x printf("Divided by zero!\n");
( [: }* N+ _. T0 M7 ~" u return 0;
" Z: F# W, h2 m }
) m. b! e9 x& z2 T else4 n5 \5 G" x* h6 C
{
0 j( _, E6 S; G$ h: l/ G' i result = x / y;
4 z4 c2 Q/ u& `. Y- t, t$ G+ P break;
; B' [: g7 Q2 S }8 _ W1 V5 B+ t y
default:
- F+ j8 Q+ D- u Q& h3 q: F printf("Bad Input.\n");
$ y& G/ X9 R9 H' T$ f return 0;
; N2 k" f8 B9 q: A- \ }$ q9 ?( _4 q5 \) Z" B6 k; y
return result;
7 Y: j) j8 P0 n- p}
. j. U+ ?% V% P& Q5 g' {
% Z6 m! G% z" s7 i6 ?1 Vfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*// z3 {9 B& K9 u
{* R7 W9 R9 m* ^
Stack optr,opnd;
6 d5 z/ s3 ]; {3 ]) [2 x2 r/ P1 w struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
) D6 O8 L/ y+ [ char c;
+ _, v1 z5 }6 U% x' L- L char buf[16];
% i0 f' x9 y1 t: U' M int i=0;
1 b c' s5 a3 f, X 4 S5 l# ]& Q% R+ R, d$ c( r
InitStack(optr); /*用于寄存运算符*/
4 G/ s9 d# b% l1 K InitStack(opnd); /*用于寄存操作数和计算结果*/
8 `) ^ }( k7 ]+ |+ I A" a; @ memset(buf,0,sizeof(buf));% Q. ?+ b" w9 _1 ^$ q1 a% L3 ^
' N# k6 s3 D6 Z% l printf("Enter your expression:");
- h. A: L) N% F! u8 K
A" R6 w7 c& _+ h& C; B- | opr_in.ch='#';
) C1 U. g: e' P; @, h+ i7 `% p( o Push(optr,opr_in); /*'#'入栈*/2 x2 U" U, S5 {4 b* l
GetTop(optr,opr_top);$ x. ?3 S1 g& R: l( i5 i
c=getchar();- E' I! N- ^$ B& s4 o
while(c!='='||opr_top.ch!='#')/ ]* a) E6 p( |
{9 v/ }; R0 J8 A' `4 B# C
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
6 w1 g4 |! B$ _1 C {
% v N* Y, Z4 X; [# p5 j/ G buf=c;
; ~; u; s6 {) Z/ x% j/ y: j i++;
1 h* I7 b6 `, ~; p; L c=getchar();
- Q# |9 w8 }6 Q' ]* A1 c }9 L& m8 |' f: O5 g# y' D
else /*是运算符*/. I0 z; }6 }' N# X
{- ?' ? q/ r" W/ v4 H
buf='\0';
4 w* a% r8 f; T Q' P# t if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
$ U( r8 f7 M) A$ [$ ~ {; b$ M# W& T. y2 \) ^+ a( Z
opn_in.data=(float)atof(buf);
0 } r ^% r- X/ r, Z Push(opnd,opn_in);7 a% [; ~% m; T: ^; @6 i9 S# y7 o! L
printf("opnd入栈:[%f]\n",opn_in.data);- y: y$ [+ i2 u, S: y9 P9 J
i=0;3 S6 r9 E( E g f5 n- Z
memset(buf,0,sizeof(buf));
5 E3 q; J* G! X& D- F }
" D" H: c- l8 u opr_in.ch=c;
7 A- O8 c c9 G) E) b switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/$ I% D# Y" W* t2 j5 j% n5 ^
{3 p" W% I% C8 @# P$ i3 G/ r
case '<': /*优先级小于栈顶结点,则运算符入栈*/) P5 L' m! o# }
Push(optr,opr_in);
: a+ D4 q1 K$ p4 i6 e; m printf("optr入栈:[%c]\n",opr_in.ch);: ` f: L3 H. m8 u
c=getchar();7 \- e+ c4 h9 D3 I# i/ r' R
break;+ ~" K/ O9 v3 \1 ?, A5 N
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/( x+ I8 J1 h8 S# n
Pop(optr,e);5 W3 |- i, W3 Q3 l2 }) z1 K
printf("optr出栈:去掉括号\n");
% C% h" N% o; F, m' ^4 }- e5 k c=getchar();
# B) o4 v: G: L! h( n# F8 { break;
' J. `3 j4 }8 d a9 t' }* { case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/; f5 M y3 [2 H8 ~
Pop(optr,opr_t);
5 W b w- x) c printf("optr出栈:[%c]\n",opr_t.ch);8 K1 X" ~6 x& G4 `
if(Pop(opnd,b)<0)
; n4 b/ K+ `5 L) V7 x8 w {
6 I! w5 Z/ ~( r: l printf("Bad Input!\n");
* R5 `8 o, I, Y5 K0 P1 s fflush(stdin);
7 ?6 |& t! Z$ w/ j* k" j return -1; e* N, O1 g+ J0 W$ ?7 z
}. z: S+ }( Y7 Q
printf("opnd出栈:[%f]\n",b.data);
& Q2 s& @5 a( Z- Y2 N if(Pop(opnd,a)<0)- w% `( k) N+ }+ b3 P# s5 n
{0 G+ ]; a' h3 O8 t) p
printf("Bad Input!\n");
/ o8 g2 T ^! [) Q O fflush(stdin);
v& S1 V) s% i return -1;
- ?7 N* x, p( O: q. b }
8 X3 c" q' W7 x* Z printf("opnd出栈:[%f]\n",a.data);9 A0 a2 L% Y" ]1 v0 q A, i
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
i L' E5 Q+ P, p$ l' z! a Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
: C$ z% i1 t* \: V: Y F* x printf("结果入栈:[%f]\n",opn_tmp.data);
9 |1 }; }9 ~) f! A4 w break;4 M5 ]( S" `- h& Q, i0 Q/ s/ a% P
}$ V3 a( \# r4 M& d) Z
}
. [) U8 f F+ `! K& o4 [6 e# G GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ! m! c4 Q" l% s
}
+ k% h( o; Y8 L! d" ^ GetTop(opnd,opn_tmp);
- ~! ^ Z; r- ]/ F! K- L DestroyStack(optr);
9 Z8 P& L# E8 [5 m DestroyStack(opnd);* ]) g) g! B9 J' a+ p& B H
return opn_tmp.data;
+ d/ P5 p' f5 M- |( }' y}4 X8 h, J9 f) S. d
; x9 d8 {" p. }& b% l4 echar *killzero(char *res,float result)
4 F. g1 A' a; W) Q{2 y: K8 D2 S6 o1 Y
int i;! A) k% I3 m }0 }9 X& k+ {
4 g# o5 p# A0 d1 @ Y5 ^& _ o9 f
sprintf(res,"%f",result);7 F( S( V% O. {& H2 {0 N
i=(int)strlen(res)-1;/ g) S/ V+ s" ~5 q# {7 x! Y/ i
while(i&&res=='0')
6 t" T7 x! I! }% o( L# { q; ~ {; ^ R( E& t. ~" ?$ _% B; O0 W
res='\0';
* f, p/ y( s B, i B3 _ i--;3 k% s# p/ F- h, _
}* }( }" a+ |# o
if(res=='.'). s- ?7 x! v; Y4 A+ c" |
res='\0';
- T+ w: \, ]- y L9 h return res;
3 [+ s) A- g/ i}
1 ^' U+ s+ _5 u! B
5 m2 a' N0 ~# ^int main()
( M! E+ Q7 g( B* r{+ J8 M7 R2 L7 Q) X$ z; s
char ch;: z( _ Q. u* Z% O3 j
char res[64];- F$ o! T# S4 V% t5 i* a
float result;$ x! x: W D Z; g' x$ ?6 D
while(1)
, v: i/ W! R; F {# C3 T, P6 P+ v" u; c" X
result=compute();
5 X3 ]4 S; m& E) _ printf("\nThe result is:%s\n",killzero(res,result));6 ?0 b5 |- l* V+ F4 J, M
printf("Do you want to continue(y/n)?:") ;
1 L, S$ H! e4 m# f ch=getch();; z" S' q! G4 [- t0 u9 G
putchar(ch);8 _ ~) y8 H8 o" p
if(ch=='n'||ch=='N')
4 Y1 A1 z) x2 m( a& w$ l break;% u8 F( R2 g. P- \0 R& A; f! ^# k+ q' {# ]
else8 X7 c6 n, v5 E H, W, O$ m
system("cls");
! w- a) U. R1 P }( t; e1 H" C& g. w2 {* I A0 v
return 0;# s/ y) @) `7 k- ^# z" M9 X* X
}9 w w; m& R- n/ N
0 O: K! _$ g5 F, d
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|