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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
( e$ R$ H* p, _) T程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
2 J3 K7 L4 Q( f) f6 W" O, B& p/**************表达式计算器************/
+ y0 K6 P( v& A#include <stdio.h>, l: |) M$ g5 j7 }
#include <stdlib.h>* l1 p* J% T- G+ e* E) ~
#include <string.h>7 n9 ]) R* n/ C, k
#include <conio.h>* x) j1 }$ j* x/ m1 Z0 w# n& L
#include <malloc.h>4 [' `4 w8 Y2 ?4 K

% z/ ~$ L3 D+ x/ j, z2 [/ ?#define STACK_SIZE 100
$ S7 Q& s5 P1 @) j! O#define APPEND_SIZE 104 L- S" E$ {8 t4 o. Z
* R5 b8 F$ d9 L- ?) Y0 Y- L& x6 T
struct SNode{
6 o1 {# h( \% z    float data; /*存放操作数或者计算结果*/0 ~  B( D$ U* K
    char ch; /*存放运算符*/
' P+ J9 [5 O4 b2 O* K! R' e};. X9 {2 D1 J' {5 G

5 i. |8 b: U8 xstruct Stack{
3 j. k+ y! {3 |) [; x2 b6 M# A    SNode *top;
* H$ S" u9 B/ c& K+ X    SNode *base;
  h/ l# _1 d, [    int size;
( Z% h  B7 \% S; F  _};5 _) y6 y) a) C2 D1 B. V

1 Z' q3 q1 l/ d# N& E4 d/*栈操作函数*/# p) ^$ R. w0 }* f* I7 Z- ?0 `
int InitStack(Stack &S); /*创建栈*/
0 g. @2 g5 @0 I$ o$ Q2 yint DestroyStack(Stack &S); /*销毁栈*/
, P, h. C, `2 \3 \, O; v0 {int ClearStack(Stack &S); /*清空栈*/
) E% M0 F) y5 B% Q, eint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
; }$ {. ]% {- B% h- dint Push(Stack &S,SNode e); /*将结点e压入栈*/. G: r* P! [( V' t
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/& \* }) s& w5 d( B
6 @) l7 b  d, X  C: c* y" r3 F- U
/*表达式计算器相关函数*/4 I! P; r4 M7 @
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
( }3 ~9 ?8 ^' g8 Q% ]int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/, G. \5 ~9 X1 z: T3 F. r
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/, t1 x0 l- ~, t) P
float compute(); /*表达式结算器主函数*/% |4 R1 l& _' P0 i1 l6 R+ Y
char *killzero(float result); /*去掉结果后面的0*/ 2 n  P2 B* y" s- T$ p7 O2 x% s- d

$ f* U) a3 H6 i+ c" b9 O5 O( z: \3 aint InitStack(Stack &S); |; X! ]) E. c6 \- `
{1 P6 m0 _& e9 b
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
! z- e4 s( R+ V, Z    if(S.base==NULL)
2 h5 y) e) s6 k4 V  c    {
  q0 I+ ^. b  u* i7 h- n        printf("动态分配内存失败!");
4 V+ P' P0 }5 U' T        return -1;6 ~% c1 x( @  S+ z" j$ p4 r
    }
9 [8 t2 @& G  N    S.top=S.base;8 }. u' i  g; Y
    S.size=STACK_SIZE;
- z2 }3 F! p' r# [8 K- q    return 0;
  f9 k" v$ G1 L: I3 p. C; l& A}" G- T- W2 ~& L& w' F5 n
7 E0 ^& g' o* ]1 @6 H* S
int DestroyStack(Stack &S)7 T6 @  L5 K& M1 q, {# V
{4 w- L& M9 v& `, b
    free(S.base);4 C# w( D# x# ?8 H: H
    return 0;
/ I4 v9 L% m7 [$ d7 C}
% K4 B$ A- q6 A4 |0 @5 g$ o" T4 \4 k& d9 D
int ClearStack(Stack &S)  D9 t, c" o& R' L/ l  f0 @
{5 t! ?, c$ \: ]6 J- D6 k. }
    S.top=S.base;1 }, ~, `( C% ], D% e3 V
    return 0;
6 R1 [* h/ j4 O6 B# W$ a4 q}
+ T( c- M9 H! h- V# N7 I# O* U/ J9 @
- G! Z4 u+ b% T) G9 R) P9 xint GetTop(Stack S,SNode &e)
$ W1 ^5 u* _& o( D1 u+ k5 p{2 L& q+ t/ b& F6 o- D( B
    if(S.top==S.base)
  f6 o6 q! w7 m& P+ I$ H    {0 @  K2 y7 G* ]5 x. M# W; p
        printf("栈以为空!");
* C. }& o. \1 a, Z! R" V! w& F        return -1;9 c' K, F- t) f
    }
5 _0 P4 c( a: w    e=*(S.top-1);
! h/ B5 ~' e, a, j: Y    return 0;" e$ \( D4 m: L8 v) i3 C5 v/ u( X
}
0 x3 {+ w* z, u: X! x% w/ ^& F9 o6 o9 z
int Push(Stack &S,SNode e)
; d! l. m8 e4 U/ _4 w* ?+ `& C% y{
! R$ ^0 R- }9 Z* o# v% ?* }! W    if(S.top-S.base>=S.size)8 d# k: A9 a% @  {) y8 U* c2 O) H$ S& F
    {  a) |' U; \6 q( D5 d; |
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));# l" @1 F+ I0 m
        if(S.base==NULL)' F! b" J1 D, |6 R
        {$ Q: C, |) W' c( O
            printf("动态分配内存失败!");# Y7 m& n  [" h  `1 U: j2 W
            return -1;. w  K7 C' L6 w0 x
        }
% \" {1 L2 H1 k3 w4 {; |+ \        S.top=S.base+S.size;
; y1 g: X, x$ \6 p4 f( Z1 N        S.size+=APPEND_SIZE;
7 |1 d) z( m/ G# {    }  @9 ?; G. m! i- J7 ~" k# N- T7 V; E% _
    *S.top=e;: j% ]' L# K* H$ a5 j- d" l" Y
    S.top++;
! p. e. Q6 R( V; h" |    return 0;
5 X- T0 O4 w, A}
; e# g0 |, [# T: o  U* R7 @1 p/ V  r" R
int Pop(Stack &S,SNode &e)0 p7 r' d3 S3 z) H! d- l9 L
{
* `: v; c. G4 a+ A    if(S.top==S.base)
4 F+ j" \" d; Y    {
; c( C# U. ^5 m1 H' V. G4 |        printf("栈为空!");
8 i; A' ^' `$ Q9 g( ^1 ~        return -1;4 j$ N  Q7 _& A, C
    }1 d, l( g, F6 h
    e=*(S.top-1);5 T$ r* `( `+ ]! }& T; j' R/ ?; `
    S.top--;. j$ Z# f1 f, Q) i
    return 0;
7 }- l5 n) A; H, e+ Z6 Y}; S+ w* L2 A9 X+ V! h

7 z1 e5 K" U) Fchar get_precede(char s,char c)
+ K; w6 S( P1 v7 R8 o9 y) q* o* a( K{
% ?' F1 ?5 i3 }' C( ~    switch(s). \! H+ u$ N1 H
    {
0 F  y9 K0 ?6 _9 H/ w        case '+':                 
: `- L0 P3 i! V( _% p        case '-':
2 ^' u; o6 T; `  S; n7 v+ f             if(c=='+'||c=='-')
2 S! F: u4 i, X% _( S* f6 ]$ u$ }                 return '>';
9 }# X  z0 r% t" K: M; u             else if(c=='*'||c=='/')0 m, _) v, w: x/ I
                 return '<';! _* {4 ?. h% [1 e
             else if(c=='('). a- L, j" j7 y$ a! `: U. L; b
                 return '<';
8 r, t8 ^0 o  q' c' ^             else if(c==')')9 s% O1 W+ U/ O: z& q3 k& h
                 return '>';3 D) {: B% S) g  m9 M- H! z
             else , B6 u, x5 M! d. T" r
                 return '>';' N7 x$ ]1 D) N5 ^: ]* L
        case '*':3 A1 T/ Z+ c. J* N# z
        case '/':0 b0 o' [& ]/ k) \7 O/ B7 t
             if(c=='+'||c=='-')
; Z, v8 F( l, X) K- m                 return '>';
9 g. j& I1 j# q6 `4 P6 m7 P             else if(c=='*'||c=='/')+ ?1 o) }) Z1 S9 }/ V
                 return '>';
2 {0 y. S7 J  Y. N$ i/ F, h0 B             else if(c=='(')" \9 j8 I$ S, ?
                 return '<';
+ g' ], O* }) S. W             else if(c==')')
& m0 U7 c5 A5 ?  |' R+ L2 O                 return '>';
3 n1 V- u$ x( B5 K, C- {             else8 t, u, ~8 E: h# X  [+ ~! q, t0 [
                 return '>';
7 Z% @# J7 s3 f( c8 \$ N# n1 _% Q: h        case '(':; W( K) r% i+ ^. Z2 P2 @/ O9 \5 x
             if(c=='+'||c=='-')
" ~! e5 {) {! Y- l" t                 return '<';$ W. ^) |4 F  ~- N% n& k. Q: |. I0 f- b4 n
             else if(c=='*'||c=='/')
/ J# p6 X% |- u. I' O                 return '<';
( {7 ?. j1 a; |2 h             else if(c=='(')# |6 w' k- P" @3 U9 a0 k" p9 |
                 return '<';
7 ?. `, {/ b5 z2 O+ N             else if(c==')')
; T3 d" k" H4 z& e9 W                 return '=';
/ ~+ l; F3 r2 X6 B# v             else/ U5 f1 v6 X: f( |- j7 @
                 return 'E';
" `; r9 m8 Z) N        case ')':+ q% S$ Y4 y# P/ F4 a$ |2 a- x4 _
             if(c=='+'||c=='-')" c( {" Y0 e# K3 o
                 return '>';4 _7 I! c& ]+ {0 C3 N
             else if(c=='*'||c=='/')  A2 A: E0 Y* K
                 return '>';, A6 i% ^9 ^) c+ T$ S( c2 w
             else if(c=='(')6 G3 }9 N8 r7 l. R3 K
                 return 'E';
% n/ ^" `3 Q- |6 c             else if(c==')')
* Z5 e4 N4 j  W' a. R9 s                 return '>';4 S4 u! J) m: K  t
             else' `7 `- I( z6 p" i7 ]1 D
                 return '>';
, ?* |7 C' r. V" n        case '#':0 F3 @2 `% l& ~8 l* X' l
             if(c=='+'||c=='-')
) t1 Q# u9 s# A1 @9 ]                 return '<';
, T7 m+ Z  b" u" q6 x             else if(c=='*'||c=='/')
: d# E6 z. z/ E8 `                 return '<';
: C5 K2 \; h9 v, @: v+ x# `' }             else if(c=='(')
4 L& z: l8 A9 e$ s3 A4 u) x# i                 return '<';
9 q( a9 Q& ?. {. X1 e$ P             else if(c==')')% i* k1 ]/ C7 ?! V' B
                 return 'E';; V; c# C! D# {1 B9 F# x
             else
+ b( R6 t+ b- k. d8 n- P                 return '=';
- j9 h3 Z5 _0 r; P3 P! `        default:" X5 C2 s% ?2 M& p3 N; G8 J
             break;% ]8 w7 E# p" O- X% D/ N  W
    }
& _& X; M$ t" x. t( e    return 0;    / J) D6 i! b' K9 V, d
}, ^# G4 @+ V' I* V
. `3 i2 _/ }  R0 R
int isOpr(char c)
& X$ g* b7 A$ S$ S# `* q{
* g6 _* @" O7 r! l6 B# ?    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
# ~8 n: ?2 n) [; l3 {/ H        return 0;
" M' o5 F, v+ E, v; z    else ( x* V, [* a! T: j  {- _
        return 1;  t7 J4 ?2 A* [5 P
}' c+ W0 R8 _- q7 _/ a' W* U
% S9 L! w6 T8 U/ h' W1 M5 e
float operate(float x, char opr, float y)
) S7 t% T/ Z* d{, w; C; w' H! A+ H/ q. j
    float result;
" y+ [0 P+ r3 c. l& Z4 G    switch (opr)
+ a$ _  b9 x4 A    {
. f- \% ~" g" F' K        case '+': ( w5 G) A7 \1 z+ `  T. b* ^
             result = x + y;
9 b8 {1 R" \$ w! D             break;( _: u, p8 X6 C: o" k
        case '-': 2 O  b/ G" t- N& T- @2 w4 A
             result = x - y;: T5 {+ y0 @  @; {4 ~
             break;
  u0 C) k$ D3 V$ i6 G0 k        case '*':   c' T& S9 J; k8 _! s$ u
             result = x * y;
7 Q7 x. W+ G* {% g1 F6 Y             break;
! T. L, D3 x( H; ~        case '/':
5 A% ?! x' ]5 g) ~" x. v) ?             if (y == 0)
! C7 w: E: M) E) w' A4 ^7 P5 w7 }             {
& U/ ?: L/ H+ g! ?2 ?5 w& {                printf("Divided by zero!\n");
7 T+ ~6 K; ?- I& k; j                return 0;2 X- ?( Y% [" n5 i8 p/ Q( k5 s7 T
             }. k+ q' v1 a1 \4 r
             else, A! e* ^" }8 z9 u4 T  V9 {
             {
) w! {9 i' C0 @7 Z5 d& W" C                 result = x / y;2 ~# n7 p+ h0 U
                 break;
% d' B" `( R. T* A) s$ |5 V             }# |# I; q/ O$ A6 t, _6 x
       default: : @$ d- F6 j/ f+ [9 q
             printf("Bad Input.\n"); 1 G* v5 V4 A, X: k, A
             return 0;% d, i, {) H* l
    }
9 x8 m, K9 L! B2 w" Q3 z' l    return result;
6 ^: q3 U, r+ f# n( N2 e}   
- l+ q2 X7 ]+ l+ a. l8 M4 e0 l; j2 q1 ?. i# X% j4 z1 o( Z
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
$ m, E0 y+ W4 x3 I' u0 O, ]{
4 C, c+ U# W+ ^  Y* l9 g    Stack optr,opnd;
" @; B8 u4 F; \8 w& U    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;0 G8 j) ^) L* r8 e9 m7 U; O
    char c;, v; P  {. c, N5 W, {3 v
    char buf[16];
% S& L: U" x" s* R: S    int i=0;
4 y% C' a% R% w" G   
5 |  _5 D0 K* r    InitStack(optr); /*用于寄存运算符*/
& D: h0 d1 N; F& \! f$ W- \    InitStack(opnd); /*用于寄存操作数和计算结果*/; _; ~& N- s- e( Y
    memset(buf,0,sizeof(buf));$ }' A6 T# P6 o& X
    4 ^; @$ G& z. t6 w% b
    printf("Enter your expression:");
! b( O3 e, Y, {6 z" Z5 O- Z% [        1 K7 T. X8 ?7 g1 x. b
    opr_in.ch='#';
+ I; L) g6 O( g    Push(optr,opr_in); /*'#'入栈*/1 R% A: s; v' C3 `
    GetTop(optr,opr_top);
2 ^- f( C; o) e    c=getchar();
6 F2 e( I% M' ]3 _, c    while(c!='='||opr_top.ch!='#')& R3 E0 S! R7 w( @$ H/ `0 [
    {) Q8 R% ^/ _# v
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
3 L3 Q: `( k$ b/ m2 I6 Y        {
. V2 o4 @8 \- K) g            buf=c;9 H8 A3 |! s& P  R4 M
            i++;; w! c- u; s" c6 F5 w( q
            c=getchar();
4 B; U/ v9 X  b5 P& n7 H( F3 J( @- h        }2 `! f1 o; R- k/ h! m( B1 `
        else /*是运算符*/
8 \3 D$ n' ~; D1 E5 I        {
$ a8 k5 l8 O2 H( n; I            buf='\0';1 X; d0 Q9 r/ |7 z
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
9 {$ E4 {4 x: a( `            {
! ?" M+ m1 n, e2 S! p                 opn_in.data=(float)atof(buf);: U& K  L# Z: M5 x5 k3 r# k( g6 n
                 Push(opnd,opn_in);
, ^4 \) E  Y5 N  ]                 printf("opnd入栈:[%f]\n",opn_in.data);/ Y- g/ w9 j" h: @2 D, A
                 i=0;' ^" z( d! y9 v7 P
                 memset(buf,0,sizeof(buf));2 A) }" Y1 f. V$ `! X: m, p
            }" m! M7 z6 {) q  n2 @
            opr_in.ch=c;
' W6 I+ x2 S; F* l' K3 a6 a. V            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5 }0 X/ S- b1 l) I            {- Z4 X* @& H- d, ^9 |( x
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
* J! e! U, n  A                     Push(optr,opr_in);& H) y8 q. r: p2 [9 |$ C9 m- ~+ u' `
                     printf("optr入栈:[%c]\n",opr_in.ch);
' k! @6 n& v( F5 |                     c=getchar();
. D. y  E' u1 t+ j9 U- B                     break;; \8 \: j) s; d2 h- K" a. w- r
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
* N0 U) [5 J  X% X                     Pop(optr,e);
1 R2 }; X- B/ Q* E& w+ c. ?$ R( C                     printf("optr出栈:去掉括号\n");
$ p8 Q. c0 K+ e  ^                     c=getchar();) S/ `' S# z: Q
                     break;8 V* f0 w  l0 ?
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/: l6 s! E2 M  Y) l
                     Pop(optr,opr_t);
. l2 v  T! c  ^! e/ H2 X$ z5 ]                     printf("optr出栈:[%c]\n",opr_t.ch);( W8 q# P% ^1 b- h1 \
                     if(Pop(opnd,b)<0)
" v. e/ y! o1 S                     {
3 v* Z( `& _$ E; c                         printf("Bad Input!\n");/ {$ F7 G7 E& |7 ?* |: _9 @" s) x
                         fflush(stdin);
% z8 i3 h9 m4 R, U& ]5 t8 _                         return -1;
- i- V( Y1 r" u) w( I* a                     }
' |3 L" q, G5 z; \1 ]8 x$ A                     printf("opnd出栈:[%f]\n",b.data);
& e* x% c. u3 y/ S                     if(Pop(opnd,a)<0)6 Q- a2 n" Q/ O0 I& Y
                     {4 X, H" B. a: S7 Q2 x
                         printf("Bad Input!\n");
  [* t/ i" W* R5 @; Q; Q# }; y/ I  a+ f                         fflush(stdin);2 D" Z: |/ u2 j. S6 O4 F% T
                         return -1;5 I% l- o, h* }
                     }* y* u. _( b) q/ d/ k1 ~
                     printf("opnd出栈:[%f]\n",a.data);
( a% x4 W& G6 G& y/ T                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
2 N( h, H+ J+ e, C% n  R+ N                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
3 s4 W# m$ |/ r! y9 l% P                     printf("结果入栈:[%f]\n",opn_tmp.data);. q  G4 ^2 v' o9 K3 \( W' x
                     break;% j/ _* C% D4 @+ @: v/ z- I
            }0 ^1 B/ s4 X. r$ w( X  o
        }
& |* W7 C* I5 C& X7 p" E        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                6 E2 \7 Q5 j& m0 C& b' R! I  ]! ]
    }
: W1 A1 T/ w3 Y8 d  f    GetTop(opnd,opn_tmp);
5 p9 |, n! I! @    DestroyStack(optr);
! `$ T1 r- X% u) \    DestroyStack(opnd);
! [* M& ~' A/ z    return opn_tmp.data;
, ]+ u& A% e- i8 z! I& e8 S8 K}4 e# L. V( w# y

6 o! r, ]  O2 O- zchar *killzero(char *res,float result)$ X7 A1 `  ]- t0 m% J
{" c5 V; i0 C7 ]6 W" @6 M' P( t/ T
    int i;
) n- U. F% p0 T7 b8 w; K
( O% [1 |- @; `4 d" M' b$ w2 w) j    sprintf(res,"%f",result);0 c  o* w7 I1 u% k
    i=(int)strlen(res)-1;
0 E' u& ]4 S' h  ^1 i! e    while(i&&res=='0')
  g; W1 c: ^  a5 h# t    {( q& v+ ?; u! s2 H4 x6 e
        res='\0';! h" S+ t7 K( C( g( t2 f) x
        i--;
5 e" S/ @" r" S' I9 {    }
/ N9 [  F, _, n2 b    if(res=='.')
, [! l, _. ]; X& U5 x* B7 [9 c        res='\0';" A+ Y' d) D6 J. ?
    return res;$ c0 D, j3 j: ~; g5 H* f
}* p0 A0 q( h0 c- ~5 D# x7 @& n

% j/ u. n* m( x' b& y2 kint main()! {5 O6 r- }3 {$ }3 Z
{2 F+ g4 q) C# x. m, P! F3 u. l
    char ch;8 N# H7 t( _( }4 q; i
    char res[64];$ v8 g) g) p' q0 P5 L
    float result;6 Q' L% Z+ Y; ?% r. ]: z; Q$ W
    while(1)
% c1 Q# O& e) b) Y. C    {
3 x4 c. M  `, O3 a        result=compute();
* G, I; E/ M, `. p, _; O        printf("\nThe result is:%s\n",killzero(res,result));
/ a" ^  V+ j$ ^: z        printf("Do you want to continue(y/n)?:") ;
9 ?  x6 r4 |* ?- m1 |        ch=getch();
- T+ d3 m' V0 b' t1 Q; m        putchar(ch);
* S. ^7 R1 P0 g2 s        if(ch=='n'||ch=='N')
. _0 p0 ]- ?, q" Y/ W( I+ K/ r            break;
( G9 z- I% z8 @& a# r3 j        else
  n  D7 B- O' d8 O5 [7 ?            system("cls");
+ L8 T2 p% {! J5 ~9 g  |) B) ?. h2 A    }6 }8 e& S- L* a; ?0 _
    return 0;
7 a% b# \+ y1 F! v6 o}

/ s" h$ y+ D0 ~# ?. W
* ?" i# ~4 n% A* q. u[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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