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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的./ ~, Y& X" D6 E, D& V  B+ w6 e
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=1 M, H( b0 k( K$ T% ~5 m
/**************表达式计算器************/
2 Q7 o, A7 U  ~- n#include <stdio.h>
: {$ ]& h% Z7 \6 }7 ^#include <stdlib.h>
8 m+ H+ l5 z1 g#include <string.h>4 D+ \6 ~- X! E* O  I/ L, D; q
#include <conio.h>) r$ q; U2 t" B$ r4 |* Y6 U  B
#include <malloc.h>
+ t3 q: Q$ v9 B( g
1 ], s7 Z# n# ~0 t9 V" D9 M#define STACK_SIZE 100
2 x8 K: u1 [- X+ I: j5 o6 C1 K#define APPEND_SIZE 10
9 e/ `) ]; Q4 [" @
2 t) h! g# O+ v9 M$ O$ k0 estruct SNode{$ Q7 ^. R: s7 C1 t3 J- K. Q3 w4 ~% j
    float data; /*存放操作数或者计算结果*/
$ W3 x9 V' y8 O( x: @    char ch; /*存放运算符*/+ ?( t. q7 _4 y, |3 Z( n
};
6 _5 z( ]$ C0 v+ q+ v- [
  v3 H$ J( T: j# H9 Q- Hstruct Stack{9 _9 k. Y) P* _( Q% k
    SNode *top;% ]: z# N+ g4 F* v) j
    SNode *base;
0 C: h: K2 A9 t% w    int size;
2 ~! U& y) T# q8 ^8 b( r};; m5 F5 ?  w" m9 U) F' @6 ]5 V: ^, j* ^
( \2 g/ [+ t- R0 ]8 Q$ i1 ^
/*栈操作函数*/1 C3 Q  E. D5 ~7 F
int InitStack(Stack &S); /*创建栈*/% s' e5 _1 A4 M; o( G$ \
int DestroyStack(Stack &S); /*销毁栈*/
% p4 ?6 v6 S& _8 a5 g9 ^int ClearStack(Stack &S); /*清空栈*/. V$ E! Q# ^- H# D. g, z5 [
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
9 a8 U) n, U# ]4 Fint Push(Stack &S,SNode e); /*将结点e压入栈*/
' k$ E0 Z7 w* g$ pint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/9 ]1 a. y+ e2 _3 g+ K/ d+ ~" k

* k* f2 a: d. T" C2 Z/*表达式计算器相关函数*/' o: q% j% ~: l
char get_precede(char s,char c); /*判断运算符s和c的优先级*/8 t: f1 J! A$ L
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
6 ~5 U& I% `: \4 @float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
2 e3 }. Z* b" j9 K4 A& Q; k5 I# ufloat compute(); /*表达式结算器主函数*/
. W+ ~" G, S; [+ g9 d6 m( j. g1 Echar *killzero(float result); /*去掉结果后面的0*/ - t1 S2 P- B! r, F2 y" d

5 n" D* p0 y3 |int InitStack(Stack &S)3 X% o9 q1 P7 ?+ n7 U. A# W
{2 ~: k, n  y- H4 c* @0 l$ a
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));0 w3 [! v* C% Q- X1 n
    if(S.base==NULL)+ J& ~+ _, V1 j
    {2 Z2 z0 e' w* e; {3 k1 l) {* {
        printf("动态分配内存失败!");
1 }8 X3 H; m4 `( ?3 q# X) x& Y        return -1;
0 F4 T( l/ T% s( V    }
' J  C" i- r+ W" z5 s    S.top=S.base;: g6 v; E: Z$ n+ f" x: z
    S.size=STACK_SIZE;
1 U% j1 r9 L! c  x0 D  D. H/ I    return 0;
( ^: A( m! I& ?}5 |5 c* R; ~# J
3 }9 t5 p1 w0 b# a
int DestroyStack(Stack &S)
3 H3 c+ d. s; s. Z% _- h9 P1 V$ ~{
/ ]! R: b. f7 F    free(S.base);
% n: a0 x9 V0 ^7 L    return 0;
/ W# X$ B- w4 }}
/ ]& u6 w* j2 A  R8 V# s8 D& p5 @" w4 R# j) m/ Y: t
int ClearStack(Stack &S)
& p' _( [  |0 j, |# I% r{# r7 I: b1 O6 _5 t7 v$ s
    S.top=S.base;
! `/ `5 k$ b$ C, z. [/ q    return 0;
  H3 @; F/ Z7 u3 _. _0 h}8 T- k) H' k8 j3 _" E5 F, `
0 g$ D. H& K) s* m9 r& B. ^8 s3 m# k/ h
int GetTop(Stack S,SNode &e)
( u: D( X' M# w{' Y8 p- u8 p4 U& B! {2 s" N
    if(S.top==S.base)
, w# G6 x# x- z$ k9 M; q9 W    {
5 H, D7 H- ]1 d; u" \- e! t9 t        printf("栈以为空!");
+ i3 }  T/ l! S0 w5 {, d        return -1;
7 C8 j5 T6 n0 T    }
5 B- ~5 w; s' y5 E9 c$ y2 F4 I    e=*(S.top-1);1 S, z9 @* D6 K
    return 0;! b. D2 ~6 g0 q. X9 w
}5 ?' R4 ]* {9 v6 y

! Q0 ^0 A  `8 o, pint Push(Stack &S,SNode e)
( L- R# C  _6 n& |) u{
. `8 N8 C/ L* s1 D$ Q- [% Y    if(S.top-S.base>=S.size)* x( Q% U! E' g$ g" Q/ K
    {- ]0 x9 l2 E- g4 A0 B+ W9 a4 T
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
: |, p5 L" X) _/ ]        if(S.base==NULL)
1 {! t) B& Z* d, F  `        {4 y5 ~1 h8 g" g' ?- K( _9 t( i4 J  _
            printf("动态分配内存失败!");1 h3 U6 c' \: G
            return -1;( P9 O7 m) C+ n( t9 g3 G/ J
        }: y2 L; i& h% e/ q; x  Y! Y
        S.top=S.base+S.size;  \  ]" ^4 z% R6 V$ k- x
        S.size+=APPEND_SIZE;
7 z2 Y) K: c: m* F* ~6 y% p    }
" x# T( _9 z/ F" r    *S.top=e;, l4 F2 W% u& u0 J6 q6 J  U9 J
    S.top++;
! @; n5 u+ N0 [+ z+ U7 n    return 0;* J% `( I! M* w0 p' l' n
}$ M$ X" e$ A& z% l  ?/ |
& b9 k. x" G* ?( D# `. w
int Pop(Stack &S,SNode &e)
  O. K2 U  M: n6 }{
, D: G( s( V  l/ e. F    if(S.top==S.base)
$ E) y1 u$ f3 T! X7 k: }    {5 [$ j9 I2 l& N) D" b  D
        printf("栈为空!");
+ z, N* u8 `3 \* X7 {        return -1;
4 j5 S2 d( t, c6 j    }! Q* J% `" b2 G* R
    e=*(S.top-1);
: J& r7 r, f7 [4 U8 g( Y    S.top--;  b# n, T" p! }/ p
    return 0;3 _+ D, A1 Y1 `7 ~* v
}. V5 z9 Q/ H. W; `; l& k) q

4 W  i; o2 r! r) a9 Nchar get_precede(char s,char c)* S2 L8 L! g1 a/ a, P, D" u
{
2 S( `5 J4 b& o+ F3 I    switch(s)) r# b: g/ w  z  I9 [. j
    {  D# z# l! N9 [4 e1 z
        case '+':                 
* @! J2 \) }$ Q( H' a8 e2 A  j5 s2 m        case '-':
2 r, H. f9 H5 h- t3 K( {             if(c=='+'||c=='-')' H0 P$ B4 z( N9 C
                 return '>';
7 r- S3 }0 W3 T$ T  G  l+ s6 X             else if(c=='*'||c=='/')
6 Z/ D$ h6 o' J) N( i7 m) Y                 return '<';
3 k5 w; G3 N  b             else if(c=='(')
% i2 v8 }: n& E7 z% f6 o  Z$ q                 return '<';
; }) W# Y: O2 q, o7 N( z             else if(c==')')# ~. c0 {& j+ j
                 return '>';
% ~" A8 \' V: g             else 1 E/ ~) e& s, F, U! }% f4 \
                 return '>';
5 K% u7 c: c9 m! |  {6 R2 u! ?8 y        case '*':
' z# }( _2 n; }  i        case '/':
. z6 j! u/ Y' f  Q             if(c=='+'||c=='-')
6 K7 Y: n  m7 I7 i                 return '>';
7 m9 c6 ^4 J. h2 x. L7 Q+ \             else if(c=='*'||c=='/')
6 {! M  n& @7 V8 L" ]$ w5 ?                 return '>';
! _9 G8 Q( A# t: R$ F. d% u             else if(c=='(')
8 e' l) o! R1 w                 return '<';+ J" j9 _* F; ^- ^
             else if(c==')')
! G5 M8 v  D2 g- U                 return '>';" {& r5 p0 f  w$ y2 R
             else9 `6 q* B0 G/ N; \* l4 x! ]
                 return '>';
5 j1 I% {! R# l8 e, w- Z4 w        case '(':
1 m4 L8 L# s5 e% F9 R' ?             if(c=='+'||c=='-')
# ~" n% {6 I5 Q, K$ K( k                 return '<';
& q) `  Y5 h' e) W% H             else if(c=='*'||c=='/')
* ?# `/ b! I1 A) @                 return '<';
% x, ^( i' S0 h. v. [             else if(c=='(')) h, J: e+ u6 f2 ?2 a
                 return '<';% L' c$ ?, p* C7 Y. Y. _5 Q
             else if(c==')'). W) p, Z  w& F+ `2 P3 N8 S
                 return '=';  Z: ?7 O4 M3 O; _: ]$ l/ q
             else
( _  W1 `" _& @6 I6 ~  _0 B                 return 'E';8 u. {; I) T5 g' y
        case ')':# G3 ?7 i, {: j! Q3 e) D3 R% H
             if(c=='+'||c=='-')
0 W' k& F# K' T( V                 return '>';
7 }- n/ k, u# g# X             else if(c=='*'||c=='/')& i, m& K3 t+ V0 m, d
                 return '>';
( U5 {8 `1 {7 T; D( a, V             else if(c=='(')
; y: t# u; `8 ^. K$ }                 return 'E';8 Z* b' D5 x8 T( }8 c0 m3 I
             else if(c==')')  J8 L0 ?( m$ G6 h
                 return '>';
1 A: ~; a1 q8 b) C             else
! P9 {8 W+ X! r. A" r6 H$ e) `$ k+ x                 return '>';+ s: e* w. h# j
        case '#':% [( f6 ?$ I* ^7 C: n* H+ U
             if(c=='+'||c=='-')
( s1 A/ H' ?  Q6 n# l7 p5 \                 return '<';
* w2 y" C. U/ q8 @5 s9 }             else if(c=='*'||c=='/')' d6 J7 Y% `1 r! Y0 A5 p' n
                 return '<';" P! _1 C) `$ V6 u/ X2 ~1 X
             else if(c=='(')$ N- V" b, H% J9 Z+ r$ M+ ?8 O2 t( r6 G
                 return '<';# b3 J* p+ x* M- D8 L
             else if(c==')')8 i4 y+ U1 K, X- D/ l8 I
                 return 'E';
# n* y. a* W8 y             else& y; [. a. ?' D% I0 K) O6 F* Q# F
                 return '=';
+ }. \! f% U8 P8 e0 L& W        default:' B. @; b: \7 j
             break;9 ?% N( N) z& |; D. [0 }$ ~
    }6 }" N* J# b' l: Q" Z1 Y# `& ]. N
    return 0;    8 U  F" u2 c- R8 U5 f+ p  i
}3 x9 K1 h# F" }0 L# }% J% q

! a: O# w0 ^1 |, Cint isOpr(char c)
1 E& P% k7 w: m- O. j/ x8 ~{2 x* p$ _% I' }5 g5 N
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')* ?- D/ Q& F# L) B6 u( h
        return 0;# p+ B: g& y1 l! V: w
    else . V, U* i8 q* F) k& I9 T
        return 1;
+ W. B% T& X' Q2 a9 Z' q4 a}
( K/ _0 t3 o5 P: v! ?$ h- g, H6 m! h! e/ z1 X( J4 J2 c
float operate(float x, char opr, float y)
- i' i6 e: N+ j7 I% \{7 ^7 Y5 k5 z% A1 D
    float result;
/ v0 i6 I5 w+ m' k# U8 o    switch (opr)
# }! X& B! P' K9 f; F    {
: W( q/ a+ J0 A        case '+': . F- Y9 i% A5 M2 F; k3 |3 M
             result = x + y;' |' B. r3 X5 m8 m
             break;# E0 `1 N5 o6 n2 ^
        case '-': ; {3 e0 d) k- |$ N" ^
             result = x - y;" B5 j  d+ K5 [& Q. ]
             break;
+ X+ a' M3 R. L/ x        case '*':
% ]  j9 M" n" u$ P* x2 L             result = x * y;* F' l* Z2 D. o2 Q( a/ a8 c
             break;
2 ~# B+ A) J9 S& p$ p& m        case '/':
" I. W7 v2 Y& T6 z1 n2 ~1 U+ B9 W             if (y == 0)
, V! S4 y. s5 M. |5 N! z* O  k6 l             {
" k* K7 i  N4 U; }                printf("Divided by zero!\n");
0 [/ u8 _; g6 P: c# }                return 0;
5 j# t8 v# t. t, p             }
/ U1 I3 G: e  |: D             else
5 p: L# }* S7 w$ l# V* }( g             {# o8 z% [" k; M
                 result = x / y;6 b3 Q* T* k( `* z
                 break;. P& D' T9 t8 S! S- F
             }
; M! S! r. {& Y0 Z% @       default:
) P; l& H2 }6 `7 q, ]             printf("Bad Input.\n");
8 X) I8 C  S" C$ {             return 0;
3 h& o/ y* I+ K. K    }2 ?/ l7 L+ O; B- A: u: B- N
    return result;/ T: j/ s) B4 z% N7 K
}    + A" r5 G! [/ R3 t- N

0 z* W" J- N6 h/ X+ r6 Vfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
% }. d( ?, j- r7 B{4 H& {, n, p% E  T7 G: l
    Stack optr,opnd;) n* r) Q$ y0 D
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
$ A! v7 P9 M9 k5 p4 |; ~    char c;
) W' H$ v; Z# w    char buf[16];% r; H0 |% P; r3 X1 z
    int i=0;
. P9 s. P( F3 J* d% ?' ]% I    - V) b+ J7 L$ S
    InitStack(optr); /*用于寄存运算符*/
% M- G& l2 e1 |    InitStack(opnd); /*用于寄存操作数和计算结果*/1 u% g/ ?) r9 U! Q/ y8 e
    memset(buf,0,sizeof(buf));
4 g0 F/ n! w7 L1 q* `$ l    " J& v* I! X5 Y1 ~3 u
    printf("Enter your expression:");5 C& x& l" C; v) k
        3 L2 F  P# _! [: C" l' U4 h
    opr_in.ch='#';- h! h9 S! [+ w) \8 l
    Push(optr,opr_in); /*'#'入栈*/5 _* _& ~. W# }( X$ y3 z
    GetTop(optr,opr_top);
& {, S% l2 a2 I    c=getchar();& T: Y0 o* Y4 x/ d$ I
    while(c!='='||opr_top.ch!='#')# q" K) {8 p: @4 l$ ~7 n
    {
+ O4 p' B! f, L3 i+ i        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
/ m$ M: l. S- h0 F/ j/ h        {
" m9 n  S9 \+ C$ i, I  h            buf=c;
0 X) W8 }% f/ M: o4 b6 }            i++;/ H" z2 k2 F, ]& X7 V; O2 }
            c=getchar();8 ?3 L9 M  O" p& D$ `3 Y: i1 B
        }3 S& ?8 g3 i' X# [$ ~
        else /*是运算符*/
6 I' U- t7 h4 J2 {        {
/ Y6 {) D; W9 a% y/ ^            buf='\0';* D  i* B$ U' x6 l0 U
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/( D& z" a  I! @: N4 i" |2 _  @
            {
: T9 g  [4 D0 D# a$ l                 opn_in.data=(float)atof(buf);) a3 k# J) s: O) `% l, J& t
                 Push(opnd,opn_in);
. I; X+ O' g# ^) \! K- L                 printf("opnd入栈:[%f]\n",opn_in.data);/ X* m! q9 G* o
                 i=0;8 @- h3 S0 m6 d
                 memset(buf,0,sizeof(buf));: V. B0 Q, Q  K( i( v
            }
8 w& Z- {# d/ |: b. T# P$ S* l* P2 j            opr_in.ch=c;
3 `. X% t& Y2 J7 A1 I            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/9 P: A- q$ d4 E
            {' n; k7 [: a/ \) o) k  c# T% {
                case '<': /*优先级小于栈顶结点,则运算符入栈*/6 B9 S/ W; E+ t7 Z3 {$ ]( U9 @) ?
                     Push(optr,opr_in);3 E2 L$ w6 Z/ K& X* V5 K0 f! e
                     printf("optr入栈:[%c]\n",opr_in.ch);
! V7 G( h' k, B/ m6 A                     c=getchar();- _, c/ z) V4 h, ?' k) w
                     break;
& ~, _: @' p" h: m7 L                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/* G6 i; r+ i3 Y
                     Pop(optr,e);3 h" H/ O# E0 N" d
                     printf("optr出栈:去掉括号\n");
9 V7 B, _! l0 e                     c=getchar();- M; a6 \2 {1 u
                     break;
% g* [5 I5 ~" J# K5 B: i6 S                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
2 {4 {* S' J# n                     Pop(optr,opr_t);
' E* {" N; I( u9 C" \4 M3 V$ }9 H! S2 p# p                     printf("optr出栈:[%c]\n",opr_t.ch);: d% O) p1 _  y
                     if(Pop(opnd,b)<0)
  q/ D5 u* d/ r* `$ R$ \                     {
: c1 y( r& @3 |                         printf("Bad Input!\n");4 @$ ]8 M* ^# k9 h9 y! x
                         fflush(stdin);
: s7 l( w* R/ d4 X0 v                         return -1;
# K, q5 D* v$ x, s% j; ]                     }
* {1 j4 n3 Z$ l1 y                     printf("opnd出栈:[%f]\n",b.data);
1 `7 ~( c. o+ |8 m( C                     if(Pop(opnd,a)<0)
6 X" k( M: j( `; o                     {6 K. Z. v; x) i' b$ e
                         printf("Bad Input!\n");
" V& d8 F; I, D- _7 V% e                         fflush(stdin);
* }8 _9 m4 x# d3 D                         return -1;
/ y0 b; z4 b5 h3 l" q6 L, m                     }7 v- V+ l+ k. l! n2 l
                     printf("opnd出栈:[%f]\n",a.data);. u0 A* s. h5 A  u. g' x
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/1 |. W- I% a8 b% {
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/' w& r' v1 I5 b6 U2 n; A" s: z
                     printf("结果入栈:[%f]\n",opn_tmp.data);
+ F# r4 e# N& N5 O7 n9 ~2 u" K! n                     break;
9 x7 Z4 n) b9 t2 J3 w  \* L$ m* F            }
7 c0 P" W, r2 j+ t. Q; M# O        }% A2 f2 @1 W7 y4 f: j- {
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ; v  |& l# }. c- R- b9 c6 [
    }
3 u! x" P% \2 ?, Z1 ~+ J    GetTop(opnd,opn_tmp);" z( u4 E; B' |! b$ I2 n$ y" I
    DestroyStack(optr);
% g" f! L% y+ v8 L9 a    DestroyStack(opnd);; R% d4 H2 @4 A5 J9 \9 _
    return opn_tmp.data;
) J* `% x6 c, K' |. P}; i& E3 H; G% J4 k5 N+ _: F+ W

7 Q5 I8 U. A$ Z/ s* [char *killzero(char *res,float result)2 \8 |5 d% Z$ |+ `( A
{
0 ]7 |7 k6 z- Q" C8 Y; A    int i;$ B0 ]* m5 }+ q9 B
$ y% _: `7 j3 M# t
    sprintf(res,"%f",result);9 N* o- b  W" _9 {4 C& b) I+ f% n
    i=(int)strlen(res)-1;
: r- S6 H. N" H3 i' ?    while(i&&res=='0')
4 ^5 z- Z9 i# t. `    {
* ?) g4 V5 \$ q+ N! L7 s: C        res='\0';) g- k! F9 q1 k
        i--;
) e( V$ n. d0 z+ ]    }
( _) x- U- }* d+ M+ \  }    if(res=='.')
# }% ^  x1 I/ p) D! ?        res='\0';' N! U: C( U1 C$ h% ]  _3 Q) @
    return res;6 ^( a" J0 d+ `' U
}5 R% R0 K% }4 B
# c* F/ E) T6 y! {
int main()
5 O- c7 L' {3 r" J( V% a{
8 S5 l, T) d8 |$ |    char ch;
) a1 Q  Z1 o3 Y  N5 P: @) k; e& }    char res[64];
9 T; u4 r" X1 _( {" P, Q- `$ ?0 X: d    float result;
" x) ?7 b7 H' d) L# {8 f8 [- g    while(1); |2 j8 m2 s; ]" \
    {. [+ H( q! R" E' x: G! y
        result=compute();
, o9 ^( O+ f& J& f        printf("\nThe result is:%s\n",killzero(res,result));) y& r) m& e9 A7 z9 a% O/ ~
        printf("Do you want to continue(y/n)?:") ;- m+ M, W; B$ Y0 H
        ch=getch();
6 Z) h8 w# y* i/ M8 {6 Y+ G7 c        putchar(ch);! t6 e- w, O$ d
        if(ch=='n'||ch=='N')
3 q0 `/ S( g1 D# K0 h# _  x            break;% w8 ]: J$ a$ ~1 N4 G, u9 M  ~
        else
# d$ N* Y/ Q% g, R; R2 ?- o7 G) c            system("cls");
6 ?* ]# ?3 t0 U" ~    }
0 [6 _8 ^. z/ J1 M, T    return 0;! d. C) i0 _7 s  E
}

  {" y( H4 j" [6 p, {  a/ Y/ @# D& }- U. P  B
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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