获得本站免费赞助空间请点这里
返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.2 j% f; X: P+ G# `8 u2 ^2 S9 ?$ Z
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
% {" |5 ?2 j9 f/**************表达式计算器************/1 o  [9 v' I* a0 V  b4 w
#include <stdio.h>3 g( K4 A1 I4 L7 N: u! o8 M8 R
#include <stdlib.h># j4 j5 d3 @) `4 }
#include <string.h>1 Z# g6 `2 j: W+ Y( _: L
#include <conio.h>
! m4 C5 u& q8 N2 y+ A% X3 t* p#include <malloc.h>
7 K9 O( S/ [* o7 U% J% i' h" z
$ k1 u4 L! s& I( F* o# i7 J! m: j#define STACK_SIZE 100+ r2 G! c( i1 d+ S# l8 W' A
#define APPEND_SIZE 103 g& a" i$ y! J5 y. `  n, U
( ~/ v$ a) N5 b+ @
struct SNode{1 {) V- C) u( `4 I" x
    float data; /*存放操作数或者计算结果*/
: E) l' o7 \, J( E: p- o' y7 o    char ch; /*存放运算符*/
1 t6 j4 ?0 \8 u3 T/ U( t};8 T( P0 Y# B/ |; d

9 x4 {8 f4 P7 T3 E0 rstruct Stack{
& i0 I% a+ B. R- b0 a    SNode *top;! ~" a6 K$ E+ ]$ }6 g
    SNode *base;5 c' }, M, A% i8 F1 ~+ _; c
    int size;
9 v( G# G% I, z* S3 v  l};* o9 Z0 u% ]$ S# ~, x
+ |' W+ h9 W3 Q' J* E& [
/*栈操作函数*/) V" l+ S& o3 u3 f& I
int InitStack(Stack &S); /*创建栈*/) x( W& v8 g  a6 {( E2 v5 |
int DestroyStack(Stack &S); /*销毁栈*/
# ^1 [1 J+ d+ s: L' g* G) ?, d. Qint ClearStack(Stack &S); /*清空栈*/
9 q* a& ^* B) e( R, ?) pint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/, w  I* Q4 M8 L" ]4 {6 ^
int Push(Stack &S,SNode e); /*将结点e压入栈*/
$ u& ]% x( d$ C; f% f( `6 A/ Q/ ]int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/% G* ~9 I# [( b5 X- c( c' S
$ e3 a, ]4 \7 I3 d5 l
/*表达式计算器相关函数*/. s  O0 k+ k) Z) x- J6 f
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
# p4 i- [/ X7 i& r, \int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
* ~1 ^6 s3 ^( }float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! i' O" A+ H5 l( J6 j0 B2 ], Zfloat compute(); /*表达式结算器主函数*/
# f* o0 E1 e  w3 Y# T1 |char *killzero(float result); /*去掉结果后面的0*/ * `9 B" t: r* p0 E

2 X. q8 o+ ^7 ^2 g" o9 z& hint InitStack(Stack &S)
6 e( m5 e' G& u{3 ~# G7 O3 X/ @) L5 f
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
( g% s0 X# J- @6 r6 r    if(S.base==NULL)
- c! R6 p. v9 N/ \+ B    {
5 E9 ]4 A3 `( s* f6 {        printf("动态分配内存失败!");
4 |6 V3 {% r6 \        return -1;
, x3 ~3 g: b. m  H; N0 r) N5 C    }
: l- b8 l* U. j8 \- B% m6 E1 ^- e    S.top=S.base;
* |/ X% l% q0 _- e' j  \    S.size=STACK_SIZE;& K" W8 \. t0 P0 A: S8 s
    return 0;
! z0 g' f1 S  K8 q" Q3 F}
4 c! f2 }8 c$ K6 y8 l: E' z/ C) Z, g6 j: M( f/ D" V, ~& D
int DestroyStack(Stack &S)
1 i# _& I# P7 A& T{" E0 D& y% {, p4 g1 v& T; h7 m! z. O
    free(S.base);
) @1 }# g" y4 R+ a4 X/ s  c& K8 B  D    return 0;
+ Z" M: t1 e9 C6 L8 f% N; ?2 z# j}  e7 s$ C/ Y7 ^* M$ f# z8 ~

9 N/ @* m% [5 P9 f9 ]int ClearStack(Stack &S)! Y9 q- ]) h8 g) j% J# H
{
! z* L6 R+ C+ U- w( e    S.top=S.base;
) ?& P8 ?& l# K9 }' U    return 0;
9 \! [. n! ~/ y3 T9 g! C  x}
$ l8 N) i# h& k
7 n; r+ t3 ]; b  Oint GetTop(Stack S,SNode &e)
! @7 }& S* N# P: K5 h, J& f{3 v9 E; v7 j  ]( {+ i
    if(S.top==S.base)/ @3 d% G0 I# i  G
    {( U! ~* ~! o( T8 G0 b  _: }* }
        printf("栈以为空!");
. T4 @8 I# ]: P2 ]/ K* L        return -1;
6 e; D: o0 r. y) p4 u    }6 a/ ^- b' X' E4 I
    e=*(S.top-1);+ q5 _1 a0 Y) P: H  D' s
    return 0;
3 c0 Y# h5 d" ^) Z6 ^}9 J- {( x+ @3 \, c- z
  r, E/ p; e* j* X7 A6 r6 _
int Push(Stack &S,SNode e)' l, @! S- q# x, |1 d+ [( h; B7 a
{. N; l& Q+ L# D
    if(S.top-S.base>=S.size)
0 L. X- o# e5 ^7 @2 z; `) h    {
9 b% h) {9 E3 p( C4 i2 p+ o2 y8 O        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
% e! [; v& |& r6 e; Y6 a        if(S.base==NULL)
& g( Q% i. r1 q& D1 o( b9 M9 W  \        {
4 k: M: a" X! c$ C# H1 P$ [            printf("动态分配内存失败!");
, T8 E8 C: N1 `, S: N. \: T- A            return -1;/ [0 f' t. N7 O- C
        }
% T5 v; N# C' u6 b3 h. ]        S.top=S.base+S.size;1 S3 O+ @- X% a- B  n3 l8 n
        S.size+=APPEND_SIZE;
' Y  p9 c' U' `+ u$ N    }/ `# g8 J3 _5 z  S2 }! r
    *S.top=e;
& d, I: x% {* Z    S.top++;- f* Y% v% w( f3 T  p' P
    return 0;
) ]4 q0 R( n4 {5 u. F4 _}8 i( ^2 ~; _2 \( G

2 ?8 N& b2 d6 |4 J# C) t! V8 wint Pop(Stack &S,SNode &e)4 e2 _$ z" Z: I
{6 o7 K9 n# c" {
    if(S.top==S.base)
3 R9 q% z) L! b! w    {
  N$ O+ H& K, u        printf("栈为空!");% f& \% ]6 E) ^, _) ~
        return -1;$ V# Z% z& r5 q+ t* A
    }
! A: e0 O  ~  F3 r. A' C; j    e=*(S.top-1);: H2 H9 {' Z% }! ]
    S.top--;
* j3 k# C  n6 ?" Q    return 0;* y/ J. Q: N8 v; H7 ?- E7 J
}% A( G% _' Q1 b4 r

- N/ j% V- B) \' ~char get_precede(char s,char c)
' t2 b2 M, X$ Z3 n1 `7 J{
  ~) t* j1 ^* |9 ^8 E    switch(s)# n6 N: u% @" D2 g0 g# H
    {( |6 x5 l2 Y6 y4 Z& b
        case '+':                 
, a: ?7 P) Z0 }& [        case '-':# f* F( A9 {6 @4 u' w' `" V
             if(c=='+'||c=='-')
) Y5 P( w$ S7 K$ d- ~* A. W                 return '>';3 }, O3 Z' [4 F3 j) o. E! H; |
             else if(c=='*'||c=='/')
+ f' i/ Y# H4 M, x; e                 return '<';: O' a% `1 A& y. A% b6 T( r& E1 [
             else if(c=='('): h/ w" y" ]2 y2 z
                 return '<';4 G, [3 h8 \1 l- U! c, x, {
             else if(c==')')
2 f' W: g8 i7 s* B                 return '>';
8 w/ w$ f; h/ ?* L- X( w             else ' s: h' ?8 q0 D2 e
                 return '>';) X# U: I  `/ M) q9 T
        case '*':, h6 k( _  S; B2 V9 `$ }
        case '/':- c2 |% w. ?  v4 F6 y2 Q
             if(c=='+'||c=='-')
) Z" `% l, s% G; L/ A                 return '>';+ l& r8 _# r% B9 W& K
             else if(c=='*'||c=='/')7 O+ g% }! X/ K% Z% s
                 return '>';5 Q( k% I/ L! R  J
             else if(c=='(')
' `% F& c! I( R( T+ B                 return '<';
* {$ `4 i- N8 p. }% H. `3 c             else if(c==')')+ c! M! ?0 i# z- U- t! e( W
                 return '>';6 A4 V- N1 k! G+ s4 Q
             else, ~1 `# ~, \& B: C
                 return '>';
- l* u9 x8 O/ q  @# G        case '(':$ `2 [! B. ?8 k9 s: v$ E, W
             if(c=='+'||c=='-')$ c* A, ]$ Z! ~; |
                 return '<';7 K$ q2 ^3 j6 m) U7 N( H0 E$ b/ n
             else if(c=='*'||c=='/')
8 M' Q) [9 s' ?8 _' D( q) R$ \5 r                 return '<';
- Y8 {, V( V2 s+ u$ R5 n             else if(c=='(')
- P+ [# r8 g2 S4 O                 return '<';
+ D2 v2 x1 t. Y             else if(c==')')
* D. G5 k/ H- Y. l) [' O! h: m                 return '=';
, `% k5 i; M; [3 f1 y- I1 T. E             else
. ?! p& P5 u! K. P* H) O$ k                 return 'E';
# j5 v& ^3 T6 I3 y' c: u6 s* B        case ')':
0 M, q; d4 w* j. ]             if(c=='+'||c=='-')
4 a$ M7 A6 Z) c0 B& I$ L                 return '>';
5 n, s# P( j( o" u             else if(c=='*'||c=='/')- |, J3 U/ s, I4 M+ @7 }
                 return '>';) B& L$ K* `' V% n5 e$ _( q: Z
             else if(c=='(')
2 m3 y/ c& g! |# w5 Q, ]% f* t, l                 return 'E';
5 c2 |- X3 Y, ~! C) {             else if(c==')')
) N1 u( ]4 r  H                 return '>';
6 f) j7 l4 C  b6 J+ I5 [7 o             else
& j& ~* l4 l2 O8 ^* O! \: U                 return '>';8 X* I/ L# D- }5 F& d
        case '#':' R3 s: P- `; _7 A& l
             if(c=='+'||c=='-')
+ t$ X% B, e7 X% L0 I                 return '<';
; D/ Z' F$ l& I3 m             else if(c=='*'||c=='/')2 p; C0 }8 G% r% s+ Q/ z" R3 O0 L  [# O
                 return '<';
: f, {0 u* s6 t5 H: W5 V             else if(c=='(')
# I1 e2 |1 p5 `8 R7 n                 return '<';
* A1 F% ]' x0 z8 K             else if(c==')')' d: K3 }( g* p3 x. j
                 return 'E';  J0 u: p+ n1 K4 x3 R
             else
( I6 i% t0 \8 r. x1 c4 F                 return '=';
+ e( |; o3 a# B7 D        default:1 X! p0 l$ C) V6 b! }
             break;9 N8 }+ B3 e9 T6 M, [
    }
1 m8 r. _( j- h, x" N    return 0;   
; H) ^* D' r6 O1 X2 V1 U7 |) Q}0 ~' Z# A# V: ]4 x
8 T/ N) g$ s/ T" p; D7 y/ e
int isOpr(char c)
. H9 h" L4 D" i{6 C8 J6 `5 b9 i4 @/ d
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')- o; c' q. R5 I9 G- `! a
        return 0;
7 b: ~* H' Z8 K$ z    else
+ _. m! {" \: E) V7 Y        return 1;+ @1 m  B6 a+ U4 r1 G* }; s
}4 j! Y5 C; \( f9 U- E& X: A: h$ j
2 H5 V+ I- E$ A# H) |9 n& j
float operate(float x, char opr, float y)* B+ W7 S, h, N
{) N9 [- a& M' Z1 @
    float result;
( V& ]+ F) ~4 @9 I5 z& Z2 g    switch (opr)
$ W1 Y8 b: K, m    {
# H: k( O8 O# K8 Y( [+ L% L        case '+': / F1 E3 \" `( n9 d! ?4 z
             result = x + y;- W. \* n, I% r" W, E
             break;
/ J9 Q% {: i; R3 b% V& I/ m2 o        case '-': 9 p' W2 Q  B6 D6 b) i& s
             result = x - y;
7 u* Y, m$ G6 V- }' F             break;  j* [) R6 U/ i, R  ~% b' {
        case '*': 4 s2 s5 z7 T- ]2 @% t
             result = x * y;2 s# X" D; o: A/ r
             break;
  o0 \; T  H; |; W        case '/':   C% P+ [4 E7 `1 i1 _) _% a, b
             if (y == 0)3 }: u- m* k! y- ~+ i' u! g2 X9 \4 g/ b
             {
8 C3 T7 G. @( F0 n                printf("Divided by zero!\n");1 p6 m: ]8 c4 B
                return 0;
& s! A* n5 o3 |2 Z; B. D/ Z( Y             }
2 [( v( L: Z0 ]" k0 Z) s5 e9 U             else
: A6 ]; L) }2 V; d3 v             {* c, F! B4 p' a/ \
                 result = x / y;$ I# `3 r4 F3 L; r! [
                 break;
: Y5 Z- ~. `+ ?$ s             }" ^3 \: x5 v  t) d/ n
       default:
5 W$ C& k+ V4 e  F             printf("Bad Input.\n"); . x& T2 ]+ F$ m7 o2 G8 G
             return 0;( {8 B/ [3 i3 u
    }
/ J' x  \. ]7 Y9 [3 v$ D! t    return result;
0 o, K" M" \" m2 V, `! X' J}   
) p- a# ]% r2 s: j. G& r# J( u1 |5 b4 J% V! o0 j9 D4 e& ^
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/  b8 B, S4 M1 D7 |
{
) e( U0 u, A" _3 I  E    Stack optr,opnd;
( d" V9 o- T9 t3 f( |' e    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;( n" O1 _& s$ E% {$ z
    char c;( `  H8 @) d) N. d
    char buf[16];. l" q4 U) D/ c9 {
    int i=0;# U* I# ]1 J  u6 n  e5 s
   
  U* R' p) l+ l& M# N# r5 G# E! E    InitStack(optr); /*用于寄存运算符*/
! E0 w1 a# F+ R    InitStack(opnd); /*用于寄存操作数和计算结果*/2 W! Q! \. U* q- `# b5 F2 F
    memset(buf,0,sizeof(buf));% R3 ^/ Z  u2 H9 a
    & f# J) B. h; \' t0 A1 F
    printf("Enter your expression:");3 X( a: F) K$ O  v' h
        
; i. S9 ~- S3 i& _    opr_in.ch='#';; W0 @& ]: u6 t) q6 K
    Push(optr,opr_in); /*'#'入栈*/, g. C) M! h  R" q3 }9 [: j5 b
    GetTop(optr,opr_top);9 w( o# E9 r7 `$ p; @  J0 ]
    c=getchar();
- |" K* ~  X$ \+ Y* b    while(c!='='||opr_top.ch!='#')
/ d5 e+ V+ I5 Y* t2 _, r" V    {
6 G/ X/ i0 C% o% v: M        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
, j! q0 B8 g! X. Q7 E        {5 \' O" O7 w0 c; p6 b
            buf=c;% h4 f2 }( P) Q: i
            i++;
: I9 k1 U: y/ N            c=getchar();+ c2 x) \6 Z# H0 t
        }+ ]. b$ Z1 J2 I  J
        else /*是运算符*/
2 D: x6 A& @# m% P  s        {
7 k% [1 A) t, t; V$ p5 L            buf='\0';1 j5 A) ~+ M& t" y1 I
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
0 b4 A% y+ x) k8 d& k            {5 K1 G, H4 g& Q. @" Y% ~
                 opn_in.data=(float)atof(buf);
. b' @  L- B  d                 Push(opnd,opn_in);- p! [0 U6 p/ p$ q7 ?
                 printf("opnd入栈:[%f]\n",opn_in.data);
: ~7 y: x0 c5 j: k( B3 G$ w                 i=0;
. j& N' R# M! u( e                 memset(buf,0,sizeof(buf));. Q( v, B) G# b
            }
& e' b. O' o* T/ \            opr_in.ch=c;
/ z4 l, `) b# v& i, ]5 o            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
6 D& d. X5 \1 h            {
# U, e. Z/ |! q! S  x6 r                case '<': /*优先级小于栈顶结点,则运算符入栈*/4 U4 D) j. U6 Q1 ~# p
                     Push(optr,opr_in);+ o; `% i( }4 _* T/ a3 b8 G
                     printf("optr入栈:[%c]\n",opr_in.ch);+ k! W7 T% D0 G
                     c=getchar();! x) h$ A6 I2 L; o0 u# }( @
                     break;
8 ?5 N, A+ J# D& o* G8 Z9 B                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/, |" q$ z: s. T0 t
                     Pop(optr,e);# }6 W5 x' S/ [- z; D9 i
                     printf("optr出栈:去掉括号\n");% ?9 @2 `* E9 T8 b. t/ D+ T
                     c=getchar();. _/ \0 B  \  `+ ^/ |8 @  D
                     break;. y0 X% n. @1 H( Y
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
& [5 k+ ?) s3 S" a                     Pop(optr,opr_t);% I) [( G( i) o- j9 Q; K& N" U2 X
                     printf("optr出栈:[%c]\n",opr_t.ch);' t9 V) Z) [3 i! P5 @. {+ A2 ]
                     if(Pop(opnd,b)<0)
; i6 N( Y, C  }; ^                     {
4 T2 r( f2 B9 C9 z1 f' `                         printf("Bad Input!\n");- Q6 C2 r( H9 P- O+ r1 L
                         fflush(stdin);
- j  H6 _3 p. X) o9 g# K& Y                         return -1;
0 Z* v& \! U9 c6 O                     }. E' S$ i" e4 s# C! c
                     printf("opnd出栈:[%f]\n",b.data);# f4 q% ]. \3 T
                     if(Pop(opnd,a)<0)7 P" ?6 K# m# [1 o9 j( k
                     {
. w+ Y' R  e# B& K                         printf("Bad Input!\n");
# e4 p, N/ d- _6 ?                         fflush(stdin);
( b8 s) _3 f) n+ P' B! A2 U                         return -1;9 X: |  M$ D! J
                     }
8 R; H5 r* Z* h/ O                     printf("opnd出栈:[%f]\n",a.data);
4 c6 e2 E8 `: F, }( Q) S                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/6 k2 {5 L- S: s- g, G6 w: r
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
0 v: ]3 ~$ ~: |& S                     printf("结果入栈:[%f]\n",opn_tmp.data);
3 o# r5 v: v$ [! w1 Y, W" |                     break;  y# y  N1 N- }& `. B
            }
7 Z! i( ]( L2 ~) m        }' ]" a  o1 p, K5 {! L* t$ b
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
. D5 U9 Q, z$ h8 u/ M+ w  z    }" O  b& o: h" D* P1 ~+ m
    GetTop(opnd,opn_tmp);/ I% S- u& i( c0 H( m6 r% s
    DestroyStack(optr);0 c1 Z/ A* Y( T0 i
    DestroyStack(opnd);
8 h+ ^9 |# W' P    return opn_tmp.data;8 M( E' Z& _2 r9 @' J. \& A
}2 x9 D2 L' C+ |& A5 X3 u  }3 o

7 {" ~( o/ g" i8 h3 mchar *killzero(char *res,float result)
& F% u, V  L  D{( k$ ]" s! V6 k4 ?# G2 T
    int i;
/ ?* X) |# G4 }0 @" w: p% ^" P; S- B+ U6 C- A3 @2 ?
    sprintf(res,"%f",result);
& {7 N: f; N2 |! V% S$ v0 {    i=(int)strlen(res)-1;( e7 m; t4 G7 I3 e
    while(i&&res=='0')
" a7 ?5 G* q9 y3 p    {3 A8 e/ R, B- f$ C. u
        res='\0';8 ~, R5 c  R; h, E
        i--;3 e- L3 G: s* z& S
    }
7 j" }0 b1 M& l( f8 i8 B( q* K    if(res=='.')! n) ^* V2 K, }! D+ W* B  W; V2 g/ U
        res='\0';& k2 H0 t' X0 Y! q1 e4 u9 g! `" ~4 t
    return res;& c; g. g* Z- [
}8 p  f, N9 L8 x" I7 E0 ^

+ [, r# t  V; H( w% V  [int main()2 p( w$ g3 ?& V1 v4 p5 A
{5 K' T  ?3 }% V7 I
    char ch;  I) c1 M3 T; z" d3 r2 @
    char res[64];
. x% A( h5 ]) h: \: y    float result;
, Z' h% b* [+ x, V7 I( Q    while(1); o% \- e4 t2 w6 O7 F
    {# G/ E8 q% v6 t7 ^
        result=compute();
6 ?* |. S' }/ k* d) u0 b        printf("\nThe result is:%s\n",killzero(res,result));6 N6 R! T' q4 P
        printf("Do you want to continue(y/n)?:") ;
0 ^' M! [3 o+ ?( _. K" n# _        ch=getch();
& t) I( p2 \5 Y& h& k' h" [        putchar(ch);
/ z* X. ~) D) r' D+ N        if(ch=='n'||ch=='N')
( h7 z3 f+ g2 i/ A" y+ @4 ^            break;8 ]4 Q8 R2 |  r- G( A; [
        else2 ~% E- I% E" E8 i
            system("cls");0 @8 u, s+ @( B. S% b
    }0 V- @- b% t; I7 W3 M2 r4 Q0 [2 R# l
    return 0;- V/ q" n5 t& [/ e: g
}
" F3 C0 D  Q- d/ w( C% z
% H( r# J6 L5 ^) p& w8 L4 L
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

返回列表
【捌玖网络】已经运行: