返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
# ~6 j8 O7 a6 |3 E  [: X. S: L程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
' z/ C; \) X7 ]  n0 ?7 h5 ~/**************表达式计算器************/3 c' o- z, j. ]. p& ~
#include <stdio.h>
+ J/ }6 q& o0 H' W' d#include <stdlib.h>
% Y& c2 ?8 h, s2 P#include <string.h>
% H, K* O$ t$ {* K6 S  R# `4 O% v3 }#include <conio.h>
& Q3 m' o4 k- Z% `3 f#include <malloc.h>
, h& d5 H2 ~! @
" Y7 ?4 @# e( k1 G#define STACK_SIZE 100- j6 t' |% q; x7 C: V
#define APPEND_SIZE 10
/ ~4 V; q& N9 P+ D* o+ Y! Q  ?0 ^0 h5 L) y' b; p+ ]% f6 ^) l$ }
struct SNode{
& ?* y+ Q6 P1 G* g! Z: F; n  i* x9 Y    float data; /*存放操作数或者计算结果*/  \6 Y0 }- m% d. I8 I8 V; f6 z
    char ch; /*存放运算符*/4 B/ F; O( C3 {& a, ]- `" g; c
};/ X  G7 ?9 ]* z" s$ ^  c# Y

2 @/ h8 S1 c  L# fstruct Stack{
  J0 e( K. n1 B    SNode *top;
2 S- u0 ^- [( z& {+ r7 {    SNode *base;
/ t3 Y" E* l# z# m' @' {8 h% z4 x    int size;
8 ^3 E: v* f" J7 H# V1 B};
6 _) |# ~  Z1 B3 G" h% b" U
7 Q$ b, e. ]# T  B' I/*栈操作函数*/
$ w4 \: D7 P$ K$ P3 a+ {4 wint InitStack(Stack &S); /*创建栈*/) Y8 t& ?  N+ w
int DestroyStack(Stack &S); /*销毁栈*/; `3 ]/ y+ ~; F9 E  x$ B# M
int ClearStack(Stack &S); /*清空栈*/% \; v4 e* Y( |
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
' f$ I9 ?4 S& R% Sint Push(Stack &S,SNode e); /*将结点e压入栈*/( f& r- W) ?( W5 s
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
/ P) @# ]6 a" f. Y: S% H; g# i* t' ]( H3 k
/*表达式计算器相关函数*/
/ v* E$ U" T! ]3 W" Fchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 d& F! o' z7 N6 S4 Yint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/9 \5 L/ R8 q% X, H0 Z
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
% |& b3 @( J8 j1 m, ofloat compute(); /*表达式结算器主函数*/
  `8 [. ]: _, M4 dchar *killzero(float result); /*去掉结果后面的0*/ : j5 W1 O/ |8 p# b; T+ w# s! F6 E) G3 r

& E; Y* Y/ I/ V1 nint InitStack(Stack &S)' t' G0 T. F' d5 s+ V* m' P
{
8 F& j( R  P9 b1 A8 u- \4 y& \. d3 z    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
- c" X' l0 A# {8 [: {- B    if(S.base==NULL)
( r+ m  T8 [  \% [" R% m; [4 x8 a    {
( g# x+ x5 S! O4 V& |        printf("动态分配内存失败!");0 S; R) J8 T, P$ j' x5 Q( E7 C1 {  U
        return -1;
6 x, C9 H: K' N4 v! }+ J% D    }
5 o! D  p( W& r$ x/ u& g1 f: j    S.top=S.base;
3 }2 z) a, D% `* H: k) a. b    S.size=STACK_SIZE;4 a& [8 E7 _, c7 D* i+ m
    return 0;
2 q: b5 X3 ^  k+ [% n! X! ^5 q}
8 z% \, m5 u8 B2 F
7 t" {8 e; \, a+ w9 V8 pint DestroyStack(Stack &S)
+ i, e% A7 T0 \{
0 U' C" J; p; {, s    free(S.base);3 t4 q; Z' n9 `& k( ?
    return 0;
. \/ g# H* g' o$ c" N# D( S}
  t, {- o' ^9 w9 `( T4 ]0 C( d# U& P4 p; J% W) ?( X
int ClearStack(Stack &S)+ S- F  h' T4 @6 }4 g
{+ i* ]! i2 u# C2 P" u& j
    S.top=S.base;
  ^/ v+ G3 b; ^# i2 B0 \    return 0;( Z* O' x& `# s+ i; E. e6 h
}
* t8 K+ j" t. p# h
$ X* F: f9 `3 O( |3 x) nint GetTop(Stack S,SNode &e)
' X8 z- X$ {# c, S+ M( O{+ |& f7 u0 W6 C6 B: r3 W
    if(S.top==S.base)4 e( {4 o8 X. a2 w: t
    {
+ S4 E; N9 S! u$ Y' M. f        printf("栈以为空!");- k$ Q( M- O2 A# D6 y
        return -1;
7 T! K% _- t, p. `. P: j+ T    }
% b$ R# {; q* K6 v    e=*(S.top-1);3 }' q% {5 P# t5 f0 V
    return 0;- x" a! s0 \# Z) I# u
}' H4 Z! q2 z# u3 n

- \; B+ p0 C* ~. V' Xint Push(Stack &S,SNode e), D0 {, m8 z" i) N& F
{3 z+ c; H5 L' ^' {: O
    if(S.top-S.base>=S.size), j4 @2 E; j/ b" I- v
    {
- l0 X$ ?( f! y! v5 @& W: Y% ~        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));. s* [: U0 h. S- m8 ?: ^
        if(S.base==NULL)
' X% c& ?" c/ `: c        {5 {+ t; u; R" _: r# Q% h
            printf("动态分配内存失败!");' N$ d& }5 y% f) Z1 \
            return -1;7 j3 K, c% n6 f) K2 _
        }
9 B  ^7 \+ O* T5 ~: ^3 {        S.top=S.base+S.size;
! V$ `4 s: }3 a4 T& p2 E" `        S.size+=APPEND_SIZE;: x6 t3 f& R) D5 ?7 v& F
    }4 c2 c3 \. Z5 H/ C3 b4 |
    *S.top=e;3 z5 C7 `9 m) @, H, e" D! s( \/ |
    S.top++;3 L5 Q- n1 P5 g6 b" M
    return 0;
0 f! s% e( j1 O  |/ S* X}: v1 G9 u6 K* a$ }6 {5 h- P* k
8 u  S5 S! B, y. @% L. N
int Pop(Stack &S,SNode &e)1 L9 d6 \) ]5 I5 U2 e
{& X2 _9 G7 G2 t* n0 i9 r( o
    if(S.top==S.base)
$ e2 G( ?1 A5 B/ k6 d: f& ]    {
# a$ h- E! g7 Q# t! R2 k        printf("栈为空!");
9 K1 o" T' }' ], p0 a" o        return -1;+ R  }" E7 K6 v5 \* K* Z# i
    }
/ N6 u) q2 P& }/ i( Z    e=*(S.top-1);8 [: j7 N2 w) v+ I$ j0 \2 ?2 {% j
    S.top--;
; T) K9 e- }% _    return 0;, [6 O( L, _$ @2 M
}+ ?8 n0 T3 n5 W0 @+ R$ M  A+ U2 T
0 |+ i( e) t4 c- Y- R% i3 ^# ?
char get_precede(char s,char c)9 F' ~# k* U  u  \
{8 U* ^2 {* x0 s  j
    switch(s): ?; s: {! {2 W* L  y; D
    {
* y* B- D* C" M& a6 {* }( @        case '+':                 
: y/ M/ |8 ]$ X" A4 Z& z        case '-':9 b/ x6 J( Y+ q+ M% E$ d+ ]4 Z
             if(c=='+'||c=='-')
& x6 D! O9 n3 _' x                 return '>';4 i/ c# v6 _0 A2 N
             else if(c=='*'||c=='/'); q0 a) _2 c/ O  V& k* \
                 return '<';9 a; w  e" [/ s' e" S) ]
             else if(c=='(')
; v6 s- X( f) c# j: a% w                 return '<';
" G8 l; R" j' C             else if(c==')')
0 r* c% s' G0 c3 z7 B) r6 e8 r                 return '>';
6 K5 J1 t( h, q; [/ o# O0 T) M, o# i6 p             else
4 z" K! I7 z( `# z7 ]; t3 Y' t% u                 return '>';
7 f7 y6 _; e' C( C        case '*':
, N8 ~! p9 T4 x, _        case '/':" b* t9 M4 \: j* R% d( g# Q4 U( v8 L
             if(c=='+'||c=='-')6 b; }* A. Z  N( v+ u
                 return '>';
- G- G/ {; ~0 _- z2 L             else if(c=='*'||c=='/')2 x0 D2 @, v1 e0 J& d0 y0 U8 \
                 return '>';
2 Y4 W1 h- S; s" e             else if(c=='(')
1 G, e5 W! N+ G% x                 return '<';# X9 s% V/ A/ M5 Y0 o- t+ K
             else if(c==')')
. q& x* J6 @4 y1 g& w# P                 return '>';
* w+ s+ o5 c. m2 ]6 S7 h             else6 q) Z1 {8 U' Y3 ~: p) E
                 return '>';+ U" s) E0 Y7 |# Y! l; b' E5 }
        case '(':
% b8 \' N9 c9 Y" E0 I3 G$ h( U8 ?             if(c=='+'||c=='-')
) K$ G+ ~' R* Q! F, B4 X* E                 return '<';' \4 u" \7 V. p2 m
             else if(c=='*'||c=='/')
& s" W) _+ S9 G+ ^3 D" N9 A                 return '<';
% z% a" E/ T$ f# q( T: t             else if(c=='(')# c5 C, W# j/ a7 b8 g
                 return '<';
. ^/ l: t9 b: P+ z             else if(c==')')+ O* M7 t) ^  ~3 ~/ @+ `6 i
                 return '=';8 l4 H/ I( g7 {% `: Y% v" u
             else9 L" @# t2 P+ R
                 return 'E';
" o/ Q  F3 v1 w7 n! F3 y4 B& R        case ')':/ K& o1 p; G4 I0 o2 S- d5 H% B* G. M
             if(c=='+'||c=='-')
  M7 P! R1 Z, ]. h$ ~                 return '>';- y+ t7 F0 ^. f8 t; t, D
             else if(c=='*'||c=='/')9 B. \1 r3 V: `/ `& ~, O0 T6 a
                 return '>';
8 y! }! b4 R7 |9 t+ a" }* s             else if(c=='(')
: C; m8 o1 p2 u7 }4 o                 return 'E';. }9 H) m+ x$ T7 C
             else if(c==')')
0 g4 I3 j+ ?/ a2 X5 o" V                 return '>';
+ X& X9 ~9 S1 ?" p             else+ H8 W9 a. x- K6 J* h5 T
                 return '>';
4 p1 K4 e: Y; ?0 s. k        case '#':# T. D! C% s$ ?1 v# B3 I" J( i1 m
             if(c=='+'||c=='-')
4 X, C$ }$ F4 Q9 N' y                 return '<';
& \; k* r& I& `             else if(c=='*'||c=='/'); C9 L- L+ h  O, ~! f6 j
                 return '<';; _! f+ n7 S: j: p6 d5 E2 c; H3 r
             else if(c=='(')- c9 m$ ]- B: e, x& c; H
                 return '<';
  t) B( |! \3 o1 P* Q' Y2 g             else if(c==')')
' L: t9 H8 t+ L                 return 'E';2 {+ q1 u; u6 o: D9 H* ?
             else
' T2 v! ^8 Y. o" ]( r* ]- j                 return '=';  P, U1 t: U( D6 b* y  e! n
        default:
$ V" @$ B# o+ |% f5 r; B             break;
/ G+ |& ^. d8 T. J    }) g0 |1 f& v: ?
    return 0;    % k/ z2 t$ t( x! |8 ?* r1 v1 g  g$ D
}& h. s: Z. ~- h8 t2 B
" `+ \5 V3 [; e9 R- z
int isOpr(char c)
4 m; t* E9 S/ T) I4 V/ y* Z. i{- {" \0 V2 d, ~- O6 A
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
+ X% E6 p! c/ j# j* h* k( D: C2 v        return 0;' t/ Z, i* Z; Q3 J" d3 t
    else
% P, j- H, Y. Y# @        return 1;
* w$ I- e5 `& d4 o4 t}( \' L1 Z5 y2 O; i; |

2 S) T( J; H7 l$ C; R, _float operate(float x, char opr, float y)
# N+ L. H2 p5 b& i{
3 }; j1 W, U! g: b) ]    float result;
2 D6 f! Z' U5 i! ^: I9 ^5 t- D    switch (opr)& A! y: d' m' j% ^7 f& V
    {
3 I$ f3 B+ J4 s8 q$ ~" z/ c+ |! g3 n        case '+': . A9 H5 @2 M/ M0 O: N( P% H4 o2 V
             result = x + y;
$ _, Y& g# B) d% i  M; I1 b             break;/ k1 _8 T% U# F. S
        case '-': ( ]. M% R3 ?+ S6 G: H' w* j
             result = x - y;& L8 k0 M" m7 t7 n. G% @
             break;
+ A% k4 p1 U6 x) _        case '*':
1 }* f/ k/ ?* l5 I& z             result = x * y;
( Z5 s* _. E1 w             break;+ J0 i8 ?1 N7 G2 U6 w8 s
        case '/': 8 O3 }+ S4 y+ k* `# x+ _3 N' f" U
             if (y == 0)$ k! t( K5 z; V! n) s0 D7 B
             {, q% m* D+ I  z! D
                printf("Divided by zero!\n");, f+ k8 Q# E0 R( g: x: u6 }* m
                return 0;' b; l; f; J4 x9 p: |, N
             }5 z5 {# U5 Q2 n! Q& _/ a
             else
: S" [( R$ _2 U7 z0 K+ C5 m  {" O             {
  t* W' e6 W! y" d. W: S                 result = x / y;4 m) U# u. ]& Q  T9 g
                 break;
) r5 K+ b& |& R5 j  m# C/ ~. R             }
$ i5 f- f4 F6 [- c* F9 Q       default: / r! y9 x* a. k, d5 H5 w
             printf("Bad Input.\n"); " h% i. t* `9 T5 P
             return 0;
+ i. e+ t/ g4 X    }1 O0 C& U( |& o) E1 E9 H: d
    return result;7 p) Y& \% B; T9 F1 S0 Z% X  U
}    * k0 ^7 n' d. |
+ ^  B! ?# L; B
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/% ~$ v0 X3 z" y' i3 W' W. s
{: T# B8 _) X2 `: ^: P6 y. K
    Stack optr,opnd;3 Y6 d9 u1 H4 t* K3 j$ \; p' M
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$ b- r( F& ~# T
    char c;
4 s9 z' Z6 \/ f) _7 H; i    char buf[16];: ?2 A/ V, I9 u  U
    int i=0;
/ a) o2 ?/ U/ T) v   
. J8 Z8 N, U( X! E* l6 s$ a    InitStack(optr); /*用于寄存运算符*/
& k5 p7 G& P$ D) x) A! E    InitStack(opnd); /*用于寄存操作数和计算结果*/
/ o  A" v# J8 t% e+ {2 G( i    memset(buf,0,sizeof(buf));, l, v! M2 l2 T4 X. \
   
7 E, g3 ?3 I3 S3 ~* v    printf("Enter your expression:");
: a) w6 q* e% @& @; j        
' N* r0 j& t2 x% B+ {    opr_in.ch='#';$ a4 ]7 L5 M0 R& s% H0 w) R
    Push(optr,opr_in); /*'#'入栈*/
; C( J; p* H0 {. y4 L* ^    GetTop(optr,opr_top);
! J$ i& I. v  `6 W0 i% V+ V: Z6 W5 u    c=getchar();
; w! y- q/ [, m. E' ^' e2 O2 w    while(c!='='||opr_top.ch!='#')
/ o( f( U/ ~& m; G    {% a( K: z$ ?( L
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
3 `: l: g5 g$ g: a+ R1 \; v        {
5 }/ D$ q  D$ m            buf=c;) p) A& q( \* X/ V
            i++;
, `+ ^2 K3 t) O5 f3 w% N  t2 ?6 r3 e            c=getchar();
1 n4 R  D$ B, W. _/ e( r        }
% y' o' A' q: c* y        else /*是运算符*/
' V: Q6 F  S" @/ G3 I& P! G5 O8 V        {
) c2 r# K7 j3 c0 a# I& X            buf='\0';
& H8 N+ ?7 i& O            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
! {. ~( \) X* a: W8 L/ M            {
8 B/ x% M0 H5 n, t- k5 D: e( Y                 opn_in.data=(float)atof(buf);
$ q0 u( U" `. N0 w                 Push(opnd,opn_in);
' G, T* X" g; M0 o                 printf("opnd入栈:[%f]\n",opn_in.data);$ W% ~7 I4 X- `+ l3 x  b
                 i=0;
2 l/ d3 ~3 l' f* F$ y* I, j/ ~                 memset(buf,0,sizeof(buf));9 n* i7 ?/ b6 [2 E4 `
            }
' \8 n- K5 A5 T3 r3 i' k            opr_in.ch=c;9 C- e+ e8 J- t) _* U
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
( F) M% |1 z$ v6 {/ }7 k1 ^            {$ R0 }' D: z9 {0 W" X( \
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
8 i3 d* x, D1 K                     Push(optr,opr_in);
1 h0 ?: v" G  u  l. M                     printf("optr入栈:[%c]\n",opr_in.ch);/ w  A2 ~2 r) V. n$ V
                     c=getchar();, M' c  E9 N' a# @. |! W
                     break;
/ r8 `/ a2 J* t6 V. H4 z$ I                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
* K. q' C% R% b% F/ ?  @8 D  c/ _                     Pop(optr,e);! e4 j# l9 d9 j. q: d6 Q8 ?
                     printf("optr出栈:去掉括号\n");* i( C! K9 q& N& c4 |7 w) A: g
                     c=getchar();& i" T7 W, x0 J# l# F. g. S
                     break;$ E/ e9 P( {  Y6 y) w3 a
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
1 L  I% E8 I6 |$ [                     Pop(optr,opr_t);
2 s) W, \( f, t, b& p                     printf("optr出栈:[%c]\n",opr_t.ch);
; J; {: g/ E" ^* G                     if(Pop(opnd,b)<0)
# N9 ]) M. K1 {) R; l                     {
1 }6 O" f3 y7 E- n: k/ K0 z- [                         printf("Bad Input!\n");
4 R' O: O2 q# ~6 R                         fflush(stdin);
4 B0 U' ^) ?9 N                         return -1;  h3 d: Y5 a0 j; Y
                     }
( Y9 F$ h; P3 Q" v- z5 Y+ B                     printf("opnd出栈:[%f]\n",b.data);
) N, ]  I$ S6 {                     if(Pop(opnd,a)<0)
5 H! i0 `6 H6 v                     {/ D1 g- I, [" }2 K9 J
                         printf("Bad Input!\n");
1 `" {3 f) X3 _                         fflush(stdin);4 p- ^9 Y$ n) M# i% E, Q% I
                         return -1;
7 W2 k, l! K  L$ h                     }
: I" a# |: N/ q) v3 [                     printf("opnd出栈:[%f]\n",a.data);
! B4 s6 S* t/ P6 V* v3 @3 V                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/& w+ [& t* P* L  ^, s
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; k; T/ c8 W0 e" F! L& B                     printf("结果入栈:[%f]\n",opn_tmp.data);
8 P2 t# |; o3 m8 m6 G$ u' i                     break;
9 \9 a4 a' @. z; ]% E( ^            }6 a! d# L2 v; \9 B- ]1 K4 p& B4 ?0 q
        }
7 D8 e  a: e$ F6 k# b9 I        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
# j5 x4 p# s* z' K' Z; ^2 C    }
( O* R* F" p( d- n! r7 h    GetTop(opnd,opn_tmp);
; D$ m( \/ ]7 ?$ ^* y4 W$ z    DestroyStack(optr);
# a% W' x/ U% F4 K  X3 i    DestroyStack(opnd);$ r: D7 O1 L$ D& c0 ^
    return opn_tmp.data;
- D5 M- t) U2 i! M9 d& C}5 O* J0 ^( T; F
; M% M/ S5 v+ H& T$ W
char *killzero(char *res,float result)
7 u& h2 m( \/ z3 O& ^5 M{
+ f* \% r9 t9 `( E    int i;( h& a$ k3 V# j; d2 o" d! T

) J2 u+ }* L- A    sprintf(res,"%f",result);6 A( z7 P# ~/ K" r/ x- A
    i=(int)strlen(res)-1;
; s) j' b" B- r9 h; o0 a  F    while(i&&res=='0')
$ K" [1 c7 h5 h$ S' l4 W/ q; C$ b    {
$ k: r) I; e: b  A# A' l        res='\0';. p9 {; p# y0 M, A7 U: {
        i--;
: M' t1 x; P* W0 `, S. F    }" o0 W' A5 B% ]* S; K
    if(res=='.')0 @7 S8 u) e0 Q3 V% Q
        res='\0';) v/ X2 z% {8 \% p! u4 v; @
    return res;
( h+ H) ~5 ?' o: ]}
8 O# t3 ^4 L" N  o+ s
7 d7 S5 W2 r& t1 ?int main()) t5 G, S4 g& N! x& n. E  C$ B
{' `! N% V( D% d4 {
    char ch;6 v6 G% O3 n" h* U' F& v
    char res[64];
* \3 A1 C4 j/ ^/ w8 z3 ]    float result;
& m5 ]( L+ A! _' {    while(1)4 z6 O# V! _: I8 U) c
    {
' ?' Q. p$ y; k0 D' F1 O        result=compute();4 ^# l$ k4 ], N/ |, |, f
        printf("\nThe result is:%s\n",killzero(res,result));1 j# M7 A+ ?) r" Q9 L9 R7 D
        printf("Do you want to continue(y/n)?:") ;- `' n+ _7 [/ h3 g" c
        ch=getch();
; Q5 H- z# `4 o  Z% N) z" T        putchar(ch);
2 ?) O0 G5 D" F# J% l, B  Y        if(ch=='n'||ch=='N'); `5 U  P7 O8 Q6 N" n/ t
            break;6 a4 |6 r4 t/ _. M) [. i' {
        else
& U2 `; ]- o% n5 f            system("cls");* n9 A- @- q' `$ [4 M/ G) D! ]
    }
! w, [) g3 O% d( n    return 0;1 y( a9 D: U! p" z8 L2 T6 a! }
}

8 X( f' [6 L" c" G. q" Y8 I% @& W) f/ r& I
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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