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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
$ J% e0 U( X/ ?4 Z5 V1 {, X+ P" J程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
. Q& K) i! R  i6 R! D/**************表达式计算器************/
, n1 [# v' h( ]#include <stdio.h>* t& c: e( o  {4 Z/ D% G: ^
#include <stdlib.h>8 G2 o1 P% t, G/ Q8 V1 N! H
#include <string.h>
; z) S0 u% O* @3 g#include <conio.h>4 c, _4 _. R# V' k
#include <malloc.h>9 i2 K- M. P% }: m. @

0 x6 }! `6 K$ b& l, d( a* Y- Q#define STACK_SIZE 100
4 [4 `  [3 W9 L( C8 u* j#define APPEND_SIZE 10
6 v$ X  H* d, a( [- B
, L) @# p5 ?  F1 estruct SNode{5 k. B4 T7 ?: B; p
    float data; /*存放操作数或者计算结果*/( N2 b: A- f( Q+ U
    char ch; /*存放运算符*/* e4 {. a) z+ H, J0 M( N4 v
};
( o5 ^$ }) I+ u( w# q  G# Q6 s1 e3 T. B
1 V+ ^( |4 v# ]5 xstruct Stack{+ g9 H% p! D6 I4 j: \: E
    SNode *top;
& K4 O9 v0 b1 h" s8 B7 t  T9 D/ i    SNode *base;' a; J. E5 S4 h" C, ]: R3 O/ s8 ^0 H
    int size;# l1 m+ A% I& d6 C/ Q- E4 k. F3 W1 q7 i
};( G( \' c+ x4 w& p  H3 G
/ ?* Y0 Q+ L1 K; L4 u1 K) q
/*栈操作函数*/3 b, B: _* i' T! b: w) }
int InitStack(Stack &S); /*创建栈*// K4 E/ `( B5 m( l
int DestroyStack(Stack &S); /*销毁栈*/' p" n$ b( D1 C) v
int ClearStack(Stack &S); /*清空栈*/$ b# I9 ^( u8 B1 P, d# l
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/- w7 l! g, ^% K& N+ k& t" A' @
int Push(Stack &S,SNode e); /*将结点e压入栈*/
9 L/ ~: {9 T% {2 ]1 Mint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/  t; c, ~& T( e/ x( m! @
: V9 |$ Z6 g' D1 K
/*表达式计算器相关函数*/- u4 X2 \' N) T1 c: y
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
. n( r$ T4 ?7 R8 d6 bint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) ^8 B9 p- J) K. e8 I7 ~' h6 X# P
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/1 j. r) b* C- Y4 z8 L
float compute(); /*表达式结算器主函数*/1 h) S; q" w6 K7 l' y5 X
char *killzero(float result); /*去掉结果后面的0*/ ' T' |6 A4 F/ m& I9 Z8 Y7 z  I

! z- z; ^! p8 i1 ]! U4 E8 Jint InitStack(Stack &S)
: z# s) w5 D3 [6 K1 N{
5 K' J5 O( G0 t8 ^' S; _0 A    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
3 E9 E, Y& d( F% f2 v    if(S.base==NULL)
! `/ n; K2 G; O2 @    {
1 p; ~( C8 `# x# u3 R. v& F        printf("动态分配内存失败!");
$ h* w) L5 Z( V% F" N        return -1;
0 T4 @" L6 j' T- L) L( C: z! f4 \8 f    }
4 W% F3 u" {" Q$ p5 s% x/ ~    S.top=S.base;
; @: T. ^& G& M    S.size=STACK_SIZE;
0 a& [% l& T4 n; ~2 I    return 0;: @9 v: s% j. g( |3 v
}
7 |4 t# P" N# P# E% u% T
& G1 e0 t$ x7 u8 T3 Lint DestroyStack(Stack &S)
+ {) p/ v" J4 F5 X  M" e2 U; q: f5 V{
6 I( K4 Z0 j1 W    free(S.base);
' R$ _/ z/ r9 R$ t' b    return 0;
; y; \0 T+ M% C7 l! q# R, V}
1 p5 k7 R8 c) M7 b6 j. E  |
. d7 t  P: e& ], ~2 oint ClearStack(Stack &S)
& L( J' e8 w/ a( x* m( @! ?{2 G9 @7 Q: O! @3 e9 C* V0 W
    S.top=S.base;6 O* o! x) [6 p6 k+ E2 v2 F# y2 G, P! N
    return 0;, q+ e: d4 ]1 C% }7 w0 ?7 h
}2 h& x+ c( [6 [' E5 H
/ {; r  I; @, ^- _6 p& N$ g5 H3 I
int GetTop(Stack S,SNode &e)  [! C! Y8 x) @* x: X
{
7 p, e. v4 d1 K4 v* m8 s  T    if(S.top==S.base)& O! E/ g7 e: K# W0 d5 x& F* x
    {
% Y4 [- U: E" Z2 V$ b        printf("栈以为空!");& I( ^9 E+ t1 a4 K, U1 Z
        return -1;5 W7 p8 e! b) G- i
    }7 \+ ^2 P- w  J  R6 \* K
    e=*(S.top-1);
- i& |4 E  U1 k0 F1 M8 y    return 0;3 e" L* X( w* g3 I8 W9 a' P, P
}9 V6 d  C9 o6 B6 @( O( X+ O4 g. k% B

" m! b' N0 ?% m+ M( xint Push(Stack &S,SNode e)
7 B& ?" @. l7 h, }' C{% w+ D  k: o/ o* r' @- Y3 ~  `
    if(S.top-S.base>=S.size), u7 p  S8 |+ ~& l  b  x
    {6 d* ?6 j" X4 c. T
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));7 g5 C3 ~4 b3 z; v, Z, ?2 Q4 o
        if(S.base==NULL)
6 H, f2 n) H/ M4 h        {
9 V" r9 b- [% Q  g            printf("动态分配内存失败!");. p; z4 Y4 t2 ]. }
            return -1;
) g( @9 e* d9 `& r, T) @6 M0 ?        }
& `, u, h4 N7 T% n6 c. {* z, C        S.top=S.base+S.size;
  [$ O& y7 ~2 C: e; e        S.size+=APPEND_SIZE;0 P" D. B. t: X
    }6 y9 q* o0 L$ ^4 r
    *S.top=e;: i) R  r. b9 D) u7 [
    S.top++;
2 C& ^- D) e8 ]0 J, W7 K    return 0;
) M# s7 U1 q) s9 x- W. ]3 h* Z}
* ~# ~" Y6 Q5 P9 n" G1 G, Y2 [# r0 }8 i& ~
int Pop(Stack &S,SNode &e)
6 O# X  `# v/ M$ i) {{' J6 c& K' |- z7 P, `- C) U
    if(S.top==S.base)& U, d* g3 @" ~" Y8 a# E
    {  f9 ^. t8 `6 `& H" V0 ?! X3 u1 p  t% ~
        printf("栈为空!");. B! ]  k7 j, t2 S4 I1 G
        return -1;- J/ d  D0 t" I) t& H- F
    }
0 X3 p1 z' D' |    e=*(S.top-1);1 B! D* x4 l8 i4 a- v0 p' B3 E& b: H0 {
    S.top--;
* w, L( [- H  r* P# m: X    return 0;- a: L% b/ ?8 {. V  ]* R
}4 r# Y! o6 g+ d+ ~

# ~2 L0 ~, e+ Vchar get_precede(char s,char c)
. n# ~: R, n. A5 r8 F{
7 d" W5 P* ]* }7 o0 E3 i: O1 H5 z! A    switch(s)
1 p7 O7 H, ?( X8 X5 v    {
2 Y) U7 q2 {! j+ a" K        case '+':                 
, O; q5 A6 l/ j; V        case '-':
! S, q9 ~( G' d: p             if(c=='+'||c=='-')4 ]6 f3 Q+ J! @. N
                 return '>';
* \# k* Z8 m) e+ k             else if(c=='*'||c=='/')' I1 M$ X/ ?0 i2 q" C3 E- g9 q
                 return '<';
1 t; H; ~: {+ [$ p: G             else if(c=='(')
% ]1 ~  e7 x, `) ]2 H9 D4 J                 return '<';  }' ~. T& b( K) d) M
             else if(c==')')- @& B  U  S% a& v; N2 b  N/ @
                 return '>';
, X. i" e; T& [4 O             else % ]3 C5 o+ q' ~
                 return '>';0 e9 \4 h4 a8 w
        case '*':
: ^) s, q' c1 {6 q& x& R        case '/':
1 Q! d/ \) [- O  k; H8 w0 W; @             if(c=='+'||c=='-')% a+ f3 H/ i2 V5 R3 o
                 return '>';
) E4 b$ X6 Z' a3 e             else if(c=='*'||c=='/')
) Y5 V6 b. u  w5 C8 d0 @                 return '>';
' o/ y8 [/ _5 r+ n6 w" B             else if(c=='(')
; T2 J+ p2 i; I! i                 return '<';+ x$ j! _8 V6 h2 V) F
             else if(c==')')
2 D# z& f, T& P4 x6 Q4 P# }                 return '>';
" Q2 z8 k; i# c& h, E2 T; P8 M9 }3 [             else* T2 |6 H8 h$ D1 Y$ e4 ]
                 return '>';2 @$ o* {6 B; K- q5 G2 d9 \* w
        case '(':% E4 t0 K( U' E  W
             if(c=='+'||c=='-')6 I7 r* W8 h8 k) l+ R" P0 A
                 return '<';( E/ P; X; K: ?
             else if(c=='*'||c=='/')' e; N' e8 w, ^, x' ?- _% |3 s
                 return '<';9 ^9 K9 @7 b: o( a+ M4 w+ x
             else if(c=='(')- {5 y; s0 m9 I/ X, l8 W' m
                 return '<';- N, h) I) E0 p+ o
             else if(c==')')+ A3 d( w0 k4 g; Y& V! r
                 return '=';
1 P, I4 b' b' g, R2 C             else8 d3 }6 Z" B% C1 ?) D
                 return 'E';3 r( e  q+ h( h6 o; J5 l& W9 c6 F
        case ')':
* H1 v9 U( `9 Q" K             if(c=='+'||c=='-')
2 b0 `# O$ {8 d/ U: F" \                 return '>';: G' {8 r( w4 M. G$ ?. Z8 o
             else if(c=='*'||c=='/')2 h2 ~* I* @: @! o6 m' u8 h
                 return '>';
' m. Z1 j4 l% [. b9 J             else if(c=='(')' N+ `1 B0 F. Z; C% d; q% f
                 return 'E';
" q) Y) @% _+ c+ `$ m0 |2 y             else if(c==')')( g/ c1 \) i  F2 d
                 return '>';3 L3 N' \# h; K# V+ K
             else
/ L% C) p, K( |0 I' u7 w4 P                 return '>';( q" n9 K" z/ L) R4 V8 h$ y
        case '#':
& M! V# T9 j  b             if(c=='+'||c=='-')0 l% ^; _2 p1 D; n9 f* x
                 return '<';6 M4 n" N9 O4 ?: T. {7 }/ u
             else if(c=='*'||c=='/')# u. Z) |$ n# ^
                 return '<';$ F4 U* P; R  W- w6 A6 D4 P7 p
             else if(c=='(')
0 t9 D. f) p" l! D                 return '<';
3 Q3 m2 @& i! c! w, b             else if(c==')')
* V7 f3 G) m+ w% G                 return 'E';. y; C9 x9 |* ?) d* h
             else) Q, L8 m3 K, `; E8 n
                 return '=';
+ [, y6 _* X, h4 ~( r# T" W; B        default:
( c* z6 z, k, w: E  p             break;
/ o2 J) }9 u! _7 i: s    }  A. f  S7 z, j* }0 t7 D$ h; P
    return 0;   
6 B4 y3 r2 H% e) L}$ A; e6 A7 ~. f0 t0 j! R
8 I; `# ^7 r/ D9 G6 ~- x2 s. Q
int isOpr(char c)
6 H6 I, L* x$ w$ j; j1 K9 @7 b{1 C- d/ g0 O! K: I0 E
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='), l6 O/ F; q3 w
        return 0;
/ \5 x' B+ I' _    else
6 W! h6 b" g4 D; D: K        return 1;$ e+ U# f$ s# A+ P$ N; p
}
6 @' n/ c/ z: w  ~9 @1 ?6 B2 d5 i9 N' a8 ?6 |9 z
float operate(float x, char opr, float y)
+ h' W- h6 e) |2 P6 \! _$ c{- D- _5 w) Z: L
    float result;
; o  f0 }. X4 h5 ^& ^    switch (opr)
! `1 P0 H; L7 V. A( Z- \    {
1 {. B& U, n: @& ~8 m0 y' K% _: h% M        case '+': 6 R6 C, p) l, A$ A5 @& o
             result = x + y;
4 r( [3 X5 d' u+ a7 S: p             break;  C# o! s' ?6 ?7 N
        case '-':
1 l1 ]6 P0 X; c, ]; L& l1 @             result = x - y;% q7 g: B! `' a% {+ U" K" r
             break;" D! y0 O0 J8 G7 {( q+ L" W# _
        case '*':
" F; ]& G1 D* j2 U7 k             result = x * y;
9 P4 e$ }  r; V$ Q. W0 ^4 Z             break;
3 m7 ^, h4 F  k1 Z        case '/':
& H7 r6 z4 \- r( l" z/ c             if (y == 0)
, L( [/ V* g; U5 P7 l             {
) l2 N' s# d0 ^* Q) Q& s4 Z5 J$ q                printf("Divided by zero!\n");
1 z5 m& R6 }0 _" u# K                return 0;  i( T0 w4 G2 K$ S4 r
             }
5 V  e; x! z. d* y9 a  M8 Z             else
. U, p  E" [  D1 F1 l0 \             {
# D1 s# z, J/ ?1 h, F                 result = x / y;1 p6 ?' u0 K/ l4 E( n2 i
                 break;5 W- [: A; a" v$ O0 Q0 h* `( z
             }
: R$ b. p2 B* N" A! s2 [       default: 6 d) g6 ~/ a% f! i3 N) {8 [+ v: Z
             printf("Bad Input.\n"); 6 k: I* z# d# Z3 o* x
             return 0;
6 {9 Z+ {9 F( d" M- N- I6 `4 [    }& `0 o8 i' a7 ^
    return result;
: Q) I* c" M: c/ E" r}    3 k. \- Z; x3 y1 f- T  k/ m9 ^

& _4 k. y' Q  P) Lfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/+ H2 S- s5 m5 K! N
{: ^' Q/ B- T, r8 `
    Stack optr,opnd;7 r, \% v/ |) E' v9 ?3 F
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;0 P& y/ U; E/ z$ C( y
    char c;# L2 @1 u' {8 J2 O1 m% x
    char buf[16];
. {3 a4 h3 u; R5 Y+ b" n& X7 q    int i=0;
/ e, Y3 m# _$ I      m! b8 }/ e3 e
    InitStack(optr); /*用于寄存运算符*/1 A7 k( W4 h2 m' C* Y1 G, @- ~
    InitStack(opnd); /*用于寄存操作数和计算结果*/
9 j2 l6 Q8 @( L; N3 {. a    memset(buf,0,sizeof(buf));
- Z; D' ?: ?9 G0 z   
' q* \# P$ e  H0 f" r. {    printf("Enter your expression:");
2 Y) c+ ]2 j2 S; f& I        
+ {( S* q9 P! ?3 W6 _3 \" ?$ d    opr_in.ch='#';
9 {2 `1 U. s1 x6 F% G+ P  M    Push(optr,opr_in); /*'#'入栈*/: h" d) Z! ^  j- U8 q# }
    GetTop(optr,opr_top);
6 I; k% H0 i% m3 P7 k6 X    c=getchar();
' x9 ?9 X9 e9 u% l1 c    while(c!='='||opr_top.ch!='#')2 l; i6 R$ \7 T5 f$ s
    {. K% i/ u9 [% S
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/9 t8 {1 e6 ~0 w1 a7 X" P8 ?( p9 r
        {; t" |( U7 @$ U: R4 D
            buf=c;
$ @' M# c7 v( h7 [* M            i++;4 q. V) p, O% R
            c=getchar();- l% D7 m$ K; ^: j3 F' }, Y
        }9 m' Y5 h1 v- X
        else /*是运算符*/0 _- E" T: `- `5 m
        {( |8 J% H/ o! w# Z; X
            buf='\0';
: V' ~, y0 l! R! Z4 H: v, d, S( E1 Y            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/9 D% U. t/ ?  z$ i/ q
            {
% x! g9 |: L3 h7 L, \6 k0 `/ B1 ~                 opn_in.data=(float)atof(buf);
9 m6 S* a# d, J5 |- g+ W( b6 i! w                 Push(opnd,opn_in);* b( S' l1 u/ C: E8 k' d) h# Y7 F7 a
                 printf("opnd入栈:[%f]\n",opn_in.data);
7 @$ q5 n0 d- P                 i=0;
: ~5 [& N( X4 N! Q* S" h                 memset(buf,0,sizeof(buf));6 k; I& ^: t# M$ b. x3 k
            }3 ^" V5 U$ d+ i6 y% f! I( J
            opr_in.ch=c;
/ g. p/ R2 N  S            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
4 W) T) g. _, ]2 N( M            {
; ^% y% T$ J4 D# ]9 I                case '<': /*优先级小于栈顶结点,则运算符入栈*/' c* B. T$ Y6 ?" ?! d* P+ g
                     Push(optr,opr_in);3 P( p4 D7 c7 a) W: n! V, M; m
                     printf("optr入栈:[%c]\n",opr_in.ch);
  a! z. M* [: g  y2 U2 ^                     c=getchar();
/ H7 y4 Q8 K- w3 }7 T  c                     break;
% A+ j9 h# L/ S2 a' y                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
* H. i$ G: C* A" c& r                     Pop(optr,e);
. z$ D3 U/ h" H) B  }# ~: v                     printf("optr出栈:去掉括号\n");
) j5 b, O, J2 w( A, i                     c=getchar();
" I/ F  u" k3 v& `8 i: N( ?  }                     break;8 }9 U1 [0 F5 U  \
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
8 H1 C7 [2 N% |4 x' z9 s+ u                     Pop(optr,opr_t);  B6 o1 G3 L# }/ J$ g0 B: d% d# [
                     printf("optr出栈:[%c]\n",opr_t.ch);2 {3 N# `# o. t4 b7 U
                     if(Pop(opnd,b)<0)2 Y7 P6 s% U; k
                     {. r; O% _9 D; c4 k6 S9 E) @) `
                         printf("Bad Input!\n");
* ~2 ~$ S$ p* o$ Y9 p0 n- {                         fflush(stdin);
* s2 c& v' d7 x  Y                         return -1;
. y5 G8 y; f7 z* A; v9 x) S/ v                     }7 g: v9 X5 Q3 U$ Y8 L7 W) B* S
                     printf("opnd出栈:[%f]\n",b.data);2 x5 S1 G) G& j! c1 W; G
                     if(Pop(opnd,a)<0)
% V2 W/ A, p! @- e" m                     {
, V2 p' j7 X* q7 L5 |: g                         printf("Bad Input!\n");& S/ ]( F! q; W4 n6 Q3 x8 a+ z8 l4 A  q+ v
                         fflush(stdin);
4 e5 U/ ?% W3 F$ {" Q                         return -1;
7 f3 Q* T% ?5 F, P                     }& w) H, W1 c( E& j2 d, Z8 M2 S: U* W
                     printf("opnd出栈:[%f]\n",a.data);4 _# v3 Z( f& H  V% }* k$ F
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/6 x+ F( O% ~7 w, z( ^/ M
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
" n! J1 N% L5 A; Q                     printf("结果入栈:[%f]\n",opn_tmp.data);
( N  m" Z! S. e6 r) \                     break;  G8 Q1 @3 L+ \9 }; C" Z# j
            }
2 U" R: ^, k; E; t5 ~8 i' [, m; Q' x) j        }
6 x# H- n7 z; t# x( y& V" F. K        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                # `  S& S2 M/ U, Z, `8 Q' E8 C
    }
9 s' p' Q, w+ y" X    GetTop(opnd,opn_tmp);
' B; W& i- l; s7 a$ C8 o    DestroyStack(optr);' o2 }4 T, t7 R7 w2 q5 d; `+ Y* q
    DestroyStack(opnd);
  v! d% o0 R: v! i, p1 H. W! j    return opn_tmp.data;. M  A) b3 G. V8 z6 H
}( n# g  n7 o, x  [1 g; c* B

, E: C2 f, r# B  G  O/ k8 n+ z4 Echar *killzero(char *res,float result)' W( R) C' S( H6 g4 f5 A
{
3 y$ d$ A9 X: f9 V& \    int i;& {# c; W- l: e/ Q0 m3 Z# [9 {; x, D9 E
8 W9 E& k$ t/ B* m
    sprintf(res,"%f",result);, Y6 y3 ^0 c/ y
    i=(int)strlen(res)-1;
8 v4 i6 r& ^* k( A    while(i&&res=='0')
/ E, f3 ]* ~! f7 p3 y( w& s    {; l& F. G! b' u- ]' H5 T. _. M
        res='\0';
+ |, U: ]- v1 h/ }: c' ?        i--;& ^8 D7 g% _6 I/ z
    }
$ g+ o1 {9 K8 R6 A1 E9 }' T+ `    if(res=='.'); r! s& S7 A- N4 Q: y+ \  j
        res='\0';
4 r0 M- Z0 ~) u( X# }' U    return res;0 _# Z( a4 F  x* \
}
- T$ G4 p  e) N" _, L7 x1 [+ ?+ `0 \7 q0 {0 {# ]1 S( i
int main()
2 I1 n$ Y2 }* q% P9 D; @& i{( p) d$ F4 ^+ q& R
    char ch;
: F3 z+ K' V$ A    char res[64];, j$ K6 n+ ^. b! W; j5 P
    float result;$ G/ x7 a7 o- a# {
    while(1)
. g% i" m# }7 J( `2 }    {! T( V/ |* m" J% t4 F
        result=compute();2 D5 W; a* |& t( Z  ~  @0 M9 H
        printf("\nThe result is:%s\n",killzero(res,result));8 `8 X! j/ m  A2 g
        printf("Do you want to continue(y/n)?:") ;% ?4 y! q/ e5 C8 i2 V3 n
        ch=getch();
. K% H) K! \( s) t, W: ~; S        putchar(ch);
. W- y; z* k: i4 Z1 Q/ s        if(ch=='n'||ch=='N'), @1 b8 v7 n1 u" b
            break;/ D% y/ }! K% y( m, j# k& n
        else+ P) Z) u% u9 p; Z
            system("cls");
9 F* X' W7 z" ?- y( J    }4 X' x$ }6 h: z" G2 Y( R- z
    return 0;0 C, t- g1 K  M- }
}
: {& k( G. v* B
- @6 P" L* l7 \7 k
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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