返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.% ], z6 q; t% p( E/ W: W
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
& l2 p8 @, I. s/ V! ^! h: L' ?0 e! _/**************表达式计算器************/
7 p3 [# a  S* u" w. N5 r: z# G% T#include <stdio.h>3 e2 O% P0 t: \6 Y- p2 S/ M6 r
#include <stdlib.h>
: I" B3 `0 q9 c: k( G  s2 G#include <string.h>2 {4 v. c7 {$ N1 X
#include <conio.h>* Y) `/ c- m" l; }4 I0 G! E2 N
#include <malloc.h>; m5 Z% A; r0 R+ ~

# ]& M1 I8 S. R% p6 L% X6 ]( @% u#define STACK_SIZE 100$ b: o5 n' k4 R6 d4 R2 ?7 z
#define APPEND_SIZE 10
% c3 e7 e, [0 Y7 V7 D
6 w& T+ w5 T) ostruct SNode{7 u, b- K$ j9 C+ x% G. ~- A" h
    float data; /*存放操作数或者计算结果*/
( Q. A! F- j( P) M( G    char ch; /*存放运算符*/
; ~  ~, F, H% _& @};
1 k8 [: H1 d9 E  }1 `5 _4 P
- n4 P% P/ d  ~: g0 A$ Nstruct Stack{
" M1 \5 A* i) d, i5 h$ C5 u; |    SNode *top;
# x+ n; Z, D0 i3 U* \0 P4 S& A% `    SNode *base;
& d# `9 J( Z% b2 F% \& W    int size;
6 V/ M+ y0 R5 L" z1 p};
1 f' o1 J- X/ M6 q; O( i
; d; m6 d8 ]7 W: b4 e/*栈操作函数*/
# F$ b- p' s$ s2 |/ K! i* lint InitStack(Stack &S); /*创建栈*/. Q/ z! C6 {' n' S
int DestroyStack(Stack &S); /*销毁栈*/+ O3 i+ ]8 a, S1 f4 D
int ClearStack(Stack &S); /*清空栈*/6 j7 `$ q# p& X. u9 I
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/( Z1 u  {, H# W- i0 j
int Push(Stack &S,SNode e); /*将结点e压入栈*/' S& c) t& v& k3 m
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
) j. J$ m9 N! ~6 e2 ?; R- R7 |) }4 x' N9 g$ z9 K  a( _
/*表达式计算器相关函数*/
+ Y! }+ ?% d' @# z* Qchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
4 d1 C' S; P2 B2 t' M  [% T* _, lint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/7 p1 K$ }8 ^$ g
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/" S! N" K* P2 G$ ]
float compute(); /*表达式结算器主函数*/
7 V# a/ V- z0 z' C3 |. @$ v5 fchar *killzero(float result); /*去掉结果后面的0*/
( @. V& ]2 J$ a
; o0 Y9 F1 L' p: z% c+ |int InitStack(Stack &S)$ x% V; a5 I& t9 i2 ~" m
{
$ o1 ^) x$ f% c( |9 I    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
" m0 m1 M" a% w+ C+ q! R9 h9 a    if(S.base==NULL)
* G4 G3 s% z( _* D5 t    {, L4 K+ o$ i) [+ y; r8 C
        printf("动态分配内存失败!");4 G+ q4 k; u7 s# Z# t3 ^7 D9 U) u7 }
        return -1;
) H9 P. {* C1 F( Z3 c, S6 P3 P, y    }# A2 s' h. O7 ~6 g" c0 b
    S.top=S.base;+ M, o8 g5 z# n4 e4 ~1 L% ]& ?  Z- @
    S.size=STACK_SIZE;& p. y9 {7 ~" a: y  Y  B! w
    return 0;
8 k; `- O) x2 S$ w' ]) n" ?5 G! q}
$ c% K8 a' {' M& u& W' {# z. P
  A4 H2 y' ?8 `5 l+ pint DestroyStack(Stack &S)2 B0 }% A7 U2 [) G8 d  s  |, Q) w
{
+ x; W, y: r9 Z& g1 L/ ]    free(S.base);
( Q8 {0 j" y4 x9 w: m    return 0;+ [/ G4 p" Q. O( y) R! U9 `
}
, t5 [% m, E) ?/ n, x: n$ N+ ?
( g: n, d$ I  u9 x- Tint ClearStack(Stack &S)
$ m3 R# O- f& j" z+ `! E{
6 [; U( h$ Z5 T0 l# P: m* U7 e* S$ P    S.top=S.base;
# l. H! k7 U( ]5 y    return 0;, K& P( \( d5 B# q6 A& o* Y
}
8 Q  m$ V3 v- z, `# d2 @
! b" T9 [2 r, C- ]4 [) rint GetTop(Stack S,SNode &e)
+ U) U& `% k0 h, ?{3 f2 ~; U( N5 A' D2 p. p0 a
    if(S.top==S.base)" u, i4 k9 u( u. V2 T" X4 u+ Z
    {8 J4 \2 }+ O$ K+ W1 B4 I% h' y  |
        printf("栈以为空!");
; A- Z( k; q8 `1 `        return -1;* n; |  v7 l7 G& R7 o
    }% t$ ?9 d- C, a) b! t
    e=*(S.top-1);! m7 ^3 u9 Q% b* i  ?* e6 r0 C( E+ i
    return 0;
. M9 t" F, |, I+ i4 q}* I7 K; R* c' v9 G! m. H2 ^3 ?

1 e6 s6 Y7 V" W4 C% I7 Zint Push(Stack &S,SNode e); S. y% `, K' S9 l5 j
{' v5 m7 A* F  [! b+ D5 @$ [& T: c" |# v
    if(S.top-S.base>=S.size)+ O7 L- d9 Y- @. S$ h. e
    {
. x! x  r( C# W        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
7 i; b, c) y- c' I# u2 y+ Y        if(S.base==NULL)
2 D1 l  A! ]  C6 V( n3 n        {9 A. B. {5 S( ?. S
            printf("动态分配内存失败!");
  v% D# |5 I6 L& b: c& J1 h. z  N' e            return -1;
; h7 T8 x! `$ ?" n, _+ q0 h3 x        }7 z; k- F$ X; j0 J
        S.top=S.base+S.size;
- h- S# ]7 d, Y0 A7 a! M, g        S.size+=APPEND_SIZE;6 A5 a% m% `* [" ~  r" p7 Y( m
    }
% @4 h2 w, I3 H) ?% f" k    *S.top=e;  H9 I6 v9 q9 G1 U9 }4 q8 ]& b, v
    S.top++;* e2 \4 R6 s% U6 x
    return 0;: g9 |% m/ N$ i/ r
}
4 ?6 b* @2 g( D6 F2 T+ i; _3 S7 N* h2 k: }3 b" d+ m
int Pop(Stack &S,SNode &e)8 a. \6 h, T# m1 A  }' q
{
6 O4 e# f) I% p/ j& f: q    if(S.top==S.base)
/ W' I% y' ?8 o& Y5 a    {
" \  d( p: n. }+ q/ k. n        printf("栈为空!");
. |+ w- `) Q" o$ f        return -1;
; b1 y  s* q  u    }
7 i3 a! ~- Q, i2 h9 R    e=*(S.top-1);
/ M( S* }' C: p0 t' N% ~( |; }2 G    S.top--;
/ s2 u: ?5 r9 w! k. h    return 0;
1 }' Q9 F. v% m  S}
) _  j, x5 C( j' P7 R! W7 [) M
% I/ D, C4 B( c9 v+ h4 X9 jchar get_precede(char s,char c)% n( P0 X3 \1 d1 i7 t5 g
{
8 m% }8 V$ L9 P* f% J7 V    switch(s)
1 b* I+ k( ~8 I* [- F2 q7 C3 R    {; G. e8 v) H6 [# h  d5 U
        case '+':                 9 i% d$ p, y: e3 ]; V: f
        case '-':0 `) w( }+ t2 y9 q8 `( a, e
             if(c=='+'||c=='-')* t$ h9 J/ y4 V# }
                 return '>';
: ^$ ^6 z1 J8 I1 j8 D) {3 B             else if(c=='*'||c=='/')4 \. R+ g: n* z: n1 \# o  _
                 return '<';6 o9 ?3 n1 L! h8 e1 o4 p, k
             else if(c=='(')
" X( [- ~7 e! c4 S+ [8 ^6 D) v                 return '<';5 s5 r8 `& v9 B1 B! u0 ^
             else if(c==')')$ [8 e. m7 @9 A. h& `9 V# l5 e
                 return '>';" Y- v2 g1 X$ I- X5 i
             else
! t$ B( p, n; {                 return '>';9 L# U, c! a5 b: H" S3 C
        case '*':
  M' U& w9 D$ U; Q0 l        case '/':; K: ^( d* v2 {8 n, {5 |% ~* u0 c
             if(c=='+'||c=='-')6 K0 g" m3 j2 N' _/ N2 ]6 z
                 return '>';1 v: K! X4 h$ g9 v/ k9 B
             else if(c=='*'||c=='/')" B- _0 r+ E* z; r
                 return '>';
" U+ K2 f* V9 N* G             else if(c=='(')7 T% y  C5 M* o1 h" x  h" d8 |
                 return '<';! X8 G7 |, R. R+ a+ X
             else if(c==')')
0 j. M6 Z& N1 y+ l                 return '>';$ A2 g1 T9 Q$ O- `! k4 _- ^) w$ n
             else
% b6 D0 Q/ g  l  d! m                 return '>';/ f6 x* M$ T" K- O& e
        case '(':) R0 D5 v  o* H, @# P" b. q- A% b2 Q
             if(c=='+'||c=='-')1 t: J3 F4 M7 K" B' W4 K
                 return '<';8 O  W, S8 J8 l, B7 A$ f! ~
             else if(c=='*'||c=='/')2 f) a( O# [: q6 b* U* c
                 return '<';3 i" _% u; h3 I
             else if(c=='(')+ U. s7 b. S- W! T2 {( o3 v* \
                 return '<';
5 W/ W3 J2 m2 i             else if(c==')')/ D% c+ i) B% d6 @& o) h
                 return '=';3 v; U1 `( E- W! z
             else' n8 t6 b8 a& ~5 g4 h
                 return 'E';
* U. G/ F& B7 {5 r        case ')':, O7 n. i% s" X% d3 G7 v5 ?. A7 r
             if(c=='+'||c=='-')
' _$ b6 D3 m8 b0 c                 return '>';& J; ?' S2 m0 i! T
             else if(c=='*'||c=='/')# v: ]+ O" }9 r: {: E4 P
                 return '>';# E. `: t- q( o7 T& Q1 m2 l
             else if(c=='(')
) D. H' e  v  b4 l" S& k" Q' V' F                 return 'E';
' Y8 b  h( Z7 E5 n. W" w2 R6 L0 h             else if(c==')')( k( k% i; ~& x/ a3 [7 g+ j% |
                 return '>';
& Y; {+ t" p" R# U% x& Y             else, x6 Q3 t% O( ^+ q% J) ]! Y9 J& D
                 return '>';% \. M5 `, I% k7 Y* a$ [! E
        case '#':
7 r# t: _8 M. |1 X             if(c=='+'||c=='-'). I5 W) A6 T4 t# \) m! u4 |1 _2 `8 l
                 return '<';; q/ V2 Y3 U- W
             else if(c=='*'||c=='/')
) G  ^" T# W( h' G" W                 return '<';
3 ~* F3 d/ u: H  e" P9 o             else if(c=='(')
) t5 M2 ^; m3 L                 return '<';
" |( T2 I3 C3 n7 G             else if(c==')')
3 O, Z0 F: G& L) P" t2 ~# A                 return 'E';  Q* ^3 q( T8 p' e4 l) E2 l! `* \
             else7 X5 i* v( C4 W* H- g3 h2 e
                 return '=';% M; k2 c2 T' h5 ?# N- c
        default:
; E* s6 T- W& o. c* ]/ R; i8 a             break;" {/ ]1 ~/ C, \0 u9 ~% O; S
    }
. R' b5 @8 g1 Y) ?# J5 ]    return 0;    ' E# g4 g$ l* B0 K% s. |
}- q( L2 j3 f/ @( B4 j) j& u
3 f/ |0 ]/ g+ ^4 T: H
int isOpr(char c)& j8 {: I- J6 t  ~( Y  K8 A
{
- |; z' e7 w' g2 Q    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4 Q* l5 N7 m: t+ J" L        return 0;$ J- N. I  ~) k- O1 s
    else
" ~$ y6 C2 I5 e* K' `( F  P        return 1;
% |( ^* R: }; e1 |  ^0 K! _4 \}) [0 G# ^- q! g  D

- x6 j* S: v6 T+ Bfloat operate(float x, char opr, float y)
5 c5 N& g! n/ i* N{
8 F" C6 {( c# L/ x3 x2 K7 y    float result;+ a+ F: X1 U+ F  t; G
    switch (opr)) ~+ i4 U/ c6 l  R7 M, [6 c7 X
    {
3 M4 v$ Y2 [6 D8 {5 W        case '+':
" o4 N* y0 N; F, a3 P+ P             result = x + y;! Q; P% \& q1 w% J8 g4 q
             break;2 j9 c( i! o/ ?" n1 }
        case '-': + |( d: b- T  K- l+ |) }( |
             result = x - y;% C: q9 k1 F& e8 l
             break;
& K& [) ]5 I/ w' y7 x0 a' c2 i        case '*':
. O7 I4 h, H- ^! r  ?% c8 D; @             result = x * y;
9 F7 v4 ]$ M' n1 M             break;
# ?# W# q) L& J) ~  z        case '/': / G# S& B& k2 k$ [7 ?
             if (y == 0)" A9 E7 x7 E# X; x% T  V$ T
             {
9 N8 `! ~( J; Q' B                printf("Divided by zero!\n");* E. [* p# H3 l8 \: b7 p
                return 0;
+ s, F0 H# [' B             }
# A! I" g3 L, _             else
/ Y9 Z( x( K1 K             {" |$ {0 {5 E! A
                 result = x / y;; R, H  q4 ^9 Y9 G8 w4 C
                 break;
- e' [8 p# W2 i6 x5 j             }
  t9 p7 z/ @5 F+ o       default: ( }0 j0 n! P& P; C3 u( G$ X* s" e3 u
             printf("Bad Input.\n"); ' ?. p  ^& u4 z+ S& R# k
             return 0;% I0 a% j" B/ z' v, p0 Z0 m  }; a0 s
    }
- [- y' C$ w( T' b& K    return result;# _: |- F$ J( }6 }5 q$ _1 W' d, h
}   
* U7 L' p4 Y2 D9 L+ m8 V& F0 G# A  n5 }
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 z/ `& G/ ~, J% g! V/ I{3 Y. T* n0 B; |0 R5 j, V
    Stack optr,opnd;
5 r2 g; b- x" C  @% |4 m# v    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;. t5 x- S' T3 f% r8 f# v
    char c;7 |2 l6 L( N/ l) B0 t1 ^
    char buf[16];+ D+ i4 R$ M" u& A( g; d! g
    int i=0;
, c9 C' Z( ?8 `    6 l, k8 D* p6 }% p) r* P! j6 E) D
    InitStack(optr); /*用于寄存运算符*/
# Q6 n( |+ v3 N0 V) s  i    InitStack(opnd); /*用于寄存操作数和计算结果*/
  j4 n" ^" M( _# K6 s: D    memset(buf,0,sizeof(buf));! B  ?0 O- ~9 z2 _$ u; D
    6 B. x- ^3 B% Y, K) q0 s: S. l3 T
    printf("Enter your expression:");
7 X, z; ]" K- d$ Q2 W        
, W3 d! ~( r' v; B    opr_in.ch='#';; D! K5 @7 Z0 l7 D0 i1 H
    Push(optr,opr_in); /*'#'入栈*/
: a& V. T) P/ Z' O$ A  @    GetTop(optr,opr_top);9 `4 `* q* e; {' o- K
    c=getchar();
3 T) \0 v7 h+ b0 N& I) Z$ _0 a    while(c!='='||opr_top.ch!='#')
. m4 w( j: @+ @+ T" L" z    {# ]& S' P" W1 `5 {3 r5 ]+ h; J
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
  q4 V  q( ~! p5 O* O        {
9 |) G8 C; e/ K& x% a0 ?8 w) t            buf=c;, [, K6 }: t9 a' v2 R; x# @+ b
            i++;# y" @, o$ o; ^, c- `! t
            c=getchar();0 s2 o5 q# Q, O' @2 s
        }
) H! c5 e" `; P# a8 o        else /*是运算符*/
0 ^7 J6 ^! M+ `6 I) p        {
6 A' u6 P/ g0 ?( k            buf='\0';
* H: h5 h4 _, g) y            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
& ?9 b' X5 E: @8 V, E* e            {
# N9 {/ f/ Y5 N  t' o' |2 {                 opn_in.data=(float)atof(buf);! {8 \. |# A" I4 N! c6 C) [# [
                 Push(opnd,opn_in);
& c  W  D- A+ Z* ]  ~                 printf("opnd入栈:[%f]\n",opn_in.data);! ?& Z$ [2 [6 R  J+ D
                 i=0;$ U/ b; K' c6 F7 d/ l  o% {0 {
                 memset(buf,0,sizeof(buf));
( |' S# O; d6 |% U6 h8 D, Z) U, \8 L            }4 a+ I9 N# _$ g- ^
            opr_in.ch=c;8 M8 W5 y7 O2 U2 O
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
, a) H# y9 o) s& s0 ]' j, M            {
$ Y9 n5 U& R) t2 i; e& ]* o/ M                case '<': /*优先级小于栈顶结点,则运算符入栈*/- [- ?: z' g4 W0 n* Y) Y- E$ }$ @
                     Push(optr,opr_in);
" g/ b& E. _$ i" p# t                     printf("optr入栈:[%c]\n",opr_in.ch);
. y* j. l6 N( |  M                     c=getchar();" T* m3 D( V" |: k' H
                     break;+ F4 t$ n3 @1 l1 ?' X) o: h' \
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 D& g0 ]" I5 f3 B
                     Pop(optr,e);
; o- g8 Z$ Z7 Y; F                     printf("optr出栈:去掉括号\n");
. L4 Y+ M. w% k1 w2 e) C                     c=getchar();# b" f: ^. b& ^
                     break;
7 q! r* P  j2 v3 ~# n+ i& \5 C1 o. _6 _                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/) l$ M) I! t8 k# H
                     Pop(optr,opr_t);
4 p9 @- ^4 _1 o  i) r: z                     printf("optr出栈:[%c]\n",opr_t.ch);
- X' }8 P5 D6 E3 F8 `                     if(Pop(opnd,b)<0)
# b# z8 g! U4 t0 d% }; d                     {
  F$ u% ~* _, G' e# H* X# X; I! s: d                         printf("Bad Input!\n");# ?# b, K* n) N4 |& u: T
                         fflush(stdin);1 Z" \) ^7 X+ L0 q. |  P; X6 z8 w. C
                         return -1;
, w' \# |" v1 ?1 C8 X- E& y; B                     }
! b) ]- Q. {7 @" L% W: B                     printf("opnd出栈:[%f]\n",b.data);
" |9 B. O* R: h3 X2 i                     if(Pop(opnd,a)<0)5 c% \7 ]" S3 w0 u
                     {
; A3 S; f" y/ q& ^) W& j2 H                         printf("Bad Input!\n");
& S8 ^5 _! B7 R) i( g5 J                         fflush(stdin);- T- y  O1 I9 z) t* _
                         return -1;
, R( q& S- ?+ u5 \" ^) D5 P4 g                     }2 b! v( N" C# u9 s, i% S  b9 B
                     printf("opnd出栈:[%f]\n",a.data);# ?, O8 K  g& ?- C
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/" U8 g* X) o6 {( A! A" |5 {
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/9 |# ^( f# u* ]. \& [- q
                     printf("结果入栈:[%f]\n",opn_tmp.data);* _* D3 b. H0 Q6 L" I- F
                     break;) z6 z2 ?' l3 g: D* p# y
            }% k8 z1 o# U9 y# e
        }
' q5 C9 G" u5 t3 s, z" f        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                / P! R  |9 I# t) M* y
    }* k0 P/ k7 ?. c: n8 B, q- L
    GetTop(opnd,opn_tmp);8 ?3 @, f( e! t* x8 K" a8 y
    DestroyStack(optr);
8 r, o* j; A0 \2 N' A% y    DestroyStack(opnd);
% r2 D" N- B3 N9 V9 w    return opn_tmp.data;
2 ~" [8 F; \7 v1 K* W8 D2 i4 ^}
" U8 i' b' Q* K: m2 L
: J' ^* U( s! B6 echar *killzero(char *res,float result)
; K9 F: g& o5 N) E{+ K$ P  L( C$ A6 c
    int i;: d, q% m& R/ M7 a. \# g
1 F$ `$ k# i# a
    sprintf(res,"%f",result);% P6 B( Y0 ]) Q) g
    i=(int)strlen(res)-1;
" s9 `7 i( u7 G2 k+ ]* v    while(i&&res=='0')
" ^% l; z; T- L  K% v5 D, S    {; L  }( i# Q9 k- Z! L( r$ z$ @
        res='\0';
, o0 \! v) V+ f2 [        i--;) ?7 F8 C: o& I! ]2 @4 E9 b6 q
    }$ \  G4 `' g+ `* A8 g$ D9 ]
    if(res=='.')
2 Y* B  v# q5 ^        res='\0';) f8 w* E; r6 [: p- q% J
    return res;
$ G9 i9 w3 z) S- u* k+ j$ o}
* E- }  @; h# s% D: }% b0 O: y+ r: X/ D4 w8 J
int main()
2 B% [4 \. e1 ^1 Q8 a5 ]! l' a{
2 e0 m9 X5 [2 u5 J* W- E( q5 T    char ch;' F! [0 ]& F8 I4 d: r
    char res[64];
) s- M4 Y5 u8 p* g    float result;$ S5 g$ D6 o, v0 T2 ?
    while(1)4 H3 M1 r) X2 r# W( k
    {
) u; g  m3 s( r6 q2 v$ |6 r9 W        result=compute();2 I* g2 s3 M' r8 T
        printf("\nThe result is:%s\n",killzero(res,result));
# ?6 S, \- M3 a1 @' |# B  J4 D        printf("Do you want to continue(y/n)?:") ;' Z8 _- L) o. G3 {1 Z" G2 z
        ch=getch();
* Y" o6 O3 |5 n* s3 r        putchar(ch);
/ W5 ?$ g# i5 b* U! @        if(ch=='n'||ch=='N')
, U% W- k, n: [/ r8 h            break;$ u  Y# r' \7 r! I$ A$ p
        else- {. G" h$ U! O3 |* F
            system("cls");5 z' F' [9 q$ E& ^6 W  y
    }& o& B) P8 y5 Z) y
    return 0;
/ @3 x' ^$ C* q1 k9 n/ L$ K3 ]' `}
% N0 }7 ?/ ~' u* P( q& H
1 [4 G4 ~' H$ Q
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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