返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.. C/ ^! V$ R3 a
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=, V) |9 e6 O2 h  m' V& R" D1 j
/**************表达式计算器************/
9 ~3 H7 ]2 ~1 M" e+ m#include <stdio.h>
4 k0 l6 E+ w$ q" Q) B, `#include <stdlib.h>
3 g1 {7 c, [" b3 E0 p% @$ N#include <string.h>+ P9 v! G' a" A& k8 ^- o6 r
#include <conio.h>
& f( K* o  R1 A#include <malloc.h>2 d4 Q, S8 E! M& |9 T* t/ ^

( S# l5 y# E+ c6 c2 K" G1 c, h8 w#define STACK_SIZE 1008 T! n7 U5 t- _! z) O
#define APPEND_SIZE 10
% T! c* z& \; s* Q3 M. h
$ x, L$ M" d0 S" C" ostruct SNode{
* J) e4 S& u' l$ ?* @2 t* P6 f* P! S* A    float data; /*存放操作数或者计算结果*/
4 r1 P. N# o5 U" l    char ch; /*存放运算符*/) z8 j  t3 [3 A* W1 h( F
};8 U3 w6 }8 G7 Z! K3 {  w, _$ n% U

; b& Z5 U+ P2 E0 r$ {! O" bstruct Stack{" b' G! ?5 F; l& i, S
    SNode *top;) f  a- T. i$ N) G5 _
    SNode *base;
* g& s# L* g7 C! J& }    int size;
/ N; C" A  n7 L" n};: D. J" Y6 i5 ^( A- M

. Q; l4 k3 v( K0 t/*栈操作函数*/) v& y+ Y& q- }  L$ i; F& j
int InitStack(Stack &S); /*创建栈*/5 Q# L4 _" O# `! ?) u6 ~3 Q7 }5 x' z! f2 m
int DestroyStack(Stack &S); /*销毁栈*/; V# j5 p; l2 `; G* z6 z% H3 Z
int ClearStack(Stack &S); /*清空栈*/
' q; {8 v  x. |1 U; x' ]6 C. S* Fint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
- H& J# e# d5 Z4 O0 gint Push(Stack &S,SNode e); /*将结点e压入栈*/2 F2 y9 g* `3 L& J3 K3 Z
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
1 e& J" L8 V! A- T0 T% W0 P, Y* ]+ l- S; l. w! i2 }# b
/*表达式计算器相关函数*/
  c# ~8 a4 ], l- s% \! Echar get_precede(char s,char c); /*判断运算符s和c的优先级*/0 e; e) S& m, I- _6 ?
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) l1 m+ }) u: ~$ ^. C2 W5 M' K
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/2 m' M8 G( m1 s3 H
float compute(); /*表达式结算器主函数*/& ~. j( O5 e/ v, s* W0 U
char *killzero(float result); /*去掉结果后面的0*/ ! q$ q$ Q6 Y: x, |" X8 j/ d
8 D) I' M3 Z, Q7 k, L1 k
int InitStack(Stack &S)
& o# L4 x* l$ a! z{
6 B8 d2 D& [8 Y" Y8 D0 }, t4 l3 y- W/ ?    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));5 p  |6 a* P0 k7 c$ o) s
    if(S.base==NULL)5 F$ V1 Y! Y+ j6 N1 b% V" t5 l
    {
/ y5 B! _* b/ E" R! M( ?        printf("动态分配内存失败!");
; b/ g' r  w4 s" m* ?        return -1;5 m& ?7 ^& i* s8 \: g! E
    }
/ }6 H/ }9 g/ I% p& s) w2 g    S.top=S.base;
& V7 }' O+ d2 J. `- w& [    S.size=STACK_SIZE;, [1 f( h) S) x
    return 0;# q! @' k9 K! n& \- w* O
}
  S% y7 |2 ~6 w3 `" h
( w. f! ?' x6 q; `int DestroyStack(Stack &S)' N% u! x2 K# ?2 u8 {3 g3 C
{
1 z& [" {$ U9 A' A, i/ \  Q% V    free(S.base);
7 K5 q3 u4 y4 r. i) m. [; m3 `, g+ p7 e    return 0;
; ]( }  z0 }) S# |* R}% k2 j1 m0 B! A8 H, y
$ i1 T) n0 g, T# t+ m' u
int ClearStack(Stack &S)
, e( \) L3 C$ N  [{) e, |+ N% H5 ?% k
    S.top=S.base;
8 k$ a1 k( D/ q9 B    return 0;: d2 X' G4 X* C* w1 q5 `
}* g; d# U& z7 Z' \
" s* h; K4 u. L
int GetTop(Stack S,SNode &e)0 P7 p! ?: u) ^: u- u
{
3 N( G  \, \( y: P* E    if(S.top==S.base)
* G9 |/ {  a: p8 t    {
+ G: i8 X; c  w4 |; u        printf("栈以为空!");, L/ O0 m" M' e1 H4 E
        return -1;; K: T3 o/ J3 z( a' Z( z" F
    }
5 a) b9 a# U, c' K    e=*(S.top-1);
' ]1 f( r& s3 L1 Z7 E8 |  e    return 0;
- T+ \' |( w4 p, V0 q}3 W% Y6 P# A, {+ U0 U

2 h+ k3 e' M/ c3 C6 kint Push(Stack &S,SNode e)( Q  i1 [4 i" N- ?: V
{7 f  P, e: n3 j( t/ i, }6 n
    if(S.top-S.base>=S.size). h( [! |! z2 M
    {
* y: E# l2 }# u4 G3 T+ r8 e: d) A: y' X        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
; i- j! D" A9 F+ v. u        if(S.base==NULL)
5 I1 }2 l% V! D, q        {
+ g/ s6 m! p9 ?* o( |* n8 E            printf("动态分配内存失败!");" c- k6 v2 n3 H2 g2 I0 f
            return -1;6 t9 B' u5 W2 K: ^
        }
5 l) ]2 E6 a9 R5 D" ^        S.top=S.base+S.size;
( i% A+ U. r/ ?        S.size+=APPEND_SIZE;
7 G8 t1 ?- E7 y    }$ j; D  H) o% [/ h) ?
    *S.top=e;3 G: q2 B$ E3 d# z1 X6 k9 _3 o
    S.top++;
1 Y9 C# @+ e6 ^7 ^    return 0;
6 z8 i5 k) [5 I! B5 A( b* {5 R}1 \" M; }( v4 A3 i
- Z/ F6 ?0 Z* W+ Z% J
int Pop(Stack &S,SNode &e)
; [; G: W4 A5 b& T{0 M" r$ X# A$ c3 W1 h
    if(S.top==S.base)+ C: k/ l  e& X3 n4 q% f
    {
) h: p- K; n+ q) j! [6 F        printf("栈为空!");: a* ~7 @9 K+ {! Z7 Z- b) I, ], x
        return -1;# I* D1 r7 }/ |3 \9 ]) }
    }) R9 `* c- V1 N
    e=*(S.top-1);
# q/ x3 A. Z( f1 R  o8 }$ y1 f    S.top--;0 N2 F4 D  k7 {# t
    return 0;" C- d" \; |; g% J  i
}
+ ?7 a1 o( t! U) y$ Q* `7 i9 _& u' i9 E. ]$ o9 M5 |
char get_precede(char s,char c)
; g+ G$ F7 j) p: c( B{
1 G+ t1 d1 `. L: u+ ]) W    switch(s)% v- x, e  j' H9 ~5 `
    {/ C1 |4 c( i$ z  l' `8 E9 g
        case '+':                 
- ]* x- O) V* t        case '-':
3 i% }$ d6 }' r& h, ?( {             if(c=='+'||c=='-')0 u0 ]  R3 J' g" I
                 return '>';
/ g, ^) w: i$ C             else if(c=='*'||c=='/')
9 u) `: x$ |. I: h# |) y                 return '<';: a* i6 D% u! P* E
             else if(c=='(')
* }7 v6 ~7 W; Y7 ]9 P0 |6 K                 return '<';9 z, R# E" `/ `6 C1 n
             else if(c==')')" @4 `* j7 @  Z0 A. E/ z: V
                 return '>';  P! m# y! `. U5 j4 D, W
             else   l  g- e' c  V5 l2 K
                 return '>';
+ l. d  v' {. y2 S0 r+ @        case '*':: V  _* ^3 a% V1 I9 F0 n
        case '/':6 b$ ~: A* K* H  z
             if(c=='+'||c=='-')
  g$ s+ F3 p) J! ]' ]                 return '>';" p2 c- r& H8 L( w5 ]8 g6 G4 T
             else if(c=='*'||c=='/')
% G- {0 X9 X" l' h                 return '>';
1 u" c7 j4 B8 E             else if(c=='(')  Q  E" [# m% n# E4 J/ k: v' z9 V
                 return '<';
6 E0 z2 o8 W& I4 J3 s7 s             else if(c==')'), |6 s8 ]5 n; s2 C. q
                 return '>';
0 g+ U! ?6 Q8 G/ H5 W3 O             else
8 Y, @( C8 o9 b. _                 return '>';
$ m$ t; }  p2 X* U" }, G        case '(':
- A; y" Q, L4 B             if(c=='+'||c=='-')  E# X: k3 I& A
                 return '<';& t# J% R) Y3 R7 s: w' _
             else if(c=='*'||c=='/')
  O3 b/ [2 L7 x6 k+ h                 return '<';1 H( D" G; [6 S$ F! w) n# C6 u
             else if(c=='(')
! o( N* _/ u6 f                 return '<';( |0 `# Y4 b7 }9 N( [
             else if(c==')')
! Z3 L' t0 c! q                 return '=';9 k6 K# K. _$ h$ Y
             else/ o! @% [( ]  ^/ z7 Q6 }
                 return 'E';& N/ S  Y1 O! N% d9 e
        case ')':3 M, d9 H% m! q/ w
             if(c=='+'||c=='-'), T4 Z, [9 n5 P: f# Y( t
                 return '>';( i. x! [9 B. ]0 \: m. k
             else if(c=='*'||c=='/')
7 }2 x3 ]- m; r0 n. |                 return '>';2 s4 g2 M' g3 {+ _4 v
             else if(c=='(')
0 B, q6 h+ e! k                 return 'E';3 I# C( A) X& G3 U! j+ p: r
             else if(c==')')
7 c* Q$ ~" r8 u5 l2 I$ G                 return '>';1 D+ V, [4 |, t  W) c$ `
             else
$ z/ Q* \6 I1 v8 H, z- R# t6 c                 return '>';
! e. p. A1 Y0 a+ `2 d1 g6 J" O        case '#':
9 ~0 j" F) b& z             if(c=='+'||c=='-')
+ e5 I4 b4 y: D7 F, b                 return '<';- }, s( u/ H# d0 {
             else if(c=='*'||c=='/')
" R. X; d- p5 i! C                 return '<';, o; z8 W" [0 k1 ^
             else if(c=='(')
# ?! o$ N# w& x3 d  o  G- B3 w" B                 return '<';4 g1 n/ e% i# S0 Z
             else if(c==')')3 y3 L# B! a( M: T* v$ h1 E; T
                 return 'E';/ y' ~* Y0 r) [6 b) \
             else
! h. m# ~* W9 f                 return '=';
, X5 B% A; T% E. \7 {5 {1 y3 b        default:
  X) f' A8 s1 L. l             break;2 Y0 w" \9 t& E& Y
    }
: g  k1 W; k& b3 w    return 0;    8 t$ n, o$ c, \5 k* x
}6 q. [8 ]' ^& Q" A# B9 V6 v: @
6 |9 {% y4 O. t' r7 `$ n
int isOpr(char c), M) j7 ^% a1 d" J1 @6 g: I
{3 c9 f; I7 i# I* t) Q
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2 k$ ]/ E7 w" b  v2 m5 D
        return 0;2 @$ S- S8 C1 V3 T8 r; H
    else " X/ P- u4 D8 t9 o8 S/ h7 L
        return 1;
- E& U6 J7 N6 ]$ g# F' z}, z/ N1 W# Y& C9 w) [( I* y. Z
. q, s( u# W; u  I+ d
float operate(float x, char opr, float y)
2 u- H# `. O+ Y; J6 b" a{, W( _+ w# M7 j6 W
    float result;6 V7 O1 N6 i, @. K0 _( n" f; Y! [
    switch (opr)/ _! r' @* I) Z+ f+ A
    {
1 i$ s, @0 w" J2 y        case '+':
! U1 x0 n" R; k6 ^& ?             result = x + y;
! j+ q3 P0 s' V) d             break;
. ^$ H' i% p/ H        case '-':
. ]% a. r" Y; y" [2 j, _             result = x - y;
+ D  Y3 Z1 m: a) e5 K             break;& g. [( f) N, T2 J
        case '*':
, J# h" E8 K5 c* P. h             result = x * y;
( c6 W8 d1 }( f9 K             break;
8 S' `- x  f# r) A        case '/': ; b* K2 u$ c0 R' e" G# \. r3 z
             if (y == 0); H0 S) ^( D" \( F* M7 t, e" }5 d  L
             {  }  v6 Z8 E2 B
                printf("Divided by zero!\n");
  D) U2 F, O# H/ w                return 0;
  I5 @4 Z% u' Q; C% R2 A. z             }
$ ~8 n& L6 Y, B- W             else
' r/ X% Q) {1 q6 x             {- F3 p9 |1 M; g8 d3 [+ {7 |
                 result = x / y;* ?! \0 e; c8 T9 L
                 break;: }' j+ ?! t3 X6 ~
             }
+ Q5 V0 O0 l0 R       default:
* l+ l) D; s! l) Y* f* j             printf("Bad Input.\n"); 5 J# A" n4 t! {" ], q5 Q* O1 w
             return 0;; Q2 T  f5 h3 Y2 p) H
    }
3 l/ t7 B7 G5 W; u* c    return result;
, x! A1 f, v$ E% t) a* v/ S4 X}   
* I! R* T4 _0 k7 p" C5 w
& O- H8 Q" g( \" ], Gfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 t  Y$ G5 B) _5 }& ?- K& u1 b{
& W& A  G8 k1 Q, g5 u6 n    Stack optr,opnd;: |6 J5 R$ W* K; j% U6 e9 [7 H
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
  i) G. x( ~) x& [5 h    char c;
* e3 B! D; I' H* ?, C) F    char buf[16];: y8 a. z. b& X: z# Y  J
    int i=0;. O# p% v* n( ]% b; ]+ x
    / n' D) N/ J* d5 L, G
    InitStack(optr); /*用于寄存运算符*/: h/ b' A) ~9 n8 D6 b1 e
    InitStack(opnd); /*用于寄存操作数和计算结果*/
3 B3 c: h2 D9 @# b    memset(buf,0,sizeof(buf));
+ |" D; X& ^) O* h0 P+ A/ h" _, N    5 k* n$ S7 }: ], U5 }" P- c" ~
    printf("Enter your expression:");6 C$ v1 y# H# ]; _; u
        ; H( ^2 J- _% n# z' @: q( y
    opr_in.ch='#';. P" g) {  E% e2 H9 U
    Push(optr,opr_in); /*'#'入栈*/" _; I+ x/ F' D9 C
    GetTop(optr,opr_top);( k! k* Y0 C$ b* b5 D
    c=getchar();2 X. |/ |0 O" ~
    while(c!='='||opr_top.ch!='#')
  H0 q/ b( I* I& w    {! a7 {. k* l. |) `% h
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
! q2 p% S2 W+ M. v6 G! K        {. b9 n' s6 V7 X  j% B) }
            buf=c;! @& u! b. y# @( g% _
            i++;
% x4 k3 u+ C. ?% L' k' M5 v, \            c=getchar();( d' C/ z5 ^' T, W
        }
3 j; N* R8 b8 i3 A. K2 B( E        else /*是运算符*/5 L; o0 s- P4 A$ Z3 z8 }
        {
- C9 x8 z+ r8 K: m            buf='\0';/ y6 s/ G$ C: J: x6 a/ c: [+ R4 l
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
5 S8 C0 S! _5 S7 A1 [6 `            {2 c( T% S; c; y+ E- ]7 D  V
                 opn_in.data=(float)atof(buf);
- p2 ]  w& }4 Q9 s0 ^- `                 Push(opnd,opn_in);  P" S+ c8 n9 r1 @  t% I5 l2 f( g
                 printf("opnd入栈:[%f]\n",opn_in.data);
8 |4 }# W! P6 g                 i=0;$ p  L' p; o# `. E
                 memset(buf,0,sizeof(buf));& |0 m! P4 j% |7 s1 H- i5 B# X
            }
" ~. M% j4 e9 s7 L+ }" j0 B3 [            opr_in.ch=c;
! ?: x; C' A/ k9 x1 u2 [            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/* R) X% D) c* w8 s$ U" X
            {+ ?, g& l, I) r
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
9 p7 E- |! B( @1 Q* L0 [                     Push(optr,opr_in);: `1 }3 m3 f9 L. B& P% A" v- q
                     printf("optr入栈:[%c]\n",opr_in.ch);
9 A1 F' }' ]% t& S2 F( D6 ~* H                     c=getchar();2 f% e' Q" n" @
                     break;3 g6 c- P: r5 c/ |2 `
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: R. z% n* @' G- H$ M8 h                     Pop(optr,e);. L; b6 v9 [  q; R/ |1 E, |9 Y' t
                     printf("optr出栈:去掉括号\n");
- T% \7 c8 Y6 v. z( z  R( z$ s0 D                     c=getchar();
) ]: b7 J$ s# z. J) R) V                     break;0 ?8 u% @) m9 H( c; W
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8 M& n( ^5 [6 o0 c
                     Pop(optr,opr_t);
# H) i5 w. o+ ^6 J" u3 [$ h2 s                     printf("optr出栈:[%c]\n",opr_t.ch);/ E" S0 Y/ f% E7 C
                     if(Pop(opnd,b)<0)+ k# ~) E# g4 w. N: q
                     {3 a/ w  B8 e' v- n# e, G
                         printf("Bad Input!\n");
4 M  m" }7 J; _0 ?8 S                         fflush(stdin);# [! E& {% e" F- a/ \
                         return -1;
9 o( m4 F: V% k) I                     }8 u* D. D5 @: O" I" h1 z
                     printf("opnd出栈:[%f]\n",b.data);( i$ D  f  z" r: i; E8 X
                     if(Pop(opnd,a)<0); C) k8 P/ q4 `8 t, d
                     {$ r! [- ^4 V- H9 }
                         printf("Bad Input!\n");+ @8 ^# \( b  n" N( j7 A  I
                         fflush(stdin);
0 U& I% @4 V1 [6 f, G" b4 J                         return -1;
  s% u+ D+ B9 _: l( a                     }" ]0 s3 v6 P$ c$ }+ d0 i8 _- v/ {
                     printf("opnd出栈:[%f]\n",a.data);# [3 p' ]! o% m& V) K, q( S# S  l
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 O( Q3 S& W7 ?6 h8 C8 e: [/ a3 Q                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
$ f# c! C/ S0 e1 X! ?: Z                     printf("结果入栈:[%f]\n",opn_tmp.data);
* N0 ~2 y' i8 X4 n. ?4 ?                     break;
3 W2 g% Y9 E- d0 U9 m6 i0 s            }* e, E6 X# C" ^% F; g( o% p/ T8 E
        }" y/ ]( b- Y, h& h5 g, ~
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
0 `8 o5 {1 N. Z9 Y    }% \9 ~5 y2 t& ^' S
    GetTop(opnd,opn_tmp);7 s2 `0 w, p) N2 R7 y" U- O
    DestroyStack(optr);
; ~4 E/ p/ R7 x    DestroyStack(opnd);7 g$ N8 p8 e7 ^) H2 R, g1 `' C
    return opn_tmp.data;
) ^1 [* D" B6 m0 o2 F5 h7 t+ R}
' m7 S8 A6 d! o2 G. S% `
& N! A; E. X, _" \char *killzero(char *res,float result). O8 ?8 v3 T( a5 a( o# i# X
{
2 I3 I1 Y# B+ d8 v: i0 }    int i;2 \% B% |8 Y4 R
( I8 A, A4 \* z% C) s5 l! H! e
    sprintf(res,"%f",result);, _2 z4 t" {" D  }# x
    i=(int)strlen(res)-1;$ P/ l+ \* H$ T# T0 D' \) k7 `/ ?
    while(i&&res=='0')
6 Z) x0 c/ g+ b* e" o+ [3 F    {6 t8 ~  o. ^9 M% D! r, Z
        res='\0';
# I  W  v6 [' B0 ^6 `        i--;8 Y8 o+ t) b6 [$ f9 V3 e: d! W
    }
( F, h- Q: t; u5 [9 i! o    if(res=='.')
; e3 H/ t- `- m+ E# @4 C        res='\0';
$ [; n/ W+ S, Q; p/ V' ~    return res;
- g* L' @  T& E8 v1 G' v}  h4 y5 o* Q0 M4 K9 }* g, \
5 O7 d# t: N6 y+ s: }* L$ T
int main()
3 B* {: [% V- ]" ~" B{
5 P5 k7 j! B/ @  v- Q9 F    char ch;  p& V4 o  l  b; l% v% K2 a
    char res[64];
, X$ ?5 c8 y: \0 _    float result;
: }( p) D# a. R0 A" C    while(1)+ Z1 w+ q6 o1 z, o/ Q; a( k
    {& [6 U, n- ]+ p' R; k+ J1 a
        result=compute();% r1 C# o, j# E( V4 l4 M, [
        printf("\nThe result is:%s\n",killzero(res,result));% J* H& i7 R6 V2 R
        printf("Do you want to continue(y/n)?:") ;) \& O$ e1 d" V+ y/ F& h  z
        ch=getch();5 V$ {9 ?$ C# X5 U) Y  C3 F
        putchar(ch);. T2 V# M6 {# S  m& Z
        if(ch=='n'||ch=='N')
& W0 k/ k) w2 A2 {2 Q' @8 V            break;
% k% K6 _6 H+ k" k- E; z        else, c" E5 d$ f8 N  E+ q0 p4 F6 N
            system("cls");3 r/ o5 \- Q# @9 G" P9 z6 g) Z! p
    }' @- S4 O' G- E
    return 0;
- [* k1 G7 w1 k/ l2 z}
( O5 m6 i& ~  c" R# d: D8 K
. j. j, Q6 p. S- m6 k% A+ g) Y
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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