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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.' H3 }5 Z0 Z( }
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=9 w9 l  D) D$ f
/**************表达式计算器************/
) l' F* x8 k8 j# [3 j$ T6 I* G#include <stdio.h>
" a4 A7 u+ Z% J3 Y- ~#include <stdlib.h>- J- X2 Z" s; Z
#include <string.h>3 t1 C' ~' q9 a9 S2 a, }
#include <conio.h>
9 y0 }8 r: O  o! c4 b* D- }#include <malloc.h>
7 ]; m) x9 D% ~- g# o: r5 M* t! o: z; I* y$ j
#define STACK_SIZE 100
5 c9 u6 J$ O) }7 l# Y6 q# U7 i#define APPEND_SIZE 10
: z3 b8 m, A$ A  v9 b4 ?7 ]0 |3 d
1 U) T& L" y: h5 u* Pstruct SNode{
/ J" T/ v' R# A$ T' r. ^8 A! |    float data; /*存放操作数或者计算结果*/
* D2 I6 |7 Q! [, X# k( h    char ch; /*存放运算符*/+ j3 F; A! t' k+ e
};$ S. \  H: x( @# Y$ L
4 Z' R0 A* A( v: W7 @6 |
struct Stack{
: M- c+ r" Q! j0 t& O    SNode *top;
+ D7 U/ U( ?5 @+ ^+ F    SNode *base;- Z/ P$ v' t% q* u
    int size;0 C3 p* Q0 S* \6 K9 T' U: B2 K
};
8 j; Z! o8 ]/ e6 c7 ^% i' n6 _7 ~7 g, {" v" T
/*栈操作函数*/2 N$ l/ L: s" V  x7 m; E4 h
int InitStack(Stack &S); /*创建栈*/
% w: \- Y+ _0 r4 |, x3 k" \3 yint DestroyStack(Stack &S); /*销毁栈*/
" t3 e" @' f' q  S3 \int ClearStack(Stack &S); /*清空栈*/
9 U' d8 r4 y( bint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/! V) Z9 x7 y9 C) f' W! ]
int Push(Stack &S,SNode e); /*将结点e压入栈*/
! l6 j0 R  y/ p( W* r4 q1 uint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/8 T! E& v5 l  }
. B. h& P- P1 [2 o
/*表达式计算器相关函数*/8 `. U7 j: u$ g
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
" m" j4 |, I. ~int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
- r1 H! e+ |$ m) a1 Ffloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/9 h6 [: r' {& `+ g" i0 ]
float compute(); /*表达式结算器主函数*/
8 |$ l+ n4 I4 U1 ?) K+ kchar *killzero(float result); /*去掉结果后面的0*/ ) J+ u  V( j$ U  a$ d- m& `1 W0 ?9 a. \

- n% X. C/ p) U! B( {int InitStack(Stack &S)
. P  j! M1 H) Z, u+ L, x* r{
. ^% B9 u: p) L% r    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));: j% m/ r' @! \" D+ p" y
    if(S.base==NULL)
* {% e( a" t3 c( p4 `. }) \8 E    {
8 @* q! I1 ]+ k$ n9 U$ i" r        printf("动态分配内存失败!");
( w1 H' d9 F. V/ v1 W, [        return -1;  e. r. ~! G. k  e$ P% K
    }
3 p& v. \& S( ^+ w- M9 x  c    S.top=S.base;3 w9 Q# i+ F  k7 _0 y! s/ T8 x
    S.size=STACK_SIZE;. {: T  H* \- [# d
    return 0;
* c4 ?- A# {4 Y  |; P- E}% A9 U' F$ {% j( E1 e

; I/ i! i- n, I0 S7 g4 Kint DestroyStack(Stack &S)
& b: W1 _2 W8 A0 T9 Q1 y1 F7 X3 p{+ x( T( y9 s9 C& L
    free(S.base);
; Z8 `+ X+ X7 j, `& p& C2 x$ j    return 0;
: B; W5 z  g! B- d5 O5 w! W}, p+ r7 W3 d* `5 e

3 B: a3 r, U6 H! O& r0 O9 x. Mint ClearStack(Stack &S)8 y2 \+ ]3 b( p
{- P  G; B7 c* ^/ G. ~  ], Q
    S.top=S.base;
  ], ]- Z! k+ Q6 i/ p9 J* Q% ]5 Q    return 0;' t2 }/ s1 q0 s8 R, s$ ?
}
: k3 ~# l: @( w. Y3 K3 Q% U
- M- y+ X9 t9 q! Y5 J" ]/ Tint GetTop(Stack S,SNode &e)
4 r' E% a1 E4 Q# L) Z/ v% ]6 _{
, [  Q+ `0 k: K, }1 ^* r" Q    if(S.top==S.base)
4 F6 L; Z1 M, C6 B5 |. M1 q" m    {
* z0 ~$ i! E3 }        printf("栈以为空!");
" C$ T6 l3 L% }$ R# j4 [/ ]8 z        return -1;: ~% A  @% f. X7 P" u
    }
, c9 q5 P) v1 P5 t. x$ F    e=*(S.top-1);, n0 c  J( E6 f
    return 0;
2 w( n/ t' v* O4 i8 k1 ~2 J}9 X& K. c% C( c  t& t8 W
& V1 O, f4 b# Q2 ]2 Z' r
int Push(Stack &S,SNode e)
: y& u. k2 I! E) Y0 {' r{
5 h% C( s: t6 s. n    if(S.top-S.base>=S.size)9 Y/ |6 g7 `/ e1 I4 R( s
    {2 B9 ^& m, y# d" Q, Z
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));& W0 e' x- H  _$ P/ j- m% i! s
        if(S.base==NULL)# l; R, _( G+ x& y
        {+ f- J$ s9 m% g) X- K8 s: Y. Y
            printf("动态分配内存失败!");5 f. e# m7 O- Z3 m! c7 Z
            return -1;
3 ~/ P6 y! z& w. b, W$ K! O! v        }
7 b- b, C/ X3 H4 z        S.top=S.base+S.size;3 h6 J+ z$ K2 A; H& R
        S.size+=APPEND_SIZE;# D- T9 J7 z$ M5 V8 A9 B5 g' Y
    }
; o  O5 K9 U  F6 ~; h! T( I4 j    *S.top=e;+ d. p) S- N; |3 R7 x1 M
    S.top++;8 u8 x2 ^1 a7 F: p, f. h; v
    return 0;  ^8 W) L, n/ k! y1 r
}
. o/ o" H4 F; u
7 F1 \& y0 X9 n+ y$ N: c2 ?$ eint Pop(Stack &S,SNode &e)
8 Y0 B# Y' P1 I! T9 x{
/ B0 y: I4 f7 d# g* L' D    if(S.top==S.base)' M# W* |# ^# A( s/ w
    {5 v3 d  `! [. R; x1 u
        printf("栈为空!");% E: U2 y8 k6 p& f5 K0 k
        return -1;- `1 u. l, s. v, {! _, p3 A
    }
: Y6 P9 \. v) D8 F/ F- v- w    e=*(S.top-1);( ?/ z' Z' D' P3 F+ m! N9 Q
    S.top--;: A+ t" t+ ^+ L* D+ z' E' D1 U$ h
    return 0;
% Z# N- D7 k* F}2 ?, w" c3 ^: D2 Z$ U* V
3 `. v2 D" Z# a4 R
char get_precede(char s,char c)7 j# l+ }, f4 x0 e$ n
{
1 J) E+ E7 @4 i: i" N% I9 z7 x$ R    switch(s)- ~4 ^; u  h4 @  s
    {; Z3 e0 V9 F5 V. o2 B
        case '+':                 
3 J, M$ n, I" k( m) }        case '-':1 \" z+ C8 Z4 g, Q# b
             if(c=='+'||c=='-')9 ]( {2 M: l, q5 Z1 `
                 return '>';. F0 o6 R% M' x7 d
             else if(c=='*'||c=='/')& l4 X9 l  @3 G4 |- r) _
                 return '<';
! s; B$ g$ o* A# C2 P' u; {# w             else if(c=='(')
  `/ k6 Z. ^  {5 `* Q: P                 return '<';
" `  j% V4 z) o             else if(c==')')
; p& ?' w2 s; ?; E                 return '>';
$ v) W1 G' x. i7 m             else # ~- R7 J3 t2 W. P; S; k
                 return '>';: P# R8 o1 _8 q" o) t3 {: y+ X
        case '*':8 b; p; ?" X2 t
        case '/':- W, o+ c" N: t& E, j
             if(c=='+'||c=='-')6 L, w7 U5 {- ]
                 return '>';/ J- v7 B+ M( q( C# B
             else if(c=='*'||c=='/')$ h+ Z0 V6 d) @: q" d. T8 L, j
                 return '>';- I0 p! M) E2 {$ A# O( s
             else if(c=='(')
( P3 ]: J3 |: S( b: z/ Z- Y                 return '<';. `; c0 t( S/ E: p$ _+ A( B/ A
             else if(c==')')  z% D" G- ^+ G- Z; B  z
                 return '>';
+ S% O$ l( R$ w2 ]             else% n5 [+ s+ H8 M, G; I: V6 e
                 return '>';/ m, o% H( h7 d" B- ^( u
        case '(':
8 G) h3 D$ O' ^8 _/ h7 J: p             if(c=='+'||c=='-')* ~# X% i$ A; P
                 return '<';
: B6 `( G: ~) J             else if(c=='*'||c=='/')
& [0 P$ g2 g4 {1 m# D  p4 O                 return '<';7 }) \" _$ U7 Q
             else if(c=='(')4 J4 W& I! j  |. B, K' c1 F1 r
                 return '<';
& ?! e0 ^0 L# S) M4 O% a% `             else if(c==')')
7 R4 [0 i. V  P3 c                 return '=';
! F7 b7 x. L. |* r# F             else  P4 W" t: z3 d; E$ U
                 return 'E';
$ `4 s& y, q) v9 K3 b        case ')':
9 `, V0 r: w5 ]9 j  Q* g& T             if(c=='+'||c=='-')
7 }; n) A; x$ U! z/ e" i                 return '>';% i' C% R2 t) S( M3 ~% J4 p& Y
             else if(c=='*'||c=='/'): g  O$ x- Z' I6 ?* j* u& P* s
                 return '>';
; F# V: m6 Q+ w- a2 u             else if(c=='(')
7 ?! k* K6 e' ~  k( F                 return 'E';
$ V: i" M  E) g2 w( g2 ?6 l) }* ^             else if(c==')')
/ ^0 A" x* ]$ R# ^- y. u                 return '>';
; w0 Z; B5 @; U, O6 T9 s- ]: v             else
3 \$ n' a+ w/ X2 W. Z                 return '>';0 ?9 d. q# o( E& n
        case '#':3 r7 ]/ b0 k+ e; u% Y9 f& m: Y! ^
             if(c=='+'||c=='-')
9 w! `& Y6 A& E: U2 b' f+ T                 return '<';
, C4 Z3 E% T: Z& ?             else if(c=='*'||c=='/')
9 _2 {6 _) R$ ?% _6 M% P                 return '<';) v% |3 k% D5 i1 i" I3 N# E+ D
             else if(c=='(')
9 ?# i- A! A& Q9 K( l, M                 return '<';
+ r% _7 t9 V: j8 F             else if(c==')')
; g9 _+ l# h' ]) @9 U8 |                 return 'E';7 c. C6 ]) R1 `# V+ t# Y/ i  J+ o
             else0 Y' v8 E% r" z* j/ {) H7 B) d
                 return '=';! ^/ L# H5 p) z4 T' j. x
        default:7 q1 I0 F8 F6 W0 v
             break;
9 x6 V" c* ?8 q, z4 ?    }  F2 x2 b- r: T/ q6 q) h8 Z
    return 0;   
) @. B' S1 D% T' x% B* u}6 P4 q6 v& u+ Q' ?! [7 M: l
* z, D5 f4 o& k
int isOpr(char c)( k1 a* ]& L; o- `2 G
{$ z% g& _$ `  b% U4 v+ Z' m6 Q
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='): x  F1 @! G4 E  F
        return 0;
# ^6 m5 G8 ^  V$ f7 ~4 f! z    else
! h" g8 u- c8 \- V  j& }        return 1;" \5 ?. ]8 @9 |9 Q8 w6 H8 J
}
  ^; P$ g: u6 g9 b: f$ b
' P7 d0 S# p6 Rfloat operate(float x, char opr, float y). r8 Z6 ^, L6 D1 F6 _2 e
{
% E- a1 E, z# I3 R    float result;- l: f2 @* V( ^/ Z
    switch (opr)* a5 r' J+ V5 s% h" o/ A
    {
9 y, a6 y9 D- Q7 y9 s  l        case '+':
4 e+ J6 T/ f$ V! k1 d             result = x + y;: X% j( ?1 ~) l$ G% i
             break;
' |# `1 k; {! D! y3 L+ n1 D        case '-':
: C3 M8 R+ l6 K) V9 b  ~6 ~! x1 k- E5 H             result = x - y;# \  g  |9 O7 {% C
             break;
+ D- A& v3 R; O        case '*': 4 B8 l4 A2 E  h5 L1 `1 \* J" q
             result = x * y;' K& l7 Y2 [4 ~4 ]0 U% [. F' D
             break;4 ^& L$ E0 b1 M' ?
        case '/':
8 M6 X3 B( q& \7 i2 b             if (y == 0); P# f2 E/ w! b& z5 J
             {
: ~% m& F7 a( ^, I, p$ |                printf("Divided by zero!\n");4 e  X& ?  Z8 M* b% D0 ^3 }
                return 0;( v. i. r  ^8 N5 l" N6 H; b( O
             }: {5 J6 p7 I; @- Y, S) U
             else, V' K5 C6 M. w. R. c  ]- z
             {. \- n4 B9 `* |  g5 g4 }
                 result = x / y;
3 a9 j  e: i' t  f4 }1 G                 break;
7 d, M* a) ?6 ]" m) k$ [7 E: _& q             }( M& \5 i7 Y5 w& t4 }" T, V1 p
       default: 8 M$ m0 j2 j0 t0 J( y
             printf("Bad Input.\n"); 3 z! o. i7 d' I+ F1 `! I: j6 n
             return 0;
  Z: f5 L1 L/ Q3 e/ r    }& U7 ^" E+ f; r1 C, f
    return result;
; X9 A$ Z" Z2 X5 K9 u8 s}   
& U/ m; G- ]+ W8 A- v, L+ W# k# U9 i( d
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
. ^# E% v0 M! J# p3 v/ m( m+ E! A{
: k! [( |# E1 [    Stack optr,opnd;
4 d0 m, V) J% V    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
& i' E, s5 s3 k9 u; X' T6 p* ^% T) `    char c;
% k9 V4 M3 n0 o0 |+ M    char buf[16];
( ^$ d. G" I& A! Q    int i=0;4 S) L9 {. E' J. s6 a- V* `; m
   
! Z, l' R$ o3 q3 \6 Z9 U/ V# |    InitStack(optr); /*用于寄存运算符*/
+ F9 s- ^4 `' Q& e3 v( g    InitStack(opnd); /*用于寄存操作数和计算结果*/. s4 \! A" v, C% D
    memset(buf,0,sizeof(buf));8 K8 j& g4 ]0 N6 r# Q
   
! L+ L, s1 v) g7 e. E% L0 o( W    printf("Enter your expression:");" t* g/ V5 c8 D6 s4 o
        
- _+ w$ o3 @* O! \2 g4 J. B    opr_in.ch='#';" b" E+ |: z# a1 q' O: e
    Push(optr,opr_in); /*'#'入栈*/! G  L9 V6 }+ |2 S" b
    GetTop(optr,opr_top);
3 l. h6 n. x* I7 I0 \9 ~$ _    c=getchar();) t0 l5 o; p, z& ^) n$ m' L  ?6 S8 s2 X
    while(c!='='||opr_top.ch!='#')
6 _% ?: X) @- O& t9 _, s5 O    {
$ L3 V' ]/ ?1 I        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
) u' [" L4 }2 ^  V4 l/ E1 ^4 M        {
4 x3 l1 h. k* E6 X7 }% `            buf=c;6 N/ h& w; X# B
            i++;
1 i' W& ], B2 U; Z0 N1 w            c=getchar();
* ?# j( ?  s5 E4 m% s        }
! M! b5 G6 u4 A4 Y1 B4 q        else /*是运算符*// ]9 ^5 v1 Y- C/ Q& T8 H  H; b+ ]
        {  }1 _# w, s( ~* y: w
            buf='\0';3 Z! d; [8 D( L
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/' d! U# L+ u+ K+ {6 z7 l' c, d
            {7 a+ ?: i5 z( i& \$ J; G: {
                 opn_in.data=(float)atof(buf);
9 Y, t2 J8 E( }+ P# Z' W                 Push(opnd,opn_in);
, q3 c& E/ u% \+ G                 printf("opnd入栈:[%f]\n",opn_in.data);( u+ m1 ]: S* h/ [- {
                 i=0;
" A' T3 b# M! y                 memset(buf,0,sizeof(buf));' C* D( |" n+ g
            }4 I- i3 E, @0 ]
            opr_in.ch=c;
# U; [# U4 @3 k; g- f- |            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/0 S# A, B; V5 f" ~% Q
            {
0 g. z- X: R: @6 R                case '<': /*优先级小于栈顶结点,则运算符入栈*/
, T4 x  D# V4 }) v( g1 `0 f, t                     Push(optr,opr_in);
' b" W3 B1 o( T6 Z- h( i, J, \                     printf("optr入栈:[%c]\n",opr_in.ch);
! p2 ?0 r; m3 }& M& d. Y4 X                     c=getchar();8 ]0 `) P* _; X4 v$ O1 b. K" N
                     break;
( \, t  _5 Y2 i- s- y9 ?- }                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
- z+ e. Z, C4 V9 V( G; T                     Pop(optr,e);
. H9 b5 t' V" T. x                     printf("optr出栈:去掉括号\n");
) E- K- [4 j# G5 K% k2 @                     c=getchar();& ^; u$ c) u( g( Q, y
                     break;
( [; F+ g- n& N2 N; x# \                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
. |7 `6 k) E/ f! m" r! j1 C                     Pop(optr,opr_t);3 P% e6 Z& U( w, [
                     printf("optr出栈:[%c]\n",opr_t.ch);
  D# z% ^! x7 P6 D4 ^                     if(Pop(opnd,b)<0)
/ Q# B# E! R: s! r- R                     {# E8 f- ]6 ^1 t! r* A/ I6 Y) o
                         printf("Bad Input!\n");9 y6 M7 Z1 A1 x
                         fflush(stdin);: @, `/ X" ]5 u  o! ~6 J
                         return -1;9 ]/ n) x0 B9 [7 T8 K
                     }$ d# U. h* Y, J
                     printf("opnd出栈:[%f]\n",b.data);
3 k5 J. P' O& \  p) \/ r; l                     if(Pop(opnd,a)<0)
) x( R3 h  |# N! R                     {
  g, v: C9 i$ k3 k1 t                         printf("Bad Input!\n");  _) r/ a/ J* l
                         fflush(stdin);7 r7 p3 r" I! j3 c
                         return -1;
" G7 `+ E0 K5 M. e# l                     }
5 t7 O, B1 A4 I5 x! W' n* u; w                     printf("opnd出栈:[%f]\n",a.data);, D) O3 Q8 n( j3 Z* V1 P
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
+ i2 G( ?! M$ o  V0 n/ N                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
: F# m( V; F0 C* f8 t  G                     printf("结果入栈:[%f]\n",opn_tmp.data);  P9 y! U3 V$ C, O' z+ x+ X1 C
                     break;, f7 ]: q- i$ i% ~- [
            }
5 j. l$ V+ W$ L$ v% G        }
) L9 ~$ V$ i+ B# z) z  R3 k8 [        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ' |( Y7 R2 W. h) r" X1 C
    }; F9 R8 @/ S! |1 c( _
    GetTop(opnd,opn_tmp);
8 i6 p, A8 E0 S9 d# Y    DestroyStack(optr);" q. k9 O# B/ y& h9 d& y7 @4 ^
    DestroyStack(opnd);. L) w1 k( U+ u$ k
    return opn_tmp.data;8 C- x/ m# K8 f& A# W5 s
}' A! D# c, d* \6 `, I' F
! o6 f% x* D9 B! j
char *killzero(char *res,float result)2 y- E0 g$ a5 U2 F2 s, ]2 `
{/ ^6 L5 _/ T- R( f4 d- y
    int i;
! h0 z; h/ |0 _
' T' x4 d4 z/ S) G4 e    sprintf(res,"%f",result);
  \- Q2 b4 x1 w' I6 B* v    i=(int)strlen(res)-1;
+ ?8 h" s' X2 e: l% o    while(i&&res=='0')
  {* `- C" j& K    {
  V" p8 `/ u/ Y6 l        res='\0';
! F$ l; N  z% t; y  L9 H$ c        i--;" x3 D9 G1 ^4 \9 Y: G: K
    }
4 c. ?* F4 e$ O) U6 D% H    if(res=='.')% X6 G& A! L" e! x" G/ m
        res='\0';. N8 }* O* h4 I1 H3 E5 l
    return res;4 d# V3 q# W( ?( k7 Z! [" X: l: [
}$ U+ t. f# @2 |$ Q: M8 Z
5 [" P' l  b" n/ q- j7 d: s* Y
int main()
/ _+ w6 l8 {: c, M8 R& Q{
; f* ~: i; e9 E  h; g    char ch;
0 L$ ]* n5 n9 x! E/ t/ S# Q    char res[64];# |+ d4 b3 I* I. c, e3 @8 e/ v  @
    float result;
: R8 m0 P# T8 b4 w6 S1 g    while(1)" h& [6 M$ `. \( ^6 G! J
    {
9 ]% c* s/ _6 x/ B" i        result=compute();
; I/ h+ v/ Z) K. v        printf("\nThe result is:%s\n",killzero(res,result));- e5 h* |) p8 E) R) V2 P/ Z
        printf("Do you want to continue(y/n)?:") ;9 a4 s$ b2 Y% P9 z& _% h% ~7 A- @
        ch=getch();
8 M3 w3 D3 C8 A! ?' M0 I        putchar(ch);4 v( _7 s$ a( F8 A! O' w
        if(ch=='n'||ch=='N')
3 P7 r/ f6 e$ ^            break;8 ^7 \: q5 Z' ^' M1 W5 \& q0 `3 O
        else
. R# i+ m, [8 L" B  v) Q* @            system("cls");
4 h6 g  z7 V: r$ x    }
! R) w: X- N) @4 C, v    return 0;
# k0 m" b! A& ^7 i" P5 v. p}
5 g' L9 @. L' a- K, c% m2 H& R
2 q: }  S, s& q0 Z  W4 h
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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