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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.1 |* W- J4 N0 X1 W
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
" d2 c- s; w1 A9 @/ R/**************表达式计算器************/
: W' F! j' d3 F& _#include <stdio.h>
  A% v! e: N1 \! ]2 b3 u+ f/ H#include <stdlib.h>
) S$ Y1 V& D9 G5 I7 U) Q+ j/ i2 K#include <string.h>
$ n: |; t6 Y/ Y% G$ N" ?9 S: ^#include <conio.h>
; o7 D: M  h* ^#include <malloc.h>
8 W5 L, D1 k3 X" r6 l3 k& G/ T$ E
#define STACK_SIZE 100
0 Z! _- Q* ~* c9 g5 r' t4 d#define APPEND_SIZE 10% |4 o8 F; E2 N. c# }

0 j$ {+ A" Z3 N: p0 T$ ]2 X. K0 k$ E. Pstruct SNode{* E5 P+ u* ^! v% Q4 C4 [+ |
    float data; /*存放操作数或者计算结果*/1 O1 {2 v) ^! J$ f1 C- t
    char ch; /*存放运算符*// p' A: \3 R9 m$ P1 {
};
9 ^# L$ Y+ s% ~& z" Q, K; R% ~
5 w, u9 c! z, Tstruct Stack{
, |( z6 ^& b4 P    SNode *top;  ^" i8 J9 x! ~8 _, o8 J
    SNode *base;8 G; p' l& J4 E* ]6 N; _
    int size;
: Z( G9 P8 i0 r" @* L1 x6 q* e};" c( |' \0 \# L7 z
% P, B; o, e# @6 Q5 b! l( d
/*栈操作函数*/
6 a  A* U& S* n9 W4 C% Z1 k: c7 w1 Rint InitStack(Stack &S); /*创建栈*/
" Q) v) k6 A  cint DestroyStack(Stack &S); /*销毁栈*/
) R" S8 G. z% fint ClearStack(Stack &S); /*清空栈*/
0 v6 q. u, G3 @' J2 eint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
3 G# T% _7 N  N( oint Push(Stack &S,SNode e); /*将结点e压入栈*/" h" C! d, a+ E8 T. U+ t4 g: u, q- l& p
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/; u+ _2 `6 N. C$ W6 U. l
! g# t) L, Y- }# N
/*表达式计算器相关函数*/
2 q# E8 {. D0 M5 p/ fchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
. A1 k. s5 [" E/ Iint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/! `/ b) I( I. V- v  U. D# v
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/  Y% A  `: |, ]5 b4 R9 }  _
float compute(); /*表达式结算器主函数*/
) v, k) ]  p2 N5 L+ J' v$ q) T$ \char *killzero(float result); /*去掉结果后面的0*/
4 N7 N- g$ T: |% R* ?; s3 R# W: }1 Z" |: E7 H1 U5 n
int InitStack(Stack &S); u" `, [# r& K! _. ^8 Y
{
" m) m3 t" G1 g/ o0 |    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
: T' @/ K/ t6 v6 W6 z  L# C' Y    if(S.base==NULL)
1 }( ^9 [9 P1 h. h% s    {& C$ X' y' n4 M- B
        printf("动态分配内存失败!");* Z! j3 Y! T  c
        return -1;
; Z: U1 p5 b! c, H4 r4 G    }
9 w5 F  j9 a$ r$ w5 l    S.top=S.base;
; ~5 K% O, H! b6 ?3 @: [5 |: ?    S.size=STACK_SIZE;6 _' Q3 f! T' S: J) P; \; J. L. R
    return 0;1 m5 T. ^" t% `, V
}
: w  P9 X3 o" E2 c/ S7 @7 L
& y! h  q* M) g5 O5 M; \# C) gint DestroyStack(Stack &S)
- i) ~$ O6 s: p4 n8 e: @$ I7 |- H{
, Z- Z' v# E/ B, w: T2 c" Z    free(S.base);. j7 W4 F- h' C- r! i/ u7 N. I
    return 0;- k: q& o( e( K+ S
}& n, T4 }6 u' I8 f7 s/ g0 [" Y
+ Q7 ?& d6 E) n+ `7 \& j
int ClearStack(Stack &S)- a# {4 ^( _- N; q  f2 Q2 h  q
{3 z! Z" \# }" p% h- @
    S.top=S.base;
, C3 ?, k: x  [! N    return 0;" X0 P7 @; Y; Q! w2 W( `. h& Y
}3 l7 w$ F/ w6 _$ `
; x- a0 f4 D0 \0 V! E$ j& i. y
int GetTop(Stack S,SNode &e)
2 @1 q% n0 \, I{
( }8 B& K# {# M& M; ]; z/ c    if(S.top==S.base)
3 l4 n; q0 m7 v3 f. y/ P    {' z1 K* [; l# O, @% ^$ @( L5 b
        printf("栈以为空!");
6 p' ^2 a. V' A4 X. o7 C8 w. y0 t        return -1;) v) H% q; U% R- t2 ^% m  i
    }  F$ i/ o3 d$ K9 m% h3 F
    e=*(S.top-1);
7 @% m5 ^9 M( G" U- w    return 0;1 C! |- A  F1 I; o: h2 w( ~
}
" M$ M' U  _6 D; {% t0 _7 \  }/ ?  \" K4 a% K
int Push(Stack &S,SNode e)9 V9 Z9 r6 O; H, d* R2 [2 d# y
{* y3 Q+ q% y, |" g
    if(S.top-S.base>=S.size)! ~2 x9 ]" W; _! ?
    {) _& S- [. q, h1 }
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
0 a7 M, r" Q$ S' E4 W$ I8 B; C4 U        if(S.base==NULL)
; a1 W; N. L# v& q9 C: r) F8 i8 p        {+ w8 O2 y2 i1 n8 q# _; H* a
            printf("动态分配内存失败!");
. _$ I: U3 l' e( X" F) g3 w0 i            return -1;3 ?, n. l6 C1 |4 U3 ?/ ~6 s
        }
8 R) n1 p4 ~1 z1 P/ v0 k        S.top=S.base+S.size;
5 F: W2 P" b, Y9 f6 y; M        S.size+=APPEND_SIZE;
2 u# ?6 e& J9 ~, R2 v- Z# T    }5 ]! O* t/ s8 S1 T
    *S.top=e;' F7 b) _8 @) h+ }
    S.top++;
7 s# d1 _+ r  R8 d    return 0;
+ z( [7 Z& }+ D}" J5 ?! g; e) F3 T7 I
$ U; X0 S8 T, Y& h
int Pop(Stack &S,SNode &e)$ S3 q$ {# o. z: G4 |! D$ t
{1 ~; V1 n) l( {8 f
    if(S.top==S.base)5 q7 p6 j7 v4 P6 q3 G( o9 \
    {9 @, L0 o6 Q. \: Z  }3 G- a: o+ ]
        printf("栈为空!");
! f9 h0 \7 G8 A7 x8 \3 Z        return -1;
) k) h' M0 I% A; y    }
. p6 d0 w$ s$ b( F/ K* S. D    e=*(S.top-1);
3 m( O4 _( s# Z    S.top--;
) D' l: }0 b& `% B' m    return 0;1 U. m2 V" X* k* Y5 C- y
}
/ T2 G% p1 c+ {, S3 |, s
- u5 i# a# z3 K$ K# Xchar get_precede(char s,char c)
+ e) n3 }- N( ^* g- Z& A{3 q$ P, I- l9 {3 i' e
    switch(s)
% ]1 q* ~, d8 r6 z. @7 g" o, T    {  z/ G- d: x& O3 B( T
        case '+':                 7 q" y) d* r/ b; t- o( \
        case '-':
" [+ O8 E. N3 K. y& T. |8 D  L5 q# y             if(c=='+'||c=='-')
9 r- J3 W# o- {) R' C8 n                 return '>';
: l* _8 u; y8 g* H  t. i             else if(c=='*'||c=='/')4 s/ N0 D. z' F0 k5 T
                 return '<';4 K% R! X+ S* `3 q0 G% ]& C
             else if(c=='(')* J+ Z8 y, F1 [6 t) L
                 return '<';: z; x  a2 M7 r  E: }
             else if(c==')')
7 C. g7 s2 X2 d  X* J' c                 return '>';  e- J8 V+ _. a& H6 o
             else
$ ?) m* Y4 A& S2 {' f                 return '>';
7 n, s) L; c" M+ l  \        case '*':
' N% \) b5 V4 Q9 n; F! @        case '/':
* m; t2 F7 m' y$ x' r7 i" E  N             if(c=='+'||c=='-')9 K4 o* R4 Y$ ~$ x0 S2 `4 D9 D
                 return '>';; B2 O. L3 a7 \0 t3 @
             else if(c=='*'||c=='/')
& [4 \0 X& U  r  t- {0 n9 [5 K& G                 return '>';
+ E' |7 R1 j- m% K             else if(c=='('), z- c5 ]% q! {8 ^4 N, W
                 return '<';
0 I! t! z+ Y" |9 |             else if(c==')')
3 ]6 x! F' [7 o3 d! W4 w0 i                 return '>';
6 g, `" A1 J% A) m! t! S             else
' X4 p: p- o) |3 O$ a                 return '>';( ?! K0 X0 `5 Z+ E" L1 i: [3 r0 C
        case '(':
( P5 i( i2 n, s! c6 w( `  h             if(c=='+'||c=='-')
+ ^0 T6 n, v2 r- r2 f                 return '<';
- F7 O( }' i" ]             else if(c=='*'||c=='/')% F  T9 h+ ?2 A$ @0 `
                 return '<';6 B, h: f; f- e. e
             else if(c=='(')
9 m- r8 n1 p( I' P                 return '<';8 K7 [4 O! T+ l: w9 G3 x
             else if(c==')')5 E9 f2 q9 i+ Y' n9 g
                 return '=';9 E' I+ g4 Q- @+ G/ p" c
             else5 F: X, A* Z7 X5 j$ i: p
                 return 'E';
/ r/ E& l% [4 V, T9 o        case ')':& P* t# `' k5 L
             if(c=='+'||c=='-')
, ]( `# q8 e: V+ L  C                 return '>';
8 ?" f6 S" f9 g5 X6 c             else if(c=='*'||c=='/')
, U7 ~0 r/ f% }( n) F: S                 return '>';
$ u. U. s9 m$ c+ Y: B& ^, f             else if(c=='(')
  {9 y6 Z' m( J6 y+ r( ~                 return 'E';
( ?% y& i, e& x1 C             else if(c==')')
0 G! o9 j4 c; a7 m+ \/ [7 F! g8 s# d                 return '>';) }0 k4 J3 i% _3 P/ Y9 n
             else3 {) I! M7 d+ B0 s$ |2 A
                 return '>';
% }+ w: Y2 k3 h5 b+ V$ ^# ?6 U3 j        case '#':
8 g* Y& O7 ]3 a7 _             if(c=='+'||c=='-')
% k& K) Q2 ]: h+ g# k: f) ^7 j; N                 return '<';+ _) r$ x, c! k# `2 a3 d' e; Y
             else if(c=='*'||c=='/')  c- ?5 W: F# |" w4 X2 j8 e# y
                 return '<';- ?5 |" u9 g; w
             else if(c=='(')+ ^% }! F" z4 g0 ~- \) c. v
                 return '<';
3 G1 X( I+ C( U% V' F: C  m             else if(c==')')
' y+ u$ g7 H# H  F5 [                 return 'E';
  k3 Q# e# ?$ T! e% I+ A5 ?             else
$ n) `$ w& d- Y) P0 r. _" B                 return '=';' X; Z2 x+ ^/ O6 T
        default:' ]+ [/ Q+ c  d, v
             break;
" z& F9 Z) `3 o1 U    }; A5 f  H% A$ _! I2 @- U
    return 0;    # ^. b% ?1 n/ p8 c; x) S
}- R) g) ^% m: }4 {- B  X; \

% S1 @, Y/ z/ N5 y3 m* w) z- J+ Xint isOpr(char c)
2 @3 Z$ ?# Z! @{
3 {4 t$ ^( v) S0 X    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
* R- j1 H/ a' w5 d, v        return 0;
) C% U8 V- N( Y' {8 H8 U3 J' ^+ P    else
4 x. ?6 x: w5 d* ?        return 1;
, }- A2 R- O* t" n; q$ j" l. S0 d}' a2 f. V' R1 ?0 f0 m, `4 o  p
% m! A* d* E5 f
float operate(float x, char opr, float y)
" L' Z0 L* W5 Z- D{
* {8 {* c. s3 W  n    float result;
: V6 b0 e* t2 g( R( O    switch (opr)! _# K. G+ p" ~5 D7 W( p
    {
0 P) @% J. X6 W8 f% X        case '+':
* I/ s9 \+ Y4 C5 H; E$ V. g9 B             result = x + y;$ Y5 D" |: @- _9 ]$ V
             break;+ H; Q: k9 B7 y! B7 u, k( w3 l
        case '-': 3 R& e# o1 p, j0 i6 t0 u  x* b; s
             result = x - y;2 o) X. B- t) n! W+ A) B
             break;
; i+ f% O2 r0 o3 u% O) P0 r        case '*': ) H- \8 [. e1 b  c
             result = x * y;6 c* _2 T0 b- V" \" @
             break;
3 O9 s7 x' F5 N' D  E: g        case '/':
8 R; g1 F# n9 W% a8 r  q. n+ O" B             if (y == 0)
' p* y; [8 Z) f1 v, `+ Q             {+ w8 x3 Q5 ?' D
                printf("Divided by zero!\n");1 ~7 S# P) q; ?
                return 0;! ~1 k/ J$ E6 C1 j( ]; V1 w
             }/ A7 p. t, Z: j, _
             else
1 |  _3 V0 z0 A! p8 M3 A! p             {
5 }/ i. `, t% t# B0 q7 V  s                 result = x / y;8 f8 n2 }" S3 B! E( I
                 break;6 _% U8 I) t' d1 }: ]% O- ]4 ]
             }
6 V5 g1 d1 X: C' C       default:
* J; t  E, V; n, @  h             printf("Bad Input.\n"); 9 ?5 [  G& h# R; G
             return 0;
. r, {/ n3 [0 f/ K# `  f* Z  }    }
. s/ ]- [& ^+ b, Q" W    return result;
; {7 s* L: m) d% U' h/ w}    2 k4 ~- v  N! V7 H1 U- ?

3 {7 S5 {4 c1 N1 e* o6 x& R: hfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1 T. [! I* {& W
{, K9 b" w( ~" l2 o
    Stack optr,opnd;1 N; n" J: \+ j+ v; U
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;1 b, y7 R/ g, w/ r9 ^' P
    char c;; \8 ?( }- l! y, l% Q# [6 A
    char buf[16];
2 I5 u' |; q" {, q2 J- T2 `5 Q  J    int i=0;3 f7 k) a7 M8 L. M) q! h
    * H, r% w  p6 M! H( [
    InitStack(optr); /*用于寄存运算符*/. s2 R9 n1 x8 x) r$ [1 [( C3 d
    InitStack(opnd); /*用于寄存操作数和计算结果*/3 ]8 S3 ?6 v; d; j0 C9 S
    memset(buf,0,sizeof(buf));; w3 Y9 U3 i" a- b* a6 i, ]: e) Z: V
    , ]- Y! N( Z( ^' {" m3 m
    printf("Enter your expression:");
. D: }5 V  b# O& T3 b        6 T& M7 V3 f5 R# Y
    opr_in.ch='#';  T$ k/ E0 B" @0 S0 a/ `
    Push(optr,opr_in); /*'#'入栈*/( k  Q6 ?; X+ w2 t
    GetTop(optr,opr_top);3 g. I: u6 R1 `' R3 D
    c=getchar();
& l' t9 |6 C- z+ X8 Q$ e9 A    while(c!='='||opr_top.ch!='#')
  R0 T+ f1 b) Q4 B( |3 [# O6 `) j    {
) I$ A8 o4 Q- L8 X0 t) W/ M4 D        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/3 y- U0 d. |9 G5 r  x% m" Y
        {0 t3 ?( {/ D1 f" A- m- w  ~) t7 @6 `
            buf=c;
) J6 ]7 V8 S9 z7 ]* i9 b! w) x/ l$ x. @            i++;. N  Z+ j* A2 Y% _& Z+ j: F
            c=getchar();! P* X/ D) q( a2 W' R
        }
6 X1 j! o# V% p( x: P: B9 z3 c8 E        else /*是运算符*/& j& n$ `" Q# L1 {" A
        {
' p' A7 D# }9 j/ v            buf='\0';; f$ w+ E$ u, `4 k5 s  r' d
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
/ ^( t. c+ J( ^  P" E            {* }! J7 f" ?1 z: v8 k1 M% O; j
                 opn_in.data=(float)atof(buf);
5 r  o( v( W+ J- ]3 P2 S                 Push(opnd,opn_in);8 f* _, {. P8 u9 S2 G, g
                 printf("opnd入栈:[%f]\n",opn_in.data);
9 U  H+ @9 ]6 N5 W  q: |% K                 i=0;
- N4 Z( u% F) I                 memset(buf,0,sizeof(buf));6 D4 g# L& @* E* ^8 C
            }
) I1 \* D8 G) Z0 H            opr_in.ch=c;& X! u5 b+ G' k7 V' }3 n
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/7 W; O& R" ]6 J
            {
- C  W5 K& @+ h; ~9 c) t                case '<': /*优先级小于栈顶结点,则运算符入栈*/9 w( C5 f; f5 U/ H+ m$ t
                     Push(optr,opr_in);8 f8 h  i+ h7 ]" a% |
                     printf("optr入栈:[%c]\n",opr_in.ch);. Q( S" l. t% W  `
                     c=getchar();
( c4 a; e# L  Y. h& [                     break;
% s% J- }$ i3 b  _9 k                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 v8 B6 i& G- l6 ?
                     Pop(optr,e);4 V6 {# N% p7 F5 m, n/ n9 n9 W5 b
                     printf("optr出栈:去掉括号\n");
# ?3 ~" d* m$ [                     c=getchar();- m" R' w3 d& ?- f- @& p' }
                     break;. \: u2 j! n9 u5 f3 z* N
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/( W0 u. Q, s9 A* s& j$ \- `
                     Pop(optr,opr_t);# C! l9 @" I: R6 h, {' E
                     printf("optr出栈:[%c]\n",opr_t.ch);! t/ q, |' h2 }  x7 p, h' ?
                     if(Pop(opnd,b)<0)
  @% p" B% s! T                     {9 j/ g; ^: m  \( S( r( p
                         printf("Bad Input!\n");  y9 t& |" g/ S) Q
                         fflush(stdin);
3 z6 S" o# c6 D4 D: z                         return -1;
) N  U7 a3 g* V" \  j& D                     }
' `7 x  e9 I  q  L  _$ a1 O1 m                     printf("opnd出栈:[%f]\n",b.data);
0 `4 Q; i" c0 @' Q5 o, I! V5 O                     if(Pop(opnd,a)<0)
. W5 |% W3 P& X/ H* ^5 m% s                     {
. u+ e3 f, {  g( S3 V                         printf("Bad Input!\n");8 R9 n' i8 G/ x
                         fflush(stdin);' V9 D, G& `' J' f/ G* N
                         return -1;5 x( u6 m- S! u3 |$ a7 Z
                     }
; [: Q( l) n6 g9 o0 z                     printf("opnd出栈:[%f]\n",a.data);8 V$ f( }: `7 o) S) e
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/* i  ?7 C" k$ s6 w8 _
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/! L" Q9 K1 D- [1 J
                     printf("结果入栈:[%f]\n",opn_tmp.data);
  e4 ^% D% m( ?( l# c% M                     break;. `0 }- k# z6 L% _3 }
            }
. f, w; h: T0 k& G8 k; [        }1 ?* Z& P  T, |
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
  D. H( S. `3 _8 z, Q    }. T: K" C' Z7 M8 [6 C3 t
    GetTop(opnd,opn_tmp);
) _! b* Z7 J. w9 z8 j8 b6 z2 ^    DestroyStack(optr);% L" Z& o/ g$ ^3 w2 k4 C& P
    DestroyStack(opnd);' d8 q9 p$ l1 e& D0 H
    return opn_tmp.data;
" t. F" o5 P/ L. ~: M+ u+ b- U}
" V2 i$ k$ e7 G
8 Y" i  g' ^% Z* J- pchar *killzero(char *res,float result)
" x- K5 c8 b5 a; _{) ]- J- l: W: E
    int i;
: L) [% e6 l: a: b* j; z$ p
1 d' [) c* y7 m4 G. h    sprintf(res,"%f",result);
7 p/ [9 L' P" X9 M! O& I& c8 R    i=(int)strlen(res)-1;3 o* c% D% B: l* E5 c
    while(i&&res=='0')% P. }: `5 U2 w; e- W! Y9 L
    {. I8 {8 `# d7 F: L0 l
        res='\0';; _4 b2 d, U, L( X! ^$ c
        i--;
% Y7 M+ D' A; h0 n$ }. X) a    }3 K3 p' h- ]% @. Y/ ]- ~9 L
    if(res=='.')
( [3 y: Q% {* M- @: M, G        res='\0';
: X! ^  w) ~$ D6 P$ Q7 H+ }' f    return res;" M0 ]! B4 E1 T" P, ]
}1 t$ m( O6 u% B. G" }

& R- S3 ~$ o* Y. A7 p( _int main()/ Z2 _& @9 s$ @
{
* \; N# [- P' j    char ch;
# r5 Q) |* ~6 M    char res[64];
- l/ D+ B1 C$ U- w    float result;* u6 z. T( A! b; d
    while(1)/ R$ m6 K5 @, D* c
    {( G4 m" P2 z: t/ X3 X/ C
        result=compute();- y/ i* |% _) n
        printf("\nThe result is:%s\n",killzero(res,result));, D3 V5 K# i) f
        printf("Do you want to continue(y/n)?:") ;0 B+ O# M" R2 ?) @
        ch=getch();
1 |/ {, t5 ^' U  M4 H        putchar(ch);
( }8 _) j+ b6 R) x# \        if(ch=='n'||ch=='N')
8 p% V- n. o0 S+ H& Y            break;
& e2 r0 U/ l3 N9 s2 V, x" Y        else  ~4 A, C: P- O: j3 @
            system("cls");8 c+ a5 |4 h: X  s' C% U6 g
    }/ N( i" r. h' @+ c- D+ J* t
    return 0;
& }' O5 B* ^; t; v}

0 m. L7 ^8 {/ l/ R  H: S) S% A6 g! x( N; }5 b- T6 y0 l4 X
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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