返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.2 \- t( U8 N/ g9 e# r! M
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
5 p( |& [& [+ {  F* |( e/**************表达式计算器************/4 [0 s0 ~7 P7 N# s5 y1 ?( ?
#include <stdio.h>* H7 @; j. Y. L% U
#include <stdlib.h>
7 L+ h" @! |2 g& \$ D& R#include <string.h>
" a- D/ y1 `; p) T#include <conio.h>8 @! J: Z8 F8 p! w4 t
#include <malloc.h>
- h) H! Q1 p+ g$ m  t/ Q; a2 n
6 w( r% {8 L' Z4 Z#define STACK_SIZE 100: @* U. D  v! N0 [6 {- o5 x4 @
#define APPEND_SIZE 10& B0 I: a8 P% r

6 Z. T* u8 [7 C$ istruct SNode{
; i% k( J( G( U    float data; /*存放操作数或者计算结果*/. W; A; W$ `$ a2 u* z6 c1 m
    char ch; /*存放运算符*/, ]  ]4 X. }6 |5 o7 _
};
1 m6 J* M+ m. ~1 I/ T
0 J5 f: f' O: C# Z! V9 istruct Stack{  a+ O0 M, I4 D2 K' b2 C
    SNode *top;0 `, {) b! q) }2 S% H
    SNode *base;) z" P6 \0 e5 ]. e5 S' y
    int size;& |4 M/ Y5 c" U2 ]0 T) q$ I9 @6 K6 Z, ^* D
};9 Q: t6 o2 Q) n, g

! B7 |  t3 C) Y6 l$ l  D. A/*栈操作函数*/& ~" E/ W0 t- r4 i' r
int InitStack(Stack &S); /*创建栈*/5 l1 h" |5 d; I6 w. U
int DestroyStack(Stack &S); /*销毁栈*/
+ ]3 i( [$ q- ?+ Hint ClearStack(Stack &S); /*清空栈*// z+ \  a4 H6 f7 Y% j$ T5 O
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
9 ?) [% i$ j5 l# S8 v" @, W$ M9 lint Push(Stack &S,SNode e); /*将结点e压入栈*/# V% c! G6 n2 P! D
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ I# K" G$ z0 v
3 J$ M3 H  L' I0 D4 z6 X  c& g. B- W/*表达式计算器相关函数*/  I7 O5 a3 b& Y
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
: o) o$ ^" k: _int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
8 T1 L* U7 q. \7 Vfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 Z# K6 X$ \+ P) i1 |9 e* i9 sfloat compute(); /*表达式结算器主函数*/
9 r, t+ q! y, B8 C% ~char *killzero(float result); /*去掉结果后面的0*/
# V; E; Y3 [5 t3 a, J8 `/ V( f9 [+ f% X! l. v/ P
int InitStack(Stack &S)
- a4 m  }; ?, ]. p6 R5 p/ A{( }' M& V+ B# a% v" ~  p( Y9 u5 R
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));( i( A' ?0 _  Z
    if(S.base==NULL)4 b+ `4 o" K  X- ]5 N( O
    {
8 C& U2 J; t6 F* J        printf("动态分配内存失败!");$ {' v3 d; W, Y3 W) ?
        return -1;
) ^$ r9 Y: n0 I5 G- ?    }8 p3 W/ N, g. w& R" ?* q! O
    S.top=S.base;) _. z& c* G* y; r- g9 g
    S.size=STACK_SIZE;. a) g0 P- U, K7 e
    return 0;
: P# n: l8 F8 l, ~) @8 i1 V+ T2 E}
4 X/ {/ _* S' d1 C* S( P* {% P9 U  N
int DestroyStack(Stack &S): b5 Y/ p; |; g5 T3 ?) A( q
{
. m: B) Z. S4 @$ w) L) |: V    free(S.base);
6 n5 @" C  G$ r    return 0;  T( C& }, L6 `, Y! q0 x: j
}
- j; n$ R1 I# {+ H( K
, }' Y, |2 y  Vint ClearStack(Stack &S)
3 N5 Y" X1 |5 U{: N4 N; ]( Q8 b+ ^9 h
    S.top=S.base;
( f4 {7 ^& [3 O. v$ S) R0 |% S    return 0;4 w# I! @; h4 T& n% l& m4 y
}
5 z. [" I- v" V7 X
$ V9 S  ?7 A. x- Qint GetTop(Stack S,SNode &e); `8 H- Q. H5 m* J5 `
{
& w1 L/ t. K8 X    if(S.top==S.base)
% s, C4 x5 L) B% Y8 G. ^" A" v    {6 `1 [. k2 b. z+ r' |) O
        printf("栈以为空!");
9 l0 G) c. Y" U        return -1;
" b( Q4 C4 O* x    }
+ W2 l% F% t: r" G( s1 O# }. x% a    e=*(S.top-1);
. O$ o/ D, V8 s# E, a3 K9 _    return 0;
' c0 Y3 g6 h7 i8 Z}
- k2 Q: n$ e5 F& I* v+ @" C' x' f/ v3 V3 t. i
int Push(Stack &S,SNode e)( B9 w" q- S: |. ~- h6 z2 w
{
/ C/ k! m3 X6 I6 W" j    if(S.top-S.base>=S.size)0 x7 g3 H! f& k$ O
    {
* h4 B+ r; x5 a" `        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
# _$ o: d5 t5 f. Z& V4 Y0 W        if(S.base==NULL)# T) B2 ]6 e1 n" a4 O% y8 n; P: v
        {5 @7 N7 o. H1 ]  V2 V8 y7 U4 O0 l
            printf("动态分配内存失败!");
8 Y1 c' L0 N" b            return -1;2 s  S9 G# ?3 s9 e6 y$ w
        }
. A6 Z2 x. U. V* w* L        S.top=S.base+S.size;/ W: s1 R% P. L- v9 I
        S.size+=APPEND_SIZE;
- a7 J; h/ e' i, x, g6 ~    }; L$ A5 Y" `) j  z- w+ p1 y" t
    *S.top=e;
) Z9 `' w* B% n& K3 t; \2 g  X    S.top++;
* w8 ]) n( q; u; I# R" ~/ z- ]    return 0;/ i0 ?8 q  z$ D
}
, A% C. H# N" J) r, o( `2 {3 \& j, r! o1 K: V/ S- x9 _; r% A
int Pop(Stack &S,SNode &e)& K$ E+ ^; a" b( m+ K
{# i6 r( o% H' P% N0 o
    if(S.top==S.base)$ o/ j2 K( u# Q
    {6 w$ Q% Q2 G  S7 v' V' W8 s% {
        printf("栈为空!");
/ r& P6 f: b. j+ _) n$ F        return -1;
, U7 B/ N0 P: K! w$ v4 @    }; r+ w2 k! ~) v) V$ N
    e=*(S.top-1);
/ Q! Q! G- y) ]' p* G    S.top--;
* U" d5 [# ^7 M( N9 ?- [$ c# r: |) }2 K    return 0;
  X1 M* M9 ?! m  O2 _) r. Q/ I# ?}
$ H- y, b0 c: P+ w* G9 ^1 r; G* V* r0 t
char get_precede(char s,char c)
9 p) |0 a$ s% w0 {5 I# `{
% _; T! u9 S& R: X$ u& i5 l    switch(s)  J: i' H2 `0 H3 p
    {  _( @- G- K; f2 g3 a
        case '+':                 
6 x: c5 d4 }# N) O0 A        case '-':- T6 M4 i1 B+ X1 n& U% W' o4 `/ q
             if(c=='+'||c=='-')- A% ?* D/ ^, b8 \$ Q6 \  N0 |
                 return '>';
& F2 K+ {; I* ]" x5 e' e             else if(c=='*'||c=='/')4 u* Q/ B+ A0 w
                 return '<';
5 z0 T/ J; W9 E  r$ G$ d0 e             else if(c=='(')% G" S6 }! h8 q" F/ [. U
                 return '<';4 B4 l9 ~- v5 G. O
             else if(c==')')/ e9 T9 C! ^5 G! k5 f+ T
                 return '>';6 g) X% u4 _# S5 F# [5 f# L5 g
             else
. s% F0 |  L$ T0 Q) j& B. t                 return '>';# B: O; ]' |/ y2 G$ K! G3 n5 _
        case '*':4 h% ~0 h( k# u
        case '/':8 o: C1 h' r- u4 U/ H4 ~
             if(c=='+'||c=='-')
" E+ @/ `3 r; t" Y! |" S# g                 return '>';
/ H( b7 ^; a; G             else if(c=='*'||c=='/')# i9 A9 n& |" f
                 return '>';
1 t- z8 R- E1 a- U             else if(c=='(')
+ X- Y; K/ F; f: _' A# ^% ?0 `8 a                 return '<';1 A- V/ p- B. E
             else if(c==')')0 t. t( s, ?( P& w  F1 k
                 return '>';
# i" A: f  K+ [# Z+ G$ ]             else2 K3 n5 [4 R9 n
                 return '>';& W0 @/ W- O% _5 K6 R! w
        case '(':* N% }$ ~$ s: p0 _3 I* t* @" e
             if(c=='+'||c=='-')
0 b2 A* B# \( h                 return '<';+ N# X" f. G5 F- Y
             else if(c=='*'||c=='/')
, c4 ~7 M( f" S( A7 Q! f$ |                 return '<';
5 _5 W7 h1 _  w4 K* B) o7 v             else if(c=='(')
$ \! y% o2 W5 t6 m  ^! ?                 return '<';' C* g; l3 S2 o1 V, h
             else if(c==')')0 K3 p( [9 E. o6 A+ `% G, u- N3 Z
                 return '=';6 h! X# A2 v3 L& S* d& X/ Y3 r; s
             else
5 m- }( q3 F* m1 ~                 return 'E';, f/ M; G2 W+ |3 Y# \! T
        case ')':
9 s1 X: H- ^0 V8 J& i* C. }             if(c=='+'||c=='-')! `( P+ V9 I1 x
                 return '>';% C5 h2 u& m7 _% C: n) n) u( t
             else if(c=='*'||c=='/')
3 ~! _1 i1 O5 B0 z- h+ p" r                 return '>';
- c8 l! ]# W6 I* t6 u& I4 g  U             else if(c=='(')
% c2 j4 X, l5 p                 return 'E';
, Y1 c* ^+ `9 T& F) w% L             else if(c==')')$ ]. S( P5 B. [: B8 B" {( r- x
                 return '>';
) ?7 `* Z5 q( Y6 ^' N             else& }  D: f7 p. A
                 return '>';, x, L, @: `& B- G- p  x& d
        case '#':% l9 r4 v) _: w1 }2 \$ p
             if(c=='+'||c=='-')
0 d; E* D! q5 P- z: Z8 e. u5 O7 |' f7 o                 return '<';
7 R( q8 e+ \. c! I             else if(c=='*'||c=='/')" Z0 Y; v; V$ \
                 return '<';
6 c, h4 ?8 F9 Q& P- C9 P$ O             else if(c=='(')
$ v( @, V# W6 T+ S# l7 [; U, h% l! o                 return '<';. @* c% T. m3 \8 y1 ]
             else if(c==')')
; l& m9 R% x# U# ?  O8 f: n                 return 'E';' ^/ }9 H' K0 M: L7 Y
             else
( S( T0 ]! ?! c) O                 return '=';* f+ F3 o+ e; u4 s; D
        default:
, E, X1 I% A+ V3 k             break;
; Y1 u1 w; x/ k    }
4 J7 q' y+ C) [* d* T, i    return 0;   
6 e. P. Y9 J6 C1 t2 ?$ [, g}
0 D( F* T8 ]5 K( d' X" T4 n/ g& o2 `& Q7 ]+ l' y! s  [% M
int isOpr(char c)
- m3 H; p; M; S6 `7 |1 F6 G1 v{2 e  p( _( b& p( C
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='). D, T+ {# n1 S- X6 h0 O
        return 0;
3 P1 D5 I! x# [% ?+ z( o" @    else
& c4 C( C, H% V# {' i- j        return 1;
8 S  E" K* ~$ ^8 Y. c* K/ Q' u* f8 w( z}
: j3 \5 z% b2 j; X
$ T) e& v2 N, @float operate(float x, char opr, float y)
7 F, J% j& s8 C- F9 T" r% x{# h: E4 a- Q! |! W, Y
    float result;
( B) @% {, i+ z+ D- k6 j    switch (opr)$ ^3 e$ O$ d: P* v& H# m
    {% I4 `! u8 `5 W: _+ \& ^
        case '+':
/ O2 w9 V* M& s             result = x + y;) y: ], k$ l/ C% o
             break;
8 w( k5 m; J* k' E6 y        case '-':
" K8 F9 Y# P# Q             result = x - y;
" G" i+ p5 B, D2 g             break;. K" _+ |- W2 Z* ?9 a7 q7 b
        case '*':
9 P$ N) K7 N8 l4 {; a, U             result = x * y;$ K8 l8 ]: Y( w9 K, g9 S
             break;
7 a3 ^* T$ W. W1 Q& _& J        case '/':
# T* B7 `( r& d# q             if (y == 0)6 t) l! f! S# _" Z3 Q
             {
* p: j% ]) s" C' p1 F; D                printf("Divided by zero!\n");
; ?" `, Y" c6 m+ R, A( Z                return 0;
; a+ [& q. `' v% ]5 f" G0 P             }' G3 P3 S, W% _3 s5 X
             else
: H' v+ ^; ]: g+ s             {7 E0 t( U+ l2 E: B
                 result = x / y;. y! t( ~0 r) v) k: b
                 break;
4 S. U0 b. W9 e5 A8 t             }# q  F6 ^2 u" z0 ^
       default:
" K4 |% b( D6 x# m% C" ~             printf("Bad Input.\n");
. A  ?- ^6 d) m1 v+ K             return 0;6 ?8 c3 T* w* R9 V0 z3 r# f# x
    }5 g1 c) I2 n$ Z2 w. q. [3 j$ `
    return result;
/ F+ G7 B# Z" k) [) x6 \0 B( i}    3 s' ^# S/ S) J
" b+ Z0 O- ]- G- h
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/" V2 c0 V* X- \5 }7 W; w; X
{; X- ~% }* {: n
    Stack optr,opnd;
7 h" S  l, f% i5 r& O, I- z. g    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;0 X3 A) g* a/ u+ m
    char c;8 f6 z' Q, n! k
    char buf[16];# Q  ?$ u4 S3 U2 |% J- U
    int i=0;
  W3 i/ W+ H& M  A& L4 Q    2 w0 U: K. z% E2 k- ?; X
    InitStack(optr); /*用于寄存运算符*/
  ^% o7 i" |0 }    InitStack(opnd); /*用于寄存操作数和计算结果*/
5 F0 C8 P( K) y. L8 \5 f    memset(buf,0,sizeof(buf));& f  n+ V+ f* D1 p
   
' U& g" ^; _. k& Z- _3 H* W6 [+ R    printf("Enter your expression:");
* Q& n5 C, ?0 B! F- C4 {; Q* w        
, Z: x: s2 \2 O, y. B; B    opr_in.ch='#';* }2 B* ~+ x4 _( F
    Push(optr,opr_in); /*'#'入栈*/
# P, Q9 x8 k' A5 Y# W7 L( E3 K    GetTop(optr,opr_top);
% ?) |6 S* G0 w& a& G9 m7 Q    c=getchar();
& E+ ]/ a1 l3 h    while(c!='='||opr_top.ch!='#')" L$ `1 A' D0 {! L
    {, K) `9 R  n0 K# d# u# O6 t$ }3 N
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
2 B0 U: f0 J) g0 E0 [; L        {( X% R1 n+ f4 g+ i+ j# o
            buf=c;8 y' K2 U" M6 a- v1 o6 |
            i++;
5 J" W9 t2 m( d& r            c=getchar();
; }. S0 X; G# p& K) C0 [" V        }
, Y' N' {. h  ~# T; d        else /*是运算符*/
& \1 @% }, b3 y: H# I0 h        {
/ ]8 _  h! q; p4 H% k& T) I            buf='\0';* s3 i' {/ W2 F4 m# S- Y% k
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/* _. A; L/ y1 e! m5 {1 c
            {
/ v  w' I; J3 m5 X  G                 opn_in.data=(float)atof(buf);4 x- E6 p( n! [' p& ~
                 Push(opnd,opn_in);& Z2 U2 I5 P2 `7 n  f$ t9 G
                 printf("opnd入栈:[%f]\n",opn_in.data);
/ i  g6 C% N* d                 i=0;
6 z- v% A3 e# i3 _5 W7 I, ]" t& N                 memset(buf,0,sizeof(buf));
$ r2 z" q2 Z/ v" F- D0 f            }
1 b! g" Y* c$ w* F& p5 d, F            opr_in.ch=c;
9 ~; w8 ], z2 k            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5 N' J. e" Y" A3 o            {
2 _8 l, Z+ ]# q7 f* e& @                case '<': /*优先级小于栈顶结点,则运算符入栈*/
7 g' |  l, J+ M' {. G5 v                     Push(optr,opr_in);
8 ?. W5 B' h8 _. {0 |                     printf("optr入栈:[%c]\n",opr_in.ch);
$ H/ i" Q/ d, q& o! S9 I" [                     c=getchar();) Q- [7 @9 w7 Y0 i
                     break;
" l$ K9 c5 M, R% a0 \, X                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: p7 x7 g9 f4 o7 n4 u1 b6 o2 [                     Pop(optr,e);
  B* h: F$ U! o                     printf("optr出栈:去掉括号\n");
. p0 d$ B& ?1 [6 |. W* k5 P                     c=getchar();- |! c' n0 r+ A* {
                     break;; H4 m# p. n. K* u5 C
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
" [. J* O+ l$ {                     Pop(optr,opr_t);. `7 a9 L+ P. ?/ x
                     printf("optr出栈:[%c]\n",opr_t.ch);
8 W( B8 E3 i$ @( c: k                     if(Pop(opnd,b)<0)3 O1 r) J9 o2 l2 n. I
                     {' |7 \7 K! g+ z& Y4 K
                         printf("Bad Input!\n");
' P3 g) E* c: M: S5 X4 A% ~; F2 y' ^                         fflush(stdin);! |3 G' l" [0 E! K. K# W
                         return -1;! p! h  S; P% K6 a
                     }
9 E- A8 c& q+ Q4 \% ~7 [                     printf("opnd出栈:[%f]\n",b.data);5 J- H$ A7 K' w9 t( K' [# g
                     if(Pop(opnd,a)<0)
3 y) A- }$ x( ~/ N6 q* ]8 S  T                     {" ~1 e7 \+ f9 z( r! r1 U: @
                         printf("Bad Input!\n");
+ c: Q6 N9 k* J* q$ U7 P+ e                         fflush(stdin);
- r8 a0 ^5 N' m4 ~2 Y3 A  W# U& j                         return -1;
1 X1 l! }2 `9 S0 B2 b! A                     }0 k: P4 J1 |6 t4 z
                     printf("opnd出栈:[%f]\n",a.data);8 P2 g4 X) w2 m$ R3 e) A
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
4 K; O5 i7 N7 s                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
% J5 ?. }. l* i+ p" W, s                     printf("结果入栈:[%f]\n",opn_tmp.data);
! Y. q  E! [. C                     break;/ d- ?- F( @, E3 t% h9 d
            }; c6 ~9 x" E2 x3 i6 I" d& b8 D% J
        }
* a8 t- T! b+ l) T        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ( h; \$ z# [8 U- R' w8 j1 I
    }
/ ^6 {) U4 P/ ~. @# _) G    GetTop(opnd,opn_tmp);, D1 E4 _! c& B4 Q" A
    DestroyStack(optr);
9 Q0 }' ~% H; e    DestroyStack(opnd);
+ K& {3 |8 a- `+ t& K    return opn_tmp.data;0 E/ {5 S7 x% D1 H9 [
}1 j& w( r7 _+ R  C' T& I$ Z
7 e, N) ?9 E$ C1 I5 U) _' Y$ x
char *killzero(char *res,float result)
; ?1 D% o) P2 w. \; U9 M' f{9 e  ?$ ]3 _$ [3 E$ E! f
    int i;
. p5 S" T5 y% W8 d9 R- z
& u4 T8 j, m4 F: q4 b: W1 n    sprintf(res,"%f",result);1 M. x1 H  a% c/ g3 z: \- ~  z
    i=(int)strlen(res)-1;. M+ D5 f! X( e
    while(i&&res=='0')
8 f+ N6 @# w0 G7 I0 [8 z    {
0 o2 [% t+ {8 N9 H  d; c9 O$ c        res='\0';( f* g1 ?! J; S, J
        i--;! s) B, i8 i8 w" ~3 f
    }+ y! i5 G1 e% s
    if(res=='.')
( y! H6 J; K6 `) P' h4 Z) k        res='\0';4 o' ~# _1 x* p; {$ t( ]4 \
    return res;+ h' k' v. j9 S/ b1 V, c* F% r3 V
}
2 v" w4 T0 Z" o- P
: E- \# q" O' Y/ |7 Fint main()
# J1 Z! F1 ~7 V{
# i; D9 |! a( J1 `& U# Y    char ch;
4 I% x3 s5 R* E( {: I    char res[64];
* B; o4 U" r: T4 f7 A, F! x    float result;! A2 ]. U6 ~9 n* E. P
    while(1)1 A4 |: ^2 c( j' }3 w# @
    {
' U# \9 Z' r2 @) C3 {1 h7 Q        result=compute();
: J- q2 X) Y* D+ t        printf("\nThe result is:%s\n",killzero(res,result));
- u3 H) S. h2 W        printf("Do you want to continue(y/n)?:") ;7 i9 P# T6 e2 A- v
        ch=getch();  t7 L" Q* \5 P. M1 m
        putchar(ch);9 R5 v5 B3 \7 t- I3 F* X2 A" L! E
        if(ch=='n'||ch=='N'). \! C, X' ]; f9 l3 S% h4 r: r) M
            break;
$ c  n4 \' ]1 Y  D; u# n  p        else
% |  k# }# B# ~) ~7 X5 e            system("cls");
/ {! }; v# u3 N% {8 M; L+ `    }
: @( D6 C, Q1 W6 p, V! f! v+ k    return 0;/ k7 g$ D' c, Z+ |% `
}
# d6 J$ D5 ~" |( h' q: P& r, Z
% J* N; t0 w* l8 N" W0 ?
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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