获得本站免费赞助空间请点这里
返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的." u+ ^0 `/ w/ ?: u5 L0 v$ X; h
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/ Y* V# G1 ]9 k9 \1 O/**************表达式计算器************/
8 i+ a& P9 f: H# d, o6 E#include <stdio.h>/ ~" V1 P+ m3 v. U$ U# Q4 a
#include <stdlib.h>4 W5 A8 J2 G/ G! i( S
#include <string.h>
* N3 n* W: @4 y# Z#include <conio.h>" O, \5 p$ {6 Q3 Y( ?. f$ `4 D
#include <malloc.h>% X& E( Z2 B# z9 I' @% r5 Y9 C
# M, K' K: }  ^& e3 x% i9 y
#define STACK_SIZE 100/ S& D- d5 n7 `6 a, \# }
#define APPEND_SIZE 10
8 R1 x+ W: H2 @; D" j4 l$ s( m" Z! ?4 X; W4 I8 u
struct SNode{4 o& Z) k3 D7 |& q) J$ d
    float data; /*存放操作数或者计算结果*/
. w- o$ u$ q: [    char ch; /*存放运算符*/
! y/ u8 K$ H2 \% n; k, e$ |};4 b9 m9 j# d* m# _1 L& F" C

8 U# e2 p& ~3 q$ R/ _9 Z1 xstruct Stack{! m! s5 V, Q, c6 V
    SNode *top;" {$ \' Z5 u, `/ N6 f5 a0 F
    SNode *base;
0 L4 t/ O3 |* ], @3 f: Y    int size;
# W8 ]2 i3 _& N};$ @; D6 d( `3 S. X0 {; a
) c- \: W* y2 L  w& |& @3 a7 B. L' y
/*栈操作函数*/
  \9 c# X$ T6 X. m. ~int InitStack(Stack &S); /*创建栈*/0 J5 N$ T5 @/ u% \$ ~" B4 r8 E! X
int DestroyStack(Stack &S); /*销毁栈*/
9 n4 p* c/ S+ p4 I- o% t, [int ClearStack(Stack &S); /*清空栈*/( _1 D! k' H. f( u
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
- E9 H/ a7 ?1 bint Push(Stack &S,SNode e); /*将结点e压入栈*/# b2 V- ?7 u, I8 L
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6 \! d' R0 g9 N7 S  u
, q, ]' z% K1 E( ~2 [/*表达式计算器相关函数*/& K/ H9 @5 o7 c- m
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
- q. c) z1 o+ [6 Aint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/3 k5 Z; g9 C5 T9 J$ \2 D# q4 w' O
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
* C7 E: X& w" o  Q2 O4 lfloat compute(); /*表达式结算器主函数*/; y" A) L3 r/ m# I. d  B5 D
char *killzero(float result); /*去掉结果后面的0*/
1 {! u- V# l; P
8 Y# V( }* I0 D0 A% \int InitStack(Stack &S)$ P. h9 E! H  L" N0 D1 H
{; M$ t! L4 Q: O" S
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
' u) i+ O- [9 U+ x/ Y0 y    if(S.base==NULL)
* ~: j& }3 S" ~; a- [/ k    {
# r' _! P+ O2 E* |$ e  M9 Y' w; A        printf("动态分配内存失败!");3 a8 [- p" U- e5 k4 v* [0 k! w
        return -1;
, S* i1 G! X4 B" B# \; D* i    }. h; z; }4 p! ]7 Y8 r
    S.top=S.base;
! N0 C" r4 }( f; J1 a/ X2 _    S.size=STACK_SIZE;
8 i6 R5 O( h+ X+ l/ I% [' H    return 0;8 d! @# V2 y  f6 P6 A  |
}
% g) g2 [# O7 R9 Z
4 T+ q' t/ K, X4 d8 u8 p' Bint DestroyStack(Stack &S)! c5 W- @% ^! Q3 D6 |8 X- _9 ~7 x0 V
{- i5 `' i1 t4 J  p0 E7 u
    free(S.base);
0 X+ Y# z% j, d4 V7 H" m    return 0;
6 }9 N1 x. l: [' c/ i}
- r/ z% [( p, |, ]& a
' ?6 u7 i) _+ rint ClearStack(Stack &S)) r, B  \6 F5 I7 Y  O; |6 Y2 W
{" a5 h. E0 z! q" Y& _+ X+ @
    S.top=S.base;' y3 J( q# q6 h: g$ u5 |/ f
    return 0;- m/ ?  g6 ?) S4 [, a
}
" S, Q3 ]: ^* d2 g( @, m' H$ u5 X: i$ k  }4 ^3 A$ {+ I$ b4 J
int GetTop(Stack S,SNode &e)
! b$ P4 K6 a- y7 o' Z/ t6 m- M! d{
1 B- e: J% |! J4 b$ s    if(S.top==S.base)
. {- V& O* _" o" S6 Z    {% S3 I1 e9 w- U0 D
        printf("栈以为空!");7 T) Y8 \: Y* K. D( ?. t5 l) N
        return -1;
' C9 w7 J; x1 ^2 Z  I3 R# X    }
' G# I9 u+ k! J: _; g5 g    e=*(S.top-1);$ J& X  o+ Z  N8 l, L+ \, W
    return 0;
4 c" k2 i6 T/ S' |& C- ?  C}, |3 N9 k, r1 P4 R+ ~) G
# u& A/ P9 }  K$ s$ T) ]% z2 _
int Push(Stack &S,SNode e)
+ @& \4 p5 l! s1 o, e{
& M) f# H: b- @" r    if(S.top-S.base>=S.size)* X* H& U5 F4 m
    {2 \. y4 S6 ?# A
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
* u+ u$ ~$ ^! X: q; P5 {1 P" v/ e) A        if(S.base==NULL)+ @& m1 h3 o, ?: a" q, Z- s; g3 z
        {/ S3 v% o8 |, j# c/ I+ X$ f1 g
            printf("动态分配内存失败!");. t' o/ u8 @# |! ^
            return -1;
8 X- ~+ R5 \# @4 H3 ~  x  t+ {8 U        }. ]% M! P2 N. y; ]
        S.top=S.base+S.size;
% ]/ L) |9 g5 D4 Z' M        S.size+=APPEND_SIZE;
5 f! [2 }: D" T0 S9 s- w- U; s8 z    }
" H0 h' J' d; w# w) n0 r    *S.top=e;+ z. e8 ]3 z& r' ^- e8 a
    S.top++;' F* N) ?4 N2 B& y
    return 0;
5 P; j( ~4 {! {  b, B}
9 y5 K" |: j3 `6 X* Z& c0 E) ]7 D; J! d* Y6 j8 N
int Pop(Stack &S,SNode &e)
) Y* U$ c3 I. y, x5 w{
& n2 P7 v$ G7 l! c8 u. t# S) H    if(S.top==S.base)
0 A8 T0 M1 C3 M7 s$ m    {; `6 p1 r% K; A0 X$ r
        printf("栈为空!");! u, V. ?3 b( k3 i3 S* v, K6 B
        return -1;; {+ w% m) g) [' w5 n
    }5 t# w2 w- y( ]
    e=*(S.top-1);
; ~* l% N5 I" g  ]* a* e' {7 a& ]. A3 f    S.top--;  @! m* u' I. e. H* u5 A+ A% t+ L
    return 0;5 z$ C3 X9 @1 }, Y5 m
}1 [6 d3 b8 m; H8 S

& K# B. t5 q$ Dchar get_precede(char s,char c)0 a- o% {  H* b
{
  A1 Z3 m1 n; A+ j' H5 q' C    switch(s)" U3 r0 {1 m( z2 c- i' ~+ }# N
    {
  x# g( P6 f$ ]: J0 K        case '+':                 
* O! C. c) u* |  `1 X        case '-':. ]  O1 ?; I- Z" @  y( Y
             if(c=='+'||c=='-')
; S- @  V( W$ l) t                 return '>';( T2 [9 O: h8 I) e8 K. [
             else if(c=='*'||c=='/')) x: _7 \5 v7 V
                 return '<';
$ k) j6 B5 z3 N8 q& V/ C             else if(c=='(')- a) o0 {, T1 p+ \6 G
                 return '<';
, m$ _$ Z3 `9 E8 u             else if(c==')')9 y- U" Y. [2 k, a6 m( x3 q( p
                 return '>';
  ~0 L% |' n4 A3 g             else
& C1 s+ Y* f* G1 f8 n                 return '>';; b" z8 p! a# F; L+ X! s
        case '*':
3 q. O6 O# Q  V3 x        case '/':
+ c7 b; W- j7 z" i: g             if(c=='+'||c=='-')
. W' t& b  e, ^2 e                 return '>';
7 B7 [& Q! U# e  L             else if(c=='*'||c=='/')7 |5 \3 [9 Y5 q9 Y6 X9 |1 w  k1 m
                 return '>';. o1 e/ l2 v! v) }) G
             else if(c=='(')
- l8 a- `) M  c* ]7 b                 return '<';; ^5 a% b8 {2 b) m: m' p# @
             else if(c==')')
+ b/ d4 L- j: U" _. K                 return '>';
+ m6 U; f& s' x$ j             else
' D5 h* o9 s: {( [( T4 i4 U6 H( @                 return '>';
, m% E( c* ~* }  w/ q        case '(':
( Q/ G! F* c9 [7 m( [5 U+ g& t             if(c=='+'||c=='-')
5 F! E9 i- e) ^& g) s! k                 return '<';
& e; a. V/ T9 {$ V  |& t' m8 z             else if(c=='*'||c=='/')1 B6 C9 A4 s7 T, D1 [
                 return '<';4 W( _0 f6 n2 X1 T4 f* L4 H. L
             else if(c=='(')9 p8 F$ [1 z- G8 B
                 return '<';4 _7 ]$ @! }; e" R! `6 `' y
             else if(c==')'); G7 ?/ s6 ?( R+ e: Q9 e  I, a
                 return '=';
3 M& s) S- K, }0 I- v, o1 C             else
: f: ^7 O7 o0 s* B) q9 H0 M                 return 'E';
( T& O1 R6 y* {! C3 b: ^        case ')':
! m3 n. F: r# N             if(c=='+'||c=='-')6 q& l$ p9 p& P- S: }- m8 N
                 return '>';8 j2 f3 p4 y0 ~" F5 r0 a
             else if(c=='*'||c=='/')
2 ]4 ]* D6 J! W$ ?5 T1 n2 H) x                 return '>';1 @2 f+ n- u( t/ j
             else if(c=='(')7 k2 e9 l1 q4 o" _7 X
                 return 'E';% F% v5 v; ~: `, P8 E  V  C9 ?
             else if(c==')')8 p1 V/ ]  Z% m/ g2 q
                 return '>';
4 R3 m# w  @( [! D6 y             else% b, K; Z; {8 o
                 return '>';+ ~) B. @; K* y( S4 V1 E) y1 ?3 t
        case '#':
- p" i+ G( G; f7 E7 m             if(c=='+'||c=='-')
0 z  K7 v+ y$ ^. \% A( F! r6 g4 k                 return '<';0 s/ F% b! w1 q9 _+ L% _
             else if(c=='*'||c=='/')
8 a. l$ P8 q/ r# Y  }/ B) a                 return '<';0 Y/ ]* x  `, \& l% C" f8 }) u
             else if(c=='(')5 e) P' r: j) z) b3 [. W0 N
                 return '<';) W# o- z" Q$ u" h- E! D- W6 @. \! {
             else if(c==')')
! e4 K$ o2 V1 U                 return 'E';
* X7 w0 k( M, s/ O             else& l; Y6 A; u. T% G9 |
                 return '=';. T/ ^$ d/ y* \; n" b/ E
        default:
, g2 |  L. j+ g" ^7 X7 Y4 i             break;
/ e! R' V; r7 \3 s$ c# f    }
1 n& S- ]9 \: c) w" m    return 0;   
& v4 O( |/ J/ s2 K2 ]  ^}
! b# A/ \! `9 e9 f
% e7 B9 D6 P8 lint isOpr(char c)
1 X. \0 o4 `+ z! U6 `5 p( a{. I7 h  S* D3 m
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
, W% i" B" }; D! W8 d1 ]        return 0;
3 H  N% k, M$ M1 q5 T$ `    else
) c+ |/ _+ m+ M        return 1;6 f( y6 F" j8 l9 [' P
}
, A2 ^7 @& r4 G9 d
% C( Z$ ^0 y/ ~$ Pfloat operate(float x, char opr, float y)" L+ K+ N) c0 v
{( n& x2 Y# O4 N! d! J
    float result;
8 Z  n; W# @2 w, p5 j7 C; Y    switch (opr)
3 H. C9 z! i! s( V/ S    {
4 u" v* q) r+ G$ E% v        case '+': / |8 G2 ?" l/ w$ C8 G4 L! _" B* r
             result = x + y;: J* i6 G5 q% m# y' a% g  L- D
             break;6 p0 Q% @1 f& R) w5 e* ?' S/ J" k
        case '-': $ [: \1 n; R/ M& J% m! [4 t
             result = x - y;
& S# u! B/ d0 j9 q# q: m             break;
( p: [4 P- W# Q# M8 W" S        case '*':
/ y5 [- \- K. ^; d             result = x * y;
7 F$ H7 Q0 W! k2 H+ G             break;
9 ~; g. w% A+ B2 J  i6 `, V        case '/': + Y" }7 \6 B/ f6 u
             if (y == 0): e" H) w6 j  T! c( F5 C
             {. g6 _+ F' a+ l' F* r
                printf("Divided by zero!\n");
8 m. K; ^: a, Q6 Y6 v* Q4 K( B                return 0;3 r2 f+ e7 C7 M: \, `% E
             }
' r; C; K/ @' @             else
# y* i; o3 z) E$ H% @: g8 d8 {% v             {4 j8 u0 y1 ^( O& ~( \$ x
                 result = x / y;4 q" R+ ?3 t+ M& e/ H+ Y
                 break;
9 T  P4 @7 w, f# l" h$ r9 [, b             }- {# T* Q, X& n1 J8 }) F% m& ]
       default: 7 b- y4 D% R9 r* B; j$ O, p# q
             printf("Bad Input.\n");
# c) s% r! T6 \' G9 A; Y             return 0;0 z& {* P% s5 g
    }3 q+ H! s& w  M& ^% I8 `6 ?
    return result;8 ]% S$ n/ b( u1 G1 H
}    2 E! u, m2 Z2 V
) ?4 i4 _* a9 e1 a1 z. {
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
( a# J8 L, z1 i$ s2 C{
! m* E1 D% C% P/ M" c5 A) Z+ |    Stack optr,opnd;. _! j$ y5 h* o2 \  c. C0 d/ W. U9 [9 Z
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
% Z8 Z5 o5 \) p4 s* m$ u    char c;
& D$ c, o' z. A/ P) U    char buf[16];
" \2 ?, o8 L0 l4 {    int i=0;
# [! w; p4 z( a8 s" B* r4 O8 |   
6 Q  b  d/ i+ y- z4 P3 P8 I" O- c) Q    InitStack(optr); /*用于寄存运算符*/
* N+ h/ D) L( E; Q/ z    InitStack(opnd); /*用于寄存操作数和计算结果*/
" a3 Q0 R8 f( L, b$ x5 c8 M' @    memset(buf,0,sizeof(buf));; |/ R6 s! L7 m/ `
    . s' m7 c8 m3 t# F1 y' g* @( \
    printf("Enter your expression:");* M, F) c/ P. x2 H
        
) v5 m. U3 e  i    opr_in.ch='#';
! z  n) t/ f+ z, ~* c    Push(optr,opr_in); /*'#'入栈*/
  ?& v. ?+ h" g# E3 a' t! R8 ^' u    GetTop(optr,opr_top);8 C# C) f' J5 L4 c
    c=getchar();
! g/ f9 y1 ?) P" p$ g, f- s: j    while(c!='='||opr_top.ch!='#')2 m9 F6 c; d5 d( H5 p7 ?! I
    {
/ |, \5 l8 j' f. y& e) Q        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
; R0 O+ p2 s$ m        {
/ Z/ T- O( s$ r- t5 \9 x            buf=c;9 z2 E2 I% t4 D2 C8 g
            i++;
9 y5 G$ s. A% x            c=getchar();
3 H4 _( _. l3 y* A  i        }
6 v3 W2 C$ A$ i$ C) A5 p2 j- v        else /*是运算符*/  R$ a* Y* c* d- n8 A% u
        {7 C/ q( v) n6 p* v+ y
            buf='\0';4 [( U# p9 A2 k
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/) T3 `8 K# h3 Q
            {
5 A# v  ?% r4 K8 Y: y                 opn_in.data=(float)atof(buf);! c1 }+ C  L3 R' Y! c  h" Z
                 Push(opnd,opn_in);
+ L6 O& s; z- E                 printf("opnd入栈:[%f]\n",opn_in.data);
+ X% v' {7 L2 M1 Y* Q- ]                 i=0;
8 G& Z( j$ L9 \2 R/ A0 v+ d                 memset(buf,0,sizeof(buf));
4 s7 v9 L5 n) U' y: }' w: v5 K            }
1 k+ z3 m* A" _5 g: m( _$ k            opr_in.ch=c;
5 ^6 u% Z/ n1 z2 ]% E% h- A! ^            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
3 V3 K. e0 X2 ^0 R7 O            {5 M( o* D4 p5 K7 P# B! ^+ ]
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
1 S' ?2 ^. E- ]% b                     Push(optr,opr_in);9 r0 L& D! c5 {6 \5 O( X
                     printf("optr入栈:[%c]\n",opr_in.ch);
* ]9 X* i% r% A2 p                     c=getchar();
: j, S# ~/ z. k                     break;; C! ^) C; v8 J. V. T- E+ _* O
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/3 S+ ~1 [& w* _7 c
                     Pop(optr,e);
& s1 S6 r" c; F* }* ?' S# H# {2 n                     printf("optr出栈:去掉括号\n");
) B0 W, P  R% Y( |  o                     c=getchar();6 Z4 D  l) g0 x5 M3 g, a
                     break;5 m& D) @9 T0 h
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8 {, i5 W* T3 G$ a! Z
                     Pop(optr,opr_t);
. a* \. `# F. W2 m: X                     printf("optr出栈:[%c]\n",opr_t.ch);
/ J2 `6 I5 k. ^                     if(Pop(opnd,b)<0)6 \: b& d& k# P) X( }1 k
                     {
9 A0 a5 N2 e* z' p6 ^; O2 C                         printf("Bad Input!\n");
! K4 C) Y0 K4 D2 z1 }0 L9 H% U                         fflush(stdin);9 d7 k& l# F" w
                         return -1;
$ c' A$ Z* k! S9 Q0 J7 O2 u                     }, |' h0 q0 f- O! C" u8 [( `" K
                     printf("opnd出栈:[%f]\n",b.data);
* B3 s3 M8 G5 q6 s0 b4 [. y* G                     if(Pop(opnd,a)<0)0 a" {0 G* m9 l& G
                     {
, N4 L# m6 j" C6 w7 y. L                         printf("Bad Input!\n");$ D, K& G" [5 R1 y" p1 Z
                         fflush(stdin);8 a3 q: w. @3 e) p/ m
                         return -1;
" k1 h" e# E" \6 a& w                     }5 h! y! t+ j+ p
                     printf("opnd出栈:[%f]\n",a.data);
+ ^6 U  y) \' F* e" l* O5 q+ E: K                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
" z1 _5 {1 q& Y+ N, d                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
" M' Q" `1 w. v; M: `* q                     printf("结果入栈:[%f]\n",opn_tmp.data);3 P. g: g, e) `8 f
                     break;
! A: q$ m6 I5 C            }1 q  j( I$ ~2 `
        }2 l7 c, ~$ ?5 ]8 Z) J4 g9 i( }  r
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                3 W# R% c2 T( x. r# e, K
    }0 g1 e! N" @8 v3 s3 y& k
    GetTop(opnd,opn_tmp);
  V4 w+ O; f$ g; q/ }3 E    DestroyStack(optr);% {! x$ t, x& Q5 h' \
    DestroyStack(opnd);8 y" Q% h; \7 u% L" o% V0 h
    return opn_tmp.data;# [, G* t, i! l' o4 v
}
# w" j7 l8 [" n  A7 _. e/ n
) e. a7 A9 a' Z% t  k" I6 kchar *killzero(char *res,float result)
# a6 ^8 O+ {7 M) f+ E! p3 Z{; ]8 i* j0 A2 F% B5 T9 x/ K
    int i;
* F) a; B2 x& c
9 L+ |9 B7 l4 K7 F0 {; p    sprintf(res,"%f",result);/ P. j- t$ F4 |5 t' `  a! U
    i=(int)strlen(res)-1;; F/ V* ^0 n- D) L; T3 W% F5 B
    while(i&&res=='0')
/ G, O  |7 p& w' H$ k* S0 b7 i# ~    {/ W& F2 @6 l: I7 p
        res='\0';
& M' C% @1 S; I: Z% Y9 n# W- j        i--;
4 \& J4 R& p7 P    }+ e, V' `. o, K6 u; M8 {
    if(res=='.')8 U, Q! f' h& q' A) F# W0 P
        res='\0';
% l% u+ V& T, V) M2 F, |$ q    return res;
* |2 j% k5 p' s6 i, k}
2 y* g, F8 w- h3 A; L9 w, T5 F/ r8 |! T/ S
int main()* c, n3 r4 T0 v, ^: Y; N
{: R) Z& M+ P( |, `
    char ch;. V8 b. g2 P0 j+ e
    char res[64];) D. ]( g1 A* D) w( d- u& j
    float result;
& X: t4 ~/ x7 L) Z# U    while(1)2 p4 k* I: ^0 f$ a) `
    {+ s( n3 p6 k1 p2 q7 D- k! `4 k
        result=compute();: e/ m1 @4 L$ M, |" e
        printf("\nThe result is:%s\n",killzero(res,result));
, h: n& r, _; x! t$ ?& Z( i2 d' A5 }        printf("Do you want to continue(y/n)?:") ;
# ?) W& N* R: `  \7 l& }        ch=getch();- X: n, f$ k+ v. J& K4 j
        putchar(ch);' J3 A* n4 T7 u! H
        if(ch=='n'||ch=='N')
# E  `$ T! l' Q* x# ?            break;
) r0 }' Y9 N) U        else
6 U7 g+ o5 e2 Y, W- ?5 Z* b2 p# n0 s            system("cls");
$ S4 c* v) u7 t    }% x5 A! `  A0 o, O
    return 0;
) n+ d$ A- }) P3 p}

& o( c) f3 @: o0 C+ H- @, S5 N5 z  I. \5 b/ }/ r
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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