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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
0 D* w" W& W* G程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=3 H* D. {3 Y- D
/**************表达式计算器************/+ c' i) H" b* e5 R) }, y' }) G
#include <stdio.h>8 p" P2 Y; R1 r/ w
#include <stdlib.h>6 I$ V, W* \. K; ^3 J& Z
#include <string.h>* z8 p4 }/ P2 h5 }
#include <conio.h>
5 N* q! T6 x) C7 r: x+ E#include <malloc.h>
9 k. o1 U4 C- }* Q: n% c0 Z9 U. D: u( G
#define STACK_SIZE 100( C, D: d; A& G1 J! {
#define APPEND_SIZE 100 C2 Z6 Y- v7 C" R1 T7 u

* q  a, o$ n' Mstruct SNode{
: n$ t! [9 m! W0 M* M3 `. c    float data; /*存放操作数或者计算结果*/# ]# |( m0 _. J" R# B# j
    char ch; /*存放运算符*/& A/ w7 e, e1 q8 n) f0 e  `8 c! o
};
6 o+ g2 g9 ^% Y
2 ]0 M" T* {/ N( ?" F2 X5 qstruct Stack{. r7 @0 l  U; i* Q
    SNode *top;' `6 ~/ Y2 J/ a& Z7 ]( ?# S
    SNode *base;5 {( G# g3 h% e
    int size;: H. Q3 t0 F4 B" k. F
};" |2 @9 ~3 c' y) T1 M# w8 }% j1 [
- M; N" F! B, Y0 L  t
/*栈操作函数*/& a& g- t7 t* R/ K& U
int InitStack(Stack &S); /*创建栈*/
6 d& `4 ]9 C8 D0 I% ^; X: F: Eint DestroyStack(Stack &S); /*销毁栈*/
; R' H! ^0 z9 ~, }* l. D( tint ClearStack(Stack &S); /*清空栈*/% R0 M% L4 s, n8 F* w
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
) }% M' m0 Q) `0 F/ U0 q* R0 E( o  qint Push(Stack &S,SNode e); /*将结点e压入栈*/3 l* N8 ^% n% V- y1 s0 N
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/8 N$ d9 h9 T, [1 c

8 K  y& e$ X" F' N  `/*表达式计算器相关函数*/  I+ t8 ~: r2 w# K3 L
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
* x5 c! P0 I6 g( pint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
  L4 Z" T- r, o( n  ?float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/% `% C; U5 @" V$ t7 P" b2 y8 \( o
float compute(); /*表达式结算器主函数*/
+ J) p6 h4 I5 gchar *killzero(float result); /*去掉结果后面的0*/
; [; z; m& b2 ]! Z) a' Z/ M" F9 G4 O' F6 U" e1 c2 q8 }7 K6 d- R1 w
int InitStack(Stack &S)
5 K# K2 X9 H0 p6 A* _{+ u3 Z7 x$ b5 U. [+ b
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));; ^$ B+ X+ R3 d0 z. O% \
    if(S.base==NULL)
" m6 [- C0 ~, l  x. X    {
. w' `3 ^/ j: Z9 @        printf("动态分配内存失败!");
' c* f! N! s! O0 d        return -1;- s9 b* U& h' H! D3 U, Y9 D  ~
    }
- H+ y1 ?$ X- s$ r3 \  e    S.top=S.base;
- j! _8 h; c0 f2 a    S.size=STACK_SIZE;$ H5 a+ V3 S9 j. w' D$ F8 B
    return 0;! T$ O$ _% h0 ?" ^
}/ Y4 K) m& f- f( f, B) i0 o

  ~3 ?3 ^. ~+ V5 _% |int DestroyStack(Stack &S)
. t: ~- `6 x- t  Q{
2 e$ X; _" m- O( u  H1 {    free(S.base);# _* o+ ^) F+ F$ l* g! b
    return 0;0 ?+ g8 d4 D; R" j) {4 Q, K
}
9 d; y: S9 e% N
. Z& [* N6 c* s4 D1 r+ {2 T1 ~int ClearStack(Stack &S)
& O4 ^7 ^% _( i1 R{5 a. ^. o- k$ B* f
    S.top=S.base;
* o# H; n  C+ u/ i  G. ?( q    return 0;4 y% b2 L. r' Q3 _5 t4 X1 G
}; m; l5 j- t2 T; V# n9 D& @
# Q; Z# B+ z' [2 X9 J9 v. b
int GetTop(Stack S,SNode &e)
  w; B/ `1 Z6 P, E+ f{
( Z+ _7 B4 H$ r$ E1 v4 \2 Z    if(S.top==S.base): ]: j( O2 c. f- g9 H
    {" Z7 R4 [# T3 G" L3 J# ]
        printf("栈以为空!");4 j& M. {( d8 z, r; ~' @; y1 T) p
        return -1;, Y$ H  z" q; ^
    }
. e1 j9 Q& Y3 |( r5 U2 K) J4 T( k    e=*(S.top-1);. C1 [! p9 `+ |/ z* V: P9 S- T
    return 0;
- ^  x; V: g) n$ @$ {# M}
' ~( x/ o; W0 W- P1 ^' q, O0 F3 U  o3 @8 o
int Push(Stack &S,SNode e)
# N/ A' u) P  X, ~. }{. }  X9 T: r& M7 t3 W, r
    if(S.top-S.base>=S.size)
7 J( N, C" C3 U, m" v7 i    {( V0 w  P# D: Z' u
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ w3 q. a6 t, Z0 J
        if(S.base==NULL)% b, V: n  i% R" r: `1 ^& y
        {
; A' i1 q0 r2 M3 j" m  o$ u3 y            printf("动态分配内存失败!");
) ^  `6 m- I9 r5 k            return -1;
: E8 T& x* v4 c2 r# T        }
# o  N! p, K' N9 G0 {0 r- S2 m        S.top=S.base+S.size;% e+ G. t4 P$ X$ c0 e
        S.size+=APPEND_SIZE;2 ]( J; e2 }/ N; ^3 J- R0 F
    }
# b. |( e1 z" {: y. w4 k7 F: c8 z    *S.top=e;- J1 a: u2 p6 O0 v7 y) \* f
    S.top++;* u+ x# G, P% c% v
    return 0;/ K: \8 F, j, ^2 e4 g, v" O
}
8 S; s9 e: p% E' Q# I2 k
9 j1 M# ]2 A4 p) [3 {9 S. q! eint Pop(Stack &S,SNode &e)% c5 ]/ o) U- L2 D  d
{
8 {9 Q& f: k- `. |4 r    if(S.top==S.base)
( e6 \7 D5 j* ^8 u. p    {6 g* Y* C/ f6 T# L' D# Y9 c
        printf("栈为空!");; d+ j5 p2 z2 ]% T" {
        return -1;
# b( m( D5 ^4 B    }) q7 N$ u: O. y  m) T
    e=*(S.top-1);
  ^' m, _, L' g2 e% g  ^9 ~, t4 F    S.top--;
. x  K2 S# x6 e    return 0;+ C8 J* \8 v8 J+ D$ V5 D5 K9 y7 E8 D
}, K9 U0 K2 U, F7 x3 `6 b: l% F& l

. [7 `& J4 h% s! f% e/ Rchar get_precede(char s,char c)' W& k" _) G6 L
{
- [; I, l! J# A( s8 k6 y3 g    switch(s)
1 G& ^  C, B$ H$ Z6 m: \    {: h- N7 r* \2 t& y! b
        case '+':                 
$ l. k1 _. d* [# B5 A6 H; A        case '-':% M1 D. S1 Q7 i- f: l/ ?: F2 X
             if(c=='+'||c=='-')2 ~/ Q7 c) @' I( l3 G4 z
                 return '>';( Q% z! H$ K- q
             else if(c=='*'||c=='/')
7 W; \, F4 H* t, M) t                 return '<';4 S4 z/ ]$ G4 O0 a) D, C
             else if(c=='(')
5 C$ Y0 h* z/ K/ U9 [1 e' J( h                 return '<';
5 Q* D9 x% g1 b: S6 }             else if(c==')')6 z5 Z' N6 {( }: ?$ w$ c* ^0 ^
                 return '>';' |# u, R3 f. e* F9 o+ B, C5 `' G
             else 7 E( p8 l; |- e: a
                 return '>';
8 O4 L5 P7 W/ w        case '*':# P# B% g6 H; X+ P) }
        case '/':
4 G! ]& V0 f( t) o0 ^+ k             if(c=='+'||c=='-')
. b5 k6 E  n4 p. H' i                 return '>';
# T  `; {+ Z9 Z( _5 C" b: {7 w             else if(c=='*'||c=='/')
: s" d! p3 v" V2 _7 k                 return '>';
. c7 q: h7 I: K+ ?6 @$ l, q             else if(c=='(')+ J2 w# [4 Q9 k, x1 z
                 return '<';6 W7 i+ O7 K# @$ [4 m. d
             else if(c==')')/ d" Z5 D& k, L1 s+ ^: H# N* }1 l
                 return '>';
3 p9 t- Q$ L, _  S1 T/ q' v5 D             else
7 S+ {- V& u) y3 W                 return '>';% a" A1 Q, N1 H& K
        case '(':
5 r' A/ [. u8 Z6 u* z" R             if(c=='+'||c=='-')$ x* A7 z9 Q0 j) I( v/ T
                 return '<';. O5 ]0 L. ~1 }0 R
             else if(c=='*'||c=='/')
; a8 r& s" r% j0 j' c8 L) S                 return '<';
$ ]3 N6 e1 a9 B% i; y0 ~6 O4 _- w, ~             else if(c=='(')% S1 j2 {6 Z8 Z2 F/ ]
                 return '<';3 ]- W+ F5 O( v1 t+ d  Z& x- |& J6 ~: ~
             else if(c==')')
7 m8 p& [; \: k9 ]% l9 u                 return '=';2 x% j+ P: W# d4 H
             else
; Y0 M5 D- Q# _                 return 'E';% M$ `; Z2 g& B; ~4 B% v
        case ')':; G$ K( D& a; U9 W" \# V" l! P
             if(c=='+'||c=='-')
  e  o! o; f: z7 J                 return '>';
1 k! o  a* U9 G4 u$ p             else if(c=='*'||c=='/')( X- t& M0 O. e3 F
                 return '>';: c& M& b4 X* @# i/ d& o6 ]5 V
             else if(c=='(')! E2 J+ M6 Q2 F2 }. y  `" j
                 return 'E';
$ K, |6 [# t$ g' X; M' P             else if(c==')')8 E) C& }7 b0 `
                 return '>';/ k% s5 w9 V; P9 m* `" U+ B) u0 N% V( A
             else4 E1 X& E& x4 R4 A+ w# D- g
                 return '>';
5 X) U9 a+ \0 }+ a        case '#':' ~, H& `. E7 c4 g) k/ T
             if(c=='+'||c=='-')/ H* d& R( M0 K, L
                 return '<';& ^, }1 A4 q+ f/ O
             else if(c=='*'||c=='/')$ P; l0 d* B7 K# {2 ?' M$ h
                 return '<';
- ~: W" `4 w4 b6 T1 n  P( v             else if(c=='(')7 E, X0 v4 e4 f; ~) x4 r0 o
                 return '<';& l5 Z3 G8 F5 e3 m6 o
             else if(c==')')( E  |) C  E, s
                 return 'E';! p$ d. {- R- o! U! }9 v9 z* Q, [
             else, A- G* r8 X, x; s1 u' m
                 return '=';
7 P- I  m3 R& C$ A) \6 @! h6 H        default:
' r' \$ L# W6 {* Q5 k' A             break;
' @( x; @; a1 I" Q2 F. |1 b    }
* F: u! O4 R, h* K9 w    return 0;    " z# l( e- h8 Z& Z8 ?: O
}
- ~3 B/ b4 s6 |  q% I5 Y8 e' p. W
% P1 e9 ~0 B0 M* h1 ?int isOpr(char c)
, N# ^5 b0 `; y( N9 n- a$ E{! W" \9 A0 q  b! K$ h
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='): B* k' F, K7 @' z
        return 0;
: h  N  l* ?/ t. [, r    else 4 X9 E2 ?7 h5 L3 S/ {6 ?+ L; `
        return 1;  J, L; O$ Z9 o* G7 K: }
}
; o. a0 X: @: p. B, s1 l" O0 x6 E3 G5 \4 M
float operate(float x, char opr, float y), x2 e7 S5 t8 N9 G7 Z
{. G# \4 k5 }+ }$ p- h0 @
    float result;( d) e2 l6 Q* O# |3 K" ?% _
    switch (opr)$ }1 [( w! v0 n. ^7 C& ^' v  p4 N: I
    {2 A# c9 C/ d) x, l, C4 B6 V, X$ B; E
        case '+': - t% r( F/ M0 D5 k; E
             result = x + y;- R; I6 H  y- L& W* |7 u' B, h9 b
             break;( g! C6 Q& @5 J5 d
        case '-':
, Y/ u2 \/ ]9 g0 J6 \$ `, O9 _             result = x - y;# m9 A0 V5 f9 s" @0 ]
             break;# ^6 b3 k: |$ a' a7 G
        case '*': 2 Q# @4 u8 g+ B: L+ r: \6 j) B
             result = x * y;# I" C3 a  d" l+ U0 W9 {+ U
             break;
" i* V9 D% ~: U" e        case '/':
: t* S/ _7 c3 w. w2 j0 m             if (y == 0)& r' m+ i' r( s5 l) i& `' C
             {
' K$ u8 d$ A9 P4 `4 w* q3 ?                printf("Divided by zero!\n");" X( J6 e. E2 j7 {' t/ z4 i8 o
                return 0;% C9 }( T/ v1 M: A  \* q  v
             }
+ s9 T, h- p9 o2 f9 l( o             else/ J. x$ n1 o# ?2 ~  y8 O
             {2 C7 \' i/ W* {4 o1 ~8 z' j
                 result = x / y;
. n4 D* X  i2 y. l4 K9 F$ }                 break;& P( n& o1 J3 T+ o3 R0 ?
             }
+ t6 S% U( r$ z7 P  ]7 T       default: 6 r0 x3 u$ n+ u: W' F: r% S
             printf("Bad Input.\n"); & C, T9 k' h4 f: t) ~2 ]
             return 0;
" t7 V' x6 V; Z* z) Z; P( p  B    }* S( O: K& ?0 Y( V# c( V9 ^
    return result;5 Z# ^. y4 o7 F) T" \2 L
}   
* Z4 S0 E; ]- |. i& J
! H# }, j9 f+ T( v* nfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/8 M# W4 x- ^- @  s5 ~
{2 C$ n. l! k6 y4 P# e: [3 @/ p: J& L
    Stack optr,opnd;
: g+ @7 b, I! U' L7 L, y$ {# |0 A    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;/ _; q& p$ F4 B" S* W* n! v
    char c;5 G- `: q' c0 g" ]
    char buf[16];5 l1 R5 g1 L1 p1 S3 s, m7 c( z
    int i=0;
. p2 K% c! E' S2 }+ a% D. T5 b   
; V% }0 Z! D! r0 G0 N$ R  g& V    InitStack(optr); /*用于寄存运算符*/: P& i8 N0 G2 s4 {! u$ ~
    InitStack(opnd); /*用于寄存操作数和计算结果*/! }- U% p" ~; A- Q; L0 k# A- @
    memset(buf,0,sizeof(buf));
. M; ^3 f3 Z* W  p& C5 s    : \5 M, e/ _/ ?1 R6 I4 |8 V
    printf("Enter your expression:");1 f/ ^* U: h6 O
        & k1 \' f3 W8 n" C, e2 c
    opr_in.ch='#';
  |- f1 O6 C  U. b# k9 y    Push(optr,opr_in); /*'#'入栈*/, u8 i. ^; {0 ^+ Q0 i2 L" g. S
    GetTop(optr,opr_top);
  ?/ O6 w, ~3 z" h+ [+ {+ N, l    c=getchar();4 g* g8 D4 `1 F  I* e9 i1 k
    while(c!='='||opr_top.ch!='#')
9 T% O2 j# L. z. B' ~. r  n/ N    {, [# m! t" G6 h! @7 [3 U: _
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' e7 L- Y8 @& E! _: ^1 C        {
6 }: Y) h; f. A            buf=c;
3 G; r9 B7 K2 k4 y            i++;. j+ B* J* s* \3 v. ]" A0 e0 K& }
            c=getchar();2 \6 ]% J) \$ c. n* T" g
        }
- b, R0 i7 S5 f) g; ?  L        else /*是运算符*/6 d1 X$ l' f/ f$ O+ Z4 i
        {6 v4 @! Y4 f8 R$ a1 y5 N$ D
            buf='\0';( }/ j( \5 e* A9 D1 @9 |6 K
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
9 ]' ~% b9 _& \            {
% M; _4 C  m% f) a- j                 opn_in.data=(float)atof(buf);
" i0 t1 C" ~$ T5 {- C                 Push(opnd,opn_in);" {4 l/ {4 ]- f  Q
                 printf("opnd入栈:[%f]\n",opn_in.data);/ ?3 f! _/ N0 {: u- r8 Z6 U
                 i=0;4 w( I- [& O+ j$ }0 B% L
                 memset(buf,0,sizeof(buf));
0 [2 V& s# k+ f- f) w# A            }
4 d- Y0 F5 B5 S; C  z# \+ c            opr_in.ch=c;
0 y  X. ~# ?" l7 d            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/5 r$ E/ U. \7 |
            {
' ?  d0 C& v+ x4 W3 o: h                case '<': /*优先级小于栈顶结点,则运算符入栈*/- {" j9 O( H5 a; X
                     Push(optr,opr_in);
% V8 G: x1 O; o3 W) A1 I5 J) p                     printf("optr入栈:[%c]\n",opr_in.ch);$ {: w8 ]% D* m. I3 D0 N
                     c=getchar();4 g; f2 P' ]. X
                     break;6 o9 t  a' B6 F) `5 }
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*// D7 M, N5 [( u* C) T' a9 y3 r
                     Pop(optr,e);  Q+ D  W7 M' m) @! V- Z8 z# K) V
                     printf("optr出栈:去掉括号\n");
. P! r4 [8 W6 k                     c=getchar();
; i! t9 k1 v& q, s& n4 S4 L                     break;
' V" E$ T5 ?) Y9 z7 I                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/, w# d6 h- a  c1 o
                     Pop(optr,opr_t);
- L# J5 I& Y7 Y" |                     printf("optr出栈:[%c]\n",opr_t.ch);' h" o( E& ]7 `7 o6 Z' V( `
                     if(Pop(opnd,b)<0)5 X" V3 c( T9 A; u+ P7 s$ ]
                     {$ ^5 Z" \5 I" R6 A' `5 s$ Q4 b
                         printf("Bad Input!\n");
" H* V7 m, {# g# u                         fflush(stdin);
  g4 ?% g6 @1 n1 ~) k6 k2 O: O                         return -1;
  X! q  k/ g# z                     }1 O  F- o2 ~( w* Q
                     printf("opnd出栈:[%f]\n",b.data);
" D; a) {: \& R( x8 P4 r                     if(Pop(opnd,a)<0)( O0 b5 [: [4 e( b
                     {' Q" i- F7 x9 t& x% h9 g
                         printf("Bad Input!\n");
# [% L8 t2 Q1 K                         fflush(stdin);
/ u' }' g( N5 j7 e2 g* i: E                         return -1;" q. R9 \. ~! L
                     }) i" ~# U# L% o2 m
                     printf("opnd出栈:[%f]\n",a.data);4 g) g9 l0 R$ D/ o
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 f' u7 V0 r( K                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
' A1 `. ~( X! S# b1 S% }# T                     printf("结果入栈:[%f]\n",opn_tmp.data);
5 @4 n+ L1 R+ B/ q* @* e                     break;
: R$ I2 z' c6 C+ z, o            }3 B3 y' X) r2 Z' y' U8 O
        }% u5 h$ u0 N! i% j+ b5 k, J- Y
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
% {1 e6 Q! d! R    }
! B& o* Q( [4 W    GetTop(opnd,opn_tmp);+ [" |+ s. j9 L2 M
    DestroyStack(optr);" b) Z  \' v/ h4 p2 g! E
    DestroyStack(opnd);
( Y! Z9 U' }0 `6 U9 P    return opn_tmp.data;
' }) [" d+ \2 l7 c. n# [}5 P. M9 D, q& W. F( Z/ Q

8 j' W3 s! Q7 O. l; ?! achar *killzero(char *res,float result)7 l" U* p9 L  Q6 O
{3 |' a4 {& k/ j8 Y. _9 E
    int i;% \% K4 v! G% H# E7 J

" p  N1 E, q% y% D, O9 `7 e    sprintf(res,"%f",result);
' e$ N0 m9 v  R5 q5 N0 @( J6 j5 P    i=(int)strlen(res)-1;! f+ J% |8 N3 o/ b& i% f% s
    while(i&&res=='0')2 R6 _& T3 y! r. d& C
    {
3 G( B6 ?9 U5 O' F2 C* j3 x( I/ v        res='\0';
& j- S' ^& Y- {) J" T$ u        i--;' Q3 r0 d6 w8 w1 P
    }
! u. e. p7 g8 F/ |: h( ~    if(res=='.')' \" D0 g* `0 X  ?8 O4 [' J: P# _
        res='\0';" b" U6 m3 N8 A1 G
    return res;. e6 @; R! c+ ]7 m: a0 T2 h
}! V$ E9 Y. `- @. E; ^( `

7 [" H6 r5 D1 a7 d: e' fint main()
7 B8 [  f6 L8 b5 p+ f. o: p{2 B, [- \1 x: W
    char ch;
5 A, E; K. T4 F2 c. y( T) b    char res[64];% W' t0 Z& F* {" R/ b% W
    float result;" G+ g7 e% c; q9 U4 z% Y8 D, G# t/ W
    while(1)
$ `5 o2 x' O0 |$ k% a! e% _" w! U    {
1 F6 S/ _1 G# u/ G4 }& S3 a        result=compute();( O! F+ S. k6 X6 F/ j
        printf("\nThe result is:%s\n",killzero(res,result));8 T9 G( l5 P" E$ ]. M
        printf("Do you want to continue(y/n)?:") ;! [2 b/ |- E* l! Q0 L2 O# v. Q
        ch=getch();
2 k: J) w# Y) ]4 j" a        putchar(ch);& p1 I  {5 m0 Q4 a9 Y& F3 E
        if(ch=='n'||ch=='N')
2 b- a- z/ j" C1 W; R/ v            break;/ @# V+ m) a& [& }
        else/ e* s4 h" V8 p7 z8 J
            system("cls");
3 Q4 U$ \$ d, ~8 e    }3 K2 Q! _$ h5 }$ G
    return 0;
; ~. c! @, T' I  g; r$ S}
! Z% g2 b+ Z$ b* B, p; ^' w

5 u, d- L9 }9 i4 E3 k8 V7 _[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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