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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
  ]! H- K9 M! n& Q: Z: S程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=. G; D6 x, z, |" n8 \( {
/**************表达式计算器************/9 O. E5 D! m8 d! Y2 P( S
#include <stdio.h>
. H4 ^; ?4 L9 J: z5 Q#include <stdlib.h>/ u! q6 N: Z9 f! S, e6 V/ p6 {1 Z
#include <string.h>
* _" {: R" v' i, d/ [#include <conio.h>
+ N: v" G* R- D4 z  B7 A#include <malloc.h>
$ \6 H+ O" n3 l4 \& z, ]
2 |. k4 M5 H5 v7 h' N; L! l#define STACK_SIZE 100: A# B5 x$ t+ F* s1 Y
#define APPEND_SIZE 10
# Z. \. \+ d( g, k. m
7 R4 X& n1 I; {1 [, t+ N: {struct SNode{
/ x2 o) B, H3 p1 e+ J% X. i/ m    float data; /*存放操作数或者计算结果*/
& `* i- b0 J# @/ }' o    char ch; /*存放运算符*/0 N9 y+ X* M" M$ r! F% t( @+ Z0 A
};" I: R4 \! U$ V6 x! k( ~1 _1 @
1 [: A% R+ x6 n: ~- f6 _
struct Stack{
. l4 D  H! V6 H) q$ j    SNode *top;
  h) A6 w% j; j3 Y6 D    SNode *base;
) \% C. p- M4 z9 _. ?    int size;: l* }' y4 C9 t9 k
};
! q- @6 _" z& l8 s& y0 ?: k9 Z# o3 r5 ^+ ?% a4 u
/*栈操作函数*/8 z% B+ Q8 ^5 x5 X5 n2 M
int InitStack(Stack &S); /*创建栈*/
! c1 _" B6 ?; O  }, P  hint DestroyStack(Stack &S); /*销毁栈*/
9 G; g* }2 R5 w  |% Nint ClearStack(Stack &S); /*清空栈*/
. s7 z8 P$ j1 C2 m% I  cint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
/ n$ F$ k4 t+ d' Eint Push(Stack &S,SNode e); /*将结点e压入栈*/# b' T0 b. |2 F- }" u
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
+ H( _/ u! d. c! A& O& P4 p+ B4 {+ m2 q
/*表达式计算器相关函数*/
  U# k# q/ n, E6 z5 Q/ bchar get_precede(char s,char c); /*判断运算符s和c的优先级*/: ^0 W  w* q& P4 p7 p0 b
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
% p: ?* H6 N/ _" _6 q" _float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
. v+ [7 e1 ?2 hfloat compute(); /*表达式结算器主函数*// e/ e  z8 K9 J2 ?) ?
char *killzero(float result); /*去掉结果后面的0*/
8 ~4 J9 f: w) Y. x$ I
7 }% D( K+ W$ Gint InitStack(Stack &S): S* n. d* g5 {
{
9 |3 A4 |- l" H$ r! _    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));) [# _* G) m# u1 {0 R- C5 l# n
    if(S.base==NULL)
9 J2 L( k0 b! \- ^% K+ T    {
- C) ?* z2 a  S* |        printf("动态分配内存失败!");/ S8 G  h* Q" }
        return -1;
0 L/ q; w) X( ~4 ?, j% p    }1 A* |0 M8 K/ n: p
    S.top=S.base;, \& G7 D% Q( d" k: o* j: }* Z
    S.size=STACK_SIZE;# }  b. U8 F* j8 |
    return 0;
' E4 o3 X3 }8 t- U5 T, Z# G}, d6 R/ M+ K" L; O, w6 c; I

) R  Z1 G" ]: O% `/ aint DestroyStack(Stack &S). W: U  Y% D3 x6 N; T
{# Y9 j; s) j! Z2 U% X5 J
    free(S.base);
& K7 _# m4 `% Q! H2 O3 H( B    return 0;: i, R! l# V3 ]4 h9 l+ R- t4 r3 Y  U2 n
}) ?& B, Y0 }5 Q
- u' F9 d; x' C4 m0 E0 N2 ?  M+ ~
int ClearStack(Stack &S)+ N7 ?. p' k4 H, ^3 I3 G8 n9 s
{
6 M! r; H" E' Y7 z9 q    S.top=S.base;
; T9 k/ T$ D' j& q- C    return 0;
, y- ]$ L, O6 H- c4 N# u; A$ e}
" E% U4 R' W' h4 R
& n2 P' l, W8 Hint GetTop(Stack S,SNode &e)
8 P; K' e. `7 }{/ f6 i) K4 @0 z* V* J
    if(S.top==S.base)
2 ~, U" k  r; @+ S    {
9 J4 h6 g" s% S/ M( g" Y2 q        printf("栈以为空!");8 ?: h& ^: V/ ]7 J. ]
        return -1;- M2 I8 k' l& o2 C! W+ }# F% K
    }
5 k9 ?2 f# ^- K$ x' R    e=*(S.top-1);
: z" F. d% D3 g6 y5 L5 D    return 0;. t6 V9 c! j: |  R+ n2 ]' t6 }9 f
}3 X2 Z* r  K# _; d$ i; S

2 M/ E) b8 D" o, n' _# n  Sint Push(Stack &S,SNode e)$ x0 v4 Q3 x9 D
{0 n- Q7 ?0 T$ N( r7 V/ \$ Q
    if(S.top-S.base>=S.size)
+ X$ v, \, H4 s' q. W8 A+ ]# j, g    {
- H9 ~; H1 e) e# Z+ x( v  v- m        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));% L" }# `5 r5 R4 p. U. Z  n
        if(S.base==NULL)( f# G* `8 h8 G. o* G' h
        {0 P: e2 V" e6 z5 z$ ~4 a
            printf("动态分配内存失败!");0 N9 V, ~1 n# L; ?% g
            return -1;
: i% U# ~4 j* o        }
5 E4 B8 M/ [6 x0 }- I# x7 ?: D6 r0 R$ x        S.top=S.base+S.size;/ B3 @7 [# i5 R- v. K% U1 [" ?
        S.size+=APPEND_SIZE;! H' I7 X7 a( H9 O! g
    }5 L* Q# b4 O& E: q" ]
    *S.top=e;) W' R' V: }" A2 E* A: K8 I
    S.top++;( v/ ]0 r" {! o1 C7 I' `+ B. z2 l
    return 0;( v# V2 @6 P/ }( A7 W3 I( K+ B
}
$ x2 w9 ]* Y( c- B5 h6 y
* v( w. o9 b) U$ o& r: lint Pop(Stack &S,SNode &e)7 ^8 K  J6 Q3 `
{
) v7 K. j+ u/ u2 A    if(S.top==S.base)0 H4 Q/ y) [% r# u8 \7 m5 K
    {
- ?* S- t: K# }: J( E. ?- F        printf("栈为空!");% a/ n- i: D0 y& x, }! J% L
        return -1;
: p% I2 m! y# d( x8 v  {    }( `3 d; h$ c1 z( k
    e=*(S.top-1);
; V. `$ E* m' k2 n5 z9 X9 _! L" G    S.top--;0 R6 H* S2 v( a% h
    return 0;
. G* ~' m2 Q( i}% `' ~. _: }% m. s
8 S3 @( L8 Y  s2 @
char get_precede(char s,char c)3 e/ y* N' B1 a6 G8 \0 k
{
8 b. i- u3 J" {; `( y( p    switch(s)
$ B8 E; a8 E& U# ~# [+ h    {( K) w: w# B- r9 ^7 [6 m
        case '+':                 / m3 C$ D, O" o' d" u  d. v
        case '-':
6 f( c% T$ h( y/ |8 T. y! d% i1 _             if(c=='+'||c=='-')/ Q/ N& X2 [; d" T7 m' F) _
                 return '>';
2 ]. A1 I8 X1 p  S2 M2 }7 B& ^3 ^             else if(c=='*'||c=='/')6 W3 x+ L  p; g
                 return '<';0 f) N. M% x3 D* m6 s, v6 L
             else if(c=='(')6 R  B2 I0 p. z" u: [* [
                 return '<';
* e: N$ R8 n1 v" [7 m4 g1 [" t             else if(c==')')4 ^' h, d) o+ {$ L0 }) Y4 [
                 return '>';
4 M2 V& Q, Y2 l; K             else ) p- S& O5 N2 f
                 return '>';( w5 a. u* n) @% ^" }/ {+ Q
        case '*':
$ n" {7 e+ |( G5 L- I5 _: s        case '/':
" ~+ o* {7 \: V% |$ B% E5 U             if(c=='+'||c=='-')0 R, q) F( ^8 ~4 ]
                 return '>';3 j5 q* ?  ?# m8 p) h( n# T
             else if(c=='*'||c=='/')8 R! E9 P2 V1 N4 E
                 return '>';) d% A8 b, f* u) Q+ [
             else if(c=='('): I  a2 ~. H) \$ B2 W
                 return '<';
9 `# l8 Y2 C6 L9 A             else if(c==')')
& `! J" K  ^7 Q                 return '>';
: W) k# {$ x7 [/ N* Z             else9 ~0 b7 r/ T  T5 N$ h: g! W1 b
                 return '>';3 R- r3 @6 G9 q8 \8 `; I- S# S
        case '(':
6 n" m4 R! V% x, Y( t             if(c=='+'||c=='-')& R1 h( Z8 J" I' @& ?3 j" x
                 return '<';
" ~. ]- e( x/ u' ~             else if(c=='*'||c=='/')
$ o( r+ o7 G9 u8 K. \                 return '<';  Y5 N7 I! x8 b: Z9 g
             else if(c=='(')+ z/ o0 W0 b, s
                 return '<';
+ f# [* N( m0 Q  k$ g0 u5 l! K% T: R             else if(c==')')
8 m1 W' n+ l$ u8 O                 return '=';
4 d6 R# `! j1 J+ q& F             else9 T, R/ r0 B. N
                 return 'E';
; \) |8 o  ?* v; D* U6 r        case ')':8 q4 Z$ m( M" b6 ]; Y! L" g0 r
             if(c=='+'||c=='-')5 u- D6 B4 B/ o. W
                 return '>';
( B9 S: m+ M* q* E; g             else if(c=='*'||c=='/')
0 l& {' x! L7 ?* p5 f                 return '>';4 Y( b. c: _* \  K4 g5 P7 G9 h
             else if(c=='(')% f. w* D' ]' C
                 return 'E';
0 r0 ]: I4 J, t5 g             else if(c==')')4 k& z4 a, r9 U9 m* ^6 R) k
                 return '>';! h/ @" p* r8 J- j
             else
: c6 o" N! y- Y$ G                 return '>';' ?9 T3 Z2 H: s
        case '#':
- @- A9 n) |, y2 q+ Y& X" r; m             if(c=='+'||c=='-')
, t7 p/ j7 g* h4 ]                 return '<';
8 k' ]0 C; ]: n; H3 V% f             else if(c=='*'||c=='/')$ v5 C# L+ J0 b6 y2 ^) D- [$ g
                 return '<';0 u6 Z% Z7 L2 f6 u/ f
             else if(c=='(')
2 j$ ]& E& v6 c                 return '<';! ?3 k3 A% a3 \3 K" X
             else if(c==')')
4 M: H5 t: i) E                 return 'E';6 {& |) y9 r, |1 L
             else2 R, C; G. X! K7 ^( r# g( f
                 return '=';; M; L+ G3 E- o& ~/ t) Q8 \2 m
        default:( _9 @% S9 N9 F. @# @' u
             break;1 Y" Q+ r8 `7 Q% s
    }" Y2 r% q- l8 g# U
    return 0;   
" L+ O' X" e, V}/ T2 L+ q) ]" C, c3 v- x9 \
+ ?0 b  T- g6 x; \% v6 u  U( }
int isOpr(char c)& x5 D  W) s7 o0 s' E7 M
{
5 q! i% k, v0 X+ b+ G9 Q: [2 w    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')9 c, C' [5 P  K' J8 G, a( p& S) |
        return 0;
8 }  }  A# l9 [2 b# A6 K    else ' I) Z2 Z1 A$ U9 R7 c6 u1 w
        return 1;
$ {$ I* S# G: |' J0 B}1 s2 W4 T1 j$ n% H5 h( x( x+ ?

' l# F' P) Y! g0 qfloat operate(float x, char opr, float y)4 p& B5 e( m9 {1 y
{  o$ D8 Z: j# R5 ?3 w  G
    float result;
5 k; \6 o1 @0 b# j    switch (opr)3 ?  Q, s, q: @4 b! K
    {
9 Z! P* W% J/ ?        case '+':
7 {1 n& \( @: Z7 N0 B  g! {             result = x + y;4 g- C( Q9 S. [
             break;
+ x# c* f% N" {: @  ^8 d        case '-':
, h+ S6 I) L* o             result = x - y;! T0 m, a6 y5 g" T; ~: x  S
             break;2 f- u  ^3 j7 y
        case '*': - G/ a. y; I. M0 j$ o% ~
             result = x * y;$ o- w6 a+ X$ K3 \, L$ \
             break;" ~, `& C* I+ L5 y/ N* r* V
        case '/':
' a2 L. Z% A, ~* H             if (y == 0)
. ~( k. o  `7 @, c% r- [             {- x2 t; {. B+ Y6 ?
                printf("Divided by zero!\n");, ]% A8 z0 _9 [* I2 K6 ]8 X
                return 0;
& p! n& B$ Y( X6 g" U1 E             }
2 h% R2 O. p. j. s0 M1 A$ ?  G             else' T- n( M0 E# s% u) H9 r! l) N% ]+ j
             {
% e" _1 I- }7 g( w4 j                 result = x / y;. u5 T6 i$ `) B* B) i7 a* W! s
                 break;: G5 h" _% Y% l1 h4 Q1 @5 o- v
             }0 J9 A/ ~- E1 j& C
       default:
  `3 W  l6 m5 n4 t; V             printf("Bad Input.\n"); 9 Z5 ^. k" m3 f5 g, Z2 E$ j% F
             return 0;2 Q5 E: N* s% {5 o7 o
    }! B5 P4 u8 S) F; i) v/ Q) |
    return result;$ K3 ^2 r/ y% W9 e# P, d/ E
}   
; w$ @  n! S4 o  V/ M) q) N( u% C2 L  k+ _5 A  r7 S
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
" u: i7 J$ X( L9 [7 Y8 Q8 C" U{9 O& R+ |# i* ]2 F) `
    Stack optr,opnd;
1 m) H4 [% x" V3 m    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;  F( x7 R8 q4 _( H: x9 T  v
    char c;* |' O( v% {! P" Y' h& q
    char buf[16];
$ d: N+ G, t8 m2 M* M7 x    int i=0;
# ^* @- l4 o2 K4 @* [  P    7 A+ `9 Q4 v2 M" t8 h. R4 F$ d3 t
    InitStack(optr); /*用于寄存运算符*/2 l4 V' D) D, z2 R! K' ^
    InitStack(opnd); /*用于寄存操作数和计算结果*/+ Y: Z* H, o9 o& x! Z
    memset(buf,0,sizeof(buf));; L# N/ E6 ~( {, o
   
$ a7 `1 \& A6 h% ^" O% p    printf("Enter your expression:");# a/ M, F! l4 C# h) t
        2 j/ m* l8 ]7 K/ @' v# u6 n( K
    opr_in.ch='#';  g  @( L. p/ Z6 q  }& C. ~' P* X
    Push(optr,opr_in); /*'#'入栈*/" R2 Z# ]3 d) |6 b: U( V
    GetTop(optr,opr_top);( t; y9 |3 ?$ l: y
    c=getchar();4 u9 J, m6 J# ]$ d; P' |/ r
    while(c!='='||opr_top.ch!='#'), }* c. l/ v! a
    {) d4 w. h" W8 l- J; n9 k- b: p6 @
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/* k$ B$ J+ \! S4 r
        {. u2 B$ T/ K8 W  K
            buf=c;
: x; v% d5 a0 [3 B1 t- [3 N  j            i++;
! _* [  b3 n( Y: O  E            c=getchar();
2 O( @  A5 b, _        }
& C, U2 D# E' Q3 E$ N1 j5 v' ^0 E        else /*是运算符*/7 u1 O; F; v, J/ w( d/ {! ]! ?
        {
2 n- \. l- Q& \: [! @            buf='\0';
  H6 T& I, q* j$ V- T            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
# j3 q4 }# d6 ~$ I# X5 w            {
2 t& v' M: C6 z5 E                 opn_in.data=(float)atof(buf);
. c* p# Z  y8 K                 Push(opnd,opn_in);
1 L: c: }$ D3 [$ k                 printf("opnd入栈:[%f]\n",opn_in.data);
4 p$ {+ M% x* k% t5 b) V                 i=0;% ?! t# H2 u' c' D/ u( y0 I& k( N
                 memset(buf,0,sizeof(buf));% y9 y# S- g: w; D, B) N# n7 p
            }( Y  N! \  {; s
            opr_in.ch=c;
+ {, P, Z' M. f4 ~3 o+ H+ v            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
$ A& U% K. N/ t' O' f            {
, x9 r& p5 M9 M( f, }# Q                case '<': /*优先级小于栈顶结点,则运算符入栈*/, b/ `8 Q0 C7 B" X9 r+ a
                     Push(optr,opr_in);/ o! N, j$ h  ^  I1 P
                     printf("optr入栈:[%c]\n",opr_in.ch);! t9 V: S0 n, N3 h" ], G, b
                     c=getchar();
/ g; S! Y2 Z% @; a                     break;( i& L7 g, K- D4 U; w/ L
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
! k5 z8 m1 H5 s5 ?0 f# g+ y                     Pop(optr,e);. I3 K0 d" {# ?2 d
                     printf("optr出栈:去掉括号\n");8 f9 K& y7 @) S, X
                     c=getchar();$ Z! U- h0 s+ L
                     break;, I/ f$ o! S1 }5 v: U
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/# h2 h( I: F* `
                     Pop(optr,opr_t);
' w: [0 ~* R9 N7 y4 B; u$ A& E                     printf("optr出栈:[%c]\n",opr_t.ch);
: A/ `  g! d3 _4 H3 P+ \                     if(Pop(opnd,b)<0)
# S7 k" A" l; E+ k                     {3 G5 t( p( g, v$ m8 A3 k: [/ a3 H
                         printf("Bad Input!\n");+ s# O5 s$ o+ q
                         fflush(stdin);) T$ C1 n# E3 E! S
                         return -1;
* K' q# I* w$ K5 H' b                     }# _* B4 i6 `/ f& S
                     printf("opnd出栈:[%f]\n",b.data);
3 B( p  e( K) T                     if(Pop(opnd,a)<0)
8 `+ Z' z  V. ~4 P; ^; E2 G                     {4 W) G8 _- u, j* n; u. `2 a# V, q
                         printf("Bad Input!\n");
. `/ _" @0 e$ z4 N+ S5 g( t                         fflush(stdin);! X# [) v/ [1 |- W5 y9 S+ O* A
                         return -1;! |" o, |! f+ |' j5 B9 z
                     }
, E- `& C4 J( k                     printf("opnd出栈:[%f]\n",a.data);9 }- Y. ]# L* g7 R$ j& W$ j
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 U/ t5 q  S2 h2 `; a                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/& Z/ i9 Y& _: R1 P. i
                     printf("结果入栈:[%f]\n",opn_tmp.data);
- m2 [+ b5 T5 q3 P" [2 q                     break;5 \  g! }$ T2 d! P/ a' K, t6 O
            }
0 o' u4 [+ Q* N1 v4 u. F8 C        }
( j9 D1 E" H6 ?0 u3 e8 U' G% y        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                9 \8 Q% w" b. J: G- Q) l! ^
    }/ n+ E0 H1 H  x& V2 a
    GetTop(opnd,opn_tmp);: {% a/ Z! s' N) a' O2 L
    DestroyStack(optr);
9 |9 ]. ^3 z( j% T    DestroyStack(opnd);( h# k( H' G7 r5 q
    return opn_tmp.data;# O9 R) S# Z) z7 K0 Z
}
$ I, @- B# j/ O* C% H, X! I) C( F8 g) Q& X2 G
char *killzero(char *res,float result)' k1 W  b0 K. L& a1 A  P3 Y
{# `4 `+ E; M5 `' J* d- f, X9 J8 l
    int i;
2 ^+ u7 x, ]5 y4 i# G- {  ^
. e  I( N$ T( H& q/ s. _    sprintf(res,"%f",result);
/ {3 e8 e$ U/ Y! y- G# k8 m    i=(int)strlen(res)-1;
" B0 s0 k( S* m: J2 f4 Y( b- x$ P" f! Q    while(i&&res=='0')8 ~7 z! l% x" y; S) R$ j2 `, S
    {0 ]9 ^( f# a! u  F& z9 N/ @
        res='\0';
" r* f1 ^+ o# l: f: g0 O; r        i--;
+ w' F. L  F8 J% T8 }    }  g+ d# ~" g- z& \  v2 @- a
    if(res=='.')* X1 I2 J1 u; t# [: T" H% Y
        res='\0';1 g( L8 o7 h/ o6 D; X
    return res;: O! P1 D0 s/ |
}$ G5 N: ?9 ?8 j3 N

! O; D# v/ D) Xint main()+ x' q4 M. d3 W( y$ Z. _5 Z8 `
{* @/ [, l+ d1 {; P
    char ch;( X# i' [- b2 V% O* [
    char res[64];
! i) Y9 K  l9 s5 i    float result;
! Y6 C2 F  E5 M9 ]3 }+ V9 n    while(1)% z' C; l& J0 a% U0 E8 B& @9 W5 G
    {4 x. ?2 A# n. C! i
        result=compute();
8 j& _/ ?1 K7 O% Q' O: R0 t        printf("\nThe result is:%s\n",killzero(res,result));
5 y2 @& B, c- L* B' N. y7 j. Y: z6 j: j        printf("Do you want to continue(y/n)?:") ;
. }' Y+ k* y( H. z& u1 Q        ch=getch();
4 O! S* q( K* H, a- Y        putchar(ch);/ \$ F5 D+ f) M7 ?( j" u- v
        if(ch=='n'||ch=='N')
& {2 O: W- Z+ O, Z: s3 F            break;& Y, n% `, a: v) s+ [
        else. X6 D( {0 y+ l
            system("cls");( m& g% {8 {$ @* z: |, Q% G
    }
. r  Y. Y. e0 J# L! c    return 0;  D( Q3 Z8 @# Z; X- `% V
}
3 J# y" y9 I; m3 B& g% ?+ `  {

+ i4 q" E/ z2 ]  [2 M[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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