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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
- M- r8 D! I; j: f程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
9 i/ Y1 b, N% D$ d4 h/**************表达式计算器************/
! L  }, k' p4 l" a$ X4 ?4 `#include <stdio.h>
; R: P) T' |$ o" c#include <stdlib.h>
8 x- O! r* N8 M, q; _#include <string.h>) Y0 [; s8 ?; P0 y+ C
#include <conio.h>
9 ~) U$ f0 C& k. Y" H* f#include <malloc.h>- ^8 j6 V$ K# j$ n$ u
: Y, y+ p/ y8 _" @7 @" O
#define STACK_SIZE 100
* I: Y- }8 I6 i#define APPEND_SIZE 10
$ b  R' `9 {* K3 G( x
- O: t; W+ w9 V! _  s: @+ Astruct SNode{
# M. H& }& V3 @7 j    float data; /*存放操作数或者计算结果*/3 a7 @+ t& U( X2 }2 t  Y+ v! C+ P$ [
    char ch; /*存放运算符*/" o0 s: A: A- _. e% q6 y
};9 B8 X% K# l' F% e  l4 V: S( A
, e0 a, j" v& `2 m2 y6 Y4 }
struct Stack{
: ?9 _6 K0 ]) @  v3 I; K* ^, I    SNode *top;' a; D7 A+ Q' L2 u& F
    SNode *base;3 P$ V/ r' H( y2 |' e
    int size;
( t- F4 n. u! n};
. ?% \' f0 o8 X5 e1 o$ o* P* x+ C
/ g6 s; }6 M* H! g9 x' M- h/*栈操作函数*/3 ?7 O+ t2 c: z! S
int InitStack(Stack &S); /*创建栈*/8 v; O. l! _1 x' i6 [
int DestroyStack(Stack &S); /*销毁栈*/% h9 q8 x! [! `! ?7 m7 N
int ClearStack(Stack &S); /*清空栈*/
8 m! b6 f$ G2 F0 _int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 H% J/ {' v3 T: s% ]2 }int Push(Stack &S,SNode e); /*将结点e压入栈*/3 v& l' w1 e8 ], c) ~4 ^! ^" g
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2 a# ?1 {! o0 j6 ?% X: M( V' J+ z/ X# g& m( b6 n
/*表达式计算器相关函数*/% x2 q* I0 \9 G7 ]
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 H/ `. M$ R. p4 o! D4 g- a; `int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
9 k! p" \6 Z% T- xfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/0 v4 L! W0 I; L- L! z
float compute(); /*表达式结算器主函数*/9 k, y2 z; R5 o2 g3 x
char *killzero(float result); /*去掉结果后面的0*/
; s% r- e% i2 Y  H- ~! o
- Z4 q. p. l% d- Iint InitStack(Stack &S)
  O0 U. K" Y+ g' @* H{8 A6 E- Q/ q# }" r
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));" w( j& v% `/ ^/ o& I' @
    if(S.base==NULL)
( o. @% r1 U5 y% n4 l- D% X7 Z& u. i    {  o+ o/ C4 P8 c
        printf("动态分配内存失败!");. x7 @# s  h- I$ E7 W
        return -1;) u- R+ c1 F! y. F% [
    }) [% B3 W/ f$ \, R9 t$ @
    S.top=S.base;5 H3 C9 I7 `4 q" `& r- c
    S.size=STACK_SIZE;" E, Z3 Y+ d! @9 D
    return 0;" i9 _% m& P: |; M" x5 M
}
$ S5 t: h7 _7 L' N2 d5 N
; L- b+ z' I# w  J. J" rint DestroyStack(Stack &S)
* O. m9 f. T+ m( E' I{
) i! h" p& {, n: C3 U, Y    free(S.base);; X9 [) Z1 Q2 r; |: E% ?
    return 0;' {  @" {+ R2 r/ m1 B: ~
}
/ Y) H  L& P, j0 U; e4 R6 N4 L. O8 Z1 J; B# U
int ClearStack(Stack &S)
: M; u+ N# R, @8 h+ g" Y. g7 M{
' w& h) ~- E# J5 y1 K$ Q8 v1 Q    S.top=S.base;: ~6 L; E5 A# [
    return 0;6 _# Z) C, g2 s  O' D1 z4 b- w
}. H9 h3 K+ T3 [' H
" i9 t7 O5 J5 |0 d, _3 {
int GetTop(Stack S,SNode &e)
- ]; B- h5 E. d4 C{
* @& \! o4 n- y% W7 O    if(S.top==S.base)1 W4 C; `" z+ z" ~: f/ n: B; q& [
    {
5 @; r. ]8 O0 @# S: s        printf("栈以为空!");$ d# h0 a3 M/ Y8 }0 G- v0 N
        return -1;" s# N; n+ P* R% Y2 q! }  U
    }6 h, K, a' f7 r' O' z2 e; W  {
    e=*(S.top-1);
* i0 r: D2 G3 c$ H. d8 m    return 0;
0 K+ H! m0 k- P( Q2 Y7 W+ O! v}
9 I- j% `3 l' G  S3 M4 \- [4 D+ S9 i. S& J' f
int Push(Stack &S,SNode e)1 Z; J, ?* T1 \" e& ~
{5 ?- A8 x* h& s8 `
    if(S.top-S.base>=S.size)" f, ?1 U8 o2 j$ z5 f5 I1 w
    {9 ^: W: P  Y$ S& N* B
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));9 N( d+ t6 P9 P( X+ I$ M' V) N* w- K
        if(S.base==NULL)1 l/ e: Y: @1 B" }$ t3 S: N
        {
# {  f" Q) x/ ?0 Y  D8 Q9 B; E5 b            printf("动态分配内存失败!");
: E8 r1 U2 W- {* K. B+ b            return -1;
* x" D4 Z9 T/ y1 {5 g8 J        }9 F. g% u- k7 p2 @- R, ?
        S.top=S.base+S.size;0 W$ I+ P- [! L. ?1 }+ Y5 s9 V3 Z9 |
        S.size+=APPEND_SIZE;
6 }, I4 K& T, d: j& E    }
. O; f/ q9 u$ t6 `2 D# k0 ^! Y& J    *S.top=e;* R% B  j# v$ A+ e% \
    S.top++;  m# M" f! n3 a. K1 @
    return 0;
5 \0 a8 U: {1 e$ g; Z+ H% }3 D}
: }) g7 O) t7 ^: I+ T8 g" \, j  v: P- J
int Pop(Stack &S,SNode &e)
9 l$ v9 n  N0 M2 C; B{) P* W9 x/ g4 q/ w- c/ n
    if(S.top==S.base)- b6 S5 e$ K! m& c
    {
; A7 N& d% ?2 z/ X, x1 o/ a; R        printf("栈为空!");* ]1 G6 P. L% {7 }( {. W
        return -1;
" f& a# b& B  O! I    }
6 V0 H8 g5 x, f+ ]1 v    e=*(S.top-1);
7 h. ~: s. q. E: P( Q    S.top--;
% ]0 O: ~2 m# N" C/ B    return 0;
% V2 i. u! ~& b) G}4 ]+ \2 ~( ?3 s. o" M# h
. e; B7 k$ T. K5 h7 S
char get_precede(char s,char c)) z) ?& x! u7 f7 [) |3 \, c
{$ |" d1 i8 c6 j2 q
    switch(s)4 N- e& x' _6 M# r* U0 X# b
    {5 j: {! w% u+ b) Z; V( |
        case '+':                 
' L1 [- O9 c# L: W! T        case '-':- y+ P! P* Z) _5 ~9 F: j% T
             if(c=='+'||c=='-')  d' N2 {8 N4 ~$ ?
                 return '>';& z/ L" X0 G8 y1 u
             else if(c=='*'||c=='/')
# z: A* J0 u; F9 C. Z                 return '<';! ?1 T& ~2 L7 D- k1 k/ `2 F0 w
             else if(c=='(')7 A% K/ k; H' G- ?) }
                 return '<';3 l0 h" W& }2 s  A" I
             else if(c==')')
( C' s* T2 e8 y. Q2 ]                 return '>';8 E) {, Y) M8 S7 M. B
             else 9 F9 O- q4 ^7 @) `
                 return '>';
) o% v% F2 g: g+ R7 Y        case '*':/ `% Z; @* ]  }- C; Q; ?( O3 W/ ~$ U4 w
        case '/':: C& ~3 J7 b3 \( \# ~
             if(c=='+'||c=='-')
% F! Q& o" |+ A6 u. m                 return '>';
. x# {2 @( u7 i( e: {' Y9 A8 k             else if(c=='*'||c=='/')
5 e' @2 r/ }! \% U( ^' D" z                 return '>';
: V( O8 c) Q( J; Y! j1 G             else if(c=='(')" V* Q8 y3 R5 n# \) d, b2 f1 P
                 return '<';/ v  X- c/ L$ \7 U. ^
             else if(c==')')5 s" ?' `: B: h7 l
                 return '>';. Q/ b* a* v6 w/ `
             else6 D* O8 Z: [, C" o8 p; Y' Q
                 return '>';
3 ~( O/ Q( a9 u        case '(':
$ Z  I# j0 f; U3 E- p7 R5 J: X; Z             if(c=='+'||c=='-')
6 A/ n9 H# u' @7 p4 J. C& Z/ x                 return '<';3 @1 c6 m2 z* y1 P. s- `
             else if(c=='*'||c=='/')
- q9 L& v/ T, T" }) L                 return '<';
% h! M5 ~! g! @" w  a2 S             else if(c=='(')
+ G/ U/ q2 P  D! H1 ?7 c; g                 return '<';$ d3 r' _. Y! @0 E
             else if(c==')'). O2 K- X% n3 W- e
                 return '=';
9 R" X* x6 A5 y9 [             else* S6 s; l, t1 y4 i  I) d; L5 c
                 return 'E';
. ~3 J: ]+ S7 W; L6 R2 i        case ')':
1 [# @1 Y5 X( f) ^2 f: {6 p$ l             if(c=='+'||c=='-')
- j$ [3 i$ B9 F. n+ ^& G                 return '>';
4 @) W8 p8 u& a2 T             else if(c=='*'||c=='/')
4 {, A, q; E+ d                 return '>';
# x. L" I! o7 O* v             else if(c=='(')- b6 t, n& o3 y# A$ {. j; a1 k. p
                 return 'E';# l/ D/ ]* i: {) g+ w9 Q( S# M
             else if(c==')')+ U0 l% |' C9 B; X4 e/ d  v
                 return '>';! g+ {7 D& J2 {& _1 o
             else
6 t4 q/ l8 @9 V. v+ z5 E( I6 X                 return '>';  s9 v. h5 c9 a5 T6 N( `
        case '#':  N4 Q2 c  b0 R4 @( C
             if(c=='+'||c=='-')2 e' G6 N, @5 n7 X
                 return '<';
, O5 T2 ?, L& O3 J9 \             else if(c=='*'||c=='/')  q  q. B: V5 j! T: R9 {
                 return '<';
  }% b+ C/ r; [: c3 w             else if(c=='(')4 p7 v+ Z5 `2 C1 j$ o7 ?
                 return '<';
. ^9 Y1 g: F) ^( z& C5 z. x- G             else if(c==')'): I, r) }) s# Z2 _
                 return 'E';% o4 c' m8 N/ y- X  y5 m
             else
! @& I% [6 R3 V                 return '=';+ O" d( Q& r0 A3 _7 h9 g; e) b- ~
        default:3 C/ q1 H- x) g( a" N
             break;6 H/ t  {/ b* m+ s# J( v  c
    }3 h" {( Y; a4 G# S" J2 R( V
    return 0;    ( j6 J: a1 y; d, o8 I' g
}0 O- k; {% O* y& Y+ p

8 D2 O+ _; V( gint isOpr(char c)
: a* Z& u( o% q; S5 y' L{
) u1 z+ @$ E9 g/ l# P  b9 b    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
) a  t% I# g4 u1 x1 C6 H        return 0;
  f9 U1 H8 f: J8 h6 u    else
% }0 w2 i( b3 \% P( R- r2 d        return 1;8 E( e) j/ _( L% h- \
}
; m- J. Q/ o+ ?/ y
; m1 A, s! q6 A, M8 Q2 jfloat operate(float x, char opr, float y)9 d4 ?, i, w( |: y
{. q8 W/ F. h% ?" K& ~) P5 A
    float result;/ b& K  L( h  s
    switch (opr)
9 B9 J9 [4 V# D# o1 `" u5 p5 R. ]    {
7 |  X4 K; h/ {        case '+': ; Q- m$ ~& @* R3 \
             result = x + y;+ U. |9 o. w0 h  p9 W+ ~
             break;7 o& K5 R6 `: \/ }7 D& _- R
        case '-':
" Z  F7 G5 M7 t: _             result = x - y;- D) V2 l5 t! ]: R& k3 ~5 F
             break;
, r2 r7 T1 Y/ R! \) g        case '*': 4 H* J( k1 b1 n5 M4 C8 i
             result = x * y;
" x6 _: V/ v) n2 ^             break;
- m2 t" k( i  r7 X! O3 A        case '/':
: {, M1 v, `; C& ]! _& C             if (y == 0)4 p4 r* y. X$ A; ~& N# [' t
             {0 T5 c5 F; y3 y6 w: T
                printf("Divided by zero!\n");9 }- Z5 p: z$ x3 D6 u) B
                return 0;0 u5 v( q; `: S2 I* s
             }
2 C. r6 R6 _7 n& Y3 B' _: U0 C& P% u             else2 C5 o- U+ D* Q0 C4 Q# O
             {
$ W6 d) w  o- c! ]7 M0 u" r                 result = x / y;
" _5 r/ l0 [- }% s                 break;
  k4 t' i* y: H9 ~0 L4 B/ F9 h! V             }. W. d! g4 O1 s0 x9 M+ _( F
       default: & Z- H0 d/ y5 n
             printf("Bad Input.\n");
( }' Z4 N3 X; l( K  b             return 0;
2 U- q4 Y8 j+ M2 j; `    }2 T  A, X7 H# ]
    return result;
3 O# |; D3 ~0 o3 \$ z}   
4 h) ~  {1 U; s" M0 J) f' l6 k: ]
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/) i' z: S  Z' z$ {/ I! L
{
$ b4 E; w) c& O- \    Stack optr,opnd;: Q1 j: C" F2 K, J* S
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;2 P8 N5 _4 P: j( ?$ ]
    char c;0 P) w1 @: D; Y
    char buf[16];
2 H' I- g8 O) G& I1 U0 q    int i=0;% y$ C( I  e% M& ^# D1 w1 R8 p- Z" F
    / G' }; V# Y: [' t# B- h) M
    InitStack(optr); /*用于寄存运算符*/
! w% Q: ^9 i. k; \0 z    InitStack(opnd); /*用于寄存操作数和计算结果*/' m7 f: u6 i  [8 Y- J; z
    memset(buf,0,sizeof(buf));
) E7 s5 F( j6 L8 W    ; {* n! b1 X6 a$ [& A
    printf("Enter your expression:");; r9 p8 Q( O/ Y; H1 p
        . n, f$ C, C- P, X+ M4 T
    opr_in.ch='#';; N1 K4 @0 y3 n8 T% h, r
    Push(optr,opr_in); /*'#'入栈*/& L( N4 A; ]2 ]
    GetTop(optr,opr_top);1 U0 M/ ~( N5 h0 W& J
    c=getchar();
. {3 o7 @% l, |3 W! Y    while(c!='='||opr_top.ch!='#')% S! p4 G( I* V6 z/ i
    {( u1 D/ L3 U; ]8 ?* }- Q
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/! U+ R& c1 B9 J+ L7 y  E0 q
        {  W1 }: k: u5 j
            buf=c;: D. I  |' K; C
            i++;% l% _* m/ |+ a
            c=getchar();) S4 q" a1 |7 m- G! a* u1 D
        }
* E4 [# h$ E7 R  r& b9 n        else /*是运算符*/
, G$ G0 ~# }& j+ i        {
2 F5 n1 U- C1 v$ N# R            buf='\0';$ v0 E0 w( ^# T; t0 O
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/6 m7 C$ \( L$ s% u- \' f1 B; S
            {. i+ D/ T- L3 B# @: ~8 }
                 opn_in.data=(float)atof(buf);. I2 m: W; {/ H/ \
                 Push(opnd,opn_in);
# o; Y2 H$ z! `1 A) ]: b* H                 printf("opnd入栈:[%f]\n",opn_in.data);5 b$ v# z. W# U& S! R+ C/ h4 I
                 i=0;/ Z$ {) u6 v9 R4 {$ w" n7 _
                 memset(buf,0,sizeof(buf));+ i/ V: b, D& M6 v+ U
            }
: }" F9 V/ f# ~3 s, V& x            opr_in.ch=c;
7 g& _; J' j2 i/ H7 f6 H$ F1 r7 J            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
  w) A" K: }" x            {
8 M1 {6 M; H- @& C# ~                case '<': /*优先级小于栈顶结点,则运算符入栈*/
# P- l, u  W7 e4 X9 r. y( k7 J                     Push(optr,opr_in);6 d* _6 a: s) k
                     printf("optr入栈:[%c]\n",opr_in.ch);( y! F8 r; h, h5 w
                     c=getchar();
! ^6 b+ q7 M8 X                     break;
1 l# m! ]4 [% {) T4 t9 j                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
9 C, J8 O/ I3 W! ]; c. a1 _                     Pop(optr,e);
" T, m# ]: @" ^4 g                     printf("optr出栈:去掉括号\n");" W, A7 c, T5 @2 H9 m1 r) L. B  [' u
                     c=getchar();' I6 I, [; y- y8 t' p2 G3 G
                     break;
5 t& T5 ~  i, D# H' d, Z+ y3 _  j                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/. q0 A# v: ?! h! J+ Y
                     Pop(optr,opr_t);- S& d" F9 {! q
                     printf("optr出栈:[%c]\n",opr_t.ch);
2 t: x! m. {& J2 m8 p  J  s+ p                     if(Pop(opnd,b)<0): ]; N  Q& I1 @" P5 s/ o* B
                     {$ D4 M# B" t+ F; a; l. j% v
                         printf("Bad Input!\n");
4 \: L3 q* Z% H, _* U  v) c& n                         fflush(stdin);6 v/ p+ a% G" J# \/ \) U
                         return -1;
/ f) {9 ]9 |8 p# F+ O/ m9 Z                     }
/ X" c# V6 [/ D% z                     printf("opnd出栈:[%f]\n",b.data);
! p& m7 ]" @+ O# d1 x                     if(Pop(opnd,a)<0)" J# o& i0 q) U) {+ Q' Y) A! j
                     {
1 x' Y% m+ Q: h                         printf("Bad Input!\n");
7 p( U# y8 _& d6 M( p6 t                         fflush(stdin);. C) e: s! U+ G
                         return -1;3 |- j* v6 X+ m/ X/ g# J! _
                     }/ T$ e0 o4 R' o6 w2 o! o
                     printf("opnd出栈:[%f]\n",a.data);. R" \% U3 b- K# Y; h) w; P1 Q
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
2 F+ W7 n& x& V                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
' [& t9 H5 d4 h5 B                     printf("结果入栈:[%f]\n",opn_tmp.data);
, X7 _$ W, l: V5 _# t                     break;
3 `1 A  \! l- ]            }
# H$ W8 r6 C! `/ |" Y$ A        }2 M. P9 R) B/ |# |/ k" q; h  d
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
. E* o; d, {( r9 \0 `    }
) v, A3 i# R# _# ?) z5 ]    GetTop(opnd,opn_tmp);) B9 [& J  [" P  L
    DestroyStack(optr);# s# w+ U3 j+ E
    DestroyStack(opnd);
$ }" |; K& h8 a    return opn_tmp.data;& G( I; g# w# W
}
' Z  o3 ?3 z& \% \
' s! I& I& [+ ?char *killzero(char *res,float result)
% P3 t: ]0 |' P0 @$ j: D4 c{) A1 q$ B0 X( L  E5 b+ o
    int i;
) ^  x' p+ r" ^8 d
6 v& T1 D6 X3 f  u2 ]+ K    sprintf(res,"%f",result);
% S% W1 X! u% b+ f3 S    i=(int)strlen(res)-1;  j4 m. e8 H, E2 X. R) O
    while(i&&res=='0')% i2 I. X. H) H3 J# A* Y% j
    {/ m- K6 n" W3 M4 A  `- Q
        res='\0';
3 Y* ^1 R  r) ^) h: V        i--;
5 g) ^  L) a- m% o    }
$ B, t9 S* H! e& [- i/ C( }+ g    if(res=='.')
. |- W2 H3 L  ?6 H6 ^0 E        res='\0';4 O+ f' a" o7 s4 W
    return res;
# ~. d! w) @7 F6 L% y0 Y4 e}
" s( r0 v& n5 a2 |: {% M4 z1 b
' S7 O7 S" k! zint main()- j9 M9 n. }( t& @9 j1 k
{1 w: U8 |! }) H5 r5 K+ Z
    char ch;
  Y  D" R! J: o; G/ U' n    char res[64];
' l/ D" X1 H# _, q    float result;0 O( A) _2 K- r. K4 T5 ]
    while(1)# _5 ]+ L3 D2 N% W5 G& o* p, O, p  q
    {
! b& S9 v3 c% r2 P        result=compute();
! m1 w% t) F% n# R. A        printf("\nThe result is:%s\n",killzero(res,result));  J- J% ]# T" H3 }! R7 z% M
        printf("Do you want to continue(y/n)?:") ;5 r5 q3 G& J& V) W5 A2 r% g
        ch=getch();
! `1 O5 f  C9 v, w, h% B6 e        putchar(ch);9 j4 I' d5 ^5 @6 S
        if(ch=='n'||ch=='N')$ s' J. q2 x6 B( a# K8 G
            break;6 A+ c! w8 i$ ~
        else
0 X' {; h& H. b  q. F            system("cls");
/ e9 B" s" |; U; A- V( ^, B& H- @    }) [, k3 q1 W5 f8 a
    return 0;  r, f! s  S7 N7 d$ C" T
}

$ ]+ M7 g: B2 C; f$ n, Q! R* g5 C2 D5 |& D; y
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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