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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5 O; P! F1 X1 l7 [- [程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=2 s) ~( G2 [/ u9 t2 m( k4 j
/**************表达式计算器************/
* E4 T0 M/ I. x7 X1 L#include <stdio.h>0 s, f6 l/ U4 @$ _# t6 l
#include <stdlib.h>1 i* G. X* H( k: K) c7 E" f
#include <string.h>. U9 ]2 R7 |% _7 g
#include <conio.h>" T' A( B/ Q- S4 `. x# _
#include <malloc.h>$ r- X5 v7 k: F, X; v7 v
, _( }/ L4 p6 ^% r& h
#define STACK_SIZE 100
" l! g& Q6 H/ x8 K#define APPEND_SIZE 10
, x# e& o3 z( j* h5 r' s( {. D' M) k% C7 ~
struct SNode{- _8 b5 W8 t; ~0 q" _+ ^
float data; /*存放操作数或者计算结果*/
: q0 A4 y# m4 E$ q% |: w char ch; /*存放运算符*/) u: F9 ]( t; N% p+ [. i/ I
};, C* w6 U) f! y/ o' h9 c6 C; |6 @
# i( x/ G& J3 M H8 N) |$ [
struct Stack{+ L2 e/ F. o4 N& q' j8 s2 p" A, L, l1 L
SNode *top;% c0 M G5 x6 f- ?0 [; N' i8 V u
SNode *base;& @. d! B+ x! o- f/ F$ x5 Q1 |
int size;0 A2 v! c% K) v5 _9 M8 n! L
};! s# s/ B7 I1 w u2 u! f8 n
) j& E# o6 @' l/*栈操作函数*/6 E0 _4 ^" p; R, @" j/ p: s
int InitStack(Stack &S); /*创建栈*/
+ H; V! L) m# R3 k9 ^int DestroyStack(Stack &S); /*销毁栈*/9 T; a+ {5 S% a% H$ _6 p
int ClearStack(Stack &S); /*清空栈*/% \' R9 p+ ]# Y Q: B9 v- @
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
" s; R4 v9 c+ q* w% i" Q* ?int Push(Stack &S,SNode e); /*将结点e压入栈*/9 g3 D+ \" Q) @% Z2 ~8 T2 m9 |/ m/ h
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
# _% ~. h2 y+ W$ B6 x" X! X& |1 f- ?5 n
/*表达式计算器相关函数*/
2 j8 |$ ^6 P+ {7 y& `0 H9 W; }, Mchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 D+ }5 C( y( E9 q+ Q3 c1 Oint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/2 v! W5 ?4 L8 j( }2 a
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
3 s! ~! B. f' a* `4 G1 W5 wfloat compute(); /*表达式结算器主函数*/
/ d, i @: @% o* J$ tchar *killzero(float result); /*去掉结果后面的0*/
: x/ ^2 l7 h/ k# I9 e) Z) i E& h+ H H! W/ g
int InitStack(Stack &S)
* T2 T+ v6 L5 b+ l9 ]( N6 v{: d! R" O: S; p, ?
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
l- j, ]" q4 {8 i7 L! W if(S.base==NULL)& K% x0 j, m% r) t! Q- @& \- \, x1 i
{$ g. d: |" R# R% a
printf("动态分配内存失败!");
& S! [0 H9 U/ ]$ e9 s return -1;
5 A0 y j& Z9 v$ k# u+ n/ Z. o) x i, b9 { }
' a6 l o/ s% U7 f S.top=S.base;
7 L( ^( m1 W) E; }3 `* G S.size=STACK_SIZE;$ p0 F/ F' \& w" @! q& W
return 0; a7 F/ ?" p ?
}+ B& `2 {% t/ s. ^: W
& X, ^4 C" h% |% F& E* M% G! gint DestroyStack(Stack &S) m- H M e! ?' K. X" Q% j: X
{
" h) r. P* ]0 ~0 b! \2 u free(S.base);: y7 g6 _9 \1 R: \1 {2 o" K+ N
return 0;' [+ R8 c* W. n. V& G6 W& S: n
}/ a# D0 [% f5 Z
& L( \* C9 B! Lint ClearStack(Stack &S)) N3 i$ Z% s# E1 }- T
{
% u1 q# a$ [2 T2 d S.top=S.base;0 k" Z( v ~) ~- O
return 0;
% C' \4 N; z3 P5 y0 g- D}
( V, |" q. m1 n, \
2 N8 C! E8 {: ?3 Z0 _& zint GetTop(Stack S,SNode &e)
$ h, o9 ]' R3 ]' f, }% w{8 P% p0 N3 U" a
if(S.top==S.base)
" h5 h% C" v2 {3 [; A {
) z2 x8 B! ]) ~ printf("栈以为空!");( o( n- Z8 B, E
return -1;
+ C9 _: u$ v+ N R }
8 `4 y; Q/ z, M. [ e=*(S.top-1);
, l7 `) J# v, _# ~2 l return 0;
9 ] b( A& S7 h K7 s' O" ~% h}
$ x0 j( q( }. {- G5 |- p! W* v; W) j9 r2 Q
int Push(Stack &S,SNode e)
1 Z/ @) g/ b0 E" E5 k{! e( {6 V! g+ k9 h4 x! m/ h
if(S.top-S.base>=S.size)" l% ^. G- G I# i, |
{: w* Q/ k) b* R" ?0 ]! Q
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
: O1 Y( p5 c9 v& n; E if(S.base==NULL)
! c5 s" M# @1 r! d' e/ p {
! a O7 g) }# h0 g( w( B& M/ \ printf("动态分配内存失败!");
; [, d; p' w) D, a# i8 } return -1;8 M5 z0 V" M! V
}
9 o' R7 G/ S& o. D' A( m S.top=S.base+S.size;& a9 g; w' \' I3 t- v/ v2 A
S.size+=APPEND_SIZE;7 a+ a2 T" `4 _
}
/ D' v- f' f. L5 ^ *S.top=e;
3 V0 y1 s( W6 j7 r( G! F' f1 G S.top++;
+ r8 C: g+ a" w5 P. a4 F return 0;
! m( I9 p% i# D' o2 g8 A* H}' A* Y, b) {9 e* E! l
2 y+ d$ I, _( c; c, u& [7 K$ T
int Pop(Stack &S,SNode &e)$ Z' v+ U! y& n' K+ }
{* I/ {; I- w: t3 u2 S
if(S.top==S.base)6 {3 ~& L* r) u$ _0 W% w- R
{
( x# f, P8 m; A, r printf("栈为空!");
$ R1 S4 ^/ j' _6 p return -1;
. F/ ]! r( \, D$ Y( D1 d: }2 s }
' j( [; {2 s; i& d; F9 p/ k e=*(S.top-1);& R) D& X3 y# N" `) f3 o" ~
S.top--;
4 j6 q* ?3 }) L return 0;
6 K7 q+ p1 Q6 `" f}
0 [ }( D; C* p" w! U3 J
1 A9 j, M' [' M2 Gchar get_precede(char s,char c): R+ _5 |: n5 i
{; T; Y S5 L" {9 h
switch(s)0 p! W1 k4 R, Q0 D: X. ?+ b5 f9 I" S
{
1 H+ V0 F4 M: U( f case '+': - H& \5 c4 i# M9 s1 q+ S& ?& _7 q
case '-':
6 z S! F& _. @- L8 R+ Y if(c=='+'||c=='-')
( [0 P3 P/ p5 f% O3 U" h0 Q return '>';
7 M/ j8 p9 [) z' w4 X, k" a. K else if(c=='*'||c=='/')' Z' s, ^$ i& V( [9 L% v" ` V
return '<';
# n3 x1 m# Z# } else if(c=='(')
' k: [0 ^# c3 [" y; o( Q* r return '<';9 t+ _( i" _7 G* z' G
else if(c==')')$ m; B: j* Z& y3 ~/ O
return '>';
' a9 J! m* C% A5 x else
" p2 e2 S& h! |5 H' V2 m0 }( j return '>';
& {( C$ I2 m- l case '*':
4 T0 `8 V0 A4 v4 R& ]* { case '/':
) G7 ]2 m0 B2 ~. l: ^ if(c=='+'||c=='-')
6 U! q# X/ u1 @5 S. K return '>';
( n# c; U6 m, N. {. G+ u6 d else if(c=='*'||c=='/')4 D. X' ^$ ]* g. X7 r, w5 c7 d
return '>';
0 T/ U# n8 Z9 |( ~7 b0 d# I. E else if(c=='(')
4 h. v% p6 H' \" C1 r5 S9 Q return '<';" O5 U/ t# H$ A1 \9 L, o* Q
else if(c==')')
3 E1 J$ Z p, l/ U% \% W return '>';
* S' H& h8 s& o else
9 h+ S- M) K) |0 j3 p# b7 p# g# l+ t return '>';
& Q# I# Z3 y. K* E, S case '(':/ w5 I: p9 L) A: Q& _* N
if(c=='+'||c=='-')+ O" x2 c1 E. i% n
return '<'; M; Y* ]# v; r9 k# n( o% E
else if(c=='*'||c=='/')% \" J! S& E) s. D/ d
return '<';
& C# O9 B" W# U- ]9 ?( O5 y2 B else if(c=='(')0 {2 a5 W2 t2 C: _& h5 [' _1 G
return '<';
; g7 p: F7 z; q1 f, x O# T! k; h* i else if(c==')')
3 ^- f. s) y7 d) \6 s return '=';3 b' k- s- l6 e- C. f7 }' M! R
else0 e- g: D8 V2 ^* U
return 'E';& `' C6 I$ H/ B6 m
case ')':
( ]# O. s6 c3 N, u9 l, l3 W# y if(c=='+'||c=='-'): Y% ~! s1 B l' d$ S l8 U6 L
return '>';) f3 K" N: l9 n# L H, w
else if(c=='*'||c=='/')6 P# W& G2 F: e! a+ T
return '>';- k' W1 ^3 h+ ^4 X
else if(c=='(')4 P5 X) Z$ Q: k+ A3 R S/ |. p
return 'E';
. e6 Z) {" F e. {) S else if(c==')')
7 u: y4 X$ u' L! J# N5 j5 ^, p return '>';
3 Z( {8 W$ H) W else% e9 M1 H0 J' O
return '>';' ~. s b$ X. D _3 g, D
case '#':8 P" D* l) U5 a' Y. H
if(c=='+'||c=='-')" J/ H: s a; [" s- M
return '<';
4 i. w+ V S& E% N" v2 A6 S! U else if(c=='*'||c=='/')3 l! F! M1 N0 _6 M' N; K
return '<';
# t! r8 M/ @9 t6 V7 ~! Z else if(c=='(')
: a& G! [( a( e- x return '<';
; P0 S2 a5 T, B else if(c==')')
9 q& g3 G! z! k( H return 'E'; N/ `5 y" R6 Z7 a$ O
else! l5 j2 u% ~2 k& O
return '=';" P X, `$ v2 Y5 N. N) E( X" a U) q! u
default:
: K, A" g& E1 X7 e- e# a break;
# C8 p' @! D W' S }
9 C3 a2 D( z2 h return 0; 8 D+ x8 H- q+ a0 V3 Y
}4 k: L. P; Q" g7 a8 U
4 a; i0 w [9 _. J+ I% jint isOpr(char c)+ l5 a" p9 h: E8 ?- C9 J6 j) `
{
2 `1 N" M6 I' x. c' ` if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
, ]1 P1 o. I* E# E return 0;1 n' b# r: Y4 p$ Z, Z0 [
else 0 t9 M$ s4 l+ Q/ B) G5 M
return 1;5 U8 D) L! V! g5 k
}
) a1 D" c$ y3 q. j" c, u+ F; h' X, Z. t N0 b* a
float operate(float x, char opr, float y)
8 ^$ Z1 }' u9 w3 x{& u( j0 T1 Q. Q" |& C1 H
float result;
* s) e+ X+ U8 K2 l9 U! A' w switch (opr)$ n2 S; |& j% L* Q' G: F2 G! n
{, F' e* {) M" y
case '+':
8 H( R: h7 C$ {+ _# C$ s result = x + y;
5 o) H! y k) u' q" Q break;0 N6 B! [6 S6 _+ I) O; P
case '-': 1 G# k; h$ V6 R+ ~( }8 J/ d
result = x - y; S9 ~* Z! D3 N+ v' \
break;
8 i: P* `( r8 p, n case '*': - o3 Y$ {, l2 _+ D' J2 ?1 M
result = x * y;8 K6 Z) W2 t% L/ W, C [ N
break;2 q9 u1 U5 j5 L, h3 ?
case '/': , t( p* D% H1 s; Q" X
if (y == 0)
5 J" R n3 o( x: q& \5 Q; C {4 r) Y8 n( U O! j' ^
printf("Divided by zero!\n");0 S1 }6 g2 T3 |. J( a
return 0;: }1 {% i) a1 l6 S* [
}. v1 z$ D7 S) D- X: o4 w
else$ L2 S; z+ d' V) T7 P" \
{
+ q# o' o0 { W. F4 g) r& t! E result = x / y;4 g6 H _1 P0 k6 P! v+ I( W
break;
$ P. N5 w F8 C }( W& Z5 |8 s- k8 V# D: u$ v/ z# c
default: ' S* B) `7 U- C+ s( b
printf("Bad Input.\n"); ' C# c$ ]" F D" V, p# y
return 0;7 b' {) ~. d" F, q0 y; h5 d1 S+ O
}, ^* o* Y' @0 _" f: [# C
return result;
4 w9 o& L \3 p, L}
6 |" g- K( C0 ^
$ w) A; P# f) i( Cfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
5 j- b, S4 c5 r{
" j9 y% O' e- X+ W5 ~ Stack optr,opnd;
' V4 t0 j4 a7 F8 \, R- ?. e* S struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
7 u: M8 J6 ~; C( m( j char c;
% K2 M$ d' S$ n \1 } char buf[16];
6 s% ^/ i/ r0 M4 F int i=0;) F, E( s Y/ ~* C9 O
/ p7 O& t! h7 m5 G- ?
InitStack(optr); /*用于寄存运算符*/
/ o- j& k& ^% D; |6 X InitStack(opnd); /*用于寄存操作数和计算结果*/; j8 B' _+ k8 ?4 _
memset(buf,0,sizeof(buf));
8 Y! z" w# ] X# |5 Y1 `
3 U" e: [3 o( v4 m+ m printf("Enter your expression:");+ _& K/ G) L' M/ q( i
& t% I- k; O$ H2 V6 N' q
opr_in.ch='#';
+ M: ]$ G+ C' m4 [5 e* \ Push(optr,opr_in); /*'#'入栈*/( d6 |5 T3 l0 g K- X. O/ Q
GetTop(optr,opr_top);
1 G% b( O% R- l3 @) K( y: o( e c=getchar();$ Z, j* B% K2 e5 O6 v* w
while(c!='='||opr_top.ch!='#')- c3 D# I2 b9 q0 ~- ?3 L. [
{
S5 f/ v% b0 y* v$ B if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
" g$ @, b4 K1 ] K2 M4 a7 U* O {0 L# o% D3 Z* L/ u: i; @) E) p
buf=c;' i% p% F) W( V o/ q
i++;
' b% V! y3 I( w- Q/ O8 ~ c=getchar();
3 N7 G2 m9 ^6 z1 S- {2 } }
7 G! U2 r; d5 s$ P7 m) @; n; i) c else /*是运算符*/
/ n# S1 s" X _$ j5 s5 p9 d {% b( ]* O4 x- m U% q% ~
buf='\0';
/ t ^1 ?, L0 Y' j if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
$ Y( P" u# Q6 ~% ~& G- M, ] {% V3 h! `1 r9 y6 |+ @0 O/ q) V/ Z
opn_in.data=(float)atof(buf);6 K1 B# ~( k2 p% B% _' _+ Y' |
Push(opnd,opn_in);
; w0 C- a5 n& t$ r$ [ X3 B printf("opnd入栈:[%f]\n",opn_in.data);
: y3 v% }$ Y a1 w [' o% e i=0;
" V+ g8 Y/ ^/ c' r/ \ memset(buf,0,sizeof(buf));% r+ B, @7 `% B; N0 j
}
* n B% q+ W9 |6 D6 C1 U opr_in.ch=c;) _3 Y. ?4 x7 E* @6 a- D0 N# ^6 g
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
# ]4 z5 _% X8 e" \7 V2 S- U, a {; d1 \, a S+ C
case '<': /*优先级小于栈顶结点,则运算符入栈*/2 d. F( p- {! F5 ?/ k* h: ~6 V
Push(optr,opr_in);
( ]6 J1 A+ G3 c- Z# G, I printf("optr入栈:[%c]\n",opr_in.ch);1 V* D9 _8 \/ f' Z3 z+ q7 ]
c=getchar();' w0 N3 q) L9 E; }; N9 D* q- m
break;
% h8 V' V+ `5 {! A$ j3 o case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 @" `2 _& Q) a7 D5 ]! h' Y
Pop(optr,e);
& A" J9 B6 S5 |- p( b+ w printf("optr出栈:去掉括号\n");5 N1 ?: T( `! j5 d: c7 d# z
c=getchar();8 h3 e& ^! p+ D9 c3 B
break;% W/ z( r' r8 [) {" E( }, Z) y# `
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
, j9 R6 B- O1 `8 | Pop(optr,opr_t);
* M' L5 O" W* x6 V, ^- A printf("optr出栈:[%c]\n",opr_t.ch);
! j- x9 ]4 y( Y. q! Z& I if(Pop(opnd,b)<0)
9 `2 I. V k/ \1 B1 a {
z; ^0 b. ~& t4 B4 B printf("Bad Input!\n");
# e3 K' ^1 M9 R: h8 G. M2 y3 ~; D fflush(stdin);
$ Y* v7 {* D6 M" r% E return -1;% R! v( k7 D$ K& \
}! @2 s! w& s, y- c; |3 L
printf("opnd出栈:[%f]\n",b.data);
( x8 f \8 ]% ^! J5 Y" a. x& ` if(Pop(opnd,a)<0)
& N' o/ M; ~8 a5 x {! I4 C6 A+ x J
printf("Bad Input!\n");/ f- @# A' R4 e6 \7 G/ ^
fflush(stdin);; U4 ~2 s2 E, E; H2 N/ ]) l, T3 v
return -1;
+ U; i5 F+ W# |- W }
# M; b/ a2 i0 L/ I# e printf("opnd出栈:[%f]\n",a.data);$ I8 J9 g3 s3 z% ]' V4 g
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/: B6 s7 f. _. q3 |0 S* r4 @& y
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
. j9 n2 q; ]9 H0 l) O printf("结果入栈:[%f]\n",opn_tmp.data);
! z. [7 g, T9 @% I break;
+ u. z, l. K6 y: i/ v }* m I) p# Z4 I$ a* Y' n
}5 Y: E9 o! G# C. V
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 2 _' V" t' z. i- ]" g2 j" F; P, J; [' M8 d6 I
}
; }) S6 n2 T5 G& M; L GetTop(opnd,opn_tmp);% k. h3 x( {4 n8 ~
DestroyStack(optr);
5 ?0 N( ]' Q% s2 ?; S6 C0 D" t DestroyStack(opnd);9 a( j2 y% |( ]; w, R$ G) S
return opn_tmp.data;: P2 H, q* \$ f& J- U
}' K) x! e8 a/ [0 D$ R0 m. g4 x+ j+ O
; V- y# R6 W4 d- ~/ v6 _' [
char *killzero(char *res,float result)
- Q0 P3 J/ `' Z p{
, \: W* H, I3 ~. N- S, [ int i;
& ^) N( g1 {* H
, h! `; f* T; l% W* h sprintf(res,"%f",result);4 o+ H n1 w6 j2 E4 q2 u7 B$ l
i=(int)strlen(res)-1;& \1 h+ \6 F6 P, t
while(i&&res=='0')
0 j h3 D, \! x' E+ B {
# d6 a9 Q2 G) O3 O9 d res='\0';, c' U8 T( } h6 @4 |
i--;
4 {- o4 _1 x7 b+ B# r5 p# _1 j) X }
& _2 d$ [& r8 B6 b) H if(res=='.')0 L" O M3 w) T3 o6 j
res='\0';; C+ _/ j# @, v; w
return res;
{. y* N1 B0 k% ~) L}; r4 M% b1 O: g* M( Z7 Y, l/ `
- L% M6 F- h- ~/ v" zint main()
: i3 E# R3 s# L$ y2 J9 b7 W# e{9 V* P. }8 x% x, C& }
char ch;& J Y% U( R. w5 i9 `
char res[64];
6 i' O- C5 c! x float result;) Q) N! Q. C* x. U! l5 u. Q# l
while(1)
5 a8 H, M( z# v6 M {
+ ?! q K- G- o. q6 W result=compute();8 |+ }. ]! ^' E
printf("\nThe result is:%s\n",killzero(res,result));# t: ~ w) ]( E' |3 `0 O
printf("Do you want to continue(y/n)?:") ;
) X- F+ N; _0 B ch=getch();
; Y) A- `, ~; M3 k; R. S putchar(ch);
) D4 X4 @# W' F1 n* ^. F if(ch=='n'||ch=='N')" _+ y& f) X' m1 F/ q! A
break;4 c0 X. N1 h. k3 i( P [
else
' p6 U c4 C+ ]* p# ` system("cls");5 ^8 K6 A [9 E) p6 L4 @% C
}
3 \0 s% e% u0 L3 u- @: o; j3 m return 0;
0 _: C$ o* m" ~9 b' y' B- B* g}
4 R8 N) N9 H& ~7 p# q8 \5 s! B1 j0 k0 i
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|