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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
7 s( L9 i* |. \. C程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=8 h8 _8 b: O- t0 @( [
/**************表达式计算器************/
: y/ H3 P# J1 Y; ?+ R( Z" m5 T- y#include <stdio.h>
/ a2 N# C3 J! }/ t# m) Y6 C# o#include <stdlib.h>- m' k5 L' _7 [/ y" }0 N' t1 K
#include <string.h>" N- e. K$ {- V  ?7 c
#include <conio.h>/ W8 v+ [( b9 O( I
#include <malloc.h>6 s% k1 r/ K1 f( z2 ^
+ h5 I  F  G: ~8 L
#define STACK_SIZE 100
3 T$ a* a& ~6 T* o' k4 `. K, \+ I0 J7 r8 x#define APPEND_SIZE 10
! K; ?4 B1 S& |7 c; d1 ]# t0 Y
0 f7 P  P& ^+ e9 r4 p% Wstruct SNode{
' c5 C. ?  A+ O$ }' ^; i    float data; /*存放操作数或者计算结果*/. t' v2 B4 N8 v  q2 |# C. z7 h
    char ch; /*存放运算符*/
) _5 f4 E/ A& v; X4 m};
/ }: k) D. t- K5 ?; i; }1 ?% u/ g
+ c5 p4 R8 R8 d9 hstruct Stack{  u- x$ ]- p: i
    SNode *top;3 x% c7 n3 j9 t+ J
    SNode *base;
" \2 g5 v; W# x  @0 i    int size;3 o" j9 j: M+ I+ b
};  b2 q0 u' {" U2 @
' S  S4 y. a" a/ ?+ {
/*栈操作函数*/, z9 N. @, i9 `2 h- @) v
int InitStack(Stack &S); /*创建栈*/
$ ^& k9 L5 L. R) Hint DestroyStack(Stack &S); /*销毁栈*/! B4 x1 |1 I. A9 n5 C( J. @
int ClearStack(Stack &S); /*清空栈*/6 ?7 s" j6 D8 Q3 k2 }' m
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/) a: y! P* ^" m" x8 V8 M# ^& x" w/ J
int Push(Stack &S,SNode e); /*将结点e压入栈*/
9 C( O! e4 V0 Q  a9 o0 T1 c" Yint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/7 d9 j/ a( w" k4 J# A

& ^0 a, C  @$ L4 |/*表达式计算器相关函数*/
; Q  F8 I: N' a8 D7 Q) Achar get_precede(char s,char c); /*判断运算符s和c的优先级*/
6 @' x# A+ h7 O/ O1 Lint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/  G0 L7 _4 h- V/ Z; w$ k
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/5 h8 `) O/ z& p! Y3 p
float compute(); /*表达式结算器主函数*/
0 f8 |1 [6 a: @8 Wchar *killzero(float result); /*去掉结果后面的0*/
( S2 f6 a1 U, d, i5 L1 o/ y0 H9 Q, k0 k/ T5 C. y) _
int InitStack(Stack &S)! D+ q7 Z0 F7 n3 d" i
{
. V4 I* P4 ~! t& A" f    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));. R1 U2 x, u6 Q3 g  l
    if(S.base==NULL)  F: v3 U1 x7 W2 z; C
    {, O  s# w+ J. P; Z
        printf("动态分配内存失败!");
" V0 H  b+ k  {' Y7 b        return -1;$ f9 Y- K- [/ u! R9 F! a5 d
    }
$ X: b# `" G$ _$ i  C    S.top=S.base;$ }. T& ]7 l7 h
    S.size=STACK_SIZE;  E; U7 h2 ~) q1 w) T0 J
    return 0;2 n$ e+ M: i8 D% j% c
}
& g. [. m" l+ B( [- B  y. z/ r* W9 Z  o3 u8 v" ?% R0 G$ H
int DestroyStack(Stack &S)
3 w; t& \. c' P/ O{
7 z3 s7 o0 R2 m2 V5 ^    free(S.base);# y: p' A' ~. h- z9 _; g3 y
    return 0;- x, e6 ]5 c, x! Y4 \8 F! E
}
; {; Y/ }, v0 y" t1 r1 S5 c( I% T; M: u$ K  L
int ClearStack(Stack &S)1 W2 {' h& }2 z. _' |
{+ O- A+ m4 @9 P! E. E; i: j8 y
    S.top=S.base;
1 J5 ]+ c1 y- S8 t5 R    return 0;2 C$ C8 K) T6 ?. j( i$ w
}0 T7 `; i- r8 w" j

* p( @7 F* h# c3 {7 S! s) Jint GetTop(Stack S,SNode &e)6 I4 J4 S) }) E. G! n0 P* P
{
) F% Y" L5 S  k6 e/ ]6 Q    if(S.top==S.base)
& x) y# p; a$ [. ~    {
( S6 d2 {7 Q8 L7 b" f        printf("栈以为空!");' z' k) ]: X! m/ u
        return -1;
- n# K9 l% W$ O+ f    }; N/ {" Y0 S6 b, w3 W  w4 B2 y2 u6 E2 v
    e=*(S.top-1);
8 _) [7 ]" c( a: y    return 0;
* S; c; M; ]; n/ [! Z  b}
' N6 \* t9 O; |; Y2 ]7 g
8 Q; q# o; w# Rint Push(Stack &S,SNode e)
* v) E- A) n7 }( X: Z{0 a7 f2 Z/ ]2 w0 {) _0 L
    if(S.top-S.base>=S.size); Y$ [8 Z0 }2 K6 T& J, x8 c
    {5 I" T7 }# a! l: e. X& i3 ~
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));; M- t- L; p# u+ B/ K
        if(S.base==NULL). `: ]; P/ Y- c0 E+ x- A! e  F9 x
        {
( f# b" r0 k; @  n0 L            printf("动态分配内存失败!");
5 ]: ~7 e3 w8 r            return -1;* F/ J2 v9 p9 u, d- m7 w# b# A
        }
, t+ ~: [0 b6 b        S.top=S.base+S.size;, n! O) V- r% j+ ]) I
        S.size+=APPEND_SIZE;$ `$ E. L. e8 A7 ]' B* ]4 h# E: b
    }( u& k( k. l* f% ]* `) M) o% E6 n
    *S.top=e;; W3 X" i) i) B+ r
    S.top++;
4 {1 a! S& Z# t* t' w; o% I7 B    return 0;
( h" K3 I2 R1 D4 @# d}
3 D9 y6 ]3 U' J# U$ r
; C6 L  s/ i! F* F. X* eint Pop(Stack &S,SNode &e); _5 v4 ^; \/ B3 f4 F9 O* g' _. ?
{
' L9 F; h0 H2 l" r2 B2 f( A, c    if(S.top==S.base)- Y; C7 Y9 H7 _
    {1 k  ?1 q$ A7 C0 C6 V) g) Y2 b
        printf("栈为空!");
  }. W/ ]9 i( E  S5 H        return -1;& M* e! Y( J  y0 O; }8 l
    }9 L* @$ }/ d$ R
    e=*(S.top-1);2 N3 G- J4 Q- k) H
    S.top--;
3 b  f5 c- c5 J1 P    return 0;
3 s; k, e; D. f- C* p: s}
6 u! X8 Y! S  ~: N! P) y
! f" {  A1 a& ?8 j3 @% Ochar get_precede(char s,char c)
: B1 I- B$ R$ G( I( ?/ k2 g# |3 M{. H( \' E. Y; n7 Z: M0 [; k
    switch(s)  m4 I0 Y/ |7 T1 S0 o
    {, `0 [' E8 ~0 E8 g, a  {9 ~
        case '+':                 5 \4 r7 Z8 k1 F* G1 ^7 s* N" h
        case '-':
6 M8 i/ M/ V2 h3 l" a0 H. y. a             if(c=='+'||c=='-')
* X" a6 O/ |% k: `                 return '>';
/ G3 u# D7 P. X- q+ p+ N             else if(c=='*'||c=='/')
6 J, P( ~1 e* i6 R( O9 G9 @, @                 return '<';7 r, C' B& m. L: m
             else if(c=='('). x" E4 d3 u! q1 a. r, [' s
                 return '<';8 k( x6 a9 H8 U0 L
             else if(c==')')
; {) z) _  F, r/ s& s- w5 l                 return '>';: ]6 s' y! Z" r( L8 q
             else
" Q+ Q& A( {! u# D3 `/ J                 return '>';
6 V+ Y5 v; S0 @2 M        case '*':
; m7 A! \( f: H$ b) u        case '/':
3 L  u) n5 G" {. \) |( u4 @3 u             if(c=='+'||c=='-')
2 F! m2 V! R9 ?$ ?! n! w6 Y3 s* i& m                 return '>';- }9 q4 c8 @5 w1 F7 U
             else if(c=='*'||c=='/')
% j- Q# Q; U5 }8 |                 return '>';
- N+ t% f' ?9 T" m  Y8 }0 d$ [             else if(c=='(')
# b2 E4 S) K; h                 return '<';' T" X. j; v+ h$ s/ R
             else if(c==')')
  y% g2 P* @1 [1 e! D" ~- d7 I$ B                 return '>';
5 C8 }6 c3 V$ n" g4 q( d% f, ~             else1 h2 f& i% r6 M  N
                 return '>';
+ `: u  |- F# S- g' \        case '(':8 r/ Y: ?. j8 A) e6 t7 K
             if(c=='+'||c=='-')6 i% P- y) h0 s1 C$ E
                 return '<';0 u: n6 J$ }! V0 m
             else if(c=='*'||c=='/')
; b& k# v; U# M7 R7 {% p  Z% B  m                 return '<';# P1 ?: R+ b; u2 m
             else if(c=='(')
: q1 b3 A$ c9 k9 @                 return '<';
3 O$ l% H6 B' ?% e7 T             else if(c==')')' B/ p6 [7 C# i7 o3 e6 W+ A; ?2 Q
                 return '=';
6 T& C5 w) s. y% p/ D5 v  m             else% ^% Y9 ^) E5 A) h4 f0 ~" f! o
                 return 'E';; R+ t+ u* t6 T1 c3 n3 G" [% H# u
        case ')':4 f. b' k, R5 \! ^
             if(c=='+'||c=='-')' g+ @  ~* c' c; R
                 return '>';& I  @* l1 Z7 |) K: u
             else if(c=='*'||c=='/')/ L( i" H: j. F
                 return '>';
# k8 S+ W2 z! V             else if(c=='(')' g& O8 @5 Z7 ~- {8 e& Y& u
                 return 'E';( `9 n# ?5 W2 Y
             else if(c==')'); {. z- u$ ^0 K* `& m- P
                 return '>';
& E0 _0 a& G9 L1 c8 o, S             else
( N, J, ]- A' F8 s4 M                 return '>';: X. J, g$ y( |' S
        case '#':2 G. X5 \3 h! _0 U
             if(c=='+'||c=='-')! J0 W) ~/ e/ \1 X6 O: g
                 return '<';
& B6 l5 x. e5 ^3 \7 z             else if(c=='*'||c=='/')
7 j0 H) n7 J( q3 |1 c                 return '<';) f- C$ `* g$ F' q
             else if(c=='(')4 r" H4 p6 `8 \; n  o: w
                 return '<';
3 `" s( ^  L0 R; p4 V. ]# g. X             else if(c==')')1 `# q4 m: q) z; p% m% G- r
                 return 'E';
. H/ K' ~/ c4 M/ L1 P             else- m; Z$ Y, P7 W" {
                 return '=';! _) l, ^$ h6 m3 G  f
        default:/ x1 Y+ R( B) i5 M; n. X
             break;5 a! g8 \/ {- f% z' X
    }& q- i; t  c- t# a1 H+ q
    return 0;   
6 s. L* @( c3 Y( G2 q5 u}
' b% S& H$ V* M
& n6 y8 c  O( N% ?3 G. M, ^int isOpr(char c)
+ p% f/ q& Q2 y) P0 {" l8 Q( |{
& [& C1 l# S: g- O4 J. T+ y. M    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
9 Q; d2 E* s" j+ r        return 0;
9 I6 V  D9 l0 d4 |! ]7 i! Y    else
, ?$ n4 Z6 [- u6 _! o4 p1 a; c        return 1;
" [$ Y7 O. n8 e  [: Q" c" |}1 V5 d, @2 U4 H" y3 m7 ]

* @: I  m- i. D3 P8 rfloat operate(float x, char opr, float y): G. w7 B. u$ Z' p1 y# Q. `  V/ v! g
{: h% }( Q: F8 g# L; N8 g& }
    float result;' @! q  o% S% \: L2 ~7 k1 ~
    switch (opr)
& k- L9 A5 n6 I* k6 `    {& W" w; M  @4 V, f2 S3 g/ j1 y: s+ X
        case '+':
5 W$ \$ Y: J; T9 l             result = x + y;
! ^6 m2 Q; R1 D             break;2 e/ s8 c) p2 K1 @
        case '-':
9 [/ y: L- T5 T             result = x - y;
) a! I) r& Y: E2 g( u             break;4 m  O  L( Z8 V
        case '*':   {7 y2 C8 V1 D
             result = x * y;
: R2 J" J0 ?0 _% b             break;
5 `. Z4 I7 n; E* f6 L3 k; }1 i        case '/': " z  \; h" }/ i+ y# \% V+ x
             if (y == 0)! ]4 S! T! I8 z- B) J! \& ^4 N. S
             {7 }7 N7 |& w6 s: H/ q& `
                printf("Divided by zero!\n");5 i8 a" B& @1 `0 e4 z9 [  s
                return 0;
" d4 m, U9 G% h) E! B, _" Y             }
! q! P, D0 j$ j8 N3 k' l" Q: o' F) V             else) N8 b& @# F2 o8 T! N% U
             {# H9 I9 I, z3 v. d3 n/ d- ^5 Z
                 result = x / y;
4 K, ^: S  g1 }: `- K. j8 M( \                 break;; P, ?3 H0 a! v+ V
             }. c' d: a& O- [) s/ z
       default:
1 e( f9 q) m4 h% a             printf("Bad Input.\n");
8 U- s3 ?! ^/ W! ^! c             return 0;
3 T5 {8 e' u$ g  \    }" E) J# t/ A7 M7 \7 V3 [
    return result;
6 q* E9 a4 p5 K: I# w9 ]6 ?}    : U7 J& |' p0 N
+ Y2 x! C2 R+ }5 B% T. ~
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
! R1 [; L8 s( {{! y* L$ k% M7 |( n) w" s" C& G
    Stack optr,opnd;
) m" C$ p" r8 t0 i; t/ f& B- c- n    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;5 }* w2 @9 I5 i9 R, t
    char c;  \  o; U$ ]* O$ @% o
    char buf[16];$ n4 b$ a7 k$ j& V1 a) I
    int i=0;- y: G* ?( b' ^' N# j
    6 R, \6 Q7 z) O3 k8 J
    InitStack(optr); /*用于寄存运算符*/
5 Q, a1 ?" l/ r% W6 v: X" M    InitStack(opnd); /*用于寄存操作数和计算结果*/2 |) b+ z3 j! B3 P& C8 d" w9 K; K) o
    memset(buf,0,sizeof(buf));
1 m# V/ f& @: V" k3 Z% \   
1 A) r/ H4 J/ N1 N% U* [+ N    printf("Enter your expression:");
6 q7 t8 m4 ~1 f/ Q3 G. f        
9 w4 S- Q4 M( x" f8 q    opr_in.ch='#';, X1 C& N6 b$ l# h1 M
    Push(optr,opr_in); /*'#'入栈*/1 K% ^1 Y2 d$ j# ]0 o3 Q  l* C
    GetTop(optr,opr_top);* d0 R6 l/ W, n$ w: C, O% [
    c=getchar();* X% E1 e' n6 I/ z
    while(c!='='||opr_top.ch!='#')
0 L9 Z+ `& D0 r5 U2 v3 _% |$ T    {/ a  ~' Z8 ^- e- U* J& e, c* e
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
7 I* ]& P5 e% x) c+ A" [" P        {
! B: T6 H, e5 k! U6 V9 ?8 y% I9 p            buf=c;3 X8 Q1 c7 Z! B9 K) L
            i++;, ^* E5 s4 B2 U, A" P
            c=getchar();
: T, E: S, S7 O2 h4 l        }1 k' E4 I+ [8 F" R
        else /*是运算符*/0 b! O! w. e! U: h* E! x, X/ {8 J
        {9 u* p6 K' x- J; v! h9 `# c
            buf='\0';" H0 n" y/ C3 a3 c. t) z
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
3 N0 n* ^! R% `6 W+ M( f/ C            {
, }$ n- r0 V6 O; [) ^+ J  s( K' @                 opn_in.data=(float)atof(buf);
  w% ~: }4 \! o                 Push(opnd,opn_in);
1 L* B& J" Q: F, p6 C8 y% s3 J                 printf("opnd入栈:[%f]\n",opn_in.data);
" b. l% |! j8 ]" k5 ^4 d6 g$ b. \                 i=0;# k4 E4 _4 G0 g
                 memset(buf,0,sizeof(buf));
& X" o/ k! h2 V/ z            }
" s9 D' K; W+ K            opr_in.ch=c;2 U$ I3 g- h& T  R$ v  W% J: l" A
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/) m# ~0 ^6 K" S" C1 g. X+ I4 i
            {! i$ S1 N4 Y1 ?( L, T0 G. x
                case '<': /*优先级小于栈顶结点,则运算符入栈*/% T! h: f! {0 l& M$ \' j7 R
                     Push(optr,opr_in);
. @" q% {7 {: A" z                     printf("optr入栈:[%c]\n",opr_in.ch);$ W) F6 q: \7 D4 n  `- s
                     c=getchar();
, B4 O9 ^# S! O4 m) Q; e5 ~) e                     break;$ j  m0 ~" \4 @' `. ]
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
. n* i) h6 d7 p& o                     Pop(optr,e);. J$ a% ~3 W5 F7 A$ n! U% j2 Q
                     printf("optr出栈:去掉括号\n");+ `% G1 M% |- V& E8 g# p& d5 f
                     c=getchar();
- ?6 Y; o( c6 i& @6 v. E( D' B; Q                     break;
. [1 t8 W6 l* x, M3 ?8 j9 e: _                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/! K* o5 Y% r5 j4 A* o1 X0 P
                     Pop(optr,opr_t);# Q: U$ h, g$ H" {- `
                     printf("optr出栈:[%c]\n",opr_t.ch);
9 A' ^  g, Y2 c# `& \4 g2 C# x/ G                     if(Pop(opnd,b)<0)
8 _$ z4 `; \8 B                     {
$ b  ?. i* E) o4 v5 ^                         printf("Bad Input!\n");( a3 K, E8 ~  y3 q: Z9 ?5 M
                         fflush(stdin);
4 F  A; p& Y4 _/ Q  ]                         return -1;+ P/ _8 T. p& y6 W- _
                     }
0 T. J2 C( n- d* D: g/ n3 G) ~                     printf("opnd出栈:[%f]\n",b.data);
0 s# q9 u9 P: t: z                     if(Pop(opnd,a)<0)8 V. A' z6 y- C0 H
                     {
  l; ^, J, O) `- x) N6 c2 A                         printf("Bad Input!\n");- @* D' q( L3 h% k  b% P% i) W
                         fflush(stdin);
. J! a, c# A* ?8 `1 H                         return -1;
/ X" \: Y7 I% o6 V9 _& ]3 T                     }
4 _& J" ^5 ~* P" C, a% w                     printf("opnd出栈:[%f]\n",a.data);" H3 |# g* ^* R0 q; n, u4 i( v
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/( f( A. p, e3 z, D" g' q! f$ M
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/" c5 P' V+ A3 V
                     printf("结果入栈:[%f]\n",opn_tmp.data);
' d3 P2 Q# Y; B: t0 W                     break;
" O; b& ^3 ]2 e" X9 h2 |            }- Z' G9 D) \; P: S+ i* _
        }
  L7 |& V& ~* ]9 P7 H        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                * K* }1 H. B8 D
    }
- J& {8 e! e. l4 z) h8 D4 _6 j* h' B    GetTop(opnd,opn_tmp);2 Y) p4 Z- M- E' u5 o2 M) B
    DestroyStack(optr);
$ M9 y( m0 u+ A    DestroyStack(opnd);
3 G# r4 @6 a2 I! B) s    return opn_tmp.data;7 H* \4 c( ~* h
}, {) O" }7 C7 R- N$ |6 E/ t: V  ?

% i* c# X3 n1 ?- |  T, ?; Vchar *killzero(char *res,float result)0 P; [3 C& z% {+ y. @- P
{& ~9 l5 k0 E4 H9 q4 f# Z; W! ?: M5 @& [
    int i;; W7 l8 N2 T$ R; k5 ?

7 u4 y3 q# a( V1 W    sprintf(res,"%f",result);
) B6 I0 @2 ]& C2 B- R) c    i=(int)strlen(res)-1;$ z# l, S# D8 e" ]2 [5 B& O% x
    while(i&&res=='0')
7 [# c) ^; G% n5 p1 I( G    {
/ {% U8 j! z! U+ n& @" |" f  }1 h: U        res='\0';
1 N# v1 Q: u3 @$ D: o' m8 H        i--;
. `4 U* [8 w9 P  |    }: ?; z% {% N8 b6 L) N  d2 N
    if(res=='.')
9 b: {7 y+ T; k2 X        res='\0';
1 V/ f) R# `6 O6 F+ p    return res;
+ d5 {) }2 }; G, `3 U8 s  h}
  o4 l6 R8 j$ W5 N5 ]8 A5 X
0 Z8 ]( e' y. M- H- |5 Y8 f1 sint main()
8 ?# l3 _( V6 n7 {( b{0 c  O8 B9 V$ ?6 L$ l( |: |# Y% b
    char ch;! \* |) ?2 v$ @" }
    char res[64];
- N1 W, X  O( x+ g8 o2 R    float result;
( ^& g( s; w. G/ S; e+ i* R6 \    while(1)
% D, Y6 _2 \; Y4 l: P) O    {3 F4 L2 j1 `* \7 [" G/ C
        result=compute();
' Z5 H# D& y& A. C        printf("\nThe result is:%s\n",killzero(res,result));' v) ?$ C* T- w/ [1 w' d
        printf("Do you want to continue(y/n)?:") ;
, t5 M; I" w5 Q0 m: B' K" t        ch=getch();4 E6 I: w- R8 P4 V" r0 ?4 e; P* L7 `
        putchar(ch);
8 a5 c/ C5 ?* g        if(ch=='n'||ch=='N')- Y; _, F) _# ?4 H: e  n
            break;  u: n" k- H! S- N, {" o0 w
        else
$ a$ w( i% }  {/ q4 |            system("cls");
* s- L- o! ^: P6 ]  v8 s6 D    }
* {; ?, X( J; d5 N5 L    return 0;& Z! R# @3 o% g, J& d$ C
}
. A  W& {! }0 @4 m9 A! ~) W

, ?' L/ f; F& F; t& z[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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