返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.$ Y3 g  E/ i- Z5 k
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! D+ {9 \( P5 w, N8 p7 A* T/**************表达式计算器************/
  j6 t+ k7 Y. S5 k9 X! L#include <stdio.h>: N( D# `3 @) }0 a, }
#include <stdlib.h>
1 i) U0 C1 @* _& J: D#include <string.h>
4 z0 R% s1 m1 @: E7 v#include <conio.h>2 t  C7 v: J/ a& j* O5 ]& V! n
#include <malloc.h>
: d& \2 _# }6 X9 ~  m5 g8 E$ D# r$ Z0 {" }$ @( n6 `
#define STACK_SIZE 100
9 H* ]9 m; q" F0 G#define APPEND_SIZE 10; U7 v: }$ r  ~/ S- z( i2 R' X

* @2 O7 p! U& c0 I& F7 e6 jstruct SNode{
6 ]; o% U. A; j! S" `    float data; /*存放操作数或者计算结果*/
/ C) s7 ~2 |' S    char ch; /*存放运算符*/0 Y) e7 H, @, M; R# f
};. @2 U1 @8 A. \$ y# R
) y6 K4 v* h: R( O4 T- S# L2 ~
struct Stack{
3 {: m1 }1 j: b' p. I    SNode *top;# O5 W# R- j5 T( E. ~8 W
    SNode *base;
" X2 O% q& i; D) j4 T  W    int size;
! V4 E. f7 p5 ]5 y3 M" p+ u& y};
0 G' D( U# h+ r- b" p6 e
- A; W' K9 T5 o0 `, I. r" o/*栈操作函数*/  Z% M4 P6 F, d- c% B' O
int InitStack(Stack &S); /*创建栈*/
) |3 f' B  d$ n  [  J5 j- [int DestroyStack(Stack &S); /*销毁栈*/) P, Q  M, k! h- X
int ClearStack(Stack &S); /*清空栈*/
$ O* Q" h' }1 D+ _1 U7 Aint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( J9 X# Z$ o  p% j  p, Kint Push(Stack &S,SNode e); /*将结点e压入栈*/- ?7 |7 C- ]. v1 U/ {; l8 `0 y
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/0 @; z; F: V+ O* k0 n2 K

: O2 ~  M! e) [; G/ `* a/*表达式计算器相关函数*/
( `# t4 \& I& a6 z0 Q$ {" v; ]char get_precede(char s,char c); /*判断运算符s和c的优先级*/) \4 o2 ^- e6 A$ ~* I4 M0 e! A( U
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
' k; O$ a0 \6 A8 G3 ]# V  ?- Vfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
) W' H! m& S$ q# M: Ffloat compute(); /*表达式结算器主函数*/
8 d2 k4 h2 r7 \; {$ c  b  rchar *killzero(float result); /*去掉结果后面的0*/
- j# L( V! q" ~+ |7 F- m
# Y) A1 b6 y# t% d: hint InitStack(Stack &S)8 \/ V3 k' }+ B8 N9 A0 q) U+ }
{$ w4 t7 K* ~9 q- g( I
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));  S# p. I' C8 t
    if(S.base==NULL)
& _$ r8 g( k" Z* f1 @    {; Z7 `7 ?  p% f# v! O" n0 j  ?
        printf("动态分配内存失败!");) z/ r& o  d% L
        return -1;
* j0 ~+ E4 L  v: L9 W    }
% y! B8 ~" Y& ?$ C3 F1 l7 P( `9 F    S.top=S.base;
  \2 z% L! V8 [+ ^    S.size=STACK_SIZE;( s1 o9 G2 O6 u& Q# Y( x
    return 0;
# ?% f" D  _; H8 V6 s  B7 V: X0 ]7 F}: Q/ s7 W4 a% c

2 D4 e7 P$ t4 v2 Wint DestroyStack(Stack &S)( Y& d) H; k6 n$ B
{
/ t. j$ c( ]& K3 P4 d; @" C7 f7 ^    free(S.base);
) d: a' w: E* z6 [! p2 y  m    return 0;# Y1 W, y' Q5 `: p! i) T. o
}
( `: `. V, Q7 g& ?  H
. z# K2 T# F/ \* tint ClearStack(Stack &S), P. _) B$ E4 D& Z( ]
{. s  [- X. F! _- {
    S.top=S.base;/ a; j* E+ {( v
    return 0;
9 w" y5 M# t# m7 m}& G6 y1 ?, j4 X# x3 o7 A+ F

5 P" |: w- c8 o' O8 s( Rint GetTop(Stack S,SNode &e)2 N8 m' d: z/ e8 A9 t# s' j* R! W
{
0 M/ c% ~' P) j3 N3 \# _8 o4 k0 V    if(S.top==S.base)* q9 _6 z; w9 [4 `5 ~0 I- I
    {' E  K+ G5 `' ]+ n' E, j. ?
        printf("栈以为空!");
2 |" A" D7 @. I. Q        return -1;
9 P: B( n5 ^8 F4 k% I* u    }
6 U9 u1 M) r  f+ {! t* |    e=*(S.top-1);  J0 K' q  A, X6 n% `  G1 O3 X& y* U; g
    return 0;4 @6 f$ ^9 ?3 |
}
* o- K) a' E" H4 U; E$ H: x  j9 v" e3 c. L! o+ B
int Push(Stack &S,SNode e)8 ?" i! s5 e" A! V! g9 i9 \; g& \
{: V: X6 d- Z3 ]
    if(S.top-S.base>=S.size)) D$ t3 L/ I" ~- N$ q
    {8 m7 Y8 }) a" Q% n& t9 v- c
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
  _' ]- o( u8 ^; U  h        if(S.base==NULL); l) _; L/ W# C- t& r7 l& o' s
        {9 l. G2 }/ x0 T! Y. [& h" _
            printf("动态分配内存失败!");
* ^! ^9 W. [; [1 J: n# E, Y            return -1;( h6 w5 G5 D3 n: ^
        }$ f2 D: P3 }4 v$ B0 g
        S.top=S.base+S.size;
4 U! e$ R1 d( d/ q        S.size+=APPEND_SIZE;, X5 `/ C! V$ ?, I5 X4 E7 P' z
    }
( T4 |+ N( Y. ?$ O9 D3 h0 F    *S.top=e;
& M9 |6 c. @( e& \; f    S.top++;# @/ _' r1 ~$ |* x
    return 0;7 I1 v4 e7 z: r( v' v' d( f  j
}2 t  w. x' n2 `: b5 ]# [" C& Y

! e0 Y: B! O! A' I; W$ m3 Lint Pop(Stack &S,SNode &e)
- m4 C9 {7 B( `. Q! Z, b9 b{
3 y1 p7 }0 x# \! M5 Y    if(S.top==S.base)) p- o5 }1 `9 T7 v3 n
    {
) U. E4 q2 U8 u, O8 C        printf("栈为空!");
2 B: }5 [8 _6 ^  t        return -1;) x2 ?$ {  k. B# ?) W/ o- z
    }
- F% l/ b+ F2 B& q    e=*(S.top-1);
3 J! G3 z6 q1 |7 q- u0 [- \- v    S.top--;3 Q8 L. D0 O0 c* \$ ^7 J" H
    return 0;4 Y3 Y+ x5 E$ m, T, |- v6 `1 o- H
}
; A  a5 M* G6 ~8 x- N1 N. g' z: R3 q' U. V9 q$ m# f, Z: r
char get_precede(char s,char c)7 a: a/ @& P) G$ i) @8 r- |
{6 _* ?- A( \- U" z7 r2 W
    switch(s)
( r5 c' M$ b/ _" @    {6 v- G4 B" k( S+ E7 U
        case '+':                 8 `6 |- j0 k( I' ?, h7 u$ V
        case '-':
1 Y9 p6 ?& F+ X" w/ R0 L             if(c=='+'||c=='-')
) M* n: d0 }( m* L& w4 f, |                 return '>';6 Q5 r( p/ I0 }/ i' G; g
             else if(c=='*'||c=='/')
$ q" T, m1 v! r/ }                 return '<';5 d" @# P% l; D* v% \
             else if(c=='(')
9 h' h6 g3 A) R" o0 R& y  n8 q) R                 return '<';
3 `2 i$ H% F, C! ^             else if(c==')'); g& v$ x* U3 N' g# k: A. @; t7 y
                 return '>';- V& W5 z* d4 C7 ~3 T
             else
2 M; f- n" C: J  t) i5 V; o                 return '>';4 p6 N2 g9 Z4 B  w1 F
        case '*':
8 E' J) W; `5 d. z' {        case '/':
* F; ^. w' X* o7 r0 C" Q             if(c=='+'||c=='-')9 O, i2 C9 {8 @0 d9 H
                 return '>';$ n- C) A6 L& g) V1 F
             else if(c=='*'||c=='/')0 M. \9 A1 R- p* _; P
                 return '>';
# w! V8 ^& e9 W% {6 e             else if(c=='(')
) B% Z2 v: @2 Q! @                 return '<';
' Z( L9 W3 U. O7 m             else if(c==')')
5 [$ i; E: o4 H                 return '>';+ T; ?: W9 o  ?: L* ]! I
             else
. w3 _( @) _3 a" o+ {1 p8 P' D8 ^                 return '>';
$ {( M. Z  T. n, ~8 @, M        case '(':
+ A' w4 S' H( l, B             if(c=='+'||c=='-')
- T3 R- ^% J) R& K* \                 return '<';
3 V3 v8 X2 N9 q3 f8 m; [$ w             else if(c=='*'||c=='/')1 v4 z1 V' J6 b/ g, w
                 return '<';- Y% \; D! ^& u) s* |
             else if(c=='(')
1 t2 D* s$ {9 \! j, @                 return '<';, D# X2 r* x/ r
             else if(c==')')1 B! o5 }: _2 h3 C
                 return '=';
) @+ P9 C/ H* P, [# d             else
0 x; b# s  C- O; J; [                 return 'E';: @6 j5 I/ n+ S7 C. W0 A  [
        case ')':2 s* ?' R1 h" Y" m+ N
             if(c=='+'||c=='-')
$ }4 C- m$ T% o) K! Z                 return '>';
1 Z! p7 ~6 a+ W1 d6 b$ \( e             else if(c=='*'||c=='/')
/ j* z* Y5 n# @$ l& n8 \                 return '>';
# I# ]. T' ?& }, Z! s             else if(c=='(')  m. a" v& [" u, E, _
                 return 'E';: e  S1 P. z/ f) d# n0 g" {  P$ X
             else if(c==')')
6 k, P5 }& J. e6 C5 }                 return '>';& }0 B0 i0 C3 ?9 U2 C4 ~6 k2 Y4 v
             else
% N( R+ H7 @  y: ~0 P& f  }                 return '>';* T$ I/ e& s( x, t
        case '#':& F* ~6 K! N" k  N/ a! i7 U. p
             if(c=='+'||c=='-')
- P6 l* H/ o7 y3 ~% Y* j                 return '<';
  Z1 Q/ }! p7 _% k             else if(c=='*'||c=='/')/ Z+ n( D7 k3 s* [% M
                 return '<';
# P& X' t" k! q% E             else if(c=='(')
2 U0 C5 r! v! K: M4 w0 @                 return '<';) z5 j0 Z8 M( _4 f5 x+ Y, X; [; u) T
             else if(c==')')
( v% J) F8 U% X+ _8 m9 V* `8 t                 return 'E';
+ B1 D* @( k4 Z, {0 r             else- `0 }5 y, N8 S$ a
                 return '=';
: U3 _: V( Y9 x# o4 W1 F' W        default:
- J9 y5 G" a6 v! A1 V6 V             break;! v- d/ r% c9 \7 N' n: e' X
    }1 v) n+ p8 m: D* l9 P
    return 0;   
# q. U. _+ w6 n+ U6 F0 X3 r! ~}% W2 n8 ?, k$ @, R; R

, J% I$ M4 i2 V" p7 N/ ~; a0 q8 Pint isOpr(char c)
5 _7 S7 v3 Z* X8 u{0 G% i2 i& I9 Q% Q) M* @% F' s
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')  J. S. r# f5 S4 s2 M6 f5 l2 T6 G: _
        return 0;% k# [6 M( T- p* \
    else 6 J* ~, g* P( _* s8 ~
        return 1;
: s, _, K3 O4 q- m$ ~}
: ^- o% ?* O1 i/ }& u5 u! ^7 j, l3 Z0 q
float operate(float x, char opr, float y)( W) L( w8 \# u. V
{
* M8 M4 g2 [* y' \    float result;
/ u. ]* e+ ]& p$ U6 I5 Q4 o3 k    switch (opr)( Z# y6 J* `- ^( G% e  x
    {
6 q( J# b" Y" [# l5 r  f* ~6 }5 r        case '+': . E1 f' F. Z% _! v7 h
             result = x + y;
6 L: a% k4 K; k             break;# L, E: H. j! I/ i# y
        case '-':
1 m9 i% I! |1 r; [             result = x - y;3 ~/ f4 G5 d0 k  P- P
             break;! p% o0 S( j7 d  q7 \
        case '*':
- n. i( M" B1 i/ S' u             result = x * y;: \# {1 v" F+ \" f
             break;
$ e) h+ j; b9 X$ s7 v5 P6 x% E        case '/':
3 l: p% i& R/ q0 V" m. P             if (y == 0). }3 N7 r% i  j4 F" K8 O/ t  x
             {" I2 J3 j' b$ D" g1 ^& I
                printf("Divided by zero!\n");
7 i* I! b( H4 A/ |% b0 U4 G$ E                return 0;- W9 N5 R* ]/ J. n
             }
  B" @, v5 d5 ]             else
; b% a! B+ f+ S+ J" R- f- v( Z             {8 S9 h  X' w4 u# @- e6 v
                 result = x / y;- ]$ d$ p2 J7 M
                 break;
* J' p% B6 n9 F$ P; `6 T             }
! Q7 J+ D$ y/ H; z( L       default: ' d4 C9 L, E5 [3 {
             printf("Bad Input.\n");
% @- q9 e+ Z3 S; }# z             return 0;) z4 x9 J; k6 H% m: i3 N7 q0 T
    }6 c5 e% _) C% `) E6 C
    return result;4 K8 @4 s/ W/ P7 y. @
}   
# g' Y4 T9 a& M$ s  }& ]9 W/ F5 s( y
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/3 W1 @& p: m9 D( R" x! b+ T( U
{
" y. `' a! O: l, @  W, d$ [  k" `    Stack optr,opnd;
! _5 m- o  o5 I6 k4 Q3 L    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
% Q0 ~: `8 x) T    char c;. l6 z+ F  c0 A, ]: h
    char buf[16];" R% X4 J: X" V6 X
    int i=0;
) [; g3 s4 o) I+ T; Y   
7 _& K: |. {3 T' r! m; L6 v    InitStack(optr); /*用于寄存运算符*/: y# S1 l# W* e  V: Y* H
    InitStack(opnd); /*用于寄存操作数和计算结果*/; c4 h% v! E2 Q( j% O
    memset(buf,0,sizeof(buf));" ~0 d! J, B! A9 V
    3 k/ O: g4 ]" V% T% B3 ?
    printf("Enter your expression:");
8 _1 d  k6 q7 D* e        
% r0 U6 \" Z" J. k  O    opr_in.ch='#';
& P* I% X' r. o$ p3 r    Push(optr,opr_in); /*'#'入栈*/
! e. i/ P0 H1 C% ?- O* I    GetTop(optr,opr_top);
5 Z8 r" D4 T! T) h* B  ~    c=getchar();
' P9 ^9 V/ v$ r    while(c!='='||opr_top.ch!='#')8 e6 M7 s- d5 e2 f
    {$ F6 a# Q* N# [3 q
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
% F+ N( r# X% e% D' R  n        {
. p# [" b: }% S            buf=c;
1 k! L( o/ U3 ]6 R            i++;
/ A3 I( e! f8 ?. Y: u7 e/ X            c=getchar();
3 I% `; D* b* u        }
( r- s) Z7 l5 B9 G8 _        else /*是运算符*/2 D2 @1 u/ ~6 z8 @1 B, E+ R" p
        {
. b7 A& G1 A! j            buf='\0';* y5 C$ Y, G$ N0 c8 S% V
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/% w( t: ]7 n. E+ G
            {
+ B- X* G* @5 X2 b! ?# Q, D                 opn_in.data=(float)atof(buf);' J6 F7 Q/ I" E) p5 p- p' O5 H! E
                 Push(opnd,opn_in);! [6 \& F% h0 E0 h0 O3 m! Y# F
                 printf("opnd入栈:[%f]\n",opn_in.data);0 D; z5 r' m! h+ [" e" |  O/ R7 k
                 i=0;+ |, K% S1 f2 c  W! V) U9 n
                 memset(buf,0,sizeof(buf));: Z3 H+ r5 @, C1 k% y+ L) D
            }8 E& y: ^+ ]6 M# D- p, c8 q- f& |( l
            opr_in.ch=c;' q# C/ g6 }+ L5 I
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
  W- r, X- c$ I; l4 m# A            {1 i: A# |' |" ^/ {
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
6 ^* @( D! ]7 x" o/ V0 b                     Push(optr,opr_in);6 b$ f( ^# X  `) G* h
                     printf("optr入栈:[%c]\n",opr_in.ch);% Z3 C" f, a! l; n  M9 p
                     c=getchar();
+ \, N" c9 a; ?5 p                     break;
2 Z4 H6 h  w" f0 B/ ~$ B- B  ~                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
5 `8 f8 E- d& Y% |5 q                     Pop(optr,e);$ ~5 j; e$ s, v0 h; d/ R' \9 f- O
                     printf("optr出栈:去掉括号\n");$ D5 j7 n3 R) Y" Z& |
                     c=getchar();: F9 q) e; S* ~0 r/ u( ]0 a
                     break;( m7 s6 z2 |: m. A
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/3 m! }, B8 {  o/ b8 I
                     Pop(optr,opr_t);# l7 z7 I$ x( P  C7 R; f7 e
                     printf("optr出栈:[%c]\n",opr_t.ch);
$ r5 p7 }- \: `' F& f  j                     if(Pop(opnd,b)<0)" W9 [3 G- \6 I" q0 q
                     {. h3 C2 B7 g; P5 j$ M
                         printf("Bad Input!\n");2 e! V* I" a3 @0 p7 J
                         fflush(stdin);" o/ ~9 C3 b2 @' F
                         return -1;
) Y# c9 x, y" Q' ]1 t                     }
$ V4 s4 k, p. L- [1 l' z& F                     printf("opnd出栈:[%f]\n",b.data);" a1 [, x7 u4 i. L) V3 @
                     if(Pop(opnd,a)<0); [8 L) X' t# V8 \5 B7 n) V! f4 V
                     {
- k# T2 [: g6 s8 W                         printf("Bad Input!\n");" \  j' N5 H" }3 R* ^0 t. B) J
                         fflush(stdin);( c2 P/ J7 w" j- k/ W3 ^
                         return -1;. [2 \9 O3 H+ @( e6 S+ l9 a: i+ y
                     }8 M' J0 O$ e: b7 G2 Y/ g
                     printf("opnd出栈:[%f]\n",a.data);& {5 A$ A/ J' Y
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
" G6 b# J* n( Q# ?( D3 Q                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
" j2 x4 y- M0 S  m                     printf("结果入栈:[%f]\n",opn_tmp.data);
  g% H5 A/ }1 u: g2 l                     break;
# A) H8 t1 F% x3 c6 A3 h8 l$ ~  F  s            }* b6 t% [. G2 y9 O4 J& x
        }
5 U' O3 U2 r# W) D/ O' i) I        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ; q# T/ v# _( @: b& f
    }' d6 L+ `: T0 l: |* H7 b! K
    GetTop(opnd,opn_tmp);
$ J5 _  a! L8 I# D. M. d, Y    DestroyStack(optr);; L2 V' N3 e8 N0 G- ?6 r5 d; M
    DestroyStack(opnd);
8 ?' l' H, b3 z9 ^    return opn_tmp.data;
7 B8 \  D0 |! D$ u. M  `5 u7 V}+ I/ t0 }1 q9 b% ~* F

4 }" b- m: ?0 Achar *killzero(char *res,float result)
" t6 L  @4 u: ~" v{
; H+ N4 f0 _+ M( O. {# p! E    int i;) _( S" g( X6 I2 z; M* `) n

! p! c( M, }. I+ K4 G    sprintf(res,"%f",result);
+ Y( p# I$ [) G% ?    i=(int)strlen(res)-1;
* }7 w, {- N- s    while(i&&res=='0')# v- W3 W! O' `7 U8 E! f
    {
: q8 s8 g. a/ z/ z+ i: n& I        res='\0';
. |; |) t8 n; i! b! H3 q! f        i--;
( n6 x1 m/ ]3 g" q0 K    }( v8 Y6 ?5 m2 m( {$ |. T! _
    if(res=='.')* a# i" Q' B+ F# a2 t; y) h3 M
        res='\0';" d  J5 O# ?1 B0 I# m& m
    return res;9 i2 o( N3 A1 }6 M: O1 V, f% C
}7 k5 V) J( A' ?7 U( T

! t+ X! i7 C4 @% \# b' Sint main()6 U7 k. ]. k- f1 u+ `: C! _9 P
{( p- T, ^  l1 o3 O# R
    char ch;
  O. ^; T# e6 z    char res[64];9 b" W( h; v3 D7 D+ K. v! I
    float result;" ]6 m$ y" n* D
    while(1)
* |# \' C( |8 N. @5 [/ W1 d- Q5 @    {* Z. t! F/ z- h/ q
        result=compute();
, V. R. d+ {# Y! r/ s' A        printf("\nThe result is:%s\n",killzero(res,result));2 J' ~" |( h4 u( b2 [* N1 Y
        printf("Do you want to continue(y/n)?:") ;- b$ c9 `0 I  k( @! d
        ch=getch();
! Z) V' S$ S. X$ f, }* J* G0 O* R        putchar(ch);5 s9 v; S) G3 B2 c5 }' O/ q
        if(ch=='n'||ch=='N')
) I3 J! {3 k; \; G6 K            break;! ~% m# p( [7 Y8 t" l: F6 K$ q% }
        else: b$ [7 R& }# E! m8 J
            system("cls");
5 ^3 ]* s$ g* r" h    }" w+ U3 u; ]% b4 f5 Q' Q
    return 0;
8 |& n- L  M9 w9 B$ z}
" R" m- x2 m! ~5 Y
; k$ `' T" K" O" V+ E# U
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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