返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6 b5 A. C/ x& ^7 i9 [+ D
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=( |) J9 `" }# o: _2 }9 ~; ?) h
/**************表达式计算器************/
6 ^) f  j! {' `#include <stdio.h>
+ G  E1 w& g  p/ i: z, ~+ @3 g/ G, w#include <stdlib.h>
7 w5 x- V  s$ Z/ p5 x) O% s2 o9 ]#include <string.h>: E, _" q+ b/ @3 ?% x! p7 E
#include <conio.h>
% ], ]. O% C- K6 [% n#include <malloc.h>
" ~1 t; c% Y) ^5 C3 `/ L
) ~  o8 d2 K; K) t. @7 I. c#define STACK_SIZE 100
# [0 ~  S+ ]. G+ N* R; k) l#define APPEND_SIZE 10
5 _* B9 B, Q, s2 a; ^" v6 E! t" t* G7 E* w
struct SNode{% K; B. \+ L% w
    float data; /*存放操作数或者计算结果*/
( `0 N2 {4 e7 l- G; s) Q8 w4 l    char ch; /*存放运算符*/! `$ x6 j+ A4 M" d8 d; G' a7 r
};% G& Z( J0 R1 ~. ?

2 N! v% x+ S2 E+ Mstruct Stack{1 T# z6 |$ k0 G5 Q- s7 m, `: Y
    SNode *top;
( h$ U- Q3 O! c6 O) O    SNode *base;
! n2 `$ J& _/ }: Y; n    int size;4 q1 h/ W( s. w
};) i9 e! v! |: Z& ]4 n4 n  Y
# |! }: |  c' r' v4 S
/*栈操作函数*/% K5 {% {6 b  ^8 e3 `
int InitStack(Stack &S); /*创建栈*/
! h% b+ e/ q5 kint DestroyStack(Stack &S); /*销毁栈*/5 c$ z9 H# }" @4 Q7 `
int ClearStack(Stack &S); /*清空栈*/
, C- y% o. |( X2 q6 sint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/0 I9 |2 I1 x- w. q! p
int Push(Stack &S,SNode e); /*将结点e压入栈*/! V$ c3 p0 o) s5 ?" r$ c' b
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
: r2 X/ r, _+ t+ ~2 p% u& n* t) `$ @0 {0 [$ n$ U; V
/*表达式计算器相关函数*/) W' J! k$ ]  M  k3 W
char get_precede(char s,char c); /*判断运算符s和c的优先级*/' v) K4 A. r* l/ z+ C  a' C
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/5 b% e* j4 G$ S( P4 r; M
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
, b! k) x$ j& p0 M7 \- @float compute(); /*表达式结算器主函数*/1 X6 {' p/ M4 ]/ n+ b9 ~+ X% G
char *killzero(float result); /*去掉结果后面的0*/
& @8 Z; q: E+ Y4 v# D+ d* V7 ~# F
; m& P3 e$ t9 u1 r9 O, bint InitStack(Stack &S)& R: G* [0 @( a  M# g8 `
{
, e+ |1 f" l8 f1 u. {    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));. ^6 H# W  L/ P5 o9 c) O
    if(S.base==NULL)
, W' m$ }1 G2 d3 ?  u$ y- h: e    {& `1 T2 x* X; Y- T2 n1 M
        printf("动态分配内存失败!");
5 M" G; M# J; n4 C8 n        return -1;" G5 A7 s: q' ?/ B  v
    }
0 t2 q0 K" P# ^3 f4 \- i, Z7 {! p    S.top=S.base;) w: a2 T3 p" M) }
    S.size=STACK_SIZE;# x* }+ P1 d- |  x, E+ O3 Z
    return 0;
& ?- v1 \3 J6 y, h- a2 t. y9 \}) z9 S. q$ W0 m: Z! i

( V$ c) l; i3 u# dint DestroyStack(Stack &S)
& P4 T) g" C. I% S1 X$ G& T1 Z{% |4 e! X( q  @. z! b0 c3 v! P1 e
    free(S.base);% V' a/ e8 z% a5 T9 c
    return 0;# o) O4 p- f& x
}1 x' @5 S# x' v$ L$ s
2 U' ^) o/ m( I0 Z9 v* P$ E
int ClearStack(Stack &S)4 ~9 e2 g, L* M3 c+ K" O3 J/ S
{
+ \5 c2 z4 A  W. Q# t1 q& u    S.top=S.base;5 x9 W7 T/ J9 ~3 G. X: Q
    return 0;
6 L  z* Q' a  a4 {}0 B/ ?' b! e8 B5 J' v  a- S
$ z9 k: \) G9 L6 t) b' b
int GetTop(Stack S,SNode &e)! h" h; ]7 ~6 R& h
{. `' H! w" V8 Z3 G6 _! I
    if(S.top==S.base)
  R0 f# s0 X7 B' ]0 H& W- Y    {- V) u. b; p  @3 p/ s: W0 Q  E: {
        printf("栈以为空!");
+ i% ?  T6 L6 g. `        return -1;- o! C+ v: p# Q. }. ^' w  Y
    }6 _4 ~9 N; e. N0 x3 q. h
    e=*(S.top-1);- v' V! J2 }) h0 S1 U4 p" y& `
    return 0;
( l6 }2 c) Z7 j) o/ m" F' h3 m}+ @  s/ }/ T% F1 n% h
2 e, }% v" R% c3 |6 z
int Push(Stack &S,SNode e)$ f9 `; ?0 o; p- c4 I! Q
{
- O& b3 V3 I5 u6 @    if(S.top-S.base>=S.size)
( u% e0 x& @) }- O) i2 k    {
* N# g2 d3 d1 Z        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ w* S5 {! ]) E) D6 s
        if(S.base==NULL)
- d- J7 e# k  Q! ?        {
) A7 T/ [2 T; O/ }3 K            printf("动态分配内存失败!");
" D5 }- p1 ^" M4 y3 r! }% r            return -1;
, v/ @7 U7 R) L$ t5 c        }- u  e! H9 ]6 a( o; n
        S.top=S.base+S.size;
; r' p+ i! t( c8 d+ v% I        S.size+=APPEND_SIZE;
4 }+ }( S* o2 W4 N! T/ ]" q    }
/ n" `' C; X- ]1 I  e) ^4 k    *S.top=e;
( x5 j+ y* x( `$ j" v    S.top++;1 x4 O" u% G; i
    return 0;9 v( b/ p. O+ F; F
}
+ {4 N6 j1 w6 K, \9 B
. B2 G9 z6 Z% N+ t4 j9 r# b5 |, bint Pop(Stack &S,SNode &e)
8 v9 B! R/ d2 S1 Y8 e{4 g8 P# q  J: i# A% `9 c( d) k- U
    if(S.top==S.base)4 P/ u# _/ y) q$ l! Y
    {
6 d1 C7 r+ ^$ n% s        printf("栈为空!");
/ ]0 m! m$ Z9 }/ m5 _$ v        return -1;
+ X' Z- s  E. N8 q    }# F' I6 P4 t% N" w, P
    e=*(S.top-1);
/ H4 Y. t1 e' {3 f3 T% t9 S( }# `! e    S.top--;
- `1 m5 E: g& F, L, y2 q& R4 B$ K    return 0;1 a. @% C7 `- d+ q" A+ u% w
}
  p# Y  _  ~/ l! W! S/ m
. Y5 f- i4 K8 Xchar get_precede(char s,char c)
3 \7 E& V" w) m( d; s2 Z{
" c; A  Y2 O8 `  O8 W! ]    switch(s)6 X8 [1 f6 h- ]0 z) N, I% p
    {6 ?. D# W% h5 ?2 E0 c8 A0 B( V
        case '+':                 
; r4 M) e( K, U  t8 ^# E; I        case '-':, h' V7 |, D& _" Q. B0 C
             if(c=='+'||c=='-')
! @, d8 i; w2 N5 `) D. l0 L6 Y) k7 j                 return '>';
; l1 i% G. H5 S6 J2 \             else if(c=='*'||c=='/')
6 M: R7 b" N% q- Z( T. H                 return '<';
! M/ w) u7 C. Y/ R' s" Y             else if(c=='(')( m1 e4 W/ r: l9 F4 L
                 return '<';
( \9 d7 u3 i+ \3 `5 t# ]             else if(c==')')- t2 ^3 f5 y4 Y# P& z! B
                 return '>';
) }# m% N% D( k' |             else
8 F! V- T- w. I* P9 z% [6 t                 return '>';
! V- k# Y; E4 g! h        case '*':4 R4 @5 u9 M: {1 G; z
        case '/':
& @. u- f0 w/ K             if(c=='+'||c=='-')9 b# I% @9 E: s; @. y; N) E0 k# |/ ]
                 return '>';
% n, ^+ r  N: T! h# r% x             else if(c=='*'||c=='/')
4 D- q4 o: Q& ^3 N                 return '>';
" {; H$ ^4 j# y- ^             else if(c=='(')/ N1 o* s: E& N5 @% P
                 return '<';
& o8 O& {4 t0 j0 S0 d4 S; X0 ~8 n             else if(c==')')
! w% z" |1 o" C  {2 L/ f                 return '>';
/ t* Z; t+ P  M$ ]' E             else7 Y. O, ]' }( I
                 return '>';
: Y. i5 q/ t/ L1 [8 ^        case '(':
. m! L5 T( z6 U) m; G( d             if(c=='+'||c=='-')9 w. S! B+ r+ b* C7 c! X3 s
                 return '<';$ w& M! f0 s# R* x
             else if(c=='*'||c=='/'); w7 ?! p/ E) s
                 return '<';
, j0 t; Z# Y* ?" a             else if(c=='(')
, U! U8 B# v. M$ o! t; s1 Z                 return '<';: w, V1 l$ p# P) P1 w0 h; \
             else if(c==')')8 l% E5 b- I- J2 A9 {, E
                 return '=';- y1 C- H! n6 ~: E$ T: c8 t  c+ w/ t
             else3 o8 Q- S- E! F: e
                 return 'E';7 U! W6 P" @- h
        case ')':
7 g1 m* a0 z8 N  u             if(c=='+'||c=='-')% [) x( l7 V. e9 B2 [4 l% T
                 return '>';
/ ^. }! Z& e4 h! c             else if(c=='*'||c=='/')2 x0 U! A" q9 q% `
                 return '>';' E* `7 l0 v' u# A  c
             else if(c=='(')8 i5 v) B8 x) R0 h, H" o: g
                 return 'E';
% Q' l  U- |9 M/ c0 H. G             else if(c==')')- N" N5 O  O( m
                 return '>';; J9 A  h. r! C5 X
             else& b7 ^4 ~1 v/ H" Y* M
                 return '>';. t% [8 w4 U/ [9 |% |
        case '#':
! s4 ~& J5 M- o; |$ J5 `             if(c=='+'||c=='-')  O# B' y6 _/ @4 t. W
                 return '<';
, D, Z2 ?+ |: j! J& s! P             else if(c=='*'||c=='/')/ j( z7 k( M) T- J0 @& m8 i
                 return '<';
4 R  q+ M4 n6 h9 V5 J5 r             else if(c=='(')! C5 c8 [$ n( Z
                 return '<';$ c  G( G& m5 Q) g* [& j
             else if(c==')')& k" E/ z% d! B
                 return 'E';# z' c5 m: e! n
             else- `) f2 o4 ^0 q. u8 u4 S
                 return '=';. p8 A& k' O. `* Z: |7 m/ c8 V. R: G
        default:
+ w2 T7 h0 c7 Z; d2 p4 p6 ^             break;
3 O# m4 r9 O; ~; [- r    }
, ?: ]) _0 C# Y/ s  d    return 0;    - B7 k8 w0 d5 [+ i: \+ }2 Q
}8 g& M$ ^9 a' E9 T7 f/ L3 w3 L

6 T8 h. ~( w$ L# z5 Yint isOpr(char c)" v+ g% G3 C8 ~& ~
{
. Z' d) P. i7 y" C$ B6 r% z& r    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')! l# P! i1 w/ L/ {+ ]% D
        return 0;4 U1 B1 q8 a, U0 F  p6 D
    else 8 V& U' Q* |, P$ j- e
        return 1;/ `! S, I+ z  E( H1 y5 k6 f9 y% `
}2 R. i7 P: f$ _" L6 W* @
- H! I' x& x% o( `8 M
float operate(float x, char opr, float y)
# l: W5 V5 Q% }/ M9 _1 W5 j* a{2 u7 R( X3 q$ \1 u5 P2 P$ D- y
    float result;
$ j+ ]$ ]& I( S    switch (opr)
# Z/ N1 {) J4 P' }/ z6 m$ L0 c5 j    {
* Y5 Y5 T" N* `1 E        case '+': 8 U7 Q5 l0 i) }4 U6 p: K
             result = x + y;
0 U. _$ ~4 Q0 h  o0 K4 V) w             break;
$ c+ u, Z" `3 Z+ c/ w4 q        case '-': - z0 B3 |$ b3 K8 C
             result = x - y;6 l9 Y. l( l' e; V
             break;
! D; z* p) `: }. ]- K        case '*':
" p1 j! |% i9 x             result = x * y;
( Z+ r3 ^! K. [  G             break;
4 ^4 F: b' c# H        case '/':   a, I! y5 _; I1 K% Y4 V$ b2 a7 {
             if (y == 0)9 Y3 v' n2 U/ Y  L1 w) D( X9 _" i* ?& i
             {
( s/ k% y$ {3 s& g* X5 d0 }                printf("Divided by zero!\n");
9 z& D$ {8 g' U( M% T4 e                return 0;: g9 c7 G. X' j2 u1 C" a  M  n
             }& p" g6 H/ a* N6 n. B( z* {
             else* l9 V4 t8 Q7 i5 g% y* v3 T
             {* T' O: S' l8 V; R2 |4 r: U$ A
                 result = x / y;  K0 c& S' h& l3 _8 m, D
                 break;9 O; C8 [+ k* U: p( m- w  v
             }9 U6 M& j3 ~& j# ?. L. a& v" ]: q
       default: ; }2 R1 h9 v, }+ L
             printf("Bad Input.\n"); # G1 o9 a$ `+ m8 X, i5 q
             return 0;& A# Q4 k& [( a/ y6 T
    }0 z, y& B! \- _& \7 j
    return result;
# v: H% e4 X& W$ D5 p5 a}    8 M: g0 f+ n; b+ b, L2 D  b# M
  |% @- ?4 N7 Q9 h3 j& ^. \
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/, j2 P7 l$ l) i! D$ C- l9 E4 Q
{
6 R8 X# w4 o  i/ {6 O    Stack optr,opnd;' m. v4 W; \& B: F
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;" L3 x- ^+ _! }  [( K7 S2 C
    char c;
+ R' S# F- a* T( \( }    char buf[16];3 p/ C$ i0 @2 T9 `+ K* L
    int i=0;
) P' V2 H0 w( Z( M# V    " l6 `- X* P- T( |& ~
    InitStack(optr); /*用于寄存运算符*/, Q2 T% l1 c6 i% s, u5 q% e7 X4 ]
    InitStack(opnd); /*用于寄存操作数和计算结果*/4 @9 g/ m1 a1 Y
    memset(buf,0,sizeof(buf));
) J$ s; Z7 `( T( i; Z) A   
" p# x% W+ k* H% a+ v    printf("Enter your expression:");
" d# W5 x) }" J- d, X        6 E; {" q7 P- c0 c) D$ B2 Y
    opr_in.ch='#';
3 ?  v3 v. P% v; p. g- J    Push(optr,opr_in); /*'#'入栈*/
2 {$ H) w* P* |, Y0 K9 R7 N' z2 W    GetTop(optr,opr_top);
" a5 S( ^3 R. Y8 ?# m1 ^+ k    c=getchar();9 g. [  P, }. P3 c/ u  S, c4 J8 ^
    while(c!='='||opr_top.ch!='#')
! X, [4 ?* F1 P" I    {
8 ?1 `/ v2 M8 M! T4 {) a4 g        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
( ?& |& J* G" ~6 k3 c2 s' H/ a: V. r        {
  @6 W* ~. R5 p  r+ W; C8 W1 z0 k4 `            buf=c;
: i2 Z" A6 @* N            i++;
& G3 x' e/ q5 q3 K$ ~3 a            c=getchar();
* R2 i8 a% Q# }8 F# o        }
* |' m7 X; {* w1 K7 s        else /*是运算符*/
9 }4 z& A7 ?$ N+ D        {' s) b4 x+ @! z
            buf='\0';4 t6 ~5 ~9 B8 Q9 q9 E* c
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
/ X/ m* d: j+ z            {$ P" s; O; ?% Q0 {2 W
                 opn_in.data=(float)atof(buf);
3 v" q4 M3 ~) J; A                 Push(opnd,opn_in);
' W" y" F8 ]* d& X                 printf("opnd入栈:[%f]\n",opn_in.data);) j. _6 a' b$ W" S4 y' S
                 i=0;2 Q; p; s& \/ L
                 memset(buf,0,sizeof(buf));7 C6 d1 U' j, G+ u
            }4 u/ i# @8 Q8 \3 ~- m9 K$ e
            opr_in.ch=c;
) f5 R: D" h' s$ n            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/& l3 ^. n7 e- F4 S+ P
            {
0 C+ G0 B4 S/ Z4 h                case '<': /*优先级小于栈顶结点,则运算符入栈*/" G/ Z6 Q6 ]8 ~2 z
                     Push(optr,opr_in);
/ I, s# ~1 ?' d" O8 e                     printf("optr入栈:[%c]\n",opr_in.ch);
6 s: U/ |$ p9 w! ]7 c2 X                     c=getchar();
0 x- X2 G# i4 C1 H                     break;* E% D; _5 u- T8 {
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
2 V- \" V$ x; u) a/ s                     Pop(optr,e);8 v0 ^  s8 L, t0 z( \7 H
                     printf("optr出栈:去掉括号\n");
7 K7 a; W  O7 b. x$ D* M                     c=getchar();1 Y0 h3 f; J! ]; a5 @
                     break;
1 \8 {# Q' P9 V9 d! a: m. W) q                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
; X0 B) \8 C! c$ Y' f) B                     Pop(optr,opr_t);
" W' }" {$ i# {  R! g$ E+ ~8 \  x                     printf("optr出栈:[%c]\n",opr_t.ch);
. i$ R6 b% u2 V5 L  E5 ]( w1 K" Q                     if(Pop(opnd,b)<0)2 X/ Q, [$ L8 X4 @8 N
                     {5 P/ i& d0 A4 i( d* N* j" e
                         printf("Bad Input!\n");
2 ?% c7 Q/ W% g2 f; q! P! ]& E                         fflush(stdin);
; r% M0 m# J. U2 e4 C# d7 B                         return -1;
2 W2 t/ \# I" E5 C                     }
# l  `7 k6 M0 C: q                     printf("opnd出栈:[%f]\n",b.data);# [7 G- W# m3 V3 l
                     if(Pop(opnd,a)<0)- }' d% M! c4 D' z
                     {
1 D* J8 I4 W3 d                         printf("Bad Input!\n");" c7 U( R) \5 ]9 B& b! K! D
                         fflush(stdin);
6 }! C$ F0 t( g0 k3 f                         return -1;; C7 V5 Y# b# @9 w' {4 i# y
                     }
; G! H& q4 g! N$ f                     printf("opnd出栈:[%f]\n",a.data);6 X; H; ^2 T9 m2 \
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/3 Y$ t6 R# e5 x
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
1 B$ r7 m% R, x) O) R$ S                     printf("结果入栈:[%f]\n",opn_tmp.data);) u% \$ j+ T+ _# S% T% Y
                     break;
; O5 h5 u1 v$ [6 q* K- \9 R9 d            }
- ?4 Y8 Y' v6 K8 y, R9 R' m6 v        }! y& G2 D. I( _0 ]* a1 I
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
' K: X2 }+ i1 X# R6 _    }, x1 w# B% L; I5 l2 o2 V
    GetTop(opnd,opn_tmp);( r& K9 I- X, s# @$ p/ o3 G
    DestroyStack(optr);
: a* j: U% W) O1 X    DestroyStack(opnd);
, \8 U5 a) m; Q! D    return opn_tmp.data;1 R1 |) t5 u5 g3 n  k: q
}5 D2 |! T) @7 a3 W4 L

  f) R- [3 V# r9 xchar *killzero(char *res,float result)
+ [8 E- X4 F5 ^7 Q/ f4 l{) s- r* d9 O6 n  Q
    int i;
1 n  F2 y5 V0 j( L
9 T2 B$ R1 W* ~, b  s. w    sprintf(res,"%f",result);0 o) c8 N6 H2 L8 S! x
    i=(int)strlen(res)-1;
- e7 o$ Q6 D! a: c7 |% c    while(i&&res=='0')+ y. g6 H% r$ o3 l. {6 u( u
    {) M- w( V) H4 M2 l( `
        res='\0';
$ U% M! W" D6 N        i--;  r2 Q& l. L  L6 z, [/ D9 `
    }
9 u8 X7 Q% A9 Y' h$ z  x' y. k    if(res=='.')3 O7 K! Z+ @: G$ u, B5 W% Z/ Y
        res='\0';6 F' R, b- w6 W5 Q$ c
    return res;
/ \9 N4 J) U. q% k}( j! `: ~* c- r
7 m4 U! P# U8 @3 i
int main()
; A4 I! P. O' n3 f' j! ?0 E+ R5 r{# p+ r9 ^; y0 m. ~( e# S6 x2 c
    char ch;$ {, @; t7 e, N+ n! w8 \5 D7 c
    char res[64];
# ?2 z! Q& y- P+ O( @6 ?* G    float result;5 C* m* L/ n( C/ u  g
    while(1)& F, n2 Q+ S' w; M4 R" Y
    {
& g( c$ Q- A' r0 f        result=compute();" x% D, |3 q3 s, Z& C
        printf("\nThe result is:%s\n",killzero(res,result));
$ s/ {/ c% W* l4 W5 d6 e1 K4 c        printf("Do you want to continue(y/n)?:") ;# D% i; n  f! u; h* Z& o
        ch=getch();
: V& J6 V8 X; _' h        putchar(ch);* y1 i; S" P9 z. L
        if(ch=='n'||ch=='N')" j/ z$ w- j" V$ \$ {: |
            break;1 m7 P6 G8 E3 I9 c
        else
9 q) H1 _" j3 r4 T            system("cls");
5 G( q/ t. E8 a( p2 ^6 j    }
4 Y# Y6 k$ n' x" B2 L# `% |9 {    return 0;
5 ~% k0 @5 a) U& `}

# x8 `- a% j7 x+ m  l! n+ T1 F/ l/ _& S' ^; t$ {; k+ M& U" q
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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