返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5 M" C2 _  W) e, T; ]& _程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
5 j) Q' h3 S* x$ U9 [/**************表达式计算器************/$ J5 q. A( U2 l# [; l+ }
#include <stdio.h>9 w) G1 R' i% S0 ?
#include <stdlib.h>
( X. _6 A: o, I6 u! X& _#include <string.h>; Q' H3 t9 D9 M4 O9 S- Y
#include <conio.h>
: Y" _) {: n4 h0 T0 d#include <malloc.h>
* \, a  Z4 _. A3 G# h1 d* W* Q" y/ d
#define STACK_SIZE 100" J' G6 \1 \3 g1 i
#define APPEND_SIZE 10
' y" i/ N! K: a6 t5 m
* D2 y! X  k+ l, `struct SNode{" O6 m* ^9 k' O: l0 m
    float data; /*存放操作数或者计算结果*/8 M; U3 J) @' t- @9 `# z4 ]
    char ch; /*存放运算符*/
! \2 W9 {, @! o/ }$ U* B6 _};
, d+ R& e% E) H; m5 t, D/ B
: s% A( G! _7 D, F% g% s/ G6 b8 k9 X( \struct Stack{5 I3 ]1 u! l4 A/ f! Y
    SNode *top;
! K2 A5 o" a1 V5 ~! r  s' w    SNode *base;
# a- i% h& X- w% f: v! [    int size;% f6 ^" j3 j8 _! W8 R1 ?0 ^
};, P4 d' B- i8 U7 G% E

# j# N' C# k4 Z8 L/*栈操作函数*/  z; B2 c! {7 \
int InitStack(Stack &S); /*创建栈*/4 {7 }6 T3 X; ^6 D0 Q2 c! d/ Z; v
int DestroyStack(Stack &S); /*销毁栈*/- b8 z5 e5 ~4 o
int ClearStack(Stack &S); /*清空栈*/
( w  {2 E6 V: {9 R2 I# ]& D- fint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
* Z' A1 Z( U* n5 {" L3 n$ dint Push(Stack &S,SNode e); /*将结点e压入栈*/
2 ^$ A" j# m+ q$ iint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/+ G! d5 c0 {- E1 G. p

2 j+ F5 [6 M+ K. z: o$ i0 d/*表达式计算器相关函数*/$ H; S  Q8 g* k$ X
char get_precede(char s,char c); /*判断运算符s和c的优先级*/( ]! R$ b0 j2 s/ P2 s# Y
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
' D# O1 X: X8 k6 i: P) Pfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/: L$ ?! L1 ~8 ^6 q
float compute(); /*表达式结算器主函数*/2 J) p: [) k% m9 H! B& L
char *killzero(float result); /*去掉结果后面的0*/ ) [- Z) d9 F8 v3 v- ^
! D$ K4 D3 V5 n
int InitStack(Stack &S)
/ j; _. E8 Y) {{
* ?3 m6 t. S. U: {% A    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));' l  ?7 Y3 D0 ?6 x
    if(S.base==NULL)/ }9 M" F0 Y8 x8 `: P
    {
9 ?2 m7 a7 x; v5 w7 t( i7 }        printf("动态分配内存失败!");
! Z! Z% L* u9 j/ \5 [+ x        return -1;+ W* k1 S% v# T2 @" W- F
    }
1 ]! t$ F+ c% d+ K0 S    S.top=S.base;
$ i9 [# _" {0 m' R& C    S.size=STACK_SIZE;3 M% L% e' `+ ?/ Y0 V+ b' b2 s4 x
    return 0;
* S0 F- M0 }: C9 z$ L}
* A- \/ L) d# s4 G' B) G) \% x9 m
int DestroyStack(Stack &S)
% _: e$ H; V2 B) F2 k8 }3 h% x{
. J, r; K& ^3 J% C# B) Q    free(S.base);8 U; @3 Y. T% `! E. z6 [
    return 0;6 V0 r4 U, l5 \
}6 ?! K- ^4 `# e0 Q' i6 K

$ m+ ^7 ^2 c% _* `int ClearStack(Stack &S). ~. P1 v7 l( s; W: w  C; U, e+ ?
{; d  X& m+ k& H8 l! R: b! d% v
    S.top=S.base;
  F% ]- ~/ O" l2 L. v& I    return 0;6 D! s- L  c+ ~) K; w: q4 Z
}
# K# ?2 F: `  c7 k& E- q# |# {
, l! N- J7 r/ p% W1 Z  I- rint GetTop(Stack S,SNode &e)( q* s5 m, ?: r" l
{
8 m9 R$ U  R1 S* [* m! }" o. k    if(S.top==S.base): H2 l3 T* n3 D) {
    {
7 c0 K$ U) S7 ~* T, l; Y3 W        printf("栈以为空!");
# M. X# J1 r4 N3 k. l        return -1;. e5 ^( b1 ^+ k
    }
/ C1 k6 y* ~4 U5 `* O# p7 z) f    e=*(S.top-1);) n# P0 n; a- `9 {+ |+ k8 j; z, L' @
    return 0;
4 M7 {4 Y' q( r8 q. I}
. D/ R6 H- l) j& \5 Q# N6 [7 X/ S3 R. {7 {7 G* \: ^( R* T
int Push(Stack &S,SNode e)
' o; ~% [& b9 W/ d; u! L{
5 E' b2 {* K3 n2 m) j    if(S.top-S.base>=S.size)! C7 W- c; H/ N8 ?6 d, C1 X) i
    {
+ q% ^4 n, r0 d6 |        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ I3 ^4 c$ @/ m3 t" k+ I5 J- n; m
        if(S.base==NULL)
  o+ |- q/ j* S5 U1 V3 x        {% f9 F4 |. ?  V$ i* I  v+ a( Y
            printf("动态分配内存失败!");# l# o- f# L' E" i3 g
            return -1;: I# g* A. _3 i9 r' b0 I
        }% L9 }/ z/ F  p
        S.top=S.base+S.size;2 m% t1 O" {1 ^* ^: v" J
        S.size+=APPEND_SIZE;8 f5 K( L7 V* w6 {0 G* H' D
    }
0 K- g, G8 |) C    *S.top=e;! O4 h; I' \5 c9 n+ n- i
    S.top++;
7 T2 s1 K, x* t& T! @7 i- W  F    return 0;9 [/ b8 a- q% f, V2 H; D; b
}' c3 w' q# a* v2 H

# R$ @4 l+ D$ X6 a4 Tint Pop(Stack &S,SNode &e)& o7 j9 c( K0 c! w$ x" o
{
- {! m# S# Z2 P/ f$ @5 p    if(S.top==S.base)- g4 y" h+ Z) ~  `+ }
    {
; `2 i% k+ L5 ^        printf("栈为空!");0 Z6 S( Q1 a, e5 r9 m8 v* |5 ?4 `( z
        return -1;) Y0 L" D. S+ F5 M
    }. O" m; O4 ^1 }8 O
    e=*(S.top-1);
+ d7 e( K6 R9 F- r" Z    S.top--;( i' ?. j( j% [1 ]: R1 d
    return 0;
3 t3 N: F, M. }# O}% k) ~- G  I1 W8 i

  ~! Y) T' E6 J4 ~char get_precede(char s,char c), ]2 U, @0 K) B$ b4 V2 q
{
# x9 M. Y( d+ y9 R  j0 Y  w    switch(s)" N, F; R7 ~# j% Z
    {
& ~0 [& R9 {5 z) w' v" q        case '+':                 - ?; y) g" l8 t$ n
        case '-':8 @( J" v: W: Z8 H
             if(c=='+'||c=='-')
! z: _: ~  H* g3 s! ~! a# ^                 return '>';. ?" K/ C+ f$ x" E0 g
             else if(c=='*'||c=='/')
8 V3 M% ]. ?! _$ H4 J                 return '<';- n# V! m) S- y& D  \
             else if(c=='(')
+ r; x9 M8 o: `7 O8 U, B7 K! U$ A! S                 return '<';
6 |6 W; ]% F  C, ~: w' Q             else if(c==')')) D8 \) K2 W  S3 Q
                 return '>';
$ L& g( ~0 F$ v0 m1 G/ P             else
+ J0 V" |) D" Y$ W1 e$ F' G                 return '>';1 B8 `9 V, F5 M1 Z/ Q
        case '*':
4 z+ B  C! z5 ?2 W6 z        case '/':
  b2 w: h$ H) t3 w" Q             if(c=='+'||c=='-')3 G. O. m3 b. J
                 return '>';
  T- @, S% ]3 g9 i( ?             else if(c=='*'||c=='/')
5 F, u- x1 K1 i7 @; X6 f: P                 return '>';
7 E+ f; {7 j. t* n- H             else if(c=='(')1 r: q6 H2 f1 ?# g, o2 V
                 return '<';- z+ T8 i$ R/ ^
             else if(c==')')
$ [# U3 C! _( ?6 x8 c/ @                 return '>';
- O% O2 F0 p+ q+ ~4 v; V" t             else+ x9 ?) D1 i: }8 \- d% U. U. K$ ]
                 return '>';/ B) g- A- ]3 h- Z1 p
        case '(':
0 g$ h3 Y( D( \; E# Y" Z             if(c=='+'||c=='-')% K1 U* Q1 r# J( ~% D' e/ R  S/ O' x
                 return '<';% r9 t4 L* F: Z. C
             else if(c=='*'||c=='/')
3 C; M6 s2 ?1 r7 F                 return '<';6 j/ N7 ]  q! I1 L# F( R
             else if(c=='(')' X7 A. t9 j; q( S: j. E3 W& o
                 return '<';
% Y- M* O0 z$ w2 ^7 ?+ \& {' R             else if(c==')')
) R) O& l7 g7 H8 _6 z: E                 return '=';
% g" c$ B" Z; {; b& M             else
3 `. S' v2 v. b( ?0 C                 return 'E';8 j0 J# ~* k: \
        case ')':
( K; u: v+ E# O. p9 c: ~             if(c=='+'||c=='-')
* w/ _0 O' u1 ~& Z* ?6 ~3 [: w                 return '>';
$ z- L9 ]- z- H/ B  p3 B% J             else if(c=='*'||c=='/')
, E. _, v& B# G; b: r                 return '>';8 s! }8 \4 b; D; R" E# m7 o
             else if(c=='(')9 g! O1 t7 A$ [  y7 e
                 return 'E';
# M  O5 R: T' [             else if(c==')')6 Q& g7 a" R& T7 l7 l8 {( j: ]
                 return '>';7 R+ I/ {2 A* }% b. W/ K
             else
4 O# _& `- P0 A$ V5 @                 return '>';" q( D% P0 `7 ~; n
        case '#':
/ G  X; u; T" Y. {2 h9 b- C. B             if(c=='+'||c=='-')
8 _# w5 |$ q2 j- w2 g  V7 P                 return '<';  D: x6 d3 B& K# w
             else if(c=='*'||c=='/')$ H0 m2 _9 w6 w5 ?- K& C8 k
                 return '<';7 g2 W8 H# L- f2 y  U1 Z/ u* T
             else if(c=='(')( Q6 i: b8 B' Z! N1 }
                 return '<';- q5 M# n5 q: Q+ M; N
             else if(c==')')
! ^- J1 ?+ ]; d                 return 'E';
8 G# |8 c( `" X8 P) U* N             else
& I0 s% n/ P4 Q' Q" Z$ O# v% F                 return '=';
8 ]0 {7 P5 D/ c( C# F2 P$ u2 D        default:
; u  A' g7 h, r: P3 u             break;
8 \, o, _: s6 Q( }3 d    }
' w- P8 N$ t4 u    return 0;   
1 t; n; _. y, R6 @5 R* ^}
- R! U5 ?% {1 A: G/ r2 ]/ ?: Y5 P/ w  S2 k' I+ Q, _. g# I, z  J
int isOpr(char c)# A9 H# r6 g. `% b) N0 _# T/ E
{
  @9 H% v1 \% L9 U) x    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4 \8 m5 l  ?" U4 w( r        return 0;
3 U, B/ `1 P+ I# u# f% Z/ w2 J1 p9 \    else 8 F4 U/ p9 I4 B/ J$ }$ T
        return 1;
; z# w/ h7 D, d0 l}
% f7 S5 R) P0 B: F
2 ]" a* E- G% u5 U# N+ kfloat operate(float x, char opr, float y)
, d( F6 S# M; F% J{3 D8 x" K" U5 X" n* A
    float result;4 A' {3 R9 b. l- B1 f
    switch (opr)
6 j/ {" E/ D7 ~    {
8 p  i2 j" ?( V3 I4 N2 e" p        case '+':
+ X0 R$ k# w# G# h  @( h& Z1 g             result = x + y;, _" k6 B5 s/ m$ y
             break;
, _  R$ ?+ K( p6 I        case '-':
5 C! W2 g$ ~7 l6 B+ _. v" C             result = x - y;9 a( @# b! f5 p" t
             break;
8 a' [+ q: @- `% a9 R4 i        case '*':
6 h1 p* ?# P- O6 T! ^5 v             result = x * y;
/ ?* z8 B9 ^- k# F8 s/ g* Y$ p             break;- j3 M) \2 ]1 }/ @
        case '/': $ @" A. _( q1 e' |/ `7 S6 ?
             if (y == 0)+ g- k$ m, H" }& j6 _, y3 Y* B+ H
             {
) F% E! X: u9 j+ p$ E# _" o% j                printf("Divided by zero!\n");# A* v6 V2 s: x8 r: e$ O
                return 0;9 x. K) [7 `+ D% O7 \" `) L4 |( I6 V' D
             }
# `+ l) ?% h3 U8 n7 q7 }3 l* z- u             else
  N* u4 z5 y/ d: @- p             {
/ w4 W7 c) ]! I$ [" q8 t                 result = x / y;
% V0 k6 e9 W; a2 @4 L. k/ g' v  b% L* I                 break;- W9 N, b6 b* z; e; v
             }
6 c6 v( |5 r, f! C  r% Y5 ~$ @1 I       default:
( E. G1 j: r! F1 N+ e$ Q9 o             printf("Bad Input.\n"); ' v! X* b2 y2 A  c9 H
             return 0;
. C" M6 \$ h2 V5 }    }8 N" S3 f7 [  b- D8 y8 N. j. n
    return result;" z9 D2 `$ J$ Y+ Q6 _& \
}    . D1 g( g, e5 s- [2 j2 X& i
5 f7 E3 g5 ^2 Q2 t- o  A2 L( `
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/) `) L" p; n& u8 i2 {# c
{
; Q; j: c" Y& n2 s/ R* {& M. p  J% f# m    Stack optr,opnd;
8 W+ A# ?1 |7 Q+ s    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;/ `/ l( ^* H& L+ i
    char c;; Q3 Q0 D% A2 {8 f, F
    char buf[16];. f, y( _2 @- ~2 A0 W& |
    int i=0;, X" I  P7 m+ Y- T) p7 W0 b
    * W1 {; T( d8 _. n
    InitStack(optr); /*用于寄存运算符*/( T& w/ @( R% }2 @
    InitStack(opnd); /*用于寄存操作数和计算结果*/9 m, w' h( w3 \, g
    memset(buf,0,sizeof(buf));% O1 E( R7 K/ u$ P+ K+ D
   
4 N4 \5 y' M" d  L, E    printf("Enter your expression:");
5 U* F) P( U' ~2 T1 o+ D        0 U9 G+ y$ U' |/ L6 J
    opr_in.ch='#';! q: T& o% a6 q$ Z
    Push(optr,opr_in); /*'#'入栈*// e/ b; g) W6 d
    GetTop(optr,opr_top);
: L6 k( {8 s! @    c=getchar();
) @! T) m: J" j$ N1 ]- n8 h6 ]    while(c!='='||opr_top.ch!='#')
2 V  v+ s2 w6 c% S; `4 {    {
4 `3 {) [; b3 h* J0 N        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/* t$ a/ k  R9 }5 @6 g, q& K
        {! o& c1 o8 I2 n8 ?* F- U$ p
            buf=c;" B5 t: P" Z8 K' s. ^. \
            i++;. S1 V3 J# i. F% m0 m" n6 a# q+ a9 Z
            c=getchar();' U! K! f* Y. e$ b7 z% m
        }/ y- z5 a* s4 U
        else /*是运算符*/+ [! h; u6 e. F, s& B3 q
        {
, \' u) S, S3 O6 T5 ?: F8 o: d8 y            buf='\0';
' J1 O" N! |- R3 B! ^. N            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
- f4 b, E. ^4 R7 ^  g1 {7 n            {
$ H" {' Q2 w3 p3 V1 X                 opn_in.data=(float)atof(buf);
+ b7 d+ u- M' Z, A/ g8 a% v                 Push(opnd,opn_in);
6 N1 z1 ?2 f8 i6 p5 Q                 printf("opnd入栈:[%f]\n",opn_in.data);: r* ]! k6 E- |# z3 k
                 i=0;5 V. {( z0 P1 \. y/ c
                 memset(buf,0,sizeof(buf));; g2 B6 y4 m% a) C; s7 c( `  {* x
            }! y! N6 ?! k& L6 K0 H
            opr_in.ch=c;
. K' T% z- y/ h: [. r" B            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/9 X: ]. W. f$ T6 T
            {0 J# l. X( ]6 ^5 n$ `6 }
                case '<': /*优先级小于栈顶结点,则运算符入栈*/% |9 h6 F4 o7 |1 X: ^, L
                     Push(optr,opr_in);
6 t+ D/ ^  u) E% k$ N                     printf("optr入栈:[%c]\n",opr_in.ch);
6 Y( y9 r5 O. h+ n; V4 F                     c=getchar();% U+ f/ P! \$ U- B& e' |4 Q
                     break;
$ p4 F) A& l, S) l! Z- j/ e+ h  ~                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/- Q8 l' Q0 c% G5 x* L
                     Pop(optr,e);
- q' T/ W1 \9 n$ c                     printf("optr出栈:去掉括号\n");
3 @5 R* n9 ^+ e, J7 M( @6 E$ P) Q                     c=getchar();" F- i: H  Q- W/ n5 |8 K% |1 N2 l3 Z
                     break;
9 ]! |3 b1 B& k7 [1 @6 [' Q' H                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/4 d: B$ m9 ^0 j# U
                     Pop(optr,opr_t);0 H& G* [/ X, w
                     printf("optr出栈:[%c]\n",opr_t.ch);: b8 I6 O- p+ `9 w1 H  S) H
                     if(Pop(opnd,b)<0)* d: C  l, a# |6 h" g' s
                     {
0 w$ M) |1 v* }; d9 g1 T. p" ~2 H                         printf("Bad Input!\n");
$ c; ?) d7 m& P( c8 D                         fflush(stdin);% y- x  ]5 M- }- ?: M7 l
                         return -1;6 m" o* V: J; \/ s# @8 k; X
                     }
: v# N; z# s7 s# Y                     printf("opnd出栈:[%f]\n",b.data);$ ^: L' B, x$ a) c1 W7 J' L
                     if(Pop(opnd,a)<0)
  J5 ], D  f+ d1 c/ L                     {
$ N) {$ W# \7 ]0 Q                         printf("Bad Input!\n");: M7 r" \, j$ x" K
                         fflush(stdin);
# W" ~! \7 R  y+ U& j: j& a" w7 n                         return -1;
/ g7 t4 Q& x/ v7 w: e2 s$ Y                     }8 U2 ]( [. j3 p0 U
                     printf("opnd出栈:[%f]\n",a.data);/ f- ^5 @8 D/ e
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/7 K' A7 E. Z, `* v
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/1 ]1 [% J7 u1 u) R
                     printf("结果入栈:[%f]\n",opn_tmp.data);, B. q6 h' `0 \, n* s
                     break;; L( [  e/ ?9 C* ]' X4 q
            }
: @6 h6 }, o3 S; Z) s7 K        }
( a$ N; m2 a  J7 j  Z) @2 V        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                0 [# D( @2 m. Q( _' l1 }5 c, J( c1 c
    }1 [0 X- B" O! g( c0 p' j, g
    GetTop(opnd,opn_tmp);% K" K) O$ r- y$ M; c+ L- u
    DestroyStack(optr);, Q& t+ D& U4 P4 j% I) t( v
    DestroyStack(opnd);
. J) I# \9 ^& z% e    return opn_tmp.data;
% w: B: H7 o+ ~7 I# @" j6 L}3 e8 m- @& T1 U+ S6 J8 e
/ E# W* k: X  H
char *killzero(char *res,float result)7 {/ K) N% s+ r# ^
{/ U- D0 O8 J. I& A' p
    int i;
/ g4 H4 y' W+ w" M+ g  P6 b( A8 M$ J! ~+ L5 E
    sprintf(res,"%f",result);
4 x1 d- h* {0 j* O8 N    i=(int)strlen(res)-1;
5 y% ]. Q( t- [0 g8 u    while(i&&res=='0')" L: j% s& Z/ Z( W# u* A
    {. |: \  [1 Q/ ~' Q3 T3 X+ Q
        res='\0';# W0 A* K* T2 G9 m! f
        i--;
  }; m+ @6 w" S# Q/ s    }
4 E! x$ O5 {) Q6 {( a2 z+ X2 j4 s% l    if(res=='.')- t/ ?' S, B' h6 Y- J" s% l# S
        res='\0';. O$ A4 e, i: T* f* P5 v
    return res;' K6 p5 R; E2 A. Y1 l: Q/ R2 Y( H
}. O1 F# Y1 l/ }
# I3 D: @) b" S& M$ K
int main()4 L1 U2 U$ B) k9 q
{
: [% C5 u4 f. h1 P- F  \    char ch;8 ^: Z- g3 t3 n; b0 q3 m
    char res[64];
( n. s2 I! u' }    float result;0 @- g  a; F$ P8 K6 Y0 L" o) }8 f0 V
    while(1)
- U/ f; R2 h+ [6 B    {
( H3 R1 p0 K$ M  q- H# k        result=compute();: k) {: T# _: J6 `) }9 R+ b
        printf("\nThe result is:%s\n",killzero(res,result));" L( J  `4 k# ]) ?: A2 b0 a
        printf("Do you want to continue(y/n)?:") ;
# H- V! `* `2 @# \" d1 i        ch=getch();8 k: f$ d- d, a) J, f! Z
        putchar(ch);
( z; b2 Q# G' i) q2 ]        if(ch=='n'||ch=='N')/ \" x) P7 S6 i. k& `: d
            break;$ q# X! c5 P; j" U3 o: n
        else# v% T0 M; T+ H6 Y
            system("cls");, n' |, Y0 R/ U: r7 L8 Q. U) O
    }  k5 j! a8 \3 g+ n9 C6 A
    return 0;
6 X4 L( y+ P! U& t}

2 \4 t0 O- d6 x- n  J  O1 o6 T2 t2 K0 `
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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