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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.0 k2 d3 v! O$ I+ J! V+ S
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
+ ^: G; x  x) Z( b0 h/**************表达式计算器************/
/ o5 Q) ?) l: s8 ^#include <stdio.h>* g' D- j+ F5 g
#include <stdlib.h>
* g6 ?, W- {" [#include <string.h>
4 ?3 M9 ^' U1 s; n8 k#include <conio.h>( l* q" I% Z! N; j& n- g% o7 E# `
#include <malloc.h># g& [3 ^" }% _, J- p+ g

, Z5 o$ A6 ^/ }1 u" Z) ~- r' f: @#define STACK_SIZE 1000 Q* Q* N/ r$ q
#define APPEND_SIZE 10
) c0 n1 B+ ~! ?8 u6 x% `1 `& u! z0 ^6 p- Z# A3 I' I! E, e  V
struct SNode{3 w8 Z2 e# C* o
    float data; /*存放操作数或者计算结果*/# a. g: A/ m$ s/ |
    char ch; /*存放运算符*/
; H! p& ]2 J  [- Y};" r0 H( Z, h7 v! t5 G

; V9 `6 q) _( u; \3 E2 Tstruct Stack{! Z7 Q9 a/ o3 ~6 `% u! b& ^' J
    SNode *top;9 f7 E" j) W9 i0 I
    SNode *base;
, {: N# l) {/ q* X3 D    int size;2 D" v" c; ?$ T% {
};
0 O# Y7 b# s: J
9 m2 D8 [* D# t3 Q" y: j) ]" A/*栈操作函数*/
8 d7 c" Y- j$ }; kint InitStack(Stack &S); /*创建栈*/
2 l, R+ h0 o' s5 q7 B9 u% ^int DestroyStack(Stack &S); /*销毁栈*/
  q  J" r" d. }3 S! O( nint ClearStack(Stack &S); /*清空栈*/
# C& t: [9 n8 ]6 g$ F5 Nint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
1 [  J) e% ]2 K& l8 z( Xint Push(Stack &S,SNode e); /*将结点e压入栈*/
* M, j* e) X7 y& ?- B* S! X) xint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
+ C& Z/ f! p9 c" c2 J2 B
# A4 z8 h+ y7 D% K$ P( A/ r! i; v/*表达式计算器相关函数*/3 w# R7 E5 r/ [2 K9 T
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
/ B3 t' W: P: C% t4 L7 A. E7 tint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
# P7 k* k, |1 u/ l/ D' e+ nfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/. F. s5 i8 W. H$ e& m
float compute(); /*表达式结算器主函数*/
  g7 x# v) F9 h+ T, {char *killzero(float result); /*去掉结果后面的0*/
1 Z! S  @( X# @% O/ ?- m6 v. N) y
int InitStack(Stack &S)
+ I5 h3 q9 Z( _6 O* f{/ v- p0 b; D: p! Y
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+ P2 m- E7 H0 b
    if(S.base==NULL)" M8 b- k9 Z* i  o9 @) @9 B
    {
- T# k- j7 Z' K/ L( Q% T        printf("动态分配内存失败!");
- V/ W2 r: T. r" o        return -1;# @3 W: `8 O2 @: T
    }
9 \# G0 s" _7 C    S.top=S.base;. u2 z, x. G  j) w4 A$ i: z3 \
    S.size=STACK_SIZE;
$ e5 m1 Y7 s* Q# K, h3 O  r+ W    return 0;! v7 n1 w( f; }
}( J$ o# T* c4 R. u6 H

0 L; E5 b( u# M& @6 R2 m2 aint DestroyStack(Stack &S)
( P% f8 h6 ^; @, P4 r" [{
. n( m5 [6 R2 U6 a  w; o    free(S.base);
: X1 P7 p5 ]% ^5 e# U" I! A9 G    return 0;
* S" l# @1 H2 F}
" n/ Q& q' w/ r9 B9 C% N" D6 {* V$ P& d5 x: f" y$ {5 Z
int ClearStack(Stack &S)
: \5 m+ H$ n: F; r; x+ t" F{! `$ ?0 P) x1 `. Z6 q
    S.top=S.base;8 f& {  n8 f  E% n, y( s
    return 0;% `6 K! R# r  A- [
}
, v* g1 N2 W' A+ S* G$ b7 o* L/ s
int GetTop(Stack S,SNode &e)& j7 s+ U6 [9 d8 k8 H
{
. S# @" [4 z  J3 `    if(S.top==S.base)* S8 n1 l3 q5 V% u, L$ v
    {( R* o$ A: M6 Z9 v5 M
        printf("栈以为空!");, B' V% j! j, ?' n8 [& w, U! i
        return -1;
% T  I" }4 I; O% [/ z# O+ l2 `' N$ x$ S    }# S* E; ]* n. N: R
    e=*(S.top-1);% O- K1 T' e9 f: v# C
    return 0;
! ^8 Z3 p  _5 X# L$ D5 r0 \}/ w, F3 W2 e+ t- k7 N* G

* N; u8 R# l* A' g( e' m8 Bint Push(Stack &S,SNode e)! y6 @* p0 A/ @3 p5 {
{
$ Y" V# X( g! e2 c  s    if(S.top-S.base>=S.size)
' M' j3 U& U7 k- |$ v1 T  X  w    {
: B; a% D1 j+ x- ?8 ^) g        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) D0 A0 j3 j# e  s% g: B$ b) h        if(S.base==NULL)* W+ C0 `, O+ L5 F
        {( f4 \# U+ g2 J/ I8 j
            printf("动态分配内存失败!");- Q/ D3 h3 H0 O& G3 X
            return -1;' r4 c5 g9 n% l* a, a3 i. f$ B
        }- F# Q( g9 R. \, e  H
        S.top=S.base+S.size;. F* ?+ I6 b% v
        S.size+=APPEND_SIZE;, ]! ]) ~4 w7 N+ `3 t
    }4 q, [2 W" e$ a6 a* ~
    *S.top=e;
) ~; @2 J6 N) \+ `    S.top++;
0 S" K  b- H+ q0 ]! e    return 0;6 C& {0 W& H8 I8 E, h5 E8 O
}
% I2 N) S; ^" k& ~6 y# R
0 t2 d7 C9 f9 y( Yint Pop(Stack &S,SNode &e)" P# u, [: I" K6 C8 z8 o" A3 f6 c
{
; H# J- c: t0 \& J$ a$ e% V( B' j    if(S.top==S.base)
+ ^, E2 z0 m# ?- M3 x    {% `: Y( A' d1 e4 r; i
        printf("栈为空!");7 s$ s" K6 M+ Y4 [+ Z1 P" A
        return -1;
6 v' [' Z% U* D    }
6 L# y: z2 K8 T5 T6 g    e=*(S.top-1);
3 C- a" E( F1 Z/ G    S.top--;
5 J# ~. m% G9 w! i    return 0;6 K/ B) y: Y6 ~
}
& d1 n8 }1 D% M# J* m
4 r# s( b# z; e! V7 E  nchar get_precede(char s,char c)2 p* C9 Y# `) f& v; U3 b
{6 s& f. F( B: D! F
    switch(s)2 }( L' y  n- r9 k3 J4 k
    {
( O5 B' n5 x0 K# J        case '+':                 
' b; c6 i! H- J; H8 Q: w6 e        case '-':- h, T9 s7 O& B- m" q8 [
             if(c=='+'||c=='-')' s1 _% t6 o4 Q1 h1 X. |! d
                 return '>';, ?5 `) x! q  [
             else if(c=='*'||c=='/')0 [5 f6 j8 x0 K& c( n" F7 d
                 return '<';
  x4 ]; v$ T( o3 L             else if(c=='(')0 m* U( L  Y$ a$ E/ K5 R! _7 v7 O
                 return '<';
9 `" ?5 H7 O7 w             else if(c==')')3 b4 J* z( d0 u; J; V& U; }  k' _
                 return '>';" _+ M2 @: ^- k  O. A
             else ) C+ F; Y8 g% Q3 v" n( f6 @1 m
                 return '>';& V7 P2 r# M5 K& z! f9 e; l
        case '*':: E: C5 U5 ?/ o; T1 ^3 N" Z, h
        case '/':% a7 |( G. e2 d5 ]; Q0 q
             if(c=='+'||c=='-')( k' j1 {& G# R7 {" @1 P9 V+ L4 m
                 return '>';
: P9 j( O0 D/ t  ~  f             else if(c=='*'||c=='/')6 Y4 \* A! p+ V: Z
                 return '>';: @5 l, ?& R4 K- V( E' }  T
             else if(c=='(')5 E9 L; z& U/ O8 k
                 return '<';
) K$ H$ M" d1 n             else if(c==')')
! Q$ X2 s& k: J% j( a                 return '>';" Y# P9 B5 u: x3 k% J6 Q: v
             else2 I. _/ M* ~2 e& u
                 return '>';
0 e- R2 Q: {0 r1 ]# y' A+ ~        case '(':' n" k2 S5 G5 c1 ^
             if(c=='+'||c=='-')& x3 M' h% O) U" n
                 return '<';
4 {$ [8 M  [2 X4 \9 e             else if(c=='*'||c=='/')1 N0 O! c$ t, ~) f, `, O" r
                 return '<';3 ^4 ^3 P* S  R3 b6 K- N
             else if(c=='(')
- \; P/ u1 O& l, @) ]+ u2 O                 return '<';
) E& ~- a' P! w( a! {             else if(c==')')& G# `9 l. q# M; l) F5 v) |, m' [
                 return '=';
- c/ c) }, c2 D% a1 ?- y             else5 H/ s3 C# `7 S! i- k/ Z
                 return 'E';' S$ [- O6 a' n9 b& K
        case ')':0 U; B2 ]2 H' ~! \
             if(c=='+'||c=='-')& T1 Z6 q2 [# k) s- e
                 return '>';
" Z7 w/ S8 v4 ^! A' b/ a- h             else if(c=='*'||c=='/')
  N, ~/ l$ \* B                 return '>';
" c5 \# |" q2 z# Y! C             else if(c=='(')9 }- K% A$ F" v* E0 V/ F3 {
                 return 'E';% E/ i: L4 ]7 J
             else if(c==')')2 Q2 U) W' g# h: G* E
                 return '>';
" A% ?* O) N2 L: T+ |! [; S5 W             else# D" T, o2 ], e/ M4 ?( l) ]; y
                 return '>';
1 B; U5 v* Z! i6 P        case '#':
% u- V+ y* @' f, Z: C! y             if(c=='+'||c=='-'), Z  F) Y, q$ O7 ]6 y
                 return '<';
2 n+ z! P; I5 u4 J0 {. T8 k             else if(c=='*'||c=='/')
9 J& ]! G; v& ~( F                 return '<';8 q$ Z* c+ b% r
             else if(c=='(')
4 _" h: X& c2 I$ f9 L3 g                 return '<';: y6 l* s% s: @! R4 J
             else if(c==')')
  K1 H* P" H5 Z$ Q$ i2 Q                 return 'E';
1 j' L8 c& O/ d# m- Z: `- ^% g# W             else
0 O" H, e7 ^. n' d% w9 B                 return '=';
( k3 o; B0 f7 M# T8 `  Z2 |& J        default:
! L6 q* l0 z9 ~& K' ~" k5 N( y# A' g! C             break;
8 F4 T7 @8 _/ A3 g    }& r# X; X  v( {. y
    return 0;    2 a' G  k* T: r  U7 i
}/ ?% S8 w( d0 h$ L4 o4 E) c
" x8 X. w0 z8 _' @# |, O/ N
int isOpr(char c)' V5 b9 I: o, s! q4 X% ~0 q
{8 C5 ~! R6 N6 O$ a9 J
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')4 ]  x+ F0 B7 J5 J5 z  I$ a
        return 0;  X4 q6 o5 i) \% ]0 ^# U
    else
9 W0 S: y6 B( p        return 1;
- L% t$ Z! e5 J}; [. d6 h% z& X
0 f6 \+ C/ L4 R! q6 S. B% g
float operate(float x, char opr, float y)
) U- X+ G0 _# v{
; Y9 w& [- Y5 l; R* u0 d$ C  h    float result;
  F$ u1 a/ b" g0 C( I    switch (opr): o# k& r  c0 V8 @* z
    {
9 X4 B: Y9 k2 m7 l: O5 p        case '+': 1 {' l+ X$ w. N: D- }  {0 }1 w! j
             result = x + y;0 K' q+ u% x! |! K3 K! {1 U
             break;
2 P! I( N& f* b/ j) y. y8 v        case '-':
$ N. F: Q7 r+ z# Y% b             result = x - y;
  r4 m1 P1 H+ Y1 q             break;
0 D" r: a; s$ J( Q$ P6 Q! g        case '*': & c& u5 H8 A  _0 t/ H
             result = x * y;. _, v3 f7 @; X3 J; o
             break;' ]# P4 |) Z2 i) z+ Z4 d7 f. K, c5 S
        case '/':
, d! R6 J9 r2 e4 P" K& s             if (y == 0)$ c/ ^. v1 Y) {* b3 g/ O
             {
+ D. v& O$ E9 Z6 a! v                printf("Divided by zero!\n");, n7 `& f+ N; Z# A  h
                return 0;  |/ i1 Z- v* @* [
             }" v5 r9 P# N+ i. N
             else
6 {7 N4 \8 t  `- U. m: c             {
. r; M$ b( H. p/ a: s- t* O                 result = x / y;
7 {$ ~- g2 `! y' Q# Q' N, r7 J5 J2 J                 break;  d- A' [; z, P& Q4 H
             }2 @, B1 ]8 t8 z' C( U9 i# `
       default:
- \8 |- U: ?; m( L             printf("Bad Input.\n");
2 c9 C% h9 `  T9 b             return 0;4 B& U1 ~) V" W' {  C7 B* S
    }/ w! N1 `& U) p
    return result;% _* o, O: O8 p, }! j$ m
}   
" O7 t2 K( G* z
$ ~1 k+ M3 _- ?2 f; Dfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/( k( R5 o. _. X/ {
{) |4 ?! L* g! K' e$ D0 A* K$ e
    Stack optr,opnd;
* H& M4 W3 _# J9 [" v  A9 j; X! ~    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
  F! G. O2 w- e) O    char c;
& D% T, S  i/ S, s# I0 m* \( a    char buf[16];. v. Y8 f) r( L$ q1 I2 }
    int i=0;: f, x# q) }: l& c' J- y3 Z) l
    " x' P" u8 e, ?$ Z
    InitStack(optr); /*用于寄存运算符*/
  `. g( }. I4 a2 i    InitStack(opnd); /*用于寄存操作数和计算结果*/
1 E  x0 h$ h/ ^1 i    memset(buf,0,sizeof(buf));/ U$ Y6 T% ^3 m
   
7 I: m4 ?; `. e# k' z) n8 U    printf("Enter your expression:");+ d; p- H0 K; X( a3 s( y5 q
        * {" r$ e0 c4 l
    opr_in.ch='#';
- K* {6 N/ D) J* @7 [- w  R    Push(optr,opr_in); /*'#'入栈*/7 Z* z  [% a7 Z
    GetTop(optr,opr_top);
! L+ Y- }6 _6 y    c=getchar();" u, V+ O- y8 l+ H! p5 S4 U' X: l: F
    while(c!='='||opr_top.ch!='#')
+ `1 ^7 i# o5 \    {
% V* i" U! _9 \- R* l        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ M2 _4 W/ H4 h" P( [& I        {. K/ g6 S7 p* }2 p( }; F
            buf=c;4 v7 P  g8 z9 t5 M5 X1 a& R# G! G$ U
            i++;
5 l- t- ~  V0 t0 M: j& Q            c=getchar();8 @# G5 q1 x7 d. ]
        }/ L  k1 P2 C8 t& |7 a2 s7 j
        else /*是运算符*/
3 R/ K& `8 o" ~' F7 F- ?  O3 Z' [2 q3 ]        {
0 U' y0 h! ^6 m# W: l5 F            buf='\0';
- _( T, S/ g; w( a4 k7 k            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
" `! {( |$ k- @' d7 O" b            {; j# j1 x) x0 Z' b1 b
                 opn_in.data=(float)atof(buf);
6 _) V( a# ]" ]4 ]" t% l                 Push(opnd,opn_in);% }- F( O0 u8 c
                 printf("opnd入栈:[%f]\n",opn_in.data);
- S, m+ E7 Z8 b2 m                 i=0;( c' I! f" Y, [' M
                 memset(buf,0,sizeof(buf));
  u* K' G% V# H. V$ X) t, _            }
  T5 V* c; L& L: Q7 x0 |9 l            opr_in.ch=c;; n3 I# F- X8 d6 R( W4 M$ b
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
% u" U  k7 j" U  E; f1 G) k+ F3 U9 W            {) h9 l( p# B+ {1 T/ h/ y, c
                case '<': /*优先级小于栈顶结点,则运算符入栈*/& M; D8 v# }# U+ Y7 Y* K) z
                     Push(optr,opr_in);
- b! D2 m4 y! t" D- I                     printf("optr入栈:[%c]\n",opr_in.ch);" {) k# n' w/ i7 p% g
                     c=getchar();
* H) P1 L7 |3 h" z0 e7 m                     break;, z( c% C' }4 s7 u' H: O
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/% o( O% b8 @  c7 Q4 T% M1 L
                     Pop(optr,e);
1 ^4 q5 H+ L, X+ q/ y  l                     printf("optr出栈:去掉括号\n");
0 S& h# A+ V% }2 N( D                     c=getchar();
( [# ]+ j' D* _3 ?                     break;
/ Z1 t0 L$ O0 N& o) g8 S                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/4 n3 F1 @  g3 B
                     Pop(optr,opr_t);, a3 @; h  M/ |# S9 \+ V
                     printf("optr出栈:[%c]\n",opr_t.ch);% Z! k% @- K% o$ I6 n
                     if(Pop(opnd,b)<0), }1 n; T/ _2 X* z. Z3 r
                     {& ?; _7 N! y9 a% c1 Y
                         printf("Bad Input!\n");8 S6 w. T) ~( |$ ]
                         fflush(stdin);
3 T; W. t( ~0 U1 P                         return -1;' V6 A' Q: ]$ k* Y- @, |, |
                     }
  h8 _# w0 k$ f4 ?- \# f                     printf("opnd出栈:[%f]\n",b.data);) X3 i. |, g3 a& E# S8 O
                     if(Pop(opnd,a)<0)$ M; e$ V' N8 I( Y* t
                     {
" A1 C! u5 F/ v" a- F0 _                         printf("Bad Input!\n");
+ |  t1 q7 P# T) y' q5 J                         fflush(stdin);( W4 w' ]: u" D3 j% N2 m! E3 @
                         return -1;+ M' i) A1 A+ s. E' J, w
                     }7 s! c1 g& u$ C: f
                     printf("opnd出栈:[%f]\n",a.data);
- p, z* m# o8 e( H% P                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
/ d2 i. I3 e# N                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
' Q2 E% s7 ~7 ^, |. E5 y                     printf("结果入栈:[%f]\n",opn_tmp.data);! [/ _% R' Z0 z/ E) A) C" n9 g
                     break;
8 M( B0 K/ E' R: d: e2 N& }' s            }& R7 k6 [. D% y+ Z7 O5 n+ a
        }
7 ~9 t- {) C% o" g9 J# X0 {        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
5 n; b, M9 ]) Q2 m5 d& Z) _/ t    }
2 J3 e7 T- B0 o$ O    GetTop(opnd,opn_tmp);# h0 ^% b& s: |
    DestroyStack(optr);. H% g* E+ d* e
    DestroyStack(opnd);& @" `' A& B1 y/ C; T6 @/ U
    return opn_tmp.data;
* x# E, f( P* p' A, P3 D5 i8 g& t}
, J2 a6 u# M9 M! i1 u2 H
# P& L9 g: T( X- c7 }char *killzero(char *res,float result)$ l* T& x) x- j) n  l. u
{
- d3 e$ f5 N3 g8 J2 Z3 D5 v- B& L    int i;2 i4 ?* Q' ?# B2 a& P- p7 f" e
2 z9 [* E: x- j" o4 j. G2 e" V7 b
    sprintf(res,"%f",result);! ^2 C' \* S6 Y( a# L
    i=(int)strlen(res)-1;
6 [9 w7 |; ^# k. J    while(i&&res=='0')
( U4 H/ v6 \3 ]3 F  E2 Y    {
0 }; z" p; {% q  M( f& [        res='\0';: Z; \9 y4 d' j# ~/ Y
        i--;( W8 ]  z) S1 |: V  A$ G
    }& j. |* D1 [- h
    if(res=='.')6 C) Z  s' w+ Q* M# F+ c
        res='\0';6 G# n  T7 u( a4 o6 W
    return res;7 o9 c8 R' V1 p# V7 ~. Y0 e3 A8 y$ _
}
  V: B$ [% _" J9 C: I
0 q0 u- m5 |* s3 @int main(). @1 s/ ^. z( p+ V) M$ N
{
0 Q, Y0 Y' B, d8 R4 f    char ch;
! N% j/ m* A* h7 @+ v    char res[64];3 T  j+ u/ x# ]* {. D+ V
    float result;
8 Z( X- X( q* W+ S' l  A    while(1)
/ s: \+ ^% z2 O9 j    {* y4 p- {; b/ \- r6 d( T3 w2 B
        result=compute();
* d+ k% a  f0 O0 X' l4 e! q$ }        printf("\nThe result is:%s\n",killzero(res,result));
! Q5 }; O! P" k        printf("Do you want to continue(y/n)?:") ;
- j  n( t( x8 d* H! i        ch=getch();1 S4 V3 Z: }9 a; [9 ~# r
        putchar(ch);
  f# Z3 o9 L  i( H+ ^  _        if(ch=='n'||ch=='N')
4 {5 M5 Z8 b1 p            break;" ^  B( ~" J! j
        else
, b4 a8 v, y, `$ d  w7 g            system("cls");' y- h/ z5 i+ \' m8 k3 Z
    }
# l" Q% F/ b, q2 T4 e- q    return 0;4 }. x6 i$ A# l9 K8 |. U
}
  ~  U5 K$ U! J  g6 s
) e6 R' f2 E4 U, j3 T6 S
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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