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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
* B0 N+ y' }8 }3 P4 U; q程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=; |* B, h) w6 T
/**************表达式计算器************/
1 P& V* q: F0 _3 f#include <stdio.h>8 h- D* ]4 B' J9 A) k( {
#include <stdlib.h>  X6 @3 C+ \4 H9 w. c4 f7 A7 T
#include <string.h>- x4 V. _! L6 q3 i5 c8 z
#include <conio.h>8 m* G: ]* I8 Y2 R+ {
#include <malloc.h>6 K; O. ~4 X" [4 g" E) r
- E6 e4 S% _/ ]  n
#define STACK_SIZE 1000 X, H% m8 ^' D  i( ^
#define APPEND_SIZE 10; d, O8 N: H8 U8 `5 u

3 s; h% F6 i  x6 f2 c9 ystruct SNode{" Z' C& s0 S" c+ N4 n, y9 g
    float data; /*存放操作数或者计算结果*/4 k2 J$ Y2 Q5 v( ^7 H
    char ch; /*存放运算符*/( Z! E7 F) W6 Y' A
};
" w3 v. ^# q' Q
' y5 ~; f- }8 i  Jstruct Stack{
) J1 N5 z0 e+ S! I. @) _$ I    SNode *top;
$ b+ _8 [/ f5 X1 K# D' Z( a4 i    SNode *base;3 H* M: h( `! i" Z" i; V0 I1 H
    int size;0 D* W! p# s' Y, \% T2 @  q# O" o
};3 f9 H1 `( p3 k4 w! P
! x2 h* U  W! t/ `
/*栈操作函数*/
& w$ s) n: S" c  E4 bint InitStack(Stack &S); /*创建栈*/$ G; Q% L0 N; R& `
int DestroyStack(Stack &S); /*销毁栈*/, q/ U+ A2 R/ z; o1 d
int ClearStack(Stack &S); /*清空栈*/( M0 N/ X: [8 ]3 F* C
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/+ G2 f- u8 L6 h0 p5 n
int Push(Stack &S,SNode e); /*将结点e压入栈*/& p$ n6 h( K+ `+ M+ G% W
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/& I. f) [$ {' \

% }' z- m  i' E2 |  t! e7 z$ V/*表达式计算器相关函数*/+ H5 v  r8 A; x. _$ h) x
char get_precede(char s,char c); /*判断运算符s和c的优先级*/8 {- f2 [2 b* [
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
3 [* l7 Z9 w. I% A( i  efloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/) i( e5 d7 D, R) {0 \* S, r
float compute(); /*表达式结算器主函数*/5 ~# M& F6 v7 X2 ^. B1 ?
char *killzero(float result); /*去掉结果后面的0*/ " S$ v% {5 \: {) [# Y6 m
# m5 P2 B8 h& l/ _* {9 Q
int InitStack(Stack &S)
' J1 c/ z: C' `/ R$ e/ e% f5 f{6 u9 k6 q1 P2 N" D3 X, l1 z9 G+ y% N
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));1 U  a3 K! _% ]$ C
    if(S.base==NULL)
' d( D7 ~9 [. j/ [' B- U) `    {7 N, U# K2 x; @/ v6 ~1 H
        printf("动态分配内存失败!");+ y& U& o8 o; |, A) U( D9 n
        return -1;
5 A9 I( i3 a; F: O    }! m' e" g% e7 \$ q, ?  k( W
    S.top=S.base;
. e0 D* e; G1 {& z    S.size=STACK_SIZE;
0 t  d+ J& G) P' a' V, E    return 0;
& x5 ]' e1 P/ a- q  L, s( U}" ?0 b" I$ |" d. C
. M/ c& w; i9 P1 H
int DestroyStack(Stack &S)
9 \) S; O' `: C4 b{
8 W9 U! V6 R3 Q4 W) t. A, c+ V0 Y' H    free(S.base);. d0 @: i! X. z0 t  g
    return 0;% u( g- n7 t, {0 R* H
}' H4 h, [" B$ j
* z9 P4 ]! W+ G# L, i  H
int ClearStack(Stack &S)+ s" b: V  \* T% M% d
{
/ @) u/ `3 s( G; o8 ^3 ^    S.top=S.base;
9 U8 {( O, n# m9 v* x! Y+ O2 S    return 0;, E6 B& c- ?( ^& e# Z2 x
}
8 _0 i  [0 S( c
, C5 L9 s' s# T% |: X+ M+ |int GetTop(Stack S,SNode &e)- V% |" j5 s8 Y2 Q- x
{' O6 g+ L; y5 b( q& ^+ R  ?9 M
    if(S.top==S.base)
. l0 @2 S- y, }% X$ ~7 c    {. i& B& F. {4 z1 b% A0 T
        printf("栈以为空!");
( h% _' i/ A: S6 T& x        return -1;
3 p; }: k/ e( {& ^" h    }
; `" d" t1 c: i9 v4 O+ }9 C    e=*(S.top-1);5 D7 J0 e2 y0 ~/ ~- e
    return 0;
3 x$ y) Z' {" U$ J; F5 Z/ A}
  {5 c& i% I& O2 g
) ~% o. ~' t, n4 P* J9 d1 G( qint Push(Stack &S,SNode e)
" e4 ?' i# S# G; H0 o6 [{
# i0 z0 _' W( z) k! }1 I! i    if(S.top-S.base>=S.size)
1 q( w4 N0 J3 J    {! X2 `3 y1 {( r! @8 [; r& q# }
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));# e0 y1 q/ P2 _- f
        if(S.base==NULL). n; k: F- v7 ~
        {
2 b5 O7 w2 ~8 ]5 t% ~2 r0 H            printf("动态分配内存失败!");0 G& @2 b' Q# @7 \! ^
            return -1;
! D3 ^3 N: j. a. i3 s5 f        }
- I) E1 \, x: Y" J4 x; y        S.top=S.base+S.size;: t7 U, g- I" _2 c- S" \
        S.size+=APPEND_SIZE;, C; L  G, P& S1 }/ D
    }6 ^9 [7 x' x# }0 J  W1 a3 w
    *S.top=e;
6 X/ k3 r1 ]' I+ R% J! x' i" P    S.top++;) l" N3 s; P; K6 J5 ]3 _/ b5 `
    return 0;: `1 V/ Y, X6 |0 z
}* q. R' T+ W' u6 Z& d
! ?6 u2 @, @6 R# u( l8 B5 d2 O: s
int Pop(Stack &S,SNode &e)
' \5 ?' R) v" a: s{8 n8 U( a, B/ g  j$ B! J; ^8 c  r
    if(S.top==S.base)
" ~( g7 C. N5 k1 n+ T    {9 ^2 C4 k& J! p# I  s# v
        printf("栈为空!");5 A% n  f, K- R; [# F: s) y0 ?# |
        return -1;
9 K1 X* Z- d' E$ H    }% H2 O; {, C4 F9 i8 a! [
    e=*(S.top-1);$ V, ~1 d! m' v0 B
    S.top--;. \9 _$ {% A- t. ?8 r
    return 0;
. p" F$ h# w* Q9 Y+ n3 d9 E: Q}. ^" \: c9 u9 T) I% L. X+ v7 g1 ?

1 s4 z1 i' a( p2 h) kchar get_precede(char s,char c)
5 N& H( s, V5 I. T+ c/ C* p' N{
) t( g. W* @. C. Z" K9 N    switch(s)
2 t3 ^6 T2 t2 P    {3 Y( n4 I4 e4 p5 ~9 g
        case '+':                 ' L1 t: }; e/ [1 m1 B: F0 q
        case '-':- O- v' Q3 F3 S
             if(c=='+'||c=='-')8 X7 H- o0 n; `, L: j
                 return '>';: j6 m. v& G8 ^6 o
             else if(c=='*'||c=='/')6 E. B; g- S6 H  ~3 u8 W
                 return '<';! U& t6 f! {+ k8 j/ J+ t& v) ?. G
             else if(c=='(')) c: k+ a9 I& d! O) I+ F8 g
                 return '<';2 [" v* ?1 \# [- E" o, e, _3 O
             else if(c==')')
+ i7 W9 ^  y5 i" {! n$ f, C                 return '>';
; D4 L7 W2 Q$ |3 `/ l! Q4 a0 L9 \2 o             else + J3 Z' E9 V& {
                 return '>';; |; s" z  v5 k  [9 z4 F& B
        case '*':5 s  Q/ `) B0 x: f4 n
        case '/':
/ f+ W) f: M; |: p             if(c=='+'||c=='-')
: J0 z, f* L4 P' F! {/ y                 return '>';
% V3 X' ~1 M2 H5 {" b& @) {             else if(c=='*'||c=='/')5 j/ ~  |0 `9 j% a
                 return '>';
' F1 S; E9 Z5 S, A( S             else if(c=='(')
* B4 v2 J* g2 j! v9 V- q                 return '<';' ]9 a' M4 s- I" `7 l2 n; x
             else if(c==')')
, B! v( `+ y$ V# P% `/ Q  e1 _# c                 return '>';
% ~; p+ Z/ t1 E  h% W' o9 X) S9 _             else4 _' P( T& x8 H. m
                 return '>';
" S- U1 Y4 ]2 Y. U, M' K        case '(':3 X6 t4 o0 i: l- V1 Y0 l; ~
             if(c=='+'||c=='-')
) d# m) h: J; m0 R, D                 return '<';0 g: e9 m" H! M  a
             else if(c=='*'||c=='/')
9 w2 q4 x, j" A& R$ P) v                 return '<';
/ J& F/ {  M5 p* Y& }             else if(c=='(')4 j) J8 _3 B' a% m
                 return '<';
& @* U& V7 \( C# ~3 r% ^             else if(c==')')+ d5 q1 W7 p' o; r; U
                 return '=';
; |2 H+ L0 v. `- h4 r% H8 h             else
" q; x4 ~, q8 b+ n$ U& q                 return 'E';) c. j9 p/ ?& y5 H) _- ?" v& H
        case ')':
6 Y' ^" f  X9 `7 k             if(c=='+'||c=='-')& T  S/ d( I) o$ w; q
                 return '>';
/ b+ }1 v) B1 |             else if(c=='*'||c=='/')0 m# f5 c# C7 @+ Q& p6 G
                 return '>';9 o9 m. B2 p" ^, G0 U9 f9 P
             else if(c=='(')- k$ v' s( g: c4 i; c9 h
                 return 'E';6 M( M7 z0 k% k8 ]
             else if(c==')')# c6 u- i" l6 T" \4 T7 l
                 return '>';, C* Z8 c5 K9 B3 W
             else/ O- n% A- H, I, u; U
                 return '>';9 `- ^1 R' C/ }* q% a- Y; t5 h5 J
        case '#':9 r- H* w# G9 O6 N  m$ v2 _, W; G
             if(c=='+'||c=='-')
9 i) ]9 z" q! M: ^/ e6 v+ s                 return '<';5 B! n& l! Q( y
             else if(c=='*'||c=='/')
3 L6 C$ r# J: D  L1 N                 return '<';# m" `0 \; I2 l6 p) s4 J
             else if(c=='(')
1 W" g& _6 y( i0 ]  i1 a                 return '<';8 Y8 D2 I9 F0 i; X# ^8 }; O1 ^
             else if(c==')')  W- G& X5 s1 p# y7 S) B
                 return 'E';2 k+ q5 @2 m' u" ]/ j- b. d
             else5 L- T8 g! A5 L: I* r
                 return '=';
9 o9 Z: E5 r) P1 _! T0 D        default:$ L& J. r  |* }1 V2 ?" G
             break;/ k1 q' G1 y! w
    }
/ g& N! R( c7 {. @& H  y    return 0;   
8 Z2 _6 v4 a" a8 o0 i/ G}0 s! \+ Y* Q; M  ?# u

3 x9 z" o% G4 c( R: hint isOpr(char c)
  n  P' e+ x- W' V) l8 r{
8 s4 w* N3 h* c9 w4 k  U    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')6 \7 W# h: G: }4 j/ j
        return 0;  J; v( M$ B4 `
    else
+ I9 \% T6 K4 ]! m        return 1;6 G/ e2 B/ @9 r4 w/ b6 `8 N5 U! R
}
9 d) F3 t+ e3 |& J( E6 u  C) Q
float operate(float x, char opr, float y)
/ E+ |- `& O' I3 g1 I{4 u# ]. A/ U$ m3 b
    float result;
+ C8 w6 q! w9 t; q; I    switch (opr)
) i0 d- H; v+ ?. {3 M; w! L    {& {4 h7 M; l7 E( P7 }- s
        case '+':
) I* l9 ?3 C; O9 L! i, Z! b             result = x + y;
* ^/ a! D) a5 h5 D5 g6 c) `3 n             break;
8 V# h5 n+ w9 ~        case '-': & U9 O4 T/ P/ d! F8 e
             result = x - y;
! Q" d# e2 W7 ~3 `* c             break;% t5 c  ^) `! h' B
        case '*': ' T/ R; [3 f' \4 q4 y. N
             result = x * y;  l1 Z. g8 [6 i6 i
             break;6 f) G+ @7 m  j, Y. R
        case '/': 0 N( x" M0 A6 Y; @# B$ c' _7 C
             if (y == 0)
  Y1 Z: H# V& A" B             {
3 A* B; Y; u* j, G                printf("Divided by zero!\n");
7 ?- N; E& u( @6 q# ?3 G                return 0;
+ }( d5 i4 t& f+ r7 ~7 s             }
: x1 m! s$ E: _             else; C# H+ f6 a" \0 T* z! u7 M
             {7 f8 {, i  e8 C  C/ v3 Y& C! v
                 result = x / y;4 Y- t& y( ]3 O' P  t
                 break;
2 {3 M9 e: v" m$ u9 n( O5 B             }; z. Y6 A3 |% I% }
       default: # _4 E2 [8 R& \5 ~
             printf("Bad Input.\n"); ' ]: K# Q6 A, {; s
             return 0;4 z1 b/ `; I  W" H# `' T
    }% o" G; R& i& W0 R& h
    return result;
/ g1 V3 N3 {0 l3 q}   
8 g, ^) l/ y9 `" ^4 I$ A* c4 j3 c8 ~3 T* D( s3 h
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/( @  t9 ~  j3 T2 H3 h4 P! O
{
2 }0 J/ x% T* O( z- y    Stack optr,opnd;  R1 y7 [1 |0 M% j1 s" r5 [
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;- H, w- h4 ~0 m" N/ S# C' S# H( k2 C6 E
    char c;
) `1 N4 w- X  Y* Q    char buf[16];0 n& r2 l1 e0 G3 u. t9 S) F8 W3 K) l
    int i=0;. s( d/ J# a5 b5 ~# ?& ~2 \
   
7 Q/ N5 [% E1 m5 N( W    InitStack(optr); /*用于寄存运算符*/
, s) s. {( A1 t: l5 s* @1 k    InitStack(opnd); /*用于寄存操作数和计算结果*/
2 x" g' Q& {, G, u    memset(buf,0,sizeof(buf));
" W. X' C2 A) A- [   
8 @4 {* U" m% z; Q7 @& T    printf("Enter your expression:");
1 A' F7 `! Y# h9 P! p5 A2 X- N        ; ?; I" N/ f" b. Z; B( _) a5 `0 o# n
    opr_in.ch='#';
4 g* w1 a6 K$ V% R8 q- N    Push(optr,opr_in); /*'#'入栈*/6 ?  w- V$ O6 j4 F
    GetTop(optr,opr_top);
' j2 I2 U& Q, d& a2 w3 {7 e* F    c=getchar();
. X" d2 {( ^9 `3 N    while(c!='='||opr_top.ch!='#'). N3 a" q' n" ~7 U1 E2 b, r
    {. G- @: p  @, t% X$ j, I2 _
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/. t3 V  F! \* S0 x/ s" v
        {) r/ \# V/ g! U" F5 ]
            buf=c;* H  u0 n, ~- F4 U. @0 x
            i++;
6 |3 l3 ^- l9 O3 |) T            c=getchar();9 ]) o* Z5 N1 D" B6 C- G0 R
        }
8 s& S% x& O2 R, b, T  o+ m% v        else /*是运算符*/, d% ?; A& ]% [5 l/ K5 o; }$ I
        {: h* e6 b" H) u- P: u4 l, v
            buf='\0';2 O2 k6 v# ^$ e+ m
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
5 S% j: ]" `  R- e& h2 v2 X3 Z2 |            {' U3 S+ O1 g% @8 Z- j$ p
                 opn_in.data=(float)atof(buf);
+ }) V# r; Y8 @- v  E/ c                 Push(opnd,opn_in);
+ h5 e3 l3 E+ [( D& W, A                 printf("opnd入栈:[%f]\n",opn_in.data);
1 W6 j5 N+ f' v) z6 U2 h- l                 i=0;
, {$ D3 b# C7 P8 F; L$ {/ j  _                 memset(buf,0,sizeof(buf));" J% @6 R5 C# k! W& U
            }4 y  r9 R/ B6 v8 G( U
            opr_in.ch=c;
) }; `+ |* X- M/ H! S0 s0 @2 Y            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/( X' _! v3 I8 e, H
            {
/ D5 s# n: I! T- @9 x, ], E                case '<': /*优先级小于栈顶结点,则运算符入栈*/% g  T* i3 x' ?0 K) z; d
                     Push(optr,opr_in);' T: O6 Q$ U+ b3 x. f" Z, c& o: S; e
                     printf("optr入栈:[%c]\n",opr_in.ch);
6 B0 E, p# Q5 N% r7 [                     c=getchar();
' H6 p& f! u5 j8 u: n! c                     break;
& }! ~% m( }1 t! o4 ^; A! G% g                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/5 J$ |4 m! D+ ?% t6 J4 \9 E5 Z) {
                     Pop(optr,e);
3 O$ _7 a/ u5 x7 n                     printf("optr出栈:去掉括号\n");
4 [0 x# D3 v  m3 F& m3 o$ a                     c=getchar();
/ U( f0 K# K7 Q- o                     break;# r# Y; s4 s* U: F' t( S
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*// z" r( j, ~1 m; O" t
                     Pop(optr,opr_t);
2 ~' R2 G9 j& O0 W- o  C6 K                     printf("optr出栈:[%c]\n",opr_t.ch);
6 L/ R4 J0 o  `9 I                     if(Pop(opnd,b)<0)
1 y# }( M- a/ D8 G: M                     {2 s+ e" c2 i6 O- T  m
                         printf("Bad Input!\n");1 @, _  S- `% u
                         fflush(stdin);- E& J0 a+ E! C7 @7 x, L
                         return -1;( a% G1 Q0 C7 b! x
                     }
' d0 q) `* N4 L9 C$ B6 l9 c                     printf("opnd出栈:[%f]\n",b.data);$ m* k6 r. e8 u% J+ f' J. h  Q7 e
                     if(Pop(opnd,a)<0), ?- x% |3 E1 m" j& t+ N# ^% l
                     {6 W2 S7 x) @1 a( ~/ e; W
                         printf("Bad Input!\n");
5 A6 {& V2 ?, ]$ y$ s1 B4 S                         fflush(stdin);
; }, c7 v0 L  o! |! y                         return -1;1 m) m# C* f: s; t7 ^8 J
                     }0 N2 d! m, v7 A) y( Y  a. l6 W5 T" j& ~
                     printf("opnd出栈:[%f]\n",a.data);
' B) `9 b: U* K4 W  W                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/- T$ g! d: p2 B$ c6 z% Z3 r+ a
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
0 u2 d& U% N7 q2 V                     printf("结果入栈:[%f]\n",opn_tmp.data);) I" l0 Q6 m% M+ u, J
                     break;
) h1 w- r" v2 \1 U  e: ?            }
# Y) d& b" W. q7 C4 u% Q        }: ~: ?7 R% R& d4 V8 t- r" {
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                7 D4 F7 q" {) ?1 w& L
    }
' A1 f$ \+ R$ {$ ]  @8 S    GetTop(opnd,opn_tmp);
' f- p( ^& i( N2 A/ Q; s    DestroyStack(optr);# i' M- _  R! i1 |$ p. |3 E: S
    DestroyStack(opnd);
8 w% z/ u' w0 _    return opn_tmp.data;/ A* u) h+ p* X; y0 z
}
% c9 E, u/ c/ }, S. B4 h1 G! d
, t& h, v: w, J2 h) b& ^' r  Gchar *killzero(char *res,float result)" B/ Z9 J# t  ^% A
{4 s, X0 w5 L: z7 v9 u: h8 ^
    int i;
6 d3 a2 ]* p4 N5 t0 J' {1 L6 \
4 N- D( ~/ {& b+ b0 h1 X* i    sprintf(res,"%f",result);
5 D, n1 C6 F7 U$ J+ Y7 u    i=(int)strlen(res)-1;2 c( p0 M& i# P% v+ ^8 O
    while(i&&res=='0')
+ c% L0 u3 z6 u0 r( M$ D3 w    {/ g( W7 O8 U5 V  v) ~
        res='\0';
8 W$ ^( h$ o$ A# A        i--;
2 x8 `" q  O1 D+ ?    }* H+ b8 _* b$ p! {& g
    if(res=='.')
& H  m2 T! |" {! C8 @$ Z5 v# @4 ^! |        res='\0';/ A1 e# K2 G+ n* O
    return res;5 F# ~& y- f" X; p2 X
}( c' X5 V7 Q1 w& b$ Q9 P6 B
) o: \- V* \( e% E3 v
int main()
' Q2 _# J' R( |' r! c) z{
4 M- E3 s& g. i( o    char ch;- p$ g9 x) u$ r) O1 L' M$ S
    char res[64];
% _, X# y0 `. s% L( V    float result;
* E$ J! ~. [  E: H    while(1): @) m) T& A" N' x$ _( G
    {
, z) ^6 j# T! {" Z5 E2 l6 w4 `5 {        result=compute();
9 B" N" F7 Y; d7 E+ @( P        printf("\nThe result is:%s\n",killzero(res,result));
$ t; B6 h9 j' z' q        printf("Do you want to continue(y/n)?:") ;
/ [. }6 E9 g9 j, d1 {! J. @        ch=getch();( _# }6 b" w* c0 R' _! I
        putchar(ch);# |  r, }9 c: d* ?% F
        if(ch=='n'||ch=='N')7 M/ n. z8 e+ M: h) b% p6 U, @
            break;, |0 O# a" k& |% C0 W$ D2 g
        else
- v8 X. V8 T  t* q7 s            system("cls");
' u! B2 o) Q2 M  {  z    }; n/ b  z8 b- N3 T  C7 R8 T
    return 0;. [2 X1 x4 N! L, M3 W5 e5 n9 q
}

: h8 a4 r4 V1 M9 r! I4 @
& T$ ]; X6 D4 d1 t[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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