返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
6 Z0 N: ^  m/ J. O" [程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=/ G& j0 f4 L' M) B
/**************表达式计算器************/
' s% E* K) S( \% b. ?#include <stdio.h>4 W* |- o7 Y6 F4 t) W9 u
#include <stdlib.h># r% o" T0 p. l% V9 h) W: g4 C
#include <string.h>
0 {5 s- G3 X& a0 j, I- [#include <conio.h>) _6 A: T: j, W. {2 M2 i
#include <malloc.h>
/ }9 [; y4 @7 v1 v% A$ H
7 V% k* j0 }# N4 q& q  b8 T1 N#define STACK_SIZE 100, m9 _& h4 G1 }/ J
#define APPEND_SIZE 10( s0 o0 z1 `9 g
; I6 J1 W: U2 c
struct SNode{
$ ]/ E$ g0 i# @2 x    float data; /*存放操作数或者计算结果*/9 B# {$ M3 O2 L, S8 }9 I
    char ch; /*存放运算符*/6 S' @4 o5 `0 w! O1 O0 p
};# F' H0 d% o/ e! E
: \9 G6 X1 j' _5 X. i) E' L3 \- ?
struct Stack{
  W! i1 h$ @) U$ r# Z5 F    SNode *top;4 E6 Z3 r6 G9 B% q. ?
    SNode *base;* z$ Q! y, `( M0 \* `8 ?  ?: p
    int size;# d9 O) m, r, r3 O4 j) m
};- \- b" B7 [7 ?' i& w
  u& s: }4 i4 d* i# }7 d4 N
/*栈操作函数*/
: w4 g9 o1 F6 B& z% lint InitStack(Stack &S); /*创建栈*/
6 Z4 h1 y4 R1 g7 H7 x6 z& F! Fint DestroyStack(Stack &S); /*销毁栈*/
1 a) e: }9 s& |7 [int ClearStack(Stack &S); /*清空栈*/2 X, J, w' e- u4 \- u/ K
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
& _' o/ @6 B8 \3 T. kint Push(Stack &S,SNode e); /*将结点e压入栈*/
/ _+ \" v1 G4 [2 ]& r4 oint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/0 W6 C1 s3 ^) k7 U2 b

8 f8 ~7 H( _1 ]" \/*表达式计算器相关函数*/
6 R9 {" _2 m5 s6 qchar get_precede(char s,char c); /*判断运算符s和c的优先级*/; N2 t* M& ~$ M6 V, Z
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
5 k( @/ {: e' ofloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
5 H5 L1 X9 @+ Z+ J& S- Efloat compute(); /*表达式结算器主函数*/! k2 T$ I0 O5 Y0 D/ J3 j
char *killzero(float result); /*去掉结果后面的0*/
/ f: `- d  a2 @8 _; H( b) A' k9 z% C' d  z% s) _2 W' c
int InitStack(Stack &S)
" d! @: Y# }  b; @{
+ X6 X- ~6 h$ C( ^    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));9 p8 J- D" \* L
    if(S.base==NULL)
0 \: P  k& |9 l1 p/ T! I    {! V2 z3 X0 f1 R5 j9 D) q& o+ [! w' ]
        printf("动态分配内存失败!");, a5 R2 }$ X, i  t3 l. T
        return -1;* V, D% Y8 w* W& a) @! Q: x
    }1 w$ y9 e# V) b# ]0 p
    S.top=S.base;
& {4 ^8 Z/ g( u4 R8 c    S.size=STACK_SIZE;5 _, p% L4 _/ G
    return 0;
* ?- s% V. r4 [  A# G}
  Z! J" g7 [; Y1 R% C2 v: r, a. I
int DestroyStack(Stack &S)
% E5 ^7 L% \6 a) V: t1 `- h2 }{# X2 x5 R6 c0 d' s; s
    free(S.base);) J+ X8 J1 [# @+ ?4 a$ O. l
    return 0;
( F* g9 r; s3 }/ z}
+ s% O, c. H5 k; X/ }
: k: Z9 O' m- T& b+ i+ O" zint ClearStack(Stack &S). D. c( }. O7 Y
{8 e. d4 r$ O" l6 w% J8 b1 |
    S.top=S.base;
/ r) p. h7 D2 d! U) l    return 0;
$ A3 I; k& D4 I0 v# r1 k7 O}  t8 o$ B' j, R6 K% B. c
6 i0 D* w2 L  X# X: S4 O* G
int GetTop(Stack S,SNode &e)* g+ ?: i* v/ k: {8 d1 @
{
: Y+ u# m7 ?1 V    if(S.top==S.base)
% F* A7 Q" C. d& b! }, ?/ S: {    {
! ]$ c5 W. X) p  ?2 [8 `' a% y        printf("栈以为空!");3 o  c2 V8 L% i. R1 l
        return -1;. }+ W, k" w6 C
    }0 o& P/ H* k7 C7 ?
    e=*(S.top-1);
$ G, K$ [$ w4 C. L8 o    return 0;/ P6 a* u3 ^$ P, A2 a' ~; w/ U3 i$ F
}
2 m( \0 Y! g7 z; `1 \
0 w9 X. B3 n8 w) i8 aint Push(Stack &S,SNode e)4 P0 Q3 O5 H9 x6 V' S1 X
{9 d1 u$ f6 N1 l( C: p* [* G
    if(S.top-S.base>=S.size)8 X* ]8 {( n4 c# X4 I3 H
    {
6 J  Z6 Y" d5 K+ f8 p  m8 x. k        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));! f; z9 M( ?' t+ V% `. F
        if(S.base==NULL)( o, R+ ], j/ Z% c" L4 v2 m
        {7 U, ~% D/ F9 A9 q- Q* p: s
            printf("动态分配内存失败!");0 N( Z9 Q. Z0 K4 |" b
            return -1;
3 ^% A7 ~7 _/ t( y        }
0 l; p2 G4 n. v0 [& `8 p        S.top=S.base+S.size;% X8 L8 O1 s! H: m+ O
        S.size+=APPEND_SIZE;
, ^6 J9 j) R' C/ g' a    }* O, H# n, Z+ s$ Z, f# Z7 ^7 n
    *S.top=e;. l1 @/ M9 p2 g9 c# j+ u
    S.top++;
" \! h. ^/ U1 F5 N4 r3 n    return 0;( ?$ M" p$ M6 }& v6 M) q  H0 p1 J+ {
}
, p  m, Z2 l3 {. S: ]2 h) F) W  a: ?* L& T
int Pop(Stack &S,SNode &e): l6 S, ~5 q" W, u& z1 v7 t
{
" a8 O* p; m6 j! D/ }" ~, j+ [    if(S.top==S.base)  ~, H+ e! c* P7 d# m3 D8 I% A6 _
    {
) m2 ^6 t; i# C  w        printf("栈为空!");
  x& G+ q6 D4 d9 U        return -1;- V; Z- z2 b0 e3 e2 }$ Q7 F5 T
    }
' A5 t9 W6 Z2 Q5 K. }$ _: l    e=*(S.top-1);
9 W3 o( d+ T( }9 q& \    S.top--;
, q+ J4 u5 G  J* V' @    return 0;
* d* D" d  D  O}
4 h9 F+ o: G& P8 D+ Y. @4 [' G' ^1 M& B, S3 I  ^/ V: ?
char get_precede(char s,char c)
1 f* [  A, V1 O% H, j. v{
6 V2 t; h1 C. @4 X8 r. Z( ?. ?    switch(s)
! s, W! \! j# N0 e' I    {
, I/ D* L" r4 l. S        case '+':                 
: n( C* ~) x& g) O, }. h        case '-':+ ?6 i+ ~  a2 [$ G) s% ?, r5 _
             if(c=='+'||c=='-')# ^9 {) T) v' @
                 return '>';" i& B  j7 S' B  p3 S5 m" K# a; ]/ @4 I
             else if(c=='*'||c=='/')1 a; u3 x% H/ P' R  t
                 return '<';
( r3 W" g0 F$ C# e  q( Q: ]* x             else if(c=='(')
# m5 U! P! D! m* Z4 G                 return '<';) k  ~! b- [' t3 Z$ c# T  G
             else if(c==')')
$ t$ c+ U. A& g- U- i/ A, a                 return '>';
  g! }1 j- ^7 I2 r6 s' [4 H             else
3 L" W, A! _3 f6 W) e' ~! i; D0 i                 return '>';$ i' B  n" m  F" n. r: i9 v
        case '*':. P( d5 i- Z& I1 a; H, k
        case '/':$ G) {8 R* i1 A% g# V2 W- H
             if(c=='+'||c=='-')% |# g5 {" Y4 Y, ~
                 return '>';
9 `( \4 D" |1 y6 q             else if(c=='*'||c=='/')( I6 V4 b/ w) J' y! ]! {) q
                 return '>';! f* R, C4 a6 h& n: e. W
             else if(c=='(')" K  P7 q. Q& d: }, J& L
                 return '<';
% T+ _) M* N( E/ p             else if(c==')')
/ V8 P0 @- n- b% B9 o% S/ s1 X1 g                 return '>';
- q" Z( F) [6 s% w             else
% v+ T% P7 d/ {- \1 x                 return '>';
( c  b! I$ A/ C6 G        case '(':
3 W* r' g. [+ Q# u5 V. Q6 ]             if(c=='+'||c=='-')
0 W; m  C3 E1 e0 a  r6 _2 r                 return '<';
& B- E2 h1 S" x             else if(c=='*'||c=='/')
, g2 g1 a( @9 M- D                 return '<';. s1 d" Y7 C2 A: [# C
             else if(c=='(')
! L  s' r( E  R( Z1 K: @) f                 return '<';" V( w$ U% Y+ D. k
             else if(c==')')
- O$ p0 j$ C  ?0 t6 N. j% D- v                 return '=';$ {/ }- N% B; I9 b$ a2 {
             else
1 z: F5 y. ]# [& c6 H                 return 'E';9 U5 S+ N4 r. q5 ]1 k8 ]
        case ')':
5 V" U  J9 ]3 X# @             if(c=='+'||c=='-')0 `4 a8 I1 K6 ^2 o/ [) @
                 return '>';
+ }7 i  T+ }7 I( }+ Y, l             else if(c=='*'||c=='/')
0 S) l* {1 ]  M& b* q# a                 return '>';
# L: _4 u6 c+ ^/ D5 S             else if(c=='('): d: Y# z3 l! W: w: v. |0 e0 t
                 return 'E';, d, c( T) x0 k9 g1 @$ X
             else if(c==')')3 n' m, }2 @3 Z  l
                 return '>';- H* c: ^/ A( y8 V+ ^+ W
             else6 V, n# y" }# \  t
                 return '>';" ~2 {+ R2 R* s* P' w% {5 v- G
        case '#':
$ p9 i$ D! n+ \, F0 m  N             if(c=='+'||c=='-')
/ p$ x6 @) ^: U5 V                 return '<';% E+ v- C' ~* ]$ a+ ?0 v
             else if(c=='*'||c=='/'); E2 O1 \( O* n0 C! B# N9 }
                 return '<';
. v: @! |+ j0 X; a, J, ?% a- i' v7 J2 |             else if(c=='(')
1 ]7 j: }+ t8 c# z                 return '<';
# R  F+ P8 a/ f% H             else if(c==')')
/ J' o4 N% L! Z8 f9 k7 Y0 i                 return 'E';& a( ?( Y7 e5 Y2 N4 t8 Y
             else
, N& W; U( @1 ^8 G* `6 e                 return '=';% y7 d6 ^- `) V. ?4 F
        default:% L6 C0 `1 e1 S5 l" `& j. Y
             break;6 i/ ^" o2 n" S
    }* f. }+ |' w8 J% K- y$ D8 ^. K
    return 0;   
  {# I4 _$ M. @; T- U}) Z; ~& @6 c" W# l6 S4 D
, r% D6 i( n" P( P. T8 {$ i
int isOpr(char c): h4 V  s- v+ P5 h/ o$ V5 w
{
/ ^+ O* @) S4 t  \6 Y& J    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')* `2 h: H; \8 i. F) z! _
        return 0;
# D  L. Z  q/ z5 D+ H5 W% U    else , e. r* j* Z6 U' x" p9 Z$ Y
        return 1;. }0 r* N% E) _/ Z
}  C& i2 H; ?1 [3 ~% f

' b: ~6 X8 r% D& K: Vfloat operate(float x, char opr, float y)% }& ?! ?7 Q" i. X5 y# u& u
{
4 E, s& S2 x. e* y    float result;; `& D' w# P5 ?# @+ q1 @3 J
    switch (opr); t$ l8 C# s8 F  h4 Z) f( J
    {6 G; W. G4 P' E" q7 x0 E9 t0 ]4 F
        case '+': ! N4 @- _5 ~6 t6 g1 v6 O# \8 C
             result = x + y;, H7 o% y6 G/ K" X
             break;
! p* f$ l; W4 ^5 I: I        case '-': $ w% {1 I% P2 [. |" y1 C! ~6 O' L, n
             result = x - y;
, O- L, k) I2 H, s3 E3 Z             break;9 O( o& U' m" i5 A' d& W
        case '*':
8 v3 R; ^1 E) z3 z6 X; y8 d             result = x * y;  J  u4 B3 L8 O, t: @
             break;
. X3 l, @7 e+ C: v/ E% X) r        case '/':
% [4 u' I) j4 R) \0 B6 r5 q6 c             if (y == 0); X8 k8 P" Q. s* j. u6 r
             {; _2 P# ~7 y2 Z: `8 {& b9 l. _
                printf("Divided by zero!\n");8 p9 t2 P" U, A5 r
                return 0;
, ]6 K$ E; \% p             }3 K  C2 D& L: B' K% M" h% H! D) P4 A
             else
4 y3 j6 G" f- v6 j, F$ z6 l             {. O. [3 q. r6 \6 c
                 result = x / y;) n- S( Y6 _- b9 ~
                 break;
/ C/ L" Q3 C$ y4 L+ y9 v9 d5 Q             }
/ W4 [. I/ _+ V4 I$ X( \       default: 1 |8 ?2 e8 {, f; V- s
             printf("Bad Input.\n"); 6 D' q4 y  D; D* V( ^
             return 0;
* k! q/ D/ G( F! j    }& O2 ^+ ~$ s0 `
    return result;( S( y2 s& O2 I: B, U4 z8 W/ z
}    1 e. z9 A: H# a+ N+ a( Y' l
1 N  U2 a" |( Q2 m
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
) C" i3 W, l" s; L+ `: t{7 q4 t* l7 |9 B1 c* O! Z+ X
    Stack optr,opnd;2 z; D( ]/ g' l! `, L0 T
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;2 t! q/ Z% k. ^' w  r
    char c;
4 }5 q3 G9 t* D/ y: {5 c    char buf[16];) X& s: ?6 {0 f) _' l
    int i=0;! ~% H% R* f* P/ Z  B& W6 B5 I+ |- f$ J
      R6 ?2 d3 u( I) i; W0 c
    InitStack(optr); /*用于寄存运算符*/& X7 Z& B" J" y' z
    InitStack(opnd); /*用于寄存操作数和计算结果*/, y' e" u  X) Z
    memset(buf,0,sizeof(buf));
7 A' v+ o( b5 ~  D    + q7 R- p* V0 F$ h
    printf("Enter your expression:");# `4 {: O' k) b# h
        
' @! P' ^' |; A; F    opr_in.ch='#';/ H4 g: q4 V. x& a
    Push(optr,opr_in); /*'#'入栈*/
4 h! C+ |/ O) T: m; }    GetTop(optr,opr_top);: C% n; r9 |+ m, a& J
    c=getchar();# z' G- W  W- D) g# b
    while(c!='='||opr_top.ch!='#')
& \9 E( `7 ?( A8 J    {* R1 X" ]: o% U4 s( _) I9 L* o
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/$ o2 Z( l0 T! U" B1 m/ I( m
        {
' B$ p: `1 T  O& O9 M            buf=c;
' O" Z. [( f- w            i++;# }  d1 x0 \% u7 k: f
            c=getchar();
$ z& ^0 u, H" e* ~' u        }
4 c! C0 O, r# c9 V) v7 h1 W        else /*是运算符*/
. H0 ]# H8 \7 O/ g5 R9 X! n        {/ V( @- E" x( E# v( l. C' p8 Q
            buf='\0';
1 e- r# D6 R6 k! o            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/, Z% h) R5 ~2 K9 S$ r' D5 w
            {
) ~% z6 j5 }* x8 V# a                 opn_in.data=(float)atof(buf);
7 i, T! `2 L0 r( d                 Push(opnd,opn_in);" q6 M  [$ w. i! F( ^/ G( m$ z
                 printf("opnd入栈:[%f]\n",opn_in.data);
; X! A& k8 A6 l; C, U/ b                 i=0;
- t# X: D3 d, [8 x$ O                 memset(buf,0,sizeof(buf));
, S3 i3 u  @( v! A. y2 M            }3 i! m4 Z, U4 b! }1 K
            opr_in.ch=c;
" X+ w' c" I& t3 Y& n+ e            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
& L, ?5 L) s+ Q            {
% N* i* Z: \" b9 ?/ i7 W/ K                case '<': /*优先级小于栈顶结点,则运算符入栈*/
$ Y2 |4 x2 f+ Q% P; m% h- j                     Push(optr,opr_in);/ F: O  x1 F( ^# B6 L7 J0 _* h
                     printf("optr入栈:[%c]\n",opr_in.ch);7 X1 _4 S/ S- w& i# r( |
                     c=getchar();
; C+ Z* Z% o3 o4 i* n                     break;$ J7 d4 t" z. U# I1 r6 m; Y
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
- e! u1 y  @& K+ c7 h( h                     Pop(optr,e);" x3 C; m  \$ k# _
                     printf("optr出栈:去掉括号\n");7 j- H$ z; _0 `4 k8 o8 A% \% ?
                     c=getchar();
, x6 r2 e9 h, t  p6 Z5 E/ L, }' Z                     break;- P/ R( A3 E$ A8 }
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
( f. \+ J' U) ~  \' s7 @, y& R                     Pop(optr,opr_t);+ {' k3 M# N; J9 f5 z. M4 M5 p
                     printf("optr出栈:[%c]\n",opr_t.ch);7 ~* c4 g! l% }# p3 Z
                     if(Pop(opnd,b)<0)! T8 C5 ^& h3 v! x. |5 o% _
                     {5 P6 y; S0 O! ^& x9 b
                         printf("Bad Input!\n");, `5 W$ u4 d$ x, M5 ]! D( u* e
                         fflush(stdin);' Y5 ^. d2 R/ G* h
                         return -1;7 K4 T8 s* i; w+ \# c
                     }8 M- p( _4 q$ ^
                     printf("opnd出栈:[%f]\n",b.data);, O1 N' K1 G# _- o# U+ F
                     if(Pop(opnd,a)<0)
2 K2 K/ L' X, G. O) j8 j                     {
; F0 G, j) q' O5 H6 l# E( D                         printf("Bad Input!\n");5 ]8 u! V- V8 q
                         fflush(stdin);
, ~9 X. Y: {7 T+ c& _                         return -1;( F) z* T2 s- b' `7 K5 t( t& h
                     }( d- @0 A; \9 k, s  j
                     printf("opnd出栈:[%f]\n",a.data);5 d; ^/ \& E$ C# f5 w
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/3 k0 c, ~& w0 @, d- I
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/$ r* V& l8 T/ v' Q+ x
                     printf("结果入栈:[%f]\n",opn_tmp.data);" p0 Z% e$ L6 L7 M7 L% J. o
                     break;
6 p# r0 R/ A& N* P2 _            }
/ o( ]# X5 c# S) m: o$ q        }/ S* j5 g6 y" O8 I) p
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
- E: y! ^8 _  g    }
% ]1 H% A& w6 b7 z3 {    GetTop(opnd,opn_tmp);
  L( {" o7 ]( ]. o) }    DestroyStack(optr);0 ]. e0 A0 p" b4 M; P) B: A
    DestroyStack(opnd);
) ^4 n# u- O+ |2 F1 p- x( A    return opn_tmp.data;( b3 E8 [! W4 ?' h
}
* i8 {2 R+ s. F5 F& K
. z. b9 c0 J0 A! W. Z% Z1 Ychar *killzero(char *res,float result)0 u- @. e0 a9 t0 _# @2 F* W
{) I! q7 e1 D! w% k$ ?: S4 c
    int i;+ Y4 ?6 i1 j. J5 a' O1 N; f, E9 U

( M+ t% A5 G+ x  T0 z  }    sprintf(res,"%f",result);: e. p& b4 h  {5 x5 s6 q2 |
    i=(int)strlen(res)-1;3 }1 N2 r& |6 Q7 e, @
    while(i&&res=='0')/ `" i( ~  w: j# {
    {. B! n. q7 `+ b4 }( M% a; n6 \
        res='\0';
& f# X; D- P' Q+ h3 t        i--;
/ a) @8 b6 u$ \# X) g; V, Y    }
( U$ G$ M( @2 X    if(res=='.')
# a7 L: w1 `; W- S        res='\0';, q; n2 i  J3 ~4 _
    return res;2 c) r# @- O- I
}1 Y0 t6 O3 t* O
2 K; C4 o6 h( O
int main(), F; `; X* n3 ^0 W& y; E
{
) b8 l: v) H  T. [; V. r    char ch;
: M6 e. I# W. [2 T, M. I8 W' \    char res[64];
' `" X' \, ~3 u, `+ R" w    float result;1 R1 ^. Q% S; c( `" s
    while(1)% K; ]4 }* G  ^" `; ^& r
    {5 f8 A; j& u% H1 B! c
        result=compute();
" y4 I5 {! Y0 T        printf("\nThe result is:%s\n",killzero(res,result));
0 W1 [- V  Z5 e; L5 L" D/ ]        printf("Do you want to continue(y/n)?:") ;
4 n7 f7 ]- b. |* g2 T( C5 M        ch=getch();5 R  k7 I  H, r
        putchar(ch);8 \2 R. w6 n* n* r( s
        if(ch=='n'||ch=='N')- e- `" |/ D5 D* L
            break;
: L; R) O/ `1 j  e        else8 e! w$ Z% ?! Z$ m
            system("cls");, S1 I$ U6 R9 `* O9 F3 n7 R
    }
; h+ q! r" Y6 H$ m6 o4 {0 a    return 0;' H5 N, R7 }3 G, y) m
}

' M' Q- X% T' p' P) c) O7 k3 S# u) C( R( w
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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