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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.) x1 s" p* w) Q. ^/ n2 h
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! I/ ?6 j. G& `/**************表达式计算器************/
  F7 V& v# v- a# H/ q' S9 d$ d" i#include <stdio.h>
2 t2 g" E5 c' z! _6 T#include <stdlib.h>
' _: h8 C: c& l; G+ [: X! z#include <string.h>
2 j7 A3 h3 q+ b! i#include <conio.h>
7 C* T' y6 F* s9 [#include <malloc.h>
+ e! A3 Y7 f; w5 b7 g0 P2 w
/ f7 D+ e) E" X, J#define STACK_SIZE 100' \0 ^  S* v: R( k2 G
#define APPEND_SIZE 10
2 w( t1 o  k9 ^* d6 [0 R
* E9 {+ }# W; x9 vstruct SNode{1 i1 i: f% j& I
    float data; /*存放操作数或者计算结果*/
4 H+ j; a- b( Y    char ch; /*存放运算符*/
4 U8 Y  |9 b# }% ]};
, O2 x4 s0 c4 K( L
$ u0 V. w% T2 Nstruct Stack{
, u: O" H2 r0 R7 n, i* [    SNode *top;6 F! m0 h3 i+ z9 J. _
    SNode *base;
( o5 b' w( ], F; L    int size;
. U  g: U; O5 R$ a};" p) b1 }6 {  q
# n) n; c6 M/ \- U
/*栈操作函数*/+ F+ [& p2 g9 h: \" [% P( w
int InitStack(Stack &S); /*创建栈*/
; z# y5 l. y* I( Nint DestroyStack(Stack &S); /*销毁栈*/) @: Y5 x1 d" l* j
int ClearStack(Stack &S); /*清空栈*/8 z9 F/ X5 N! O" m- W9 n
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( P$ F2 q) Q- ^/ W9 i7 Tint Push(Stack &S,SNode e); /*将结点e压入栈*/9 x  L" @8 F# a0 z2 d* G; j7 ]- h. C/ @
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
& J- V  E3 d' _, U9 Z# v- `0 {6 p! s6 H# [# ?- ^% ^& O1 P
/*表达式计算器相关函数*/
. i+ ?0 U3 S+ B5 |& D: O2 X2 K. a: }char get_precede(char s,char c); /*判断运算符s和c的优先级*/
) t( w7 _3 z0 P" }* B" g+ vint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/8 a; p0 |7 }( o% ^
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/1 G- z/ p, o5 f; f2 P7 j
float compute(); /*表达式结算器主函数*/
; y- u' Y: e5 \! [6 rchar *killzero(float result); /*去掉结果后面的0*/ 5 w% l+ M% a$ ?
$ k% h/ V7 N+ c' h9 D$ Z- ?9 T, v
int InitStack(Stack &S)
+ j8 K4 V/ o4 Y{
. U. [1 P9 _2 _2 ]% s- H4 r    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
$ s1 ]: ^9 i7 i( X: k    if(S.base==NULL)7 m& l  m; \. t6 T- s( V
    {
- V3 R1 V1 x9 O0 |; c5 L        printf("动态分配内存失败!");5 Q" J: a. O" o5 Q) n
        return -1;/ s6 K& r- b8 ?2 j$ c/ H0 v5 k
    }1 z+ ^7 ^, H, S, j4 R* Q
    S.top=S.base;
5 g- T& y( g6 ?& v7 }    S.size=STACK_SIZE;
& i* c5 v* b. M7 J1 S7 T! `    return 0;
; i1 ^, w  f6 C5 w( ^, I. [6 p}2 t) a3 q, t# ?  P" i

+ i. C) G2 o6 W' o) P+ L) aint DestroyStack(Stack &S)6 h0 T# \8 f  Z! q0 L' i: i
{3 |2 J0 S. t- I# d) A: {
    free(S.base);
9 T. b2 j1 x# [0 ]. u    return 0;  p% H; ]- w; ^7 f
}
, [9 W% f; \( T/ u8 G
6 k- m! x0 D# ]8 c5 b: u+ kint ClearStack(Stack &S)
7 N9 c2 z. ?) ^0 g5 H! ?: q. z/ U{
, u4 Y/ h1 Q. q/ L& s0 A0 D    S.top=S.base;
: h3 A1 S* _6 u$ ?" C    return 0;- `/ ^9 U: c7 _2 x/ i
}
  A* _# R. z6 q% g
/ j  Y- i$ G" v+ z! Y! Cint GetTop(Stack S,SNode &e)
$ A+ T7 Z3 N* E; J2 I- C/ F{
0 \5 M/ i/ u( J1 P    if(S.top==S.base)
( v& f* S8 N1 x; B    {% a: x# t7 q  k* e& Y# M( K
        printf("栈以为空!");
5 X, W" M: Z3 a8 e. ~  q! t$ O        return -1;
% s; {+ p! U: S  D8 s6 R    }
2 T) o% K" E- m    e=*(S.top-1);1 q0 r1 {) A5 H0 l
    return 0;
" x( X8 e4 x7 {( I}" }& u  F; _1 A) R& G, f1 c

  g- H0 v2 U  ^1 _+ O; o  C0 u' m" Aint Push(Stack &S,SNode e)
9 o$ }; Q8 ~$ K* E{: q+ p5 p' A1 G* W* W& J
    if(S.top-S.base>=S.size)( h! W! R7 Z9 p
    {
. I. p2 `- r/ U3 q/ X6 y        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
; X. _( ~5 t5 b3 o; a5 p        if(S.base==NULL)
' C" E1 q! G" |0 B- A5 W' ~2 E        {
6 N. f( i- O# ~            printf("动态分配内存失败!");
1 g1 Y) o; b2 r- h& r            return -1;
8 t3 {; v; W2 ~& m$ ]& o% B        }5 G# f; g7 a0 R/ g  Z8 Z3 \
        S.top=S.base+S.size;
9 s* P4 a+ I6 E: m  d4 u        S.size+=APPEND_SIZE;( \$ t. v$ S5 m" u& B
    }
9 l3 @# n6 U0 s2 M* W$ Y    *S.top=e;
7 ^' F8 i$ Y4 a$ ?0 T& k    S.top++;
, t2 g: o" c" u& f; Q0 L4 s& D    return 0;
; q$ ^! O+ `0 h! r' M2 u% _' [% \}
% K9 D5 n7 `( P0 p( C6 W0 v6 d1 ?. h' V' U
# n& D; W* p* H) W$ b0 Kint Pop(Stack &S,SNode &e)
* v' R* w' x* h" U{
- b1 a, I: H9 A    if(S.top==S.base)
( G8 U3 k6 z/ h1 Q9 V    {- o2 V  y+ m2 U$ G3 s3 t  X1 l
        printf("栈为空!");
. S  B! T/ S+ D0 @9 E' K        return -1;2 `. x6 j' T4 Z) p2 l
    }5 j/ }/ T6 f& ]' A1 H+ ]6 A- T
    e=*(S.top-1);, A: I3 d$ b* r. R/ l; `
    S.top--;
; v# J3 C& {  a' D    return 0;  l/ A) B0 j9 W
}
2 h3 v) _& R, b  `0 G5 O" }
+ R+ x: b$ D* p0 kchar get_precede(char s,char c)3 l! l5 P- S6 w) g1 `# k
{9 o3 K$ r% w: o5 H3 e+ B5 l8 p) R
    switch(s)% R7 B0 b; e& j" q
    {( e1 v' d" o: ^5 x1 A% y. z2 m1 e
        case '+':                 2 o- d" I$ q' J2 P) E
        case '-':6 ]9 b1 E0 f6 s# e* ]- r
             if(c=='+'||c=='-')& L. E& b1 V8 r' Q8 C% N
                 return '>';3 s9 ]4 A3 \1 P, f4 q3 K3 K- n
             else if(c=='*'||c=='/')
- x: r( U& h7 S2 B9 E9 W1 w                 return '<';
" p7 Y2 A3 u! Y  W, o9 u             else if(c=='(')$ M5 z7 ?6 q7 w* u7 k
                 return '<';  |: v( B9 P$ y; t) D4 F: `
             else if(c==')')6 s4 [; o, A* w6 l# A2 k* p
                 return '>';9 k' I7 ~0 e/ D8 u
             else # U- G2 v. C. R" ?  |2 k* v
                 return '>';! |$ S2 \7 P; Z6 d1 n7 i1 ?
        case '*':" k& v2 s& y* Y, [2 `: C
        case '/':
$ j- |9 V( U: e; n5 q' {, v  m6 V( M             if(c=='+'||c=='-')
% g; {5 k+ U& a7 e. N' i0 r                 return '>';
; C3 c  W) H" D4 [8 s             else if(c=='*'||c=='/')
9 y: G; D: p9 A                 return '>';0 u9 t- m. K( b, p- O- P% z( p
             else if(c=='(')
: z" ]' }8 W0 Q8 O$ \  v                 return '<';
* r. D6 N7 l5 v) r3 i             else if(c==')'); I) o' j* @; `! ]
                 return '>';: n2 i9 j/ s/ P$ ]0 }) W: }- z
             else
7 y6 X0 C# n$ ]; L9 ?                 return '>';
8 k$ a9 w9 Z  D. V$ r( D: }        case '(':
4 s9 K) i: X0 K) n$ \, Q5 |             if(c=='+'||c=='-'): ~# x1 `' v7 k( l
                 return '<';4 U! }3 r3 W5 r0 O2 T4 E* _
             else if(c=='*'||c=='/')
/ l2 W8 n, {3 R- n" N+ g                 return '<';
: n# |( E# I$ K( H# [             else if(c=='(')- i/ e+ Q# f: D6 s* B- s
                 return '<';0 e. g; U2 g, d( Z: P" L
             else if(c==')')8 v, t3 K! v9 z+ [
                 return '=';9 c7 l2 i" e. y2 l/ z1 P
             else
# t  F& O2 _9 P; q) q# J+ u4 L                 return 'E';
+ p1 ?" X; m  y5 @2 G: ?1 c        case ')':
$ {+ {- O' @& X* E% G             if(c=='+'||c=='-')
$ J# H9 d% ~5 L2 p                 return '>';
' g. k: g$ w9 `' r2 ^6 u             else if(c=='*'||c=='/')# |3 r8 `7 d% w9 i7 i+ i- R- N5 k) @
                 return '>';! w+ a% n# j* P/ {& i$ _( v) H
             else if(c=='(')
; H/ v" S' D( e                 return 'E';
" r- Q2 z' R" Y5 L) M) @2 W             else if(c==')')
; G% n2 h& q) X/ ]3 v* h1 M! C                 return '>';9 x; R: [, Z0 V% q7 b
             else& M7 {' f3 _& V  j4 J0 g1 I
                 return '>';
/ R2 y, |: W5 i        case '#':
( Y5 L9 T. a" W3 u- a             if(c=='+'||c=='-')
. s4 W# C! i! u8 t                 return '<';3 F2 Q+ v8 A2 D0 b
             else if(c=='*'||c=='/')0 p1 d' T! o, n
                 return '<';- k6 v$ r% L: r  A: m4 Q1 q$ \
             else if(c=='(')$ E2 f0 M. T) E- p
                 return '<';
+ [5 L$ L: E- b4 C4 f0 q! y, \( z             else if(c==')')5 T) \- p6 i* S' x
                 return 'E';
) L: R4 I3 V. _1 y+ A9 H3 d             else
3 c# Y2 U7 p( m7 q0 M: S( Y' r                 return '=';
4 t# D: I6 W7 j        default:
. s" D5 y: K" s$ o             break;
3 o( i( p+ ?7 t0 @    }3 [" [, b  q  g7 P4 N/ g; N& V
    return 0;   
) J" R5 ^+ H% T}
% }( _. y- d  L' b6 I2 P! `- p; _8 {
# ]7 o5 n3 B' u( _) Z) X, dint isOpr(char c)
, J8 ~# w4 d) M5 M) \' f  D' |{
* V0 X. w$ \9 [! Z    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
* f" z4 v5 m4 Z4 }% C/ x2 S        return 0;
5 @( _$ o$ M7 d; |    else
6 o* Q' Y) h: A% b' Q        return 1;
) n3 i: f: e+ H9 ]& Q}
  D4 s' I* }  g/ N$ r+ b, I; |; O- O* I9 P) I
float operate(float x, char opr, float y)2 h& C3 H; W. ]7 a& u
{
, Q. U7 z: r# D1 y0 O1 I7 I    float result;: k/ C' G9 @$ Q/ |/ t( _
    switch (opr)- I2 c) T. s# p4 a5 r) g2 @- ?
    {: ~1 J+ w2 ^! V6 A7 U
        case '+':
: L4 j5 O7 Q" f9 Q, Y0 Z2 \             result = x + y;, g) [5 C0 p/ I- G
             break;/ B) k7 W/ V) ?: G+ F0 z$ \# l& J
        case '-':
& \; M& F4 c9 [- d             result = x - y;
: ?6 t/ O1 v% }$ |             break;) g/ p) y( ?* G1 e/ i
        case '*':
; Z; |1 H: e; H; n9 Q             result = x * y;1 n. @) H" X; ~$ e1 c
             break;
$ O$ i) h$ e- W: n4 c9 f        case '/': 9 c. {% [1 V3 b% l  y
             if (y == 0)
. ?6 ~0 v+ c# T" {4 Q$ ]0 t. A* B0 |/ L             {
. ]( a9 A4 q, \7 P                printf("Divided by zero!\n");
3 G* A5 |: \% \                return 0;
8 K; o( u/ Z+ W; A; s5 m; o             }
" x' G* F  X2 g. S             else& O% O3 Q1 B* F/ ~- s- R
             {
) |5 i( I) K. e                 result = x / y;9 G! E5 J$ H6 u9 p& @! S
                 break;
! V& w' P& g) m! S8 N, \             }2 D8 a- `& `: }$ F) @4 V
       default:
8 E: U2 i, U: D! ^             printf("Bad Input.\n"); 8 c, u& C) }: J2 K
             return 0;
% G) D/ C( ~# c$ F9 f1 a1 U5 E# A1 |    }
1 I: z$ |0 ^8 V' j. Q+ N    return result;% R/ m  k1 j9 a
}   
) J+ ^: Q9 J: k& D
; T1 N4 a! E7 w: H  e! K9 e  _float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/: R: Y) z1 B* x
{
) H0 E2 G) ?+ q/ A: E7 ^    Stack optr,opnd;
5 J0 E- e5 P& M! ^: [, Q' n8 a! c    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;8 l6 @. C2 d7 z2 o  H
    char c;
( N3 j# H5 \! j4 k" Q( Q    char buf[16];
: E+ Y% Z* l9 j& B) B; r: {8 I( S    int i=0;" A7 }! X2 b* q
   
$ e# }6 Y7 l% T8 I5 R0 ]    InitStack(optr); /*用于寄存运算符*/
+ C# [- s% q  _  k6 B; ]2 T    InitStack(opnd); /*用于寄存操作数和计算结果*/3 s$ k, ]$ m( m4 z( X4 \6 F' Q0 V
    memset(buf,0,sizeof(buf));: D: d4 W: \2 E' C/ X) k8 Y
   
$ s( a9 ]6 R. q( K$ P! I    printf("Enter your expression:");% ^  b, h- {: w* F4 t
        ; D) H7 H* i8 p3 D+ R) ^
    opr_in.ch='#';
5 N, W5 U) L2 b: D+ n$ p' p* A* n0 A+ h( `& Z    Push(optr,opr_in); /*'#'入栈*/$ t  s5 Y& L  t9 O  x9 B( k
    GetTop(optr,opr_top);! Z! i3 e, p# o& J
    c=getchar();2 n8 ?" Z+ b6 |/ b9 B2 D
    while(c!='='||opr_top.ch!='#')3 q& E3 f9 P1 x
    {
& S4 z' T# r' }& J0 z- s+ r        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
# U! G; }. _* W( A+ J* }        {# k  w1 o& P0 o3 s: [
            buf=c;( F  a% z2 |1 D) ?
            i++;
% y- _+ V" v6 I            c=getchar();
/ b3 L9 S1 U* C* l7 [        }5 s! ~, U! r; E$ J
        else /*是运算符*/" I9 T/ ^5 X0 D. y
        {
6 Q, i0 A7 t& N! G. P% v$ z' N            buf='\0';9 ~  {2 |0 T$ y6 V4 q
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/; Q* x/ W- E. K
            {
( D: i: h- P4 ^9 D5 p" m7 h                 opn_in.data=(float)atof(buf);  w+ k( z* v& V) k* \! r
                 Push(opnd,opn_in);
, F/ w+ R7 Z- q; p9 z, n                 printf("opnd入栈:[%f]\n",opn_in.data);. W% W, O) T: E- Z9 P5 {6 k6 F
                 i=0;
: d( s# i1 X; N% ^. T                 memset(buf,0,sizeof(buf));6 y0 D+ r8 p' ^4 m
            }
) x0 P+ f8 }" w( t            opr_in.ch=c;: k7 U! j! p; y! c& @& e
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1 W1 [9 E. P" o* h            {
3 A7 k# R) K4 E$ N4 ]5 j# X# Z                case '<': /*优先级小于栈顶结点,则运算符入栈*/
9 m: T* A8 k  h3 U9 z                     Push(optr,opr_in);
7 O/ p. U) }) j' N* a8 A, r                     printf("optr入栈:[%c]\n",opr_in.ch);8 D- O' m/ s% b
                     c=getchar();
0 ]6 o+ b6 o; V# q1 [  u                     break;
. Z) E2 z% E5 w; P, ~                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/# ^$ B4 t$ q# E' o. u
                     Pop(optr,e);/ ^, Y6 S# P: N1 @2 e8 F
                     printf("optr出栈:去掉括号\n");
+ {8 [- B  _( B7 g! Z                     c=getchar();
' E# G. v8 G3 O* A5 L( c, _+ |                     break;
- e6 W  T9 Q9 \9 f# S9 f) n                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/# j+ D( o: k% h" E# e
                     Pop(optr,opr_t);
) H  O: B- S* D2 a7 j% F5 ?                     printf("optr出栈:[%c]\n",opr_t.ch);  e6 a+ e* ?  o3 F, N3 V
                     if(Pop(opnd,b)<0)
# [9 b/ t. S. l8 x% p                     {; C) c, r1 o3 {, |4 d  Y
                         printf("Bad Input!\n");9 k  O4 l6 Y- E( U
                         fflush(stdin);
6 V4 ]0 t% Q% d# l                         return -1;$ i: M. n0 D9 y) N
                     }
! [: y0 N: l) {4 @$ R                     printf("opnd出栈:[%f]\n",b.data);. G4 d; x" K3 g; L
                     if(Pop(opnd,a)<0)
  L1 e/ ]7 |+ X$ t* H5 V                     {
. B9 X" `. `% K/ o& r7 F                         printf("Bad Input!\n");; d1 d2 c2 b) H6 R
                         fflush(stdin);
* G/ e! h$ U  v, {3 D9 i                         return -1;
* Y/ V& `! c( k! Z                     }
# O# K" e" @. [" l6 D3 P                     printf("opnd出栈:[%f]\n",a.data);1 k; u' K- D  W0 I0 j* d' S7 I
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/* B5 n9 G7 `  x- Q' T$ y
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6 y, ~* _* p2 n: s( B$ w
                     printf("结果入栈:[%f]\n",opn_tmp.data);
' R1 B! I* t0 C, K  f                     break;
9 B1 ?7 v( [+ t4 N/ J6 Q, i) o            }$ H2 ~0 U# g+ B6 W
        }
* s, h) F5 O' T( U6 M; ?+ N- g" @        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                $ V9 z8 f) z& S5 ^+ z' F# F4 T
    }
/ d) X# g1 l3 O  C* }    GetTop(opnd,opn_tmp);
7 }, }8 _' F. T- i5 t6 ~, d    DestroyStack(optr);' M* E! v1 h9 R- D# W2 Q8 n4 k
    DestroyStack(opnd);+ O5 n+ q# X' s$ D
    return opn_tmp.data;1 {  e* z8 T. a) V$ W! M: u
}; R$ B2 a( M  H
" w- j0 @% ~0 Y8 x# v
char *killzero(char *res,float result)( Z8 I2 s: y" g4 p5 e
{
" s/ h- ]" _) C    int i;
9 q" e8 M: u- M7 @7 X& {" K, ~- @9 ~: ~
3 v1 t; `) [2 \9 f' S! X" c3 n& L1 J5 `    sprintf(res,"%f",result);1 h! r+ K8 k* ~& B* g2 ]3 k6 A# T
    i=(int)strlen(res)-1;! s! p# u/ @' p4 r. V- L6 ~$ T
    while(i&&res=='0')
4 C/ a/ D+ z# Y    {# h. v4 ]( ]3 D7 w( \( B! l$ `
        res='\0';
' H8 D! ^  _$ J$ y. R1 U8 U$ H        i--;0 N4 J- N- a7 f) t% b) Y" N  F
    }. A" S! W) J$ R  }0 C
    if(res=='.')
, }: @7 I5 c" h& a1 W  r        res='\0';" B4 L. g" f! y) k# d% s- C
    return res;% o3 R2 c* D. m! t8 [. x4 |9 ?
}
( d5 i3 E" }3 J& I9 _& s& E' [1 f/ v' y% ?( [
int main()( _4 m, j2 G' ~6 g0 h( U
{8 e, R- O  u; L+ l: c5 Q
    char ch;% C9 J, X- N+ ?) }
    char res[64];0 B) b' w' t4 Q6 ?
    float result;
3 k# ~" b, ?. K    while(1)
" f! g# h$ i( J" p    {8 ?9 ^; v# L2 |! X& Z8 D9 M( v8 J
        result=compute();& q9 v) ?4 I  {$ `7 U; E
        printf("\nThe result is:%s\n",killzero(res,result));% G3 R+ r% j1 {2 ~' C) V
        printf("Do you want to continue(y/n)?:") ;
& F' J/ _8 D+ B/ P7 }6 R: t        ch=getch();
! i, i6 H! `8 Z% i7 C        putchar(ch);
% b8 P# C) h7 q2 d% ?4 m: S        if(ch=='n'||ch=='N')2 V5 y- m/ z2 X8 K
            break;- T0 Y1 w0 Z  K7 d3 I
        else
, G' ^0 C1 k/ Z0 G: X3 Y            system("cls");
2 l% p* ]5 R% x) p    }3 T% ~  Q! `, P2 Z1 [' c1 o$ c) o) G7 ~
    return 0;
( g. t! c2 E! o0 R9 L0 {. e}
' M8 q6 J: U% ~3 X) T
1 d7 O! E( g  l. p8 Q% {$ \  F
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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