返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
* u4 ?# x6 `& H6 \# f程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=( X1 I" T. o# l- S; |0 D
/**************表达式计算器************/% n/ I( z7 J6 ^+ r* Z  @
#include <stdio.h>- i0 C* H- g) K' F
#include <stdlib.h>$ m" K0 I" ]; v1 g  Y- Z# v( d) A
#include <string.h>5 D" O$ z" b; ~8 m5 a
#include <conio.h>( k4 ~6 I4 q" r
#include <malloc.h>; f7 J0 H5 q8 C
. i& L- A7 O5 i) W% \
#define STACK_SIZE 100
3 [/ w1 V5 d( M9 }% h" Q0 i# H#define APPEND_SIZE 10* A6 Y" j' r" d8 N0 Y" Q( u

4 l9 O6 ^) h& }struct SNode{$ s  a% Q- ]" p4 u
    float data; /*存放操作数或者计算结果*/
% E# J! j5 l  j- h+ k( ?. N$ P2 T0 R    char ch; /*存放运算符*// m- }2 h% \, p
};
# W. c$ B' Y5 K* e9 l# _  U- J* u; ~& Q/ r
struct Stack{
8 `/ G9 y1 y+ A0 ~    SNode *top;- J3 T* ?$ G7 G1 O9 M8 b  z% \' T
    SNode *base;) M! N) e0 P0 `  A& f
    int size;$ v: }0 ]$ B+ k) h2 h% F
};" M8 @1 b+ n- \  h0 W' o4 Z+ m

; u3 g! k, V. K; i# |1 P. T: x/*栈操作函数*/
* M6 \) O7 W  ]) d; Xint InitStack(Stack &S); /*创建栈*/
& ~3 U. Z6 X, k9 Rint DestroyStack(Stack &S); /*销毁栈*/! J4 ?+ d0 J! l8 f$ K4 {6 |
int ClearStack(Stack &S); /*清空栈*/
- z3 ^$ X3 p  I- e) [int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
6 n- [( I8 t0 n+ r# R3 b& pint Push(Stack &S,SNode e); /*将结点e压入栈*/& o6 g/ x' E, l$ }2 G3 ]6 z
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/" h3 z; R8 [8 h# c4 E
; a& G: T6 w# p" \' x
/*表达式计算器相关函数*/
' j4 O0 K6 j* d2 o$ J, Y- Ochar get_precede(char s,char c); /*判断运算符s和c的优先级*/% t7 U6 U, P  ^9 K) k" ~
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/! O' E% x+ |! O- b" {) u: q$ E5 n
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1 v. z( f# Y$ d0 `6 X$ |; B: Tfloat compute(); /*表达式结算器主函数*/
# d) g# P6 Q, u0 U- b1 jchar *killzero(float result); /*去掉结果后面的0*/
: n0 F; B# j/ ?6 ]) c  w3 M0 M1 C2 q2 x0 c" K
int InitStack(Stack &S)$ t/ {- G3 s, d& c) H
{
# g6 Q- F  k6 ^, I" Q' z, w1 G" o- T    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
) c) C7 c, G# _* ^( b    if(S.base==NULL)
% B9 I; s* x  J7 k  `' f9 O$ b& R    {
' F3 M9 g7 [8 [- a0 P        printf("动态分配内存失败!");, l  S7 W1 [0 t: q4 O" ^
        return -1;
  T+ X  @/ V1 f  @    }
' b2 j6 c  D# q6 ~    S.top=S.base;" _  n' U- T) y5 E* I& z
    S.size=STACK_SIZE;
" x* E" A( O: }7 i    return 0;
7 `, p+ {/ d" J% a8 N}
8 g+ e- ^- f2 g, D" ?" G, x1 \
! v5 ]% a0 O  q  O8 H# jint DestroyStack(Stack &S)
) {/ K4 Y' p7 C# l{
3 d/ K# `$ r( d% y* u    free(S.base);
# Q5 d$ g+ U& ?# j    return 0;
& p% E: Z! c- F6 M1 ^$ t2 H}
% a+ U/ w9 A" c3 c; m# V# O( B! x/ A2 _, k, ]" \% R. l
int ClearStack(Stack &S)
2 r4 d" ~5 T/ \{7 [! m( X: w1 g3 [$ ?: ]0 Q5 n
    S.top=S.base;; n6 S: Q( Q6 ], \' \
    return 0;
* k3 ?; d: E8 S9 G% c, D6 T}
1 i2 g4 c: E2 v  K1 [- ^: N/ W7 \
int GetTop(Stack S,SNode &e)$ p, H5 F/ {. h# b; J6 ~- w; {
{
8 @  S$ R1 B, Q) \' Q' U7 l    if(S.top==S.base)9 Q7 `# D$ [" ]; f7 u! U
    {2 F) F0 `. H7 e  g+ M( t( U
        printf("栈以为空!");
. h" ?: e- D! r        return -1;
: @3 O6 \- i1 v; t/ ^9 a, y$ C" E/ R    }1 {+ u8 L, O" U6 e$ ?8 S% b
    e=*(S.top-1);2 x% _) w6 M6 G
    return 0;8 k- l% U5 @& E. O0 h
}/ d' A! V+ `) x  O0 R

: [3 M3 K; o& [* `int Push(Stack &S,SNode e)
; y6 T* E& Q/ r  q. y6 u{# r% F6 B8 _" u2 U! K2 ?
    if(S.top-S.base>=S.size)
- J% X# o3 _) J. Y: F+ R    {
! o0 e+ F( E% {        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));8 D1 r& t: G. D
        if(S.base==NULL)
/ h/ I" e0 p8 M/ |0 |        {# t  G/ ^* `5 A' A' k& v( M- D
            printf("动态分配内存失败!");; g( W+ h$ c; f$ Y' W
            return -1;
9 U% y9 k- n. h6 G/ M5 B        }& D+ ?% |* @; s
        S.top=S.base+S.size;
" O+ G( W$ h2 f        S.size+=APPEND_SIZE;/ D( I# u& j) b
    }. h( i4 S6 c0 [) ^+ m& L4 {
    *S.top=e;% F( k# J' r% R% @9 g
    S.top++;# o; b( a3 R1 t, P8 D# }3 |
    return 0;6 R( X0 U6 z" Z* j, s
}% D) L9 u0 J7 ~* s

% v6 K( g; B0 `( Z, X: tint Pop(Stack &S,SNode &e)) y$ P8 S- _. f1 ?! U0 V. |
{; d) X. d, d& V% B
    if(S.top==S.base)" T% J$ |& T$ C: k+ _
    {* Z7 M. x) S8 K' S+ D% Y* m
        printf("栈为空!");
, V5 W7 C& z$ n- k* W! Z% N        return -1;
7 z( Z- F# A% B( E9 ~2 {# [: @    }
& \3 V% }& T  r) l6 Y+ \& x. c    e=*(S.top-1);( e. T7 O; @+ s! m1 ?7 r
    S.top--;# A6 e8 w3 `, \
    return 0;
( ?& ?! N2 B$ Y  _  Q2 U; g}0 G4 I5 `3 I4 @  Y3 _6 L9 M
' H6 o" h( |6 n4 y
char get_precede(char s,char c)
5 `1 {9 X& W. O9 ]+ {2 _" d{6 L% P! \: U: t  u! L, q/ |! }
    switch(s)
+ q- j) ~1 [/ p' D0 {/ Y5 d  C    {, e8 Y3 P. e3 U+ t8 s8 W# q; H* s
        case '+':                 
1 o4 V$ @$ A' u7 }3 c        case '-':* h8 d) N0 ^: x6 t3 x% h
             if(c=='+'||c=='-')$ W5 r( S( h( x; k' f
                 return '>';9 |0 M! s7 S# @' P
             else if(c=='*'||c=='/')% F( P1 T! x+ E, v% v
                 return '<';  P' M: h! q1 i+ w, }* \
             else if(c=='(')
) A+ N. i* ^- W1 i5 |! u  Y+ C( q: L+ ^$ E                 return '<';
. Y2 S6 l- \( R& j' c5 U0 B             else if(c==')')
! `" f6 K( X) L& s                 return '>';
3 o. }  Z% }. i$ y1 s             else
  H1 Z! y* `! E$ G: j                 return '>';+ i0 Y; U: b: t$ U/ [3 H8 C% D; R
        case '*':
( x  j( F5 B% B' `        case '/':# e8 V8 h1 W; l% r0 ~
             if(c=='+'||c=='-')5 j4 s( |# N* m. O+ o. N/ b
                 return '>';
( [- }/ s4 @* p2 v  z             else if(c=='*'||c=='/')
: D) g9 Q5 v, M- P8 z                 return '>';
; F' D9 K- S5 c1 T2 G             else if(c=='(')
" R7 h7 s( U3 G5 _+ X                 return '<';
# {" T6 g# |$ I6 Q+ C6 b( ]             else if(c==')')
6 y, n/ V5 n, f. I$ W! k& o                 return '>';
0 _% W. @% b  b1 L/ j1 d             else1 C) t( j. m' S# {8 O4 v) n5 d
                 return '>';1 V3 ^9 p  v% Z" @! A0 b
        case '(':
4 s2 |) k+ n8 z: e8 h9 ^( z             if(c=='+'||c=='-')% M$ O& m' @! R# v5 A1 \$ X# R
                 return '<';
# Q/ o; u. U6 C* g             else if(c=='*'||c=='/')
8 X5 S) P' j, N                 return '<';: y* a2 [4 r; K' x  `8 s3 v; C
             else if(c=='(')
3 W$ k$ ?9 [# {0 E( ^# U. N6 X                 return '<';2 }% S2 e$ O3 x) ~
             else if(c==')')/ C0 [) O# H  a8 T3 o
                 return '=';! i! c) f& {, x+ r  M& m0 q
             else- H% b4 U& y6 ?4 |( M$ j8 l
                 return 'E';
1 k: o/ S- H- |. z0 g        case ')':' [9 e/ ?) x' P# x6 u
             if(c=='+'||c=='-')2 [! |- g2 W( o" [
                 return '>';, ?  y* F6 `+ ~0 Y3 }
             else if(c=='*'||c=='/')
* Y6 X1 B; H8 |5 \! @                 return '>';
/ |, {6 U7 N. `6 N. c5 E% @             else if(c=='(')
" U6 w1 y( ?) U7 g                 return 'E';! o3 t  L" C3 H
             else if(c==')')! R& x% B9 s* P+ {7 E% ~+ Y
                 return '>';
7 l, I4 c/ d3 j( o2 l2 B             else- p7 A' M# K2 t. d9 y' ^# z; K
                 return '>';) T/ @  @) ?& R
        case '#':
5 q0 F! {4 r' @0 t. ~6 q0 A             if(c=='+'||c=='-')9 P5 ]" F$ E9 F& f$ b8 E3 D2 v+ \
                 return '<';
; d" \' E; J0 K$ r1 E! l( [' m! U             else if(c=='*'||c=='/')
. o8 M1 g1 J  Z. Z* Q+ {                 return '<';8 |8 T7 J( M: C6 _$ b% r& {+ x. o
             else if(c=='(')
! n$ u+ ]% x1 W3 Y" B                 return '<';
9 R( h2 R; q+ b6 v' s, {+ b             else if(c==')')
3 q# @' x3 }# n6 y# t2 p9 V& R                 return 'E';
6 L2 z" C0 k+ E9 M! z/ R8 p2 p             else
; F% B  \  y5 F5 i% g: _: A( ]                 return '=';5 D1 ^/ a' L! M$ K
        default:
4 Q  L: W4 a5 G7 H             break;3 G4 z: s0 P7 `7 x7 A: A
    }
. Y, V$ s& @! k- v/ u    return 0;    9 _3 }) X2 T) |8 i( A* h
}
2 C1 {: h" [, z/ t$ r) `, r, t1 N7 \, d5 S- r7 ?( k
int isOpr(char c)1 c! b- R% k% \
{# D' A8 I: h3 J' _" b
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')1 h2 j) t( j" y5 A4 @1 q
        return 0;
9 x0 y5 h$ z4 V  e( x8 ~9 d    else
$ q+ }6 l- e/ u) Z1 U$ N: Y        return 1;4 K. j( Y* E6 v* t* v2 K
}
8 m0 L  \5 I( x/ r1 t/ C
# P7 U5 f* r% G$ |8 {float operate(float x, char opr, float y)8 @) Z. S" w5 G" V) R8 U$ E, j. L
{
$ N& ?$ I/ h# G1 Z' g) r/ B    float result;/ u2 K+ e$ \; }: Y: C
    switch (opr)
' U6 v2 l/ }( l0 M    {
8 ^  N) @9 {2 X9 e        case '+': ' `4 j7 u, _" h* O( {1 {7 w' F
             result = x + y;+ _2 T7 y  P6 E- I9 b
             break;3 r& K, R' `- C& F
        case '-':
) d6 {' }/ l* k: v! o/ B# K) a             result = x - y;
$ I4 Y; |% g: w+ d             break;; o: F6 O! w3 U; b) G
        case '*':
' V  t3 C: M( Q) `( J; z/ p" e             result = x * y;
. w: u# n- x4 ~) v             break;
* H% T+ ]5 B1 r        case '/': ' c% Y! l( q+ |2 t! z$ _9 q% C. I
             if (y == 0)
) S5 g' h! ]5 v8 m- c             {
2 G7 T1 R1 W# x7 Q                printf("Divided by zero!\n");7 r0 F3 g6 B% ^) Q- a
                return 0;
, ]" H, W- u" H+ R. S, P' C& P) W             }
, q" f* f0 m6 U9 O8 c( ]4 B0 E$ q' ~0 J             else
, Y. S4 u% h" U4 k4 G9 n* ~& V4 w             {6 m( e: S! \9 m9 r- ]8 _) L
                 result = x / y;8 a0 s% G% P5 v+ J2 w6 R6 _
                 break;1 S( P. Y1 x9 U3 ~+ u( N# R
             }
2 g1 J: |' U) |( c. ?2 U( y       default: . w  @1 W: v* w' ]! c; v3 _4 d
             printf("Bad Input.\n");
) O$ q$ }7 p2 t6 B8 `* R( ~1 W1 k             return 0;$ F. f1 {# B; S6 a4 E8 G; g5 n
    }( t2 A9 K  I6 D7 a
    return result;, T& J# L& N# T
}    ) C& w3 F& [9 ^. ]$ e
) O, j9 F, Q1 N# K) A
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/' \* ]7 s2 H) ^6 u, S* P6 v
{
: K0 i8 @3 v3 ^, ?' }- X2 h    Stack optr,opnd;& r8 C7 J  o) h; N/ q9 {8 z; s$ u: M7 a
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;7 b+ P& C7 I! T
    char c;
$ T5 i+ k$ U( _, ^$ R" J' W    char buf[16];2 s- M6 e* |$ Y1 u3 t" Q/ ?% m
    int i=0;
8 Y9 b, h3 Q$ ^' a7 x    * g, D1 R+ _4 M+ s/ O& L) Y. K
    InitStack(optr); /*用于寄存运算符*/% z% `: Y4 d: g* N+ w# g
    InitStack(opnd); /*用于寄存操作数和计算结果*/1 X6 R2 d# w! g' W( ]8 m
    memset(buf,0,sizeof(buf));2 r2 E0 E( E9 j% b- C/ a
   
' ^* n' V! j4 S, E+ P    printf("Enter your expression:");5 v7 J9 M+ Y% w% @, {& P1 h6 `! |
        
3 F9 [; K8 B$ x" t    opr_in.ch='#';: Z2 P# V% t, o/ w7 C) B- K
    Push(optr,opr_in); /*'#'入栈*/9 r/ J: f, X0 A$ v
    GetTop(optr,opr_top);
& _& r6 w& K. A) @4 x5 E) @7 N& b    c=getchar();
2 A: c: C, E! a4 v0 G9 R, K    while(c!='='||opr_top.ch!='#')
$ Y6 o5 y- ~! f) S( s7 l, D    {3 @3 E2 h# k0 [
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
6 B' x7 ~# b3 u9 a# A9 _        {
$ x* l0 M+ g. Q5 K* p. F* H            buf=c;3 D3 W4 t0 r% [1 Q0 j5 d6 |$ T
            i++;
6 I8 f5 l7 N! S1 y+ S; e$ Q  ]5 D6 A            c=getchar();5 j3 F+ E( L6 Y0 y& Y, T) g
        }. }) O2 @& i( j  ~
        else /*是运算符*/
9 |, Y( l! [0 u. v% ^6 v; H        {, F& V/ s3 [; @5 \7 q9 x+ L
            buf='\0';; O+ X: [( D) @
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8 D7 e7 r1 L9 ]3 C4 i! f            {& c# u% b! i5 ~2 f5 J& V6 u5 s: `
                 opn_in.data=(float)atof(buf);( n, z4 r, f" |4 U7 n" u
                 Push(opnd,opn_in);
0 }/ D/ j7 T4 H, u  r( V/ t                 printf("opnd入栈:[%f]\n",opn_in.data);7 V6 x$ e9 z9 W' ?7 a: k
                 i=0;, a$ J6 u* R6 E
                 memset(buf,0,sizeof(buf));/ a2 S" k- i! T1 G
            }
: l4 A% I3 \, I            opr_in.ch=c;
& G3 k: k+ g( G            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*// `9 C7 Y/ W# A3 f% R5 a1 k' {/ {
            {
6 O( A' k- f: N7 p" u' Y                case '<': /*优先级小于栈顶结点,则运算符入栈*/
% ?* b# K" ^& S+ j4 Z                     Push(optr,opr_in);* j( Q' @, J3 z( P. D7 n- G* I
                     printf("optr入栈:[%c]\n",opr_in.ch);/ |+ }5 X  ?8 R  ]- q8 Z7 V
                     c=getchar();
' Y( u8 W& B( O: G7 Q( Q# J                     break;
# f. _" \7 Z$ q+ G# D* }                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
& S% U2 U9 L; N+ G! \                     Pop(optr,e);
& j' U  U9 s/ e& f                     printf("optr出栈:去掉括号\n");0 n  [1 g. h7 ~* N
                     c=getchar();
9 y/ m8 K3 x0 Z6 C3 [. A& l                     break;! M  O' q) [3 _2 V! ~* K
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
% [& j: G0 r6 b- `2 g' Y) J) C# i; O. E1 w                     Pop(optr,opr_t);  g. n( ]# k1 }" O( x
                     printf("optr出栈:[%c]\n",opr_t.ch);
( B9 N& j$ l3 Q9 x                     if(Pop(opnd,b)<0)" {, n+ C" _$ w# }# H
                     {
7 c' o1 L. m5 ?. ]; X0 c8 O                         printf("Bad Input!\n");% T: n  n5 f% ^
                         fflush(stdin);9 v/ K" Y" l+ M( V) i( n
                         return -1;" T3 X) i1 w1 u$ z6 S  H/ f2 n: {
                     }
( Y/ O6 `8 p$ v$ h8 ?9 H5 r                     printf("opnd出栈:[%f]\n",b.data);
- E$ s$ i8 A) W" L' }                     if(Pop(opnd,a)<0)
9 `; |' f) W# n% Z, s7 b& b                     {
, h1 {4 Z) }6 A, ?; P" n- K7 T                         printf("Bad Input!\n");6 Y* j7 K- `; x' @7 l
                         fflush(stdin);
' z' B7 W8 S) E( O                         return -1;( V# U6 b( x  J, S, ]1 F. c3 b
                     }
" e+ e8 O3 b% g& H, |/ W4 p                     printf("opnd出栈:[%f]\n",a.data);/ F  r* P  x- f0 }2 w
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/0 ^+ N: i$ Q2 v
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*// b$ w+ R0 B2 t/ G& }
                     printf("结果入栈:[%f]\n",opn_tmp.data);8 I  p' Y+ |1 T: o+ u' G7 _
                     break;3 B, r6 C  f  t& `0 S( z
            }
# G- K7 f# [, V0 b5 \  Y/ \        }; N; H/ k0 i2 T$ `% D- L
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                + O7 ]6 h+ J- u
    }% [' R, g/ r8 u4 F- }. C
    GetTop(opnd,opn_tmp);& B  a& g# G5 D
    DestroyStack(optr);  k4 d' H. Z6 P4 p% S# p
    DestroyStack(opnd);# x' R' h7 C. l) Y
    return opn_tmp.data;3 Z; m% @0 h& g
}
$ l+ [; H3 n- r  N0 j3 f) O* g. K( c1 y' C
char *killzero(char *res,float result)! g2 W6 ]$ ~) h1 r; X
{  m. _  K8 b. H+ V, w
    int i;1 D0 Z7 j/ J6 d- m

/ s$ \; m  [+ w$ A    sprintf(res,"%f",result);' i& b, [( U# l- [: c; D
    i=(int)strlen(res)-1;; k' m* x- U/ j1 V6 |2 r
    while(i&&res=='0')
( S" _! [# Y4 a& Q: K2 O% P" R# s8 O    {
. B2 [% K) V2 e. W        res='\0';. c% b% n; p1 P+ F% v- e
        i--;; @# O" }$ V- o, a( s9 z8 n, U
    }
" a1 I: @% i' |, M( V- y    if(res=='.')0 D8 O+ J9 P6 j0 O5 L3 T  \1 J5 [/ ]
        res='\0';+ a* ]' K% A7 o+ T
    return res;1 F; C- |! |& f- }) ?
}1 ?9 v( t8 H: }2 T
1 F' ]5 f( v9 O4 {: T8 x- O; L
int main()5 |2 d5 g+ g( |; J* ^
{- v& V2 k+ \( [! b3 [+ v
    char ch;
  m7 M1 Y/ `. t5 Q; j, e! u    char res[64];  o3 r% t1 Q5 C( I
    float result;. u. P/ `4 K6 g% Y% [1 L! C
    while(1)
1 u& G" S* @( a/ O+ O' y    {
$ F/ l& |) u, j- k3 k( O% q/ E        result=compute();
7 W/ _) {5 O9 [        printf("\nThe result is:%s\n",killzero(res,result));  b: I0 v1 g# n7 x6 ^
        printf("Do you want to continue(y/n)?:") ;9 h2 ~7 n8 O9 L3 I
        ch=getch();* U4 j, {. D' ]/ P- c2 c2 r6 r
        putchar(ch);& s' q( L5 W2 t4 B, }: T
        if(ch=='n'||ch=='N')
. m: e# k+ V+ C5 w" W( v            break;
. J5 K/ Y4 U. }6 r2 l! e        else8 n6 v; q9 ?  O/ L+ H2 V! D
            system("cls");
" L5 [# p1 i/ t$ a3 T) Y    }- W% E9 R! d. X+ z
    return 0;5 ?  H; B$ o# i. t. W2 Y$ x
}

+ A: c! {& ?1 A3 Q4 e  Q- G
, ?% \* O4 p- N: q& V8 g[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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