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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.9 ^4 B4 @( k# O$ ?3 J3 i6 j! W
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
) Q; M+ H# }7 l; E+ d2 X  G) o% P/**************表达式计算器************/
/ b0 @) H' R9 ]- D#include <stdio.h>
; l' Y3 d. V. [# b#include <stdlib.h>2 f, n4 ~1 Q- u5 i! P- r
#include <string.h>
8 u/ {2 r7 }9 J) N$ ]#include <conio.h>
& R2 o: H. I8 u/ M; }#include <malloc.h>$ e" v1 K1 i6 Q9 f- x. Y7 h( n
. a  p+ K. E  }, ?- D0 V) p& U' `
#define STACK_SIZE 100$ s2 F( b* r8 C6 H& S/ h
#define APPEND_SIZE 108 J5 H2 A% D; \% n+ p
  U6 Z9 q( s# T$ R, T# b3 |5 h5 Q
struct SNode{5 @* ^, z, t. g7 G# l$ ?9 k
    float data; /*存放操作数或者计算结果*/
8 Z( @( w  H# `$ T0 `- ?6 N! ~    char ch; /*存放运算符*/
7 A; X# C8 w' |$ N* n' {};
& k! G  r  w6 y" g' {8 p4 d- k; n0 Q* `2 W
struct Stack{9 A( T' E; D- |# q7 O
    SNode *top;* I' B) K) H7 g6 m9 b
    SNode *base;
; z, k$ P* l. Z+ `6 P    int size;
8 z! J+ h& l# ~7 W};; {! Q! O  \: [" N5 w6 Q

" n9 u: P: B+ F- _/*栈操作函数*/$ l( b0 J) y5 p+ S
int InitStack(Stack &S); /*创建栈*/& A$ }5 U$ Z% H1 U8 K, r6 |; J
int DestroyStack(Stack &S); /*销毁栈*/
3 ?" F' w; f6 n* W$ i& m' i: Kint ClearStack(Stack &S); /*清空栈*/3 d3 D) P1 ^! _& z9 Q/ \7 o# M
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/4 C9 l# E+ f7 ?, \" `$ @' x- z
int Push(Stack &S,SNode e); /*将结点e压入栈*/
% n+ V# C% ]1 Q/ _int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*// R  P- l  ?. }: C- m

$ F- g! r# L) p; M, P; ^) c1 M, B" D) x/*表达式计算器相关函数*/. K8 h9 N: y7 t! }5 h
char get_precede(char s,char c); /*判断运算符s和c的优先级*/& F# P8 y3 D0 A( q5 @- d
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
6 ~4 f3 Z% U- I& ~& `7 w, _float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
" [6 t+ B; q5 \6 ]7 xfloat compute(); /*表达式结算器主函数*/6 a- y+ ^/ T' |, }- y
char *killzero(float result); /*去掉结果后面的0*/
2 @+ k  V* I2 A8 e
; q: X# n' t/ m- t! i0 Kint InitStack(Stack &S)" x0 A' z  @( C, x
{
! n  H7 A) X) p" k% R  E+ @+ E    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));4 }) f) l& a$ a+ ^2 U4 d4 D! Y
    if(S.base==NULL)5 r7 Q+ c" }+ X$ G. ?% }
    {
, R4 J; B) L- r, x        printf("动态分配内存失败!");/ w3 p( d! B, z# j0 A3 Q
        return -1;$ C0 ~: l$ L7 ^; y
    }
. @% Q' T7 L" Q    S.top=S.base;+ m6 W: {! z& E8 o" G
    S.size=STACK_SIZE;
; ^5 E: `6 y% ?- x& m    return 0;
+ x& A& z( J' z, t}
9 o6 J, J" \# K9 ?- h" Y) ?8 V! Z3 g! C+ [
int DestroyStack(Stack &S)8 B7 [6 s3 K6 Z. M' s" A
{
4 N8 s# X# q3 _' i, r) Z; ^    free(S.base);4 Z6 t& \' W& y8 \1 z. }% k
    return 0;
; m  z. a3 ]2 J  ?) S5 Y/ s* e}9 N* D. F* X+ A4 [7 C
& I+ g6 B; ^: h* \8 _
int ClearStack(Stack &S)
8 A7 H2 X4 |% S. U# X/ x( Q& q# I' z{2 C( N9 {) h4 G0 ~  D4 J
    S.top=S.base;
& \! @  z5 b2 m1 G- F+ p    return 0;
4 Y2 O$ z/ g7 A% Y5 P* j}7 P  [; u7 p9 a8 A3 X: h$ x
- A$ w9 u- @' I/ a) A. ^4 @; Q0 y/ G
int GetTop(Stack S,SNode &e)
5 f' K' d: A7 Z' ~! v{4 I; {; W4 b' G1 A* _- k) a
    if(S.top==S.base)
7 n1 _0 g, E2 ^" f+ U  g    {7 b) P4 X2 t9 V, O
        printf("栈以为空!");( }* Y! F  w- g
        return -1;0 y/ r4 S" R! x
    }
6 g& U, G' y& J& ^5 A/ q8 v  |    e=*(S.top-1);
, Y0 U7 P: P/ [8 u8 V- i    return 0;- w% P# d9 f' R; L6 N0 D
}
7 X+ Z( ~8 ~+ X: F# \: {* i* s
0 P8 A, e" m1 [. P! M3 mint Push(Stack &S,SNode e)
; q3 N6 ]5 k5 v# T( _9 B{+ y, ^8 H. d! G6 P- v6 {0 Z
    if(S.top-S.base>=S.size)
( Q/ g# N" f7 B/ M1 i9 K6 S4 w    {! d3 t; C/ N8 r, X
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
* K; ^9 l) Q" B+ h6 z0 |  D        if(S.base==NULL)9 g' w' J$ p- y- G
        {" E" }( A! U5 y# Y
            printf("动态分配内存失败!");
2 D3 M5 d7 Y9 {+ F" \9 q+ b7 S4 Z2 T! C            return -1;
4 m) l& N$ v* A0 W        }
" A6 x4 N9 U4 a        S.top=S.base+S.size;
' U' G- y- @8 a! E- V        S.size+=APPEND_SIZE;
7 ^3 i- m& e% S/ ]6 i    }
5 n( F# G# M% K1 M* S    *S.top=e;
. U6 J$ c6 r! {6 Q/ L2 a- w+ V9 V- y    S.top++;0 C8 W% U- v) P
    return 0;$ M# |/ l% ?" e) b* W4 `$ o
}
' U: K" ~0 n1 F" G% M9 z! z6 o
- \) Q0 O9 z+ I" t# yint Pop(Stack &S,SNode &e)
6 `; V( ?% `* M% J{
8 ?) N0 K/ i8 V7 J( D    if(S.top==S.base). D) d8 L/ ^- `
    {
- z" b3 C: O3 @8 U) J8 e        printf("栈为空!");
3 M3 s+ ?. D- G, k5 W- v        return -1;
7 Y6 B4 b  h  N" a4 a8 q% f7 `    }
/ Z- i. B8 j9 E- A# H" |    e=*(S.top-1);* \: ~; C( B# ^7 z- E& o. \2 B
    S.top--;6 r4 {/ c1 q: U& k7 m. d  a8 }
    return 0;) D8 u9 S. ^# K- z$ P3 I
}. S( c( O' m3 {# }0 z- G2 W
! a% Z3 H- U( s) y* o
char get_precede(char s,char c)
4 c; i- a" f8 n1 N{6 `8 X: t% V7 F: G
    switch(s)3 l/ s+ x0 E/ @  y% ]% V& E
    {) R" N' l) X$ D( K$ h7 s  R
        case '+':                 
- ?/ J3 p/ Y  k8 T" `5 G        case '-':
3 _1 G7 E& Y/ a( h. M# j             if(c=='+'||c=='-')
2 Q9 h) Y' j" c( E% e                 return '>';8 D1 u3 v' Q4 H3 A  k& ]: D* B" s
             else if(c=='*'||c=='/'). I9 g8 {  e; f9 u
                 return '<';
0 N6 @1 O$ v4 s$ k4 p             else if(c=='(')
7 n2 r/ o$ H# G, |% i1 U+ g: B                 return '<';
/ B% H7 g, N( w2 H. q( x             else if(c==')')5 f: a4 i! ?8 F4 L* Z+ v
                 return '>';
' {8 R+ H( Z. q; E             else 3 ~; s' m' k8 \3 A% v+ S1 P$ p
                 return '>';
9 I6 I" W: k' F2 ^: [7 y        case '*':
8 R# Z1 R3 f* V+ K        case '/':% w) p) ^" h; @. s0 G
             if(c=='+'||c=='-')* T, A9 D- R0 ]# `' C: X
                 return '>';# r% s* K5 A" a5 |/ w
             else if(c=='*'||c=='/')
; k* N. y" q' |& f, Q                 return '>';" b6 H7 c! E6 ^2 y4 ], B) e
             else if(c=='(')7 p! b% F0 o" U% O
                 return '<';
* b9 T) }: _/ M4 [# T7 |* l) c             else if(c==')')
4 c! Y+ o, ?( {( D, N                 return '>';' E4 m% {; }6 Y
             else
1 a! ~3 r' y2 G2 Y9 a+ E6 \$ }2 P                 return '>';
2 z3 j# i+ x2 |6 e        case '(':
" e; N5 S5 v/ D+ X! B& O             if(c=='+'||c=='-')$ |# V0 ^6 N6 d/ I
                 return '<';/ ]. W- L+ N7 U
             else if(c=='*'||c=='/')" y2 k* z3 S0 H, {$ ]0 W* h) `& E2 _
                 return '<';
1 |8 G3 J, m2 {$ J' E7 w             else if(c=='(')
9 v6 p& k9 z. z8 f$ A, }; C                 return '<';
) \0 n* g9 h5 D3 c7 K$ v( W* Z             else if(c==')')
8 a7 ]* J9 f2 D                 return '=';
7 o9 p, u2 \7 l" S* O# X             else$ ~, p# R3 f% w' T
                 return 'E';
+ l1 G) }: Q0 x0 L        case ')':
) P* ^5 T; r3 j' S0 A3 a             if(c=='+'||c=='-')& r; I8 `7 k5 w" r: q9 W) l4 C$ S
                 return '>';
2 Z$ `7 ?2 t$ @0 G8 I0 m             else if(c=='*'||c=='/')/ `) u. I' O! d5 Y/ C* w
                 return '>';
! e& m5 J/ S6 d2 c. V  p- _             else if(c=='(')
( s0 L! c( B$ C/ t                 return 'E';
/ Y+ f# A$ i4 j) A  H             else if(c==')')6 R* b. u# t3 K- W8 v; p" i- G/ t8 a
                 return '>';
1 w  X! C7 l% B             else
! e( Q& u4 A0 g8 S3 J/ y                 return '>';) v7 o% Y2 a2 A# f! c' j0 j
        case '#':
5 v8 a6 B4 i+ c2 A" m2 e$ \             if(c=='+'||c=='-')
  P0 I6 |, h  Y3 z                 return '<';
' V6 q- f2 I# u! Q' b. p             else if(c=='*'||c=='/')0 z& d) ^2 h# z
                 return '<';
. t: B" ~  s+ g             else if(c=='(')
- V3 @2 V% c7 j, ?( C; ?, {                 return '<';
2 V8 w% v0 ~4 ^+ M$ C+ c) Z$ N/ Q             else if(c==')')
# `( |. D% _6 v  @$ ?1 E                 return 'E';
7 s$ ^5 e# b( s, P, ?2 p             else5 h/ D% I% w0 ?* a1 r* h9 O
                 return '=';5 V  C8 L) {6 n. E8 z
        default:
5 p: U7 h& Q* s             break;
9 h) m  j/ F7 u) V; a    }
  A  W/ C  F/ X    return 0;   
' D6 k$ V; \) w! O$ I}) Q" k* P! K7 Y9 ?" H$ D

, k7 i( j' Q# p; L9 Q1 _' _8 Vint isOpr(char c)0 y, F/ j5 B# s0 e! q! H) y7 Q+ z, i
{2 B6 a: Q7 H' m3 W
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
# Z% X& Q$ H% a6 a' n        return 0;
7 S+ r3 a4 h' x. M6 j! c8 j1 o$ ]2 V    else
5 k) C) k  C+ Z        return 1;) q( e7 ?/ s/ T
}& ~; q1 d# B% K
  w. }* y/ j  z& J6 o
float operate(float x, char opr, float y)
% D7 L& E: W* B: }{
; `+ j, ^+ \+ c7 a8 k& k; f, z    float result;
; I! y* Q9 H( Q- K. m    switch (opr)
/ c/ ?# c# b4 k/ K1 \    {
, R6 o$ }, W5 c* ~& C# Q        case '+':
9 C9 y) g# M5 T5 N3 V$ [; {             result = x + y;
% F4 B# B, R% S             break;
( V7 r5 j* _+ `8 F6 Y, I5 Z        case '-': + A+ i8 j% N3 S: U* X
             result = x - y;/ g/ e6 n* Q0 e6 M$ D; l$ V
             break;6 K0 p2 d5 u4 _* l" c+ l
        case '*': $ g+ O9 |# V2 T5 A3 L2 P
             result = x * y;$ t4 o; J: f7 y* J$ M$ P
             break;( O# z" u. @, ~+ m
        case '/': - Q) F; G6 r/ ]8 o) o* Z/ l5 i( g
             if (y == 0)1 p! @% p- F* |" ~, b0 y$ T9 J  b
             {$ ?; p" K9 _# o5 m/ O' t$ ]
                printf("Divided by zero!\n");
0 T0 v3 I3 F2 u1 t" r                return 0;# B  p' S& [9 ~" a+ p
             }
: N- l( z# V2 Y) x# C             else. H1 J& {- m1 b3 a6 j5 A8 e$ s
             {
& v' ?, \- c$ W- U& O! t                 result = x / y;  M5 _- T5 K) c. e$ N2 K- I
                 break;
  @- F7 k& g- O( X* ?5 [% Q             }
1 O4 _9 Q/ o9 G' }$ f: m- U4 x       default:
( b' [/ B# B( u; R1 ]3 M( i             printf("Bad Input.\n"); " p( u5 f2 J& a- }
             return 0;# o1 }' I. z7 q( P! D& Z; p
    }
6 h" _( f, ^8 o0 d0 ]) j    return result;
1 j3 r2 m% P8 }, i}   
; n: [5 b, d: ~- }5 u
! A5 S8 s; I5 |' k3 J" x0 h, Bfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/3 y2 v: W3 B. i
{$ b1 f' z9 U4 j. F- a
    Stack optr,opnd;
6 e: l" Z& E: x3 J4 e- G6 v4 T    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;2 j: X4 Q( j  g0 W
    char c;5 c* l+ f7 J& o& }
    char buf[16];
* ~- Q1 m( `  E7 K7 J7 D/ K    int i=0;! U/ n3 W6 x0 e$ r6 R, n, K0 N
   
- o/ \+ R+ }, h) x; V+ Z) Q    InitStack(optr); /*用于寄存运算符*/  V) z6 n: l% F' K
    InitStack(opnd); /*用于寄存操作数和计算结果*/
; C$ Z* K1 a5 x    memset(buf,0,sizeof(buf));
: Y& a! z1 F* b* @, D' n; w   
$ k& U0 Y" o- t6 A3 `    printf("Enter your expression:");. H" v- |( L0 ^  x$ D) {- d: _
        % I( L- q9 z, S5 n  ]3 m
    opr_in.ch='#';- t( @) R4 {9 M8 _3 p
    Push(optr,opr_in); /*'#'入栈*/
( [. E5 t  v8 f    GetTop(optr,opr_top);/ R1 j0 \" p+ v( N/ M5 g4 X
    c=getchar();
0 w$ j) d& O- H+ c* y    while(c!='='||opr_top.ch!='#')# }) \  Z/ h8 {" Q. Y( R
    {3 ^3 j, m  g* u. F2 j4 Y9 F
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
) C6 ^: E+ y! z        {: F3 t# p8 Q2 ^* Y3 _: b8 P
            buf=c;* b- L/ P# r" q  }
            i++;& O5 x6 l' N  ^0 |( K2 m
            c=getchar();0 y) \: M2 M1 S
        }
' S1 O5 i' j  k/ V        else /*是运算符*/7 U# J" m& u$ q1 h* O8 W
        {
2 n* d7 F: o0 I9 f  t/ I( L, s            buf='\0';3 Z- v5 V  \) U$ B! a
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 d; x. e( ^9 d% h4 J3 A, O* O
            {
5 K8 B$ ?+ U* B- C. x                 opn_in.data=(float)atof(buf);
5 W9 q. k$ M3 m# Q6 ^% B; w6 R! J                 Push(opnd,opn_in);
# Q9 R! k2 U$ p: X7 X/ T                 printf("opnd入栈:[%f]\n",opn_in.data);
/ j8 @- m9 t1 G4 r! [# s7 U                 i=0;/ }8 L5 E1 d6 C' \1 a3 D
                 memset(buf,0,sizeof(buf));
$ n6 J$ t8 U/ A4 C& M$ O            }. [+ g* Z5 g' e2 J
            opr_in.ch=c;1 y* e2 f- Y; z5 c8 {
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
& v  F6 ]8 t5 a7 V  M# c3 ], W            {
% c( p! Z( S2 [7 ?# C4 U( e7 D; d& }                case '<': /*优先级小于栈顶结点,则运算符入栈*/+ Y( A( q5 j- p& W: X$ T
                     Push(optr,opr_in);. U. a+ H! R8 t( C* Q$ y( W
                     printf("optr入栈:[%c]\n",opr_in.ch);
& |' P+ E- G! t7 B                     c=getchar();
" K  c  _; a- R- r+ s& D" N+ W, q% q                     break;
2 s( X$ w4 ^8 r- s1 d" a4 H# Y                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/' u* x$ M+ _$ q
                     Pop(optr,e);
& [3 r, i( P/ ~                     printf("optr出栈:去掉括号\n");
& u- S& H. Z6 L' i. A8 W                     c=getchar();
, u3 t+ {0 Z0 M                     break;
" }% f" e' c. k( U                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
) h- A( L$ A' }$ M. r- q                     Pop(optr,opr_t);, R7 y+ t1 N$ f, {; {; r9 s( B
                     printf("optr出栈:[%c]\n",opr_t.ch);
6 b8 |! J3 z6 n2 z7 M3 b% y                     if(Pop(opnd,b)<0)
! |2 ~" N2 S! W1 B, n6 m                     {3 `) l: Y0 k: I1 |  c# C
                         printf("Bad Input!\n");* I" ~5 w9 G) b& H
                         fflush(stdin);6 N# H$ Y& F, D6 F, y
                         return -1;: l" w+ r' H" H, ^7 R
                     }/ a" M8 a6 P* ~$ C  w# h
                     printf("opnd出栈:[%f]\n",b.data);
! h( P+ [; W3 n# `8 L, ~4 w                     if(Pop(opnd,a)<0)3 A5 B6 `0 e% i& t0 v4 n6 Y
                     {6 a/ U1 o& n' k
                         printf("Bad Input!\n");
4 K  H* f. Z; W/ t* Q3 S$ m7 L                         fflush(stdin);& q6 A! N. e% r- }$ T: f  C; ^
                         return -1;) l  G9 B7 I; q" i% R6 Y5 n: ]
                     }
0 P( ^; A8 s7 C% E- q                     printf("opnd出栈:[%f]\n",a.data);$ p2 @# N( N9 K
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
7 M) _$ @; b7 d                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/5 ]- A- M4 i+ x. z. G
                     printf("结果入栈:[%f]\n",opn_tmp.data);; k6 [+ v, o- v/ P" H" F
                     break;
( _# m$ H6 T) [8 r1 c            }* ^; j7 x4 g5 H) F2 c
        }
# y# e# |5 P$ ?; V( d- Y8 U. Z        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
% r0 V, f6 k2 P    }
0 S5 ^. i7 X* _' R8 j% \7 E    GetTop(opnd,opn_tmp);
3 E& g7 C5 Q- K* B* d+ U+ q    DestroyStack(optr);
9 @# b/ a: x- v$ e3 l7 j0 J    DestroyStack(opnd);
: ?+ n! |) H8 o& H! C; q" E    return opn_tmp.data;
" f! U; w( M& _2 X* N}8 R/ R/ z  `+ U" Q0 M+ ]

0 n# V: e# L9 T! e5 {char *killzero(char *res,float result)
9 z& C8 c4 i! e, u{: K3 k' b6 Q: E2 W9 M
    int i;5 q  e" x- a4 b/ O4 Y

" v; k3 |! |  e3 W2 U    sprintf(res,"%f",result);" x5 [9 @# ]4 y6 e% A* @% `$ d% L% K
    i=(int)strlen(res)-1;
& k  M: Y' D1 ]6 C' w/ ~4 M5 w& d    while(i&&res=='0')
5 M) c8 `0 i& o$ a    {# l3 U/ S: [: s  {+ S6 {# ]
        res='\0';
" O' k1 b4 p2 v/ F5 w1 N8 ^        i--;' d9 s$ Z% C- K& E+ F
    }
+ g* O$ D8 ?) J" a5 W6 r    if(res=='.')
) D8 k9 m4 O5 C; a: h8 {        res='\0';' y. a- n/ W7 F8 L; n0 M
    return res;# g) V/ n; \/ f
}$ x! ^" u, C/ _! m) Q" _
7 G1 T5 c+ z; w5 o
int main()
7 ~, ?% a* Q7 O' q# ]$ `2 y$ {! S) B{, i# a) X% L4 z7 ?
    char ch;
7 q$ J: s  s8 K. Q    char res[64];
1 I* |& r* U" y! u9 \/ L* T, g7 j    float result;, l1 g! p/ ]5 k% p
    while(1)
7 H- `/ F; o- U    {$ k" Z0 z- _/ B. F( ], i( [
        result=compute();1 c3 ~/ ~+ Q9 A
        printf("\nThe result is:%s\n",killzero(res,result));
! `: _2 A. ~  y3 T$ F- g        printf("Do you want to continue(y/n)?:") ;; r# d0 Q$ w% B! u$ E4 S# e
        ch=getch();
% B: F6 J. h0 T/ t        putchar(ch);3 W* M+ d. c1 |9 C
        if(ch=='n'||ch=='N')) E0 L+ g% p! S- h, ~
            break;8 c5 S% g& E6 w. n- d+ E
        else
% _7 |% [0 z! F) |/ H            system("cls");) z9 z6 r' }/ J8 Q( O$ O
    }
! I3 T. V8 p# Y8 \    return 0;
( H( X$ f. g* q# [: J% ]% U3 n}

: {! [9 i* g4 a. Y" z' q4 A" k0 W# o, d$ k/ n) P* f8 l% R
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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