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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.! T9 K# O2 i$ {, V: K3 o- ^0 }
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=+ g2 K$ m9 q3 Z- d
/**************表达式计算器************/
: l& e. j. ~/ J7 ?+ s2 E#include <stdio.h>
0 {; f4 B. k+ W$ y% U! Y0 M#include <stdlib.h>% F0 h6 T4 C" \3 e3 f" W: l
#include <string.h>! k+ |2 B  y/ r% x: {" n
#include <conio.h>
. x4 O) Z5 G$ o#include <malloc.h>
, k& w8 _6 l. x2 ?# G+ s- N& y2 [, ^/ v( D0 l& r! ~- [" e- L
#define STACK_SIZE 100; l1 a9 s  k" J# ]8 S1 {2 H
#define APPEND_SIZE 10& \7 q& r7 W# Q6 N
; Y6 X" h- j  K8 d. O3 w  `
struct SNode{7 x" E( W. P* G& N' G
    float data; /*存放操作数或者计算结果*/
1 z5 R1 t6 H+ z- Z% ?    char ch; /*存放运算符*/8 B" O8 H$ t! d; J0 ]
};
, v6 _$ c0 t4 {  m7 b2 G2 D2 s% J
struct Stack{
5 I+ Q! R& u& k& t( j    SNode *top;
+ m3 F' ]) K( `: A% {- \    SNode *base;$ p; V9 w, y8 p$ g0 U
    int size;
8 G+ e7 f. C# ?2 I};
. U/ D# j$ s% j) u. ?! M+ w: G# R8 H) e. W( y
/*栈操作函数*/
% v/ k1 ~" C5 T4 x4 \2 ]int InitStack(Stack &S); /*创建栈*/
% p. L4 _9 I# {: @% g! u* o! Xint DestroyStack(Stack &S); /*销毁栈*/, H- m' Z  e& t, @
int ClearStack(Stack &S); /*清空栈*/
, c# V# G/ h% u) r8 |5 pint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
. Z" v: p% J# c; [% o! {int Push(Stack &S,SNode e); /*将结点e压入栈*/
) X! Z# ]" x5 U0 l+ w, pint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/- e; u  d6 G8 Z3 L# E2 T  T
2 u7 L& p6 O+ g
/*表达式计算器相关函数*/
* W2 e+ j$ ?/ @, I  pchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
( o0 A: s1 H8 M3 v" V# _  M& Vint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
4 g; }2 e3 V( P! \$ A  h6 b: wfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/& M& s! p! p+ w! r3 E( h
float compute(); /*表达式结算器主函数*/6 X& S) S9 R4 r2 k$ V) c  j
char *killzero(float result); /*去掉结果后面的0*/
7 I, n" d6 f% r+ y6 L/ I: W0 x7 ?0 x5 n* o/ x% }/ V
int InitStack(Stack &S)
) B; R- d' p; L: z; F$ L{$ a/ P( d+ i7 Z; e% ~3 C8 T' z6 F
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
  T* Q2 R# J/ C0 P( g% V7 y; o    if(S.base==NULL)5 A+ O( @  m  f1 N1 V1 y
    {7 V1 n$ t2 g! y9 Z
        printf("动态分配内存失败!");
+ c$ n4 w6 }3 E6 ]) z( }        return -1;
3 A) `* Z6 I$ X* m' R0 w    }( _& l0 L6 ^. y, P: ~+ J, Y& L
    S.top=S.base;7 z8 }' }. a6 l8 z" E0 F
    S.size=STACK_SIZE;0 n6 O4 m$ p$ U" \5 `
    return 0;
: I: W+ {2 \# h: t% {}
' c. R3 R1 x* w5 e" W# u  f. p$ a6 V" F, @0 u; ~8 N! E" X
int DestroyStack(Stack &S)
7 M& ^) r% [1 g/ F4 z/ K$ h; y% W{8 q. G$ Z5 T3 q. ]
    free(S.base);# z! ~; q6 a+ \: O* x3 B. o
    return 0;0 O7 ]" A$ J0 {7 Y$ X! o
}
4 b. Q/ h5 E+ e$ A; U& s" u: W+ M& m
7 X. y3 V8 Q& @3 G/ Oint ClearStack(Stack &S)
$ U# Y- ~; ]/ V) f{
* i5 u3 L- H( F0 p8 _; }; S    S.top=S.base;
5 m1 X  ^* K3 r" r7 l: A. P    return 0;
7 Z$ m' B# }) ^}3 E- J. v2 f2 B3 `: R
, I8 z8 u2 V/ E. V$ i* D* r
int GetTop(Stack S,SNode &e)$ p2 z3 ~3 `# n! p, E
{
5 d* N6 h  g) ~" ^    if(S.top==S.base)6 {( k; K0 U( ^7 q8 c# g" u3 s, \: {
    {
# W" `& Q) p" L1 }; y        printf("栈以为空!");
* i4 Q/ D' G- W0 k5 Z2 V        return -1;, p3 w8 E2 @' o* |
    }9 _" T7 Z3 S/ I9 |  p" x
    e=*(S.top-1);
- U" z! M$ w( M- l  R$ R' w    return 0;2 u0 K# X$ Y: E6 t* ^
}
0 M" T# u7 m' ~# b# C3 `2 |; r
' J. C: l# I+ iint Push(Stack &S,SNode e)' J! S3 W5 @2 I5 e
{
# O; z5 G3 h* i2 q- t8 ], {+ u    if(S.top-S.base>=S.size)2 r( M& r; N- N% T
    {
8 H( a4 K' t1 `' y. j: U4 ?        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));$ D+ I! F" e' c1 S0 V% s
        if(S.base==NULL)
9 \" K9 ?& m8 i: @        {2 u1 t9 w; L' v* P# t! i# O( ~
            printf("动态分配内存失败!");5 K  w& `: a7 |- a" J/ u
            return -1;
2 K9 f( d/ W7 d* r- ~; q        }. R. o: A% M0 z, ^0 l
        S.top=S.base+S.size;
, ]+ \- M! E, T( x+ E8 o        S.size+=APPEND_SIZE;% K" Q: o+ h2 U6 _  f
    }, @  t4 ~/ b/ `1 ]0 U" s  Y
    *S.top=e;
, G- y5 V, U' W. \' v    S.top++;
( a1 I/ [+ K  A2 S    return 0;# L( T0 S, X! V# \6 x0 J/ ]
}( Z* H* M6 k; t' ~2 Q) m" Z

- Q, \" E- `+ Y+ j! q' Gint Pop(Stack &S,SNode &e)  F4 K1 [3 a3 w5 I2 g  A
{* o* s) o4 v6 v; T9 N* P6 U
    if(S.top==S.base)
) Q% D) |$ {6 M: r% Z5 _6 D    {% L' h3 |% T/ s+ m
        printf("栈为空!");  c- `( Q1 W2 S- C8 \# _9 C( F- o
        return -1;
# \6 U- j: e% g' G  H    }! Q" W* C$ B0 |6 Y4 y
    e=*(S.top-1);
# a. \: G9 z' U  d0 c7 {    S.top--;
6 n9 E6 Q- e/ _( k( _3 G    return 0;) _" {$ d' [& {2 g: B& i4 a
}
# u3 L& e0 k" g' W; ?$ E' {9 K" M# @9 G
char get_precede(char s,char c)2 {. F$ G, z# X* U" M
{- {3 j6 X# h+ ~8 d3 W) i
    switch(s)
1 `0 X3 x+ F% K: ]  @* ~9 H6 q    {& h  e/ F! E% b# p1 @6 X+ G; y  s
        case '+':                 
0 |9 W. H7 k9 m, @. X' z( O4 L        case '-':$ H0 L; f1 D1 t! m
             if(c=='+'||c=='-')
0 ^% _0 F2 M3 r. D  Y: g% L2 s                 return '>';, O, h) S* h. H: w7 A
             else if(c=='*'||c=='/'): W5 n  L" _# x0 G. ?
                 return '<';8 U. N1 B! P  a$ f2 O
             else if(c=='(')" L6 t! Z) {6 z4 _8 Y: W
                 return '<';9 d6 {- N9 U4 K& G) X1 V4 }1 k- |
             else if(c==')')
$ J+ c. I: h' O9 H2 {. g' @% a                 return '>';# w% }% y# `8 T7 v$ j0 b0 K9 p
             else
4 c* @+ O8 k1 _9 w* A: F0 r/ S  v                 return '>';
. D# h2 ~$ ?5 P' o; @" M        case '*':2 |6 [" p4 S0 K& @& W
        case '/':  y$ y6 B8 _8 W3 C$ g3 M
             if(c=='+'||c=='-')7 F; _' `0 u# h
                 return '>';
9 ]7 U5 t  B6 B0 b% G7 O             else if(c=='*'||c=='/')
! P* s2 i5 G- h                 return '>';
. }2 B, r0 E# h# |             else if(c=='(')
8 O0 j& T7 w0 B! j- z                 return '<';
# z) g5 x& j7 n$ {. l4 ~             else if(c==')')
- _5 v& m3 A2 z- R. J* n% \                 return '>';
9 \6 X5 f" T0 ^: U* G; r8 R             else
0 {2 W+ J+ V+ w; [4 ?( X  J3 [. [                 return '>';
$ T! ^1 ]% Q; P0 R' j$ h/ B1 s+ u+ c" C        case '(':) J- M5 e6 z# p; T
             if(c=='+'||c=='-'); [% C+ [$ z: F2 [3 {% d( d
                 return '<';  _6 u6 [6 w0 F- N9 F) L3 X
             else if(c=='*'||c=='/')5 ?! |$ s7 d6 `7 q! u
                 return '<';
4 S" B) |( a4 @9 s4 |! e             else if(c=='(')
0 Z! m' q6 N5 R( m7 y6 Z                 return '<';
1 ~2 _+ m' M) O9 ?: Z4 ?0 ~# [) w             else if(c==')')2 X$ F( A2 S  ^- E* f# ]3 U* D) C
                 return '=';
8 V6 @& ]  ]: O' I2 K$ w- f$ W1 I; b             else
8 G7 k( t3 p7 }) U                 return 'E';
3 K9 j- ]0 w! \        case ')':+ F. W. K' t; Q" k) M) A3 a
             if(c=='+'||c=='-')
# r# P/ p0 k' \3 Q: M                 return '>';
- E: @  b& L$ j4 {4 k             else if(c=='*'||c=='/')
4 a" G. A' @; [' \4 f& n                 return '>';' h& m: s, s/ p2 M! T
             else if(c=='(')
4 F0 J$ d: N( p3 E2 g/ l                 return 'E';: _0 i# t* S' f3 n; R
             else if(c==')')
, j: G9 E/ J. Q% {% a) t, W# K                 return '>';$ j6 R& a: R; u8 D) R
             else0 B* d3 y+ r/ ^' y! a3 Q
                 return '>';: ?+ G7 C% D+ K  q, h
        case '#':
1 |; b1 \6 B& P: m             if(c=='+'||c=='-')
  c4 v2 |6 \1 k                 return '<';  [$ P" x, s6 e; O( w. `% ~
             else if(c=='*'||c=='/')+ f8 B/ Z4 t' h/ K& q% |; d$ ]
                 return '<';* c( `- \! @( {" g, Y5 z
             else if(c=='(')
% y/ i) ~) m$ S7 }5 L                 return '<';
1 y: Q2 l/ j6 m             else if(c==')')
  Y( w+ K. m' X' i/ q! Q/ u                 return 'E';
9 G# {1 r# f0 _. r. k5 N             else/ Z$ s3 o! {  a2 X+ b: v& d
                 return '=';/ {* A/ ?% a8 ^' Q% b8 s. I6 Z$ v( v
        default:
/ r* G- j9 u, A( F* _4 `+ b             break;
8 p" U5 x# p+ |* m) H    }* G1 Z7 S+ b6 [  n4 u- ^/ I2 v3 K& S
    return 0;    , O) g+ I+ Z$ U
}' L  v6 Z* h( r. Y

! U) |; w/ W/ h) C6 H: U: Q5 {int isOpr(char c)7 h) ^3 C) j$ ~# t# M3 i
{& N5 E8 N+ }; g2 K1 T+ @
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 A  T) D; n( {3 U2 F1 A, `        return 0;
6 }! h" ?2 t6 u9 ^6 n# I    else
* z  J  r3 M2 ?/ M% ]# O        return 1;
. O2 s3 k$ h( W  \( W}  G$ M0 K" t* [. e

6 w0 E  o& k* V8 v- u, ?& U/ ffloat operate(float x, char opr, float y); X  t# \: ]/ R
{# Q1 E% W: Z/ j; V. p0 a0 c
    float result;: V! k9 o: F- R9 Y
    switch (opr)) Q) f! h0 V5 @) T- X2 n
    {
8 S! C- C6 {( g! O        case '+': 0 y( J, U: R9 u1 g, ~
             result = x + y;
4 p& k% L0 V* L" N& t             break;
6 m: {# K. Q4 Y# Y. d' d" F        case '-': # o; H2 u$ j$ F+ t7 A* y: @
             result = x - y;
3 L$ J/ W) q* E             break;9 C7 N- D' I; q7 K, c" z
        case '*':
" A8 g, o4 t0 Y' z; s0 ^             result = x * y;( B1 `1 w) f- j% v" o# \% h  e
             break;1 H0 ?% n; n! B' M2 V1 y
        case '/': - c2 F" b( K/ b7 o' w/ k
             if (y == 0)# f0 Y* P7 C4 e& Z% X" X0 T
             {
3 X4 N1 A/ A2 m$ P4 h/ s                printf("Divided by zero!\n");) U) U, U6 N% V$ q
                return 0;
8 w" m: q+ p2 `             }
9 k: G4 i# n) z! o! x  [             else5 n9 P( z5 U/ A0 g+ U+ d
             {
* v. {/ T5 A9 ^" Z                 result = x / y;
0 k/ X8 A0 m  P" @7 ^                 break;  z7 D, m+ `$ ^3 \: t3 T/ ]+ F
             }
6 c' s3 _  Q! ~; [! a       default:
+ G& a6 D1 `  d1 w4 o             printf("Bad Input.\n");   N5 `, P0 L0 ^1 u" f+ n6 U
             return 0;% L% I5 i& A7 V' z
    }+ T3 A/ G$ u, C+ W* H1 ]) @
    return result;! j% D, j) z, U# @5 Z
}   
" k8 t8 C" a4 `# X
+ y% }. C* f" @% X$ e. Zfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/$ c, c6 j5 R$ G$ B
{
2 y2 q1 G: A0 f& {* T    Stack optr,opnd;! Q/ c0 P% }4 v
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
7 |# ?1 M" S* `. Y    char c;4 l( ]! G- e- M% h
    char buf[16];
* t, Z0 V( x7 R# t+ y) J    int i=0;( A7 T% j9 ]& E! M9 _5 P
   
8 ]% P% O# T: r. j    InitStack(optr); /*用于寄存运算符*/
+ T6 r. f. ]$ D7 O    InitStack(opnd); /*用于寄存操作数和计算结果*/
8 R5 k7 w. P/ o    memset(buf,0,sizeof(buf));
" J( i$ n7 y( V5 T$ m, A$ ?& N% p    8 F; q$ y9 S& Z5 x/ M
    printf("Enter your expression:");
3 _& R, q8 }  W        
" j4 _  f0 J7 d! B* @) K( g) h3 K+ Z2 ~    opr_in.ch='#';" J8 g1 Z- ~4 B' f/ }
    Push(optr,opr_in); /*'#'入栈*/1 y7 N, ?; v$ ~8 s. R
    GetTop(optr,opr_top);5 f  W  ^! J* I3 L8 {" K- |/ M
    c=getchar();
' m3 G2 w7 W4 m' ~    while(c!='='||opr_top.ch!='#')
" G! i6 v& F$ E, c# i9 A    {
7 P4 P/ e) ]3 [4 @& y        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
7 m3 a, g; C& v( m, C  G" e2 ~  |' j        {! `4 {$ j3 n$ S' }2 q
            buf=c;
& W, V- e% |3 @3 w3 v" J* ^8 V            i++;: K$ d4 ?/ w, \. H
            c=getchar();7 C& `( e! E" O: J7 T- \0 Z
        }( i0 O4 S1 u$ L( m, a9 S% _) B1 H
        else /*是运算符*/# Z" {8 K! }  h7 ]0 W. v
        {
) I: G2 q- s6 U& a2 t' m( {            buf='\0';
) c6 R6 W. r5 W4 S4 ]! \            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/& P$ A$ H# C2 ~& Z
            {1 l& r8 M" S% M! S
                 opn_in.data=(float)atof(buf);
1 U7 w. U( b: M0 F& Y  u2 M                 Push(opnd,opn_in);
/ G, P7 n$ h3 j+ J' Y9 B8 u9 n1 G                 printf("opnd入栈:[%f]\n",opn_in.data);
3 T; i; V- {) |# s+ G/ D                 i=0;' a: B2 i  `: v7 \
                 memset(buf,0,sizeof(buf));
8 J$ D  K7 H" A5 L. g5 S            }
) c/ V! s0 B! l& S0 N5 i2 Z            opr_in.ch=c;
7 P, Y! E" H$ x# ^) G9 X/ O            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
* R- ^& v3 v1 p# r1 @; I            {
& E9 x) _% \5 ^$ R% ?& p7 m                case '<': /*优先级小于栈顶结点,则运算符入栈*/
: S! A5 @' ]& G' X6 O3 U1 W                     Push(optr,opr_in);
, c! O$ Z6 ^* R- `1 f                     printf("optr入栈:[%c]\n",opr_in.ch);+ F7 ]. c, ?% q# x8 _0 }! B* p" c
                     c=getchar();* {9 ^, r' }+ M7 v* r
                     break;
4 ^7 |2 V6 G, ~                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/1 I, n( P1 p. P
                     Pop(optr,e);. i1 y- o) X3 d0 t
                     printf("optr出栈:去掉括号\n");4 E2 i) Z) X$ }$ g' t
                     c=getchar();% w; X' E" P  ?% q8 R$ g) k! a8 q, b
                     break;6 W( a, y: F7 q+ ?7 [
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/; T. O, ~0 A* K8 F4 V
                     Pop(optr,opr_t);4 ?! T% `* c4 s9 t! _7 r
                     printf("optr出栈:[%c]\n",opr_t.ch);4 ^# ]; ]$ R  z$ j4 i+ r
                     if(Pop(opnd,b)<0)
8 Q4 S1 X3 j. O! ?2 f                     {) H9 F4 N; E; Z) M# d& l/ X- ?
                         printf("Bad Input!\n");5 V6 q. L# @0 y: Q9 f
                         fflush(stdin);1 O5 [+ Q3 D/ l- C! k% {
                         return -1;5 X9 y  R6 u* k  @
                     }  n) n0 I6 N  |
                     printf("opnd出栈:[%f]\n",b.data);5 L) s/ ]9 ]: _6 n& M' Y
                     if(Pop(opnd,a)<0), ]2 G& `& U$ b. o4 ^
                     {
. ~/ Q, b+ O% Y, P3 e                         printf("Bad Input!\n");& \5 `' ]# B1 e* {/ K# y+ c$ I2 d
                         fflush(stdin);+ R" w+ y- q1 O; t3 G3 k% Z
                         return -1;9 U* M+ ^. p+ ]
                     }
: b* @$ _+ ?; A% Q                     printf("opnd出栈:[%f]\n",a.data);
! N' S- Y# m. w' }; s                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/7 _! i- J) e- ^4 P
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/5 M" w+ K0 \- S4 L& Z7 ]& r/ j
                     printf("结果入栈:[%f]\n",opn_tmp.data);
$ [1 Q1 x7 t% K& T                     break;/ x' `$ j0 |% O7 P5 @: d9 _$ y
            }  H+ \( @. `# @6 z/ q7 M% S
        }
1 D( H0 o: o* c. h9 C6 z3 E$ ~( V        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
( L0 ?+ L4 Z5 \" J5 ~- Y    }. O0 l8 J. O  A: Q1 J! b! V
    GetTop(opnd,opn_tmp);
  ~. W4 k4 V! Y( F    DestroyStack(optr);
) @) S! ], {7 g! e/ U3 C/ t    DestroyStack(opnd);" D8 C9 u) b2 G! p0 s" |& b
    return opn_tmp.data;
- \" R" Q: m7 P5 @. B7 A}
( ^5 `8 g( Q+ _0 t( m" A2 s( O# {! f  u5 c/ K
char *killzero(char *res,float result)
* [+ i: W& Z! H" z4 ]8 j{
( R# h; @, d1 N: f$ ?    int i;
* u$ c- {+ p5 G) j' ^, W' X
* g! \( N4 q: @2 }    sprintf(res,"%f",result);
2 u7 d% @2 {) P+ |. M( N    i=(int)strlen(res)-1;
: C2 D/ f& n. Y8 b/ Y8 B. U% `    while(i&&res=='0')
# l1 {3 F* t. b7 ^    {# o* {% }: M5 n4 @: Y; b3 Q
        res='\0';
5 W9 D* O: ~3 j2 l4 r5 d: f        i--;* ?: x8 ?. ?3 i
    }; D3 Z# S' `; K" R  p4 d' v
    if(res=='.')# A* Y2 ~& Z# `( M
        res='\0';
: n: a" m" I' q" ?; o" Y! J. A    return res;! q: b2 G9 w9 G* Z8 P
}  A% o! g: _' E$ U& {  ]
5 I. s" A+ B2 }: x* w0 p0 d9 Z
int main()+ \4 ^  v/ k7 Y* A7 _+ P% X$ C
{
6 u  z* T5 N3 K) b! y    char ch;) H' `/ V1 i4 l5 O  [
    char res[64];6 C7 _% p$ }$ w( \
    float result;. G2 Q" s! C8 ]) i  Z
    while(1)
: L: e( M* Z5 Q  ^- P. w7 J# i    {
) ~: y% j0 @' Z' s& D        result=compute();6 J7 Y7 D2 @: Y$ `) W( `
        printf("\nThe result is:%s\n",killzero(res,result));
8 L4 S2 A1 j! t! y- F        printf("Do you want to continue(y/n)?:") ;$ n+ Y; R' q. |
        ch=getch();; Z# J) ?' S& H6 R* Y# E( s9 v
        putchar(ch);
) V8 o# s5 R( [" ^        if(ch=='n'||ch=='N'): t4 S; D5 ]* Q+ z. e6 c5 h/ V
            break;/ ]. j/ V0 ?. _
        else3 c- B( S  H9 n- N6 `- ]% _) q$ E9 l
            system("cls");
& |# B" i% d, C    }
7 U0 m+ `) Z8 q; w* b: B% ?9 X* W    return 0;
; g0 M2 o& P5 H& b+ ~  [}

0 H) d7 n+ w9 g# p! A, }' l( z/ ~1 n+ X# \6 K& L7 m4 x
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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