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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.0 E9 U8 Y7 \) P. G
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
* n0 r( ]; `9 m, e" Y6 G/**************表达式计算器************/
+ a8 }1 E, F% W& s#include <stdio.h>' s: U) ]) E, }$ z
#include <stdlib.h>3 R( s6 w! a- c6 u* |5 P
#include <string.h>' r  X# n1 Z$ B$ y: E# ^
#include <conio.h>
1 p  u( A" G. L4 C( `, O  W#include <malloc.h>: [- U2 i0 O2 L; k9 k6 t% Z

" x- `8 z9 C, N1 b5 _5 c. }9 E8 D#define STACK_SIZE 100& f0 L' G4 i4 ~4 p
#define APPEND_SIZE 10
, T% F& c, W. F' {0 K8 M- Z0 C) `, C& X+ g& l
struct SNode{
* V# c6 \1 F6 m9 P* ~$ f% m    float data; /*存放操作数或者计算结果*/
/ u" v, a" R2 C& @. e" t    char ch; /*存放运算符*/
6 m% b$ S8 N) h8 @- T" E};
( n" `1 p) S, K# S1 H8 u8 W# [5 N# g/ P
struct Stack{
9 J0 f% p2 D0 U9 n3 h2 S! K    SNode *top;8 h+ U; D; l! V# B
    SNode *base;1 V/ N2 q# C- m9 Y) }
    int size;! ~! B$ \6 ?  X6 U" A8 `: I& U* D% N1 H
};# t$ n& Q6 |" P% j

9 G$ z! T" f8 n: O" r/*栈操作函数*/
( r. A: }+ |: Q6 F  F$ d6 n- j4 }: Iint InitStack(Stack &S); /*创建栈*/
# q, M7 m% T% l. \int DestroyStack(Stack &S); /*销毁栈*/; ~( b# m$ ^6 I9 G
int ClearStack(Stack &S); /*清空栈*/
9 z* F% t0 J& S/ |int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/9 A/ m2 @: y" N) Z' O
int Push(Stack &S,SNode e); /*将结点e压入栈*/0 Z) w8 G2 b6 T# s( o
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
  V/ q. S! k6 A, d8 G& x8 ~) {
% G# K) K3 Y. t/*表达式计算器相关函数*/$ r; {  ], R- P' B0 k
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
) v$ m  @9 M" y: O4 ~+ e  y/ E9 F$ xint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/+ i5 `. R3 f/ O% C& P% P" _. l
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
; ?& }6 a3 a1 t! M4 ?/ M, w4 Qfloat compute(); /*表达式结算器主函数*/- @# A7 Y$ G+ D* r0 e" a
char *killzero(float result); /*去掉结果后面的0*/ 2 I- n* `* s) T: C6 A" j* f- d) b) Q
* ?9 J6 v& |7 z9 ~# p
int InitStack(Stack &S)
0 R, q9 Y0 b4 y' T4 q# U! R{
$ r( W5 `0 H+ j0 V1 x    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
  u3 P3 }. }2 Q6 k$ m    if(S.base==NULL)& ]1 d' ]1 |# J2 t
    {
  ~2 c4 R3 x! c+ G3 M# n        printf("动态分配内存失败!");& l6 L) H4 [8 y! ^  P+ Y
        return -1;
% ~& r: v/ x! }' p2 C3 d, l    }
% n3 D3 m. O. |3 b) w; [3 y' q. V1 b    S.top=S.base;9 c" l$ R. m6 W
    S.size=STACK_SIZE;
9 T, D: H" V) ]  S( j) u    return 0;
7 E! b( x/ i, r8 `- e4 O}
: `- |% y# t" g
  o' o( c9 D/ Q9 z; H, _1 J) Jint DestroyStack(Stack &S)0 c6 e3 Y' G$ A' [, k. w
{& S% e4 a3 v1 r, J
    free(S.base);
6 P) Z" M. n6 k    return 0;
; a5 y- L& z: G" B}
; y3 V7 L3 p/ y- q  j& ~$ ]2 Y% u# |. |
1 {0 E% u- t1 ?% w$ ~int ClearStack(Stack &S)3 e4 p2 w1 S: g( Z4 j2 D
{+ ]( U0 L7 T' `: @1 Q9 W
    S.top=S.base;& }+ J5 V$ ]# B) V3 `! K/ \
    return 0;' C: ?9 x& r, z1 K$ E  I3 @# a
}& t/ c* f" S+ W8 o. T( ?
! A1 ?: J- u5 m0 s( V" t
int GetTop(Stack S,SNode &e)' l0 |8 N  V7 Z' A; r2 S1 G& f
{. p6 B8 g. p) I6 V
    if(S.top==S.base)$ l0 ]  ?  Y" ~2 _5 [+ N6 u
    {' ?( I6 n& R8 V# A  u, s! P
        printf("栈以为空!");
; l% N2 W9 [/ a3 C+ U        return -1;/ \2 c  p' \! t5 Z0 H
    }
4 r$ M; v3 e0 Q4 K% u    e=*(S.top-1);
: e+ L* B+ L5 E- `5 v  A0 @    return 0;
! f+ u+ W% M+ G: H8 s; s}
+ }+ T' s2 R5 C  x2 v+ Q
) E) V: W0 f, J9 ~* x+ Oint Push(Stack &S,SNode e)6 b& l0 X% z) J5 X
{
, m: v! v  r/ C/ Q& X- c( l8 ~    if(S.top-S.base>=S.size), l$ z$ P4 j" ^: c. j" S) C) M7 w
    {
3 T$ W  H5 X( O4 x- Z- A$ n# g        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));' s, G' O& k, F. U
        if(S.base==NULL)
% z, i0 P: M( ~  q& n# q: g" T* |        {8 P0 j8 Y8 x; z; b+ a- C  D0 {( P
            printf("动态分配内存失败!");
' W0 ^4 o8 N- L! q& G# n            return -1;
1 u( L) {0 s+ J: W' A8 B5 l        }9 D! n  ^- u$ E5 j
        S.top=S.base+S.size;
0 ]7 P3 H! Q6 ~        S.size+=APPEND_SIZE;$ v2 _7 P! ]( M; h3 ~- C
    }
4 g$ s  m. ]" s0 ]8 {' \3 S    *S.top=e;3 S: a: f" _% X2 A& |" S  u
    S.top++;/ k3 F8 q) l* Q! m+ A
    return 0;
, x2 X! \5 D6 f/ [}# |) }/ `) k* Q0 \3 F: ~
  C% I/ T" E; A2 d  i
int Pop(Stack &S,SNode &e)3 Z5 g3 g; ^( _- V& `
{* _5 H) y5 X0 ~, O- X7 c+ T
    if(S.top==S.base)2 E  R+ X" V" C  |4 D( o1 }0 K2 u
    {7 [- \- A6 ~) e0 Y* I9 D& X
        printf("栈为空!");3 Y. z% j4 @7 s$ `: N9 F" }
        return -1;- p# w& A+ }( y, x9 }' H8 M5 q1 Q6 b
    }5 m( v2 k; l9 x6 a7 c- M, u
    e=*(S.top-1);
  [6 Y% I8 z  X/ V) r& q3 {* [) T    S.top--;
0 h+ j8 f1 g1 Y" ^$ u% K2 B    return 0;
& a( Q, E1 ]- [" ^. i6 G3 a) z; L}- s$ ?6 z, Z5 H' Q

' g+ w: C3 I9 O: e: M9 `: l, U8 [- Gchar get_precede(char s,char c)' O- c4 l  o( L& C/ p, T  q
{* b1 d8 Y+ t/ T. T! r: K5 g. C- h
    switch(s)
6 b. C$ a9 j1 n% a+ N) C    {( `4 ^  w% a2 c4 g# t- `
        case '+':                 & p, X8 \  ?: z1 l, ~0 ^
        case '-':/ ?+ z- y- y3 O0 H, d2 Z
             if(c=='+'||c=='-')$ q4 f; p" C; t1 l1 q3 i6 h
                 return '>';& _  I7 `% c( w) X: F
             else if(c=='*'||c=='/')
' P, C+ u# J2 ^+ S' F$ e: P                 return '<';
6 W+ L9 z" _3 ^4 {& g- X             else if(c=='(')* C" l2 ?" R' f7 y  u
                 return '<';
4 a7 o0 @# p9 _4 l8 l, }             else if(c==')')
1 L- R, z7 {0 n/ m                 return '>';
4 L6 t5 H" j' ?7 t6 C: E1 q             else 2 o0 c9 x+ @! Z! I% B9 |. m. h
                 return '>';& f" L: ]- |& c
        case '*':
3 _, z7 ?9 ?  J0 r( n        case '/':
% F# t5 }! x, h4 z/ w0 e             if(c=='+'||c=='-')
# k4 G9 W6 Z. V6 ?8 M                 return '>';( m# Y8 |, D+ }& \+ i/ z" o
             else if(c=='*'||c=='/')* I# O1 @% z. u6 l, K- ]( E
                 return '>';
1 W. p  c# s* w' [# d" u             else if(c=='(')
9 u  K1 f9 L$ }, Y                 return '<';
9 o6 f0 D+ o5 Z- k% U" E" z             else if(c==')')( ~9 d- H. l& p) h0 @8 i  Q* r3 {
                 return '>';
( e$ T' w, F9 f, u7 b             else7 L+ j2 z$ O, Z" y( p( X
                 return '>';/ G  j7 G' E: s4 z! E
        case '(':
+ B' x/ \# Z  f( D             if(c=='+'||c=='-')! M; H1 J& t) v/ ]
                 return '<';" E7 R0 m  [, E
             else if(c=='*'||c=='/')
$ B3 U4 \$ D& ~$ \                 return '<';3 b! m( z( _" T) `5 q
             else if(c=='('), q' Z2 f7 F* G; H1 ^
                 return '<';, g* B) }" E8 u6 G+ z" J
             else if(c==')')0 g. g4 H2 j% n2 D+ ]) A4 R  y. b
                 return '=';6 T8 g4 d  U1 T# f( \( @
             else
+ h2 M+ Q3 d" v3 O4 \' H7 I                 return 'E';
! A# K$ m, X! F        case ')':
+ {) v/ Y) ~. f             if(c=='+'||c=='-')- Q4 O$ k2 y  W! s" `0 `
                 return '>';
4 |- B. u/ m0 k& W, j/ L, d( M             else if(c=='*'||c=='/')
' G# v. l+ S7 T6 N; n                 return '>';1 m5 H! I9 ?5 U; y! c; D. }' K
             else if(c=='(')
$ l2 ]2 D3 c: f; g( |& @* j                 return 'E';
! ^! }/ ?2 E4 O& p0 u% I             else if(c==')')
( [' ?0 U3 ^; Q2 s( T2 j+ C8 o' h                 return '>';: W+ f  \' H: [- d
             else
7 A4 r- X, e. t$ u4 @                 return '>';
# c8 ?9 u6 o6 `0 b' Q% g        case '#':- a+ `  a6 ]1 E+ r5 U! }& `
             if(c=='+'||c=='-')
. e7 W9 \" k4 a. ~' W; t" r                 return '<';0 r% ]" g+ _- S1 R
             else if(c=='*'||c=='/')) h1 e6 l' S, @9 @
                 return '<';0 }0 W- ]; w* N
             else if(c=='(')
, B  @/ F5 |6 s& E                 return '<';2 G+ H% M! T. v. k4 O! I- A
             else if(c==')')
8 S5 j( s! v8 ^4 B                 return 'E';
0 z3 N) J9 l! W- l" e; q             else
1 ~. q" W+ t7 T                 return '=';5 I! W' o+ j8 Z
        default:
7 I+ K  y3 ?+ {             break;; x$ ]- f% C+ s# O
    }
/ L6 y' k2 \4 R0 M' m    return 0;    3 H. z; P+ M) ^9 L8 {" t
}1 l; L+ H7 g8 d: b

; W; t, }, y0 T# d2 G  aint isOpr(char c)
' L/ ]# s! u; D. l) z{
- b$ a0 T5 U) X/ c3 G0 ]3 g    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')  s9 n1 d. U* z9 {( r9 w
        return 0;3 i2 |! L  h2 y5 D
    else
; X$ N3 _$ Q% B. u        return 1;1 m$ A$ M0 A7 G* {
}
* ]) _& _7 Q( x7 a5 C9 N3 ~& O; }% q
float operate(float x, char opr, float y)$ ]$ c$ D/ F9 w* y4 z" F
{' x6 A% }* b/ g8 c: r
    float result;! [5 i/ Z+ u* a5 ^* B4 M
    switch (opr)( {; W7 O& E! [) R, L
    {7 Z# v/ }. s. V& C9 q3 H
        case '+':
) ?+ ]( n* y  q3 Q             result = x + y;
' C6 Z; P6 }. n- S% A             break;$ h3 C* u# j2 _' H) Z# o
        case '-':
! n4 P* f% a7 j/ M( N" B$ n             result = x - y;
9 q2 V9 Z* P; ~) b4 y6 O1 L, D8 V             break;
" t" F6 B0 I8 r' M1 G        case '*': 6 R2 r5 y! h: K
             result = x * y;4 `& w% I( K# a2 G3 j2 D' K. i
             break;2 P4 j# `6 }! e2 s9 a
        case '/': + b: W& P3 w* V
             if (y == 0). m7 V2 p9 p2 r) n2 o" i
             {( o- _9 w8 _; h
                printf("Divided by zero!\n");4 D# j: t& I" J: s
                return 0;) L6 v$ n, }  m
             }( {; T' `4 n, c9 a! U2 d
             else
6 ?- M& w$ K: H+ {+ P- M: K: Y2 j             {7 g4 q8 V1 [' `) Z  j& J( Y
                 result = x / y;
4 k: r) }; n$ }. s: P* E  d' o$ s                 break;
7 [1 s# l) _7 F2 t             }" }9 w  r6 A0 Y1 Q5 R0 ^9 U; r
       default:
' v$ f& Q3 C7 |4 U$ C             printf("Bad Input.\n");
$ b& t, i) A2 f. l+ c5 S% t* q             return 0;
: h) J& D9 _. B) A5 q- e1 o5 |: F    }
' [5 \, U% [+ A, F0 p    return result;
; z% {, V" T4 L( r0 O- I  m}   
/ q' ?; k8 j3 z% w' o
! r- M! z; w$ g9 |3 {# L& o+ B5 x$ ffloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8 j7 y* t, U) I( |1 z- X{
# @. ~; p' @, c$ X" ?# U" V$ `    Stack optr,opnd;
/ d2 K; F) \# t) b0 S, E    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
  c3 }. O( c) ]8 e2 x9 z# j    char c;
5 v$ C# ~$ {+ }    char buf[16];
' |8 b- L2 \7 O, B1 {5 |+ J( ^  r    int i=0;8 J2 _# N$ s* v6 j& f; ^4 W
      p8 f% h! k8 C4 g& {  {" k3 d- G9 P
    InitStack(optr); /*用于寄存运算符*/
8 Y+ K5 _6 c; `! m& R. u8 r. i    InitStack(opnd); /*用于寄存操作数和计算结果*/  P! [3 e" T, J! F1 Y  b% M- Z6 d
    memset(buf,0,sizeof(buf));- T3 H- m2 ~! p2 b4 i7 K
    & d$ n! I3 @5 E: t) C2 N
    printf("Enter your expression:");
# M/ g/ |  ~2 a8 z7 a8 Q  q3 ~3 _1 h        
2 i  l( ~: A4 o: S% H    opr_in.ch='#';7 L( [4 L  I/ R" m- E
    Push(optr,opr_in); /*'#'入栈*/, N# @; ?( L$ T8 m- A
    GetTop(optr,opr_top);  F5 [' ^" l3 D# I
    c=getchar();  y  k6 @: ]$ w1 `1 D
    while(c!='='||opr_top.ch!='#')
8 F1 N; K1 \. e8 c. [    {
0 B0 i' u# x) M8 d4 E- s2 x        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
% p* j2 z8 y4 U        {& u: a6 ^, e; ]' j1 ?
            buf=c;" L" y& W# H$ ]; W! M; W. {7 q' Y: _
            i++;7 w  d* W8 a" e+ ?. U0 d
            c=getchar();
8 M& N" ~8 u4 U' u! i% `        }- b/ v. k! F2 I
        else /*是运算符*/
' O( r2 I1 r# x' i$ `6 b4 j        {
; m3 h5 n4 T8 z" i) ^" b. }            buf='\0';
- \3 m. r3 z5 P7 A* O- J! l& o            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
1 X/ `4 G- K7 g# M. w            {' p8 s6 X( d* L0 g7 h9 o& v  `! v
                 opn_in.data=(float)atof(buf);
' u9 _* g4 \8 U7 d                 Push(opnd,opn_in);
- g# g$ t5 ]# H; I                 printf("opnd入栈:[%f]\n",opn_in.data);2 d1 c- z5 S7 c4 F! u+ R
                 i=0;
' \. Q( u0 h; C6 i( l                 memset(buf,0,sizeof(buf));, w1 X) O1 W8 H7 `- a" P+ a
            }
4 t7 W" x- e! j0 m$ L" N            opr_in.ch=c;
0 b! P  F7 l2 U- O! ~: g            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
" s/ }3 U( w  _            {: A) G8 F9 t6 t3 `
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
  X3 ?: v+ P# r7 ^: g) x                     Push(optr,opr_in);
0 n" o/ \" P' Y1 S' k                     printf("optr入栈:[%c]\n",opr_in.ch);
# n7 s5 W. x$ i                     c=getchar();2 y2 L5 p( D3 T7 c6 c$ d
                     break;: x3 L# ?* A! ^3 n5 T4 v9 }! {
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
, p% W) X4 _+ G# `                     Pop(optr,e);% e2 P, z* l7 {1 N& D
                     printf("optr出栈:去掉括号\n");% y$ r7 G2 x: d& L8 f( X( I
                     c=getchar();5 P4 o4 j9 P/ m5 G' B7 e9 a
                     break;
  ]5 t0 P7 V' f4 i5 c' ~                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
2 u0 e  }7 L0 N) k/ a4 M7 I. p                     Pop(optr,opr_t);
( v2 X( V- }: \* ^6 ^9 V" P/ [                     printf("optr出栈:[%c]\n",opr_t.ch);; T) @. y1 X: C7 K& O
                     if(Pop(opnd,b)<0)6 q% i, S. `& s" I& Y9 w% u
                     {& S# [1 {* N9 ]4 R" U3 C
                         printf("Bad Input!\n");
( I' A3 `2 M0 B, e( `                         fflush(stdin);5 I$ Q: z5 E" R) W# g) A
                         return -1;. R3 _) x0 l6 L. @' r. c
                     }
& C+ d9 g& h3 E6 S+ |) N! r0 g9 b                     printf("opnd出栈:[%f]\n",b.data);
) H, S" K  X  S1 o0 k- I6 L                     if(Pop(opnd,a)<0): v  K& Q2 [$ k! U* g
                     {
+ Q6 F7 ]2 K4 W+ Y4 g% @9 M                         printf("Bad Input!\n");# o: z, r: U$ |* G7 w
                         fflush(stdin);
3 r# ]; i) r, ]9 s* D! E                         return -1;. w8 ~* c( h! R. p9 D' y1 H3 h
                     }
9 O; L" [# `6 h. F! O                     printf("opnd出栈:[%f]\n",a.data);% M2 r# g: e) W: j1 s* Q
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
; F0 Y: T) U# s# s4 E3 }+ b$ |                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; h8 I; V# z( a: e                     printf("结果入栈:[%f]\n",opn_tmp.data);
: o& i  B% F+ P                     break;
1 p% v2 ^, W4 c, c) v            }& l- Q6 `! G) q0 i# Q
        }+ Y/ b8 V4 ^, G5 P1 T+ a2 w; x
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
5 x) Y: l/ l& b7 c    }  f6 J' G) p; _0 l: t
    GetTop(opnd,opn_tmp);9 [" N5 L. u* x, Z1 m+ G- k7 p$ y
    DestroyStack(optr);
3 x7 O7 s  [3 X, B! z, T    DestroyStack(opnd);  `3 O+ [. X# r' X8 o  E" |
    return opn_tmp.data;0 k. e6 N6 D: S9 f" i+ w% ~
}
( [, }1 Y+ c* m1 p$ Y$ K; r" Q! _" I
- c6 i$ E9 W. g& {! `4 g% n# Ochar *killzero(char *res,float result)
% C; }# `9 j; V  B{' E$ }. n8 z$ y3 f. p$ T' d
    int i;6 n1 {/ _  u: K6 v
. S0 E* X! T0 ?3 W& O
    sprintf(res,"%f",result);
6 s: Q+ C/ O" m: `( d; }    i=(int)strlen(res)-1;$ }( v2 m8 T/ D2 A7 ^2 w
    while(i&&res=='0')
: a* A3 m- L. I6 j    {+ a, S' v) _' r0 t, o
        res='\0';9 t3 l5 h( H! U
        i--;! }! T7 \4 c8 Q) L6 j8 ~, m
    }  p5 N2 \  i$ M7 }  C
    if(res=='.')
) X: b; B* V" g# H( h0 R. ?5 a        res='\0';
) L4 l" Y- o* `    return res;; ?1 l1 ^* |. V
}
7 O2 _$ g. p- A8 n# y; R
1 Q7 k2 d/ k$ U  C2 Sint main()* l- z, h* u/ H  t  _5 d, b- H
{
0 f" g5 e& _6 n    char ch;
" i' t5 `0 [/ \! }2 {7 R) l    char res[64];
/ o2 m8 i; Y/ q9 F    float result;) }8 _9 m( _! K1 y" j
    while(1)
: `1 h" P. T" Q2 A* C    {7 @" S% [5 P! A: F2 P
        result=compute();
" C9 {" h; B# n        printf("\nThe result is:%s\n",killzero(res,result));0 u8 }- [/ `0 i& i; u- K9 _
        printf("Do you want to continue(y/n)?:") ;
( y9 W! j# D7 A* N( x. e- g  S7 {        ch=getch();
0 S7 K3 G- g$ E4 b7 @: t1 c7 O        putchar(ch);
/ E! b* c- G; X( n+ ]) p8 U        if(ch=='n'||ch=='N')! u- K6 O1 d4 ]& N% J( t6 g
            break;) }- \" K8 f  ?6 Y  X
        else
4 l! b" E) D) e            system("cls");  V# \+ Z5 K1 K% n. I0 X
    }
& G' N' n6 a. R  A    return 0;9 A! ^" c' `- t7 d5 v% i3 E
}

/ u/ o8 p$ C2 Y1 L2 {) O
3 e7 @$ h1 M( [# x) M[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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