返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.7 j; C) e7 a: w, _/ K9 e4 h
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=7 W- a! h3 D# o- f9 {
/**************表达式计算器************/
4 F% C4 o; m$ l#include <stdio.h>
5 |* K% i# e0 f# C#include <stdlib.h>
% t& _$ Y$ ~/ C" S, Z#include <string.h>4 m/ _8 `# o: w" i( d
#include <conio.h>' x3 [. g5 q$ V5 @
#include <malloc.h>0 C' f: l; o) R2 N0 b0 y
/ _0 i$ b2 }, s; y) U9 n5 ?' S
#define STACK_SIZE 100
$ R& T! E$ U5 L5 \- ?' z* T% e#define APPEND_SIZE 10
: V+ r9 F/ `# @6 E
6 g# i, j& y# L, o; y3 Nstruct SNode{2 V2 _; [2 F7 W" `+ U8 k
    float data; /*存放操作数或者计算结果*/1 \  |3 h; p3 W! v! r% H% L+ T
    char ch; /*存放运算符*/  ?. j" d. E: J$ o, H
};
# j8 e* u& a. Y7 _0 L. m; U; Q7 \& C7 s, s8 j
struct Stack{
( b5 P4 A% D0 J6 Q+ z    SNode *top;
) t' A. ~7 E# A1 u- `    SNode *base;9 t& a3 z& I' W6 m$ d
    int size;9 j" m' O; f/ N; R+ P
};
7 d6 f, S! c  v- \: h0 _% M. m
9 c: K2 N& p! ]8 T1 s# C/*栈操作函数*/
4 C) c. i" l2 c# m1 [int InitStack(Stack &S); /*创建栈*/
/ ?  ~% m; d0 s( W& [* `" B8 Gint DestroyStack(Stack &S); /*销毁栈*/
5 d: N" U( j5 _8 zint ClearStack(Stack &S); /*清空栈*/- Y& y% v1 [6 M9 [7 k: R% C7 T
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/* R% _1 e5 @" K- a" f
int Push(Stack &S,SNode e); /*将结点e压入栈*/- m; ?0 |) S2 u* L/ z& l5 C( M
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/; h; M. I: ?+ S7 q/ B9 O
7 |9 ^- T& H' y6 g6 v' v: `
/*表达式计算器相关函数*/! J6 X8 Z+ [) x  e: k8 N3 F0 `5 @3 H
char get_precede(char s,char c); /*判断运算符s和c的优先级*/  Z5 }0 B% ^9 z* o3 X' {
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/( E4 U  \1 @5 U& h4 z
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
' g/ U& a9 s% [4 K) j0 y8 I2 R3 afloat compute(); /*表达式结算器主函数*/
! R, ^; b9 D6 ^9 ~0 {( G& u! \% @char *killzero(float result); /*去掉结果后面的0*/ ; x1 e- r7 ?6 k
0 H5 Z2 p; x$ I  S6 H4 A9 R
int InitStack(Stack &S)
0 d0 V( W- K- U/ ^' Y( e: \{
# H. r, w* n8 G7 s    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
! n0 h3 b. {# q    if(S.base==NULL)
$ t6 t& k0 ]/ |6 Z# X1 _    {
: r$ B9 P1 s$ r2 e9 O        printf("动态分配内存失败!");) I1 j3 G/ B9 h1 D
        return -1;+ W0 S6 B5 n/ s9 x
    }2 h  @6 n+ R8 a' [, q( ~9 Y3 D
    S.top=S.base;
8 c# k, _0 z6 M8 f% Y# q) x6 e; m    S.size=STACK_SIZE;; W% s; S6 l6 h5 x5 N
    return 0;. @( Y; }) `$ J
}
7 s* I7 b, q( X4 L$ C8 B, M; l% w7 H" i0 i3 f4 a8 \
int DestroyStack(Stack &S)8 S. Y  a* m  [6 I: Z
{
$ \; z1 u* o, P0 O    free(S.base);% \, P( V; w# ?, j2 a' D; E
    return 0;
5 c( _5 P; p. j}
. `; Q9 a# H/ O+ I2 K  }
7 @! w) p& T9 N, t3 U; tint ClearStack(Stack &S)
: x, {+ B5 n1 n( H5 _! p* t{
( c8 `+ A( h+ H  p% v5 J0 u. B    S.top=S.base;
; M* o+ g0 d7 k! Z" ?0 x' \( _    return 0;
) [- @8 Q& o* s" ~, z, s* r}
5 s" p1 I8 k6 f. e/ ~% F  C7 Y5 E0 a9 b1 `7 ?
int GetTop(Stack S,SNode &e)
2 e9 Q& [, U; n& Z1 Q  n{
: Y% b' c1 |% d    if(S.top==S.base)
$ Y# C5 W: _# m1 {  R    {2 z/ z6 \( O, S" d, s+ l
        printf("栈以为空!");) d) y4 R, P. h4 V( x. j6 I$ M) U/ L
        return -1;
. k  P" l- y4 e$ R' w$ u& E    }, ]* r: T2 _5 v: }9 |( Y' s+ J
    e=*(S.top-1);
6 L1 Y: ~4 e, Y' z' t, g$ ]* T* u    return 0;
$ Y4 D& l" W' O. `" z, F$ W  R}. v( j  S/ q# L9 R. s9 O
  h# ^# S' M: a( d- ?( V4 A
int Push(Stack &S,SNode e)# N, O; n' s' U9 r$ Z
{4 y! s5 V2 I. g# u, `0 Y: G
    if(S.top-S.base>=S.size)  H  h# Q2 F* g" I: m) m& Z3 j  \1 t; g
    {
! ?) p  n$ ], p. |- V, D        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
& V& p: `1 @$ B9 g' m" h; k        if(S.base==NULL)# {6 _/ H: J( ]* {5 k
        {+ m4 S' Q, X/ j
            printf("动态分配内存失败!");
9 M1 [* C3 X7 w3 i  b! b* F            return -1;
2 w2 F) E% S& Q0 k# k$ k8 {        }
2 |- l% a& K+ b        S.top=S.base+S.size;
( I0 R  p# }. l& B        S.size+=APPEND_SIZE;) O6 i- @  l& J  ^. C7 K
    }
6 `* G$ u& _: u5 O    *S.top=e;7 o2 d8 {/ J" Z9 j, e% R
    S.top++;' C5 ~5 |- M7 D. ]) o
    return 0;
' g& J. K$ S" m- e' w# o}
9 @% ?, w& l; o( P- O
5 u- L0 ~. r  u* D; ]int Pop(Stack &S,SNode &e)  V: n0 A9 K, m- u4 L( {+ z
{
; _- b7 B4 Q5 M8 k! ?9 }; z. v    if(S.top==S.base)
  H: A2 d9 k4 _    {
6 D- g$ Q, X  ]        printf("栈为空!");
+ i  I7 S; V$ W2 M8 H        return -1;" m1 l' C7 ~3 m, D  U
    }
5 \) S# H- G+ w' g3 o    e=*(S.top-1);/ n5 W# C& l, b; ?% v1 J  ?
    S.top--;: m; }2 R( u$ R7 F; b$ ]& }' S
    return 0;
/ Z5 t3 W" H! ~8 X: a}, L8 Y2 I* ?! i3 ]# \8 ?0 O

  Q% c& Q$ I0 U) Qchar get_precede(char s,char c)* i7 ]( ]1 I, E
{
3 w( G( e5 u( ^; H    switch(s)/ P9 I2 b$ K5 G4 V' H4 a! E0 q
    {
0 I+ A. \( N$ w0 p        case '+':                 
3 {! n9 v. Y( e8 V        case '-':+ ], `" M/ d4 N) \7 H' A" e
             if(c=='+'||c=='-')
, `6 K$ l# N9 m# t4 t) E5 {                 return '>';: i8 |" |' C2 v' k. D; z
             else if(c=='*'||c=='/')+ S" ?* d; }$ j+ ~
                 return '<';4 G: f: k9 U, U. \: _$ P: j0 }  \+ u
             else if(c=='(')% d" [* s! \# X7 h! K
                 return '<';6 Y( e  {; u4 c3 H. l4 Q! G! i
             else if(c==')')
& o# E5 @5 G$ a" U! V2 F                 return '>';7 C& ]) x* x: o3 @. m
             else # A- k3 ?0 x: O
                 return '>';9 f0 t5 M/ w" f# a' ^+ E9 {7 Z
        case '*':+ ]; `' f3 h0 K; N' S+ ~
        case '/':
1 m! W. q; \. P0 d7 I. `/ U             if(c=='+'||c=='-')
6 v: `$ k6 V+ D/ _                 return '>';
- e0 T3 C6 E" a6 y! D             else if(c=='*'||c=='/')
. @5 ]: X7 {* L: h                 return '>';8 d4 F+ M9 c) U) V
             else if(c=='(')3 n5 l1 J( H/ H
                 return '<';$ r. P) I3 u3 P2 D+ p- h, L1 \
             else if(c==')'); T$ F4 |0 Q: u: O9 U
                 return '>';& h3 E! _  t2 t! g5 |  g7 Z
             else
; [5 i0 U0 j6 `# [! p                 return '>';
4 }* s2 h9 u) M6 g! B3 y        case '(':
5 B& h0 i1 r4 `+ a             if(c=='+'||c=='-')
) w6 I4 H" t8 g) R' W5 X                 return '<';
, Y' @2 w5 ?" f' ?* D: R" s             else if(c=='*'||c=='/')
  \; g* a4 E8 G/ g; |  s                 return '<';0 m& Y: d* H- x; r
             else if(c=='(')
6 Y" f4 ?/ {7 D0 W7 x( _                 return '<';6 O) r$ u0 b- {0 m9 T0 U8 B' z
             else if(c==')')9 g# U: m: T5 \5 \) K7 V8 u
                 return '=';
$ i- z3 ]1 m) {4 H5 r& {- D" @             else
( R& y  W* N9 D3 b; X, U. B                 return 'E';) u; F( H1 R1 B6 S5 Z( y
        case ')':7 p8 j( V8 T7 N- A
             if(c=='+'||c=='-')" L9 z- z9 i9 T  I" P" ~  |
                 return '>';1 k% i4 V& Q9 Y0 l/ e# d
             else if(c=='*'||c=='/'): v9 h# m$ x6 Z
                 return '>';
3 C; b+ P( [  e2 p, z  o# {0 ]" X             else if(c=='(')
& c8 O# K9 U9 p- C8 t( E$ b% i0 R                 return 'E';
) P/ t" o$ R2 ~& G             else if(c==')')9 f, ^: W# F9 o2 B
                 return '>';
0 C! q; O+ P0 T6 `# c, ^- Z5 o% T             else
% n: y$ N( v5 ?6 X                 return '>';
5 y* e( ~! h& f        case '#':
$ }( Q; Y* ^( n- B& u             if(c=='+'||c=='-')8 Y2 d6 E8 b+ n
                 return '<';
# N6 e) g( t  F  E0 I, W             else if(c=='*'||c=='/')0 H' ^" ~! Q' e4 r# W* E# p
                 return '<';3 y5 ~, ]$ U; N# y) J
             else if(c=='(')
  A7 q4 I0 x  E1 n# `* M                 return '<';, x4 h, O' Z* c/ x% o8 R
             else if(c==')'); i% h- Y8 X* Z- |
                 return 'E';; [7 A. a3 g" t# n3 g8 f
             else, ~0 h; _. ]/ V) f
                 return '=';
) O! P% G3 J' e6 J* c# ^        default:
( l6 g. c$ D  A0 R1 M% X             break;3 g0 }0 T% k: [% F% [7 t5 K" E
    }/ {! Y& ^( T' A
    return 0;    ' `" p$ m+ Z, s7 g
}$ ]! x4 |6 O: e) W5 ~9 g, O! \
9 A* z: S$ o5 [' @9 i2 \
int isOpr(char c)+ e/ r. S" k0 p7 e, l5 G
{, ^) U4 E1 a& J- D, i6 `$ j% Z
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
* `: K. }1 I2 U. h" Q* H! N        return 0;
6 z" V1 n. d6 H3 R$ c4 p9 Y* m    else 0 ?$ w% C; q+ M9 J5 t) a9 T
        return 1;
' |' k3 W8 X  {2 L}
. B. l+ x0 H+ i7 {0 U* k5 b+ `
0 B) A& e4 v5 M( |% efloat operate(float x, char opr, float y)
0 V4 |  m2 w) M{
* K/ ]  p, o- D* f" c; e8 _    float result;* h  P+ S) [. \( c
    switch (opr)
, L" _- D/ `2 D/ l    {: {1 b% C/ r* w8 b; n
        case '+': - L0 P) c4 Y) e) x6 [' e# B
             result = x + y;8 l0 Q5 W# O8 d9 e$ ?2 ^7 O3 G
             break;, r! I8 E& T. V: _
        case '-':
2 _! N$ j( c4 C# `; p             result = x - y;2 _! P! q; f, Z* W' D
             break;" T5 q* f8 L; q- W% C. ?* d8 M
        case '*':
3 p  K8 M9 O# ~: B0 [9 ?' X- y             result = x * y;
- A( S6 T9 J  O2 e; |             break;
: Y' u! Y: l1 E, K' V        case '/': * j9 |1 x& Q& V5 H
             if (y == 0)
$ ?" l* h# q- z, f% y             {
: n) v! ?) b# S; ?- a+ p3 s+ g                printf("Divided by zero!\n");! w4 F% a: O9 `; `2 n8 s
                return 0;/ j: f5 X( R/ ?% }  H2 e
             }6 A, y7 w/ c- l( T
             else
5 o) ?5 G+ G/ g" i+ T( U  I+ x             {
4 \/ W+ {% C9 `. Q                 result = x / y;
  S, D& I) v' p" R% f/ K) S$ |6 x                 break;
( H" Z1 E! t! F2 g! x, l             }
& |8 a' B9 Q2 K; \2 O       default:
5 _' G+ z4 I& k& g: J  e             printf("Bad Input.\n");
  b% u% p. V' d7 y             return 0;3 w) |3 z  ^0 o( ]6 x
    }6 Y7 L2 d' D! N' X
    return result;; v* z0 a% M8 q; P, L
}    * s; Q% z5 `1 r+ w
# v/ q6 k+ z0 x/ U
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/4 c& J" p% ~- U2 k# y3 f' P; w
{
9 g& s* \# r7 U, L3 \, q# F4 W    Stack optr,opnd;
8 u. N: y+ U% B9 G, ^    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;& B  f4 L- \% L1 i3 g5 Q- A1 ~
    char c;  J  `0 j3 ]% q
    char buf[16];4 u" ~; m; I, `
    int i=0;. V' p) A' n) [3 X& G  p6 m
    ; b8 R2 K  V) j) T  E- S
    InitStack(optr); /*用于寄存运算符*/. h% @2 o% [: j! |% ~
    InitStack(opnd); /*用于寄存操作数和计算结果*/  e4 k5 C. L( H7 d
    memset(buf,0,sizeof(buf));( G5 U; M( e8 g! `( `  O$ h- y* U
   
# O' |, Y/ t, D* U    printf("Enter your expression:");: M3 `( S3 j8 u! {9 O; \8 O
        
2 I8 S. |  e% Z3 A    opr_in.ch='#';5 M  I% I6 f0 X# m6 S
    Push(optr,opr_in); /*'#'入栈*/
- a$ s1 P2 p% j7 w! [6 ~    GetTop(optr,opr_top);
9 @3 T% W% ]) C    c=getchar();- _. E  [' U, h
    while(c!='='||opr_top.ch!='#')
6 r. K. w2 h2 `% J/ x9 W    {2 N/ ^8 o# s- `4 h+ F  y
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
& m/ Z2 m9 P% s6 R% R        {; Y/ `* w% l$ L9 }' W
            buf=c;0 `" x9 C4 W( c' p1 I& z
            i++;1 c1 Q/ l, ^; }, j# o9 D
            c=getchar();+ U. Y- M* A3 t& Y$ Y. E- U+ |
        }* j: C  `% d. o
        else /*是运算符*/
& j, S% p0 Y5 C( T        {
% x8 y; {0 g" Q8 h1 f            buf='\0';
# ]; P" {! p8 L9 l' g            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/1 P- s, x* R+ X7 }! {' M
            {4 Z$ p: c& d1 I& ?% Y
                 opn_in.data=(float)atof(buf);
. w9 _# I& ^; x& k' x                 Push(opnd,opn_in);- G4 b, q  Z, ~) Z. K7 z! \
                 printf("opnd入栈:[%f]\n",opn_in.data);% a1 @* m( P9 \1 q
                 i=0;
" `3 z+ j- S7 s; u                 memset(buf,0,sizeof(buf));) n# X1 s  J- i( d4 ?. [9 f! O
            }$ Y; O0 C7 ?! W& y. [- z4 |; S
            opr_in.ch=c;3 o# z; i+ x  N+ D1 `
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
, {9 S8 b4 V- K, J6 Q7 Q/ x4 d            {# d, L& z( x, V# E3 `. {7 {
                case '<': /*优先级小于栈顶结点,则运算符入栈*/. d9 p8 [2 Q1 o/ J3 d/ E0 M. [
                     Push(optr,opr_in);/ x4 p7 f! G* v  A8 o
                     printf("optr入栈:[%c]\n",opr_in.ch);( c) z8 ?2 J2 _( H" x6 H' @
                     c=getchar();
- S( l; {3 i" h" n9 }                     break;, S; G+ L- u: `8 B4 K
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/; e) {$ g/ J3 L# z2 z( l# Z
                     Pop(optr,e);
( R* u- N/ r/ |$ s1 s2 s- S                     printf("optr出栈:去掉括号\n");! _; e& q2 X* I/ E! B% x% o; f
                     c=getchar();
1 B! e% P# c9 L, m                     break;
; c2 b. Z4 j& ]6 ]0 c0 Z) Y                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
4 D4 Z/ v# U& @4 p                     Pop(optr,opr_t);
9 X( H+ j; w) x; {) h' w5 P                     printf("optr出栈:[%c]\n",opr_t.ch);
! g" d( Q. [6 Y1 B                     if(Pop(opnd,b)<0)- g$ |8 P" y0 |7 V& \
                     {+ o- m4 w0 e2 X. k
                         printf("Bad Input!\n");& c! ]6 I) F+ C3 x+ J. b; M
                         fflush(stdin);
* H( u: l9 J/ W. V7 e5 n2 G                         return -1;% H+ l8 A5 o6 K$ {5 q
                     }8 |  V# Q5 A6 d
                     printf("opnd出栈:[%f]\n",b.data);
1 K( \. S8 S" t6 Y" l                     if(Pop(opnd,a)<0)1 j$ ?/ q- T2 @
                     {
% K. W* w7 e, a' I5 n* z                         printf("Bad Input!\n");9 |: j  T3 [" \2 Q' X% w
                         fflush(stdin);: R1 y; b; I1 `/ Q
                         return -1;
4 G. m3 ?2 s- A: i, s. u* q                     }
9 ?, r  K3 M5 C, Q8 w* m8 V                     printf("opnd出栈:[%f]\n",a.data);( W/ `/ g& x: g% O9 y: S
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
" u. x1 S& H: r" Y& [# X, Y8 x                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*// @  R( N% f6 Y/ ~2 {
                     printf("结果入栈:[%f]\n",opn_tmp.data);8 J$ q2 W; ~: L% r, g4 H6 ?
                     break;; L8 a3 S1 q. i  f& A
            }. g/ L) [! e$ [. ]4 n9 b
        }  N, }4 S- R$ ^+ M, T. ~. l5 ^- T
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                $ p1 J3 }5 Z' y
    }9 ?, U) b0 Y/ t' }/ R9 a* K
    GetTop(opnd,opn_tmp);
* U9 c% W9 L1 p% O) ?    DestroyStack(optr);- Z6 C  O! O7 f. q% p
    DestroyStack(opnd);1 N# d2 M8 x6 ?7 `9 R$ _
    return opn_tmp.data;7 ]/ c+ \9 I; m( ^/ ^% ~
}; {" Q! z1 o8 `% O1 Q

( y. f, l9 R& S+ g1 u  D+ rchar *killzero(char *res,float result)9 o  z2 j% R- `+ t) V3 M
{
4 Q4 v0 T- d% G" R$ |- j    int i;
6 V( u- G; @) \* m3 m8 S
1 F3 m- s8 l7 Q9 v    sprintf(res,"%f",result);
% w5 I3 k( r. i  t    i=(int)strlen(res)-1;
5 P9 w" M+ x, }+ G( a    while(i&&res=='0')
8 |* ?/ e8 c4 V2 [    {
# R" N( S( n$ w9 A! H3 p        res='\0';! }, `9 K' N, L/ i$ r) m7 Z
        i--;
+ K! D9 J' y$ `6 E9 L. |' L. [    }1 }/ A* V( ?, p: z8 |% z/ J( P
    if(res=='.')
: L: U4 l" w7 L" }* |- d) T        res='\0';
% X9 k! x% X( _7 x- x  {& e    return res;9 ?  {. V' g  ?% l
}
+ H3 A5 A9 X: R$ [6 O3 k) x7 y+ V% B2 t- D- q* P
int main()* o' [( R. u1 W2 {7 C- Y
{8 i- l* P" R& M2 [# H8 B: V+ l
    char ch;, ~$ M0 w4 `, ?1 p6 H/ s$ D
    char res[64];0 u1 w6 z. Z7 r( z. h
    float result;, B8 R  A  a! y+ l
    while(1)
  h" ?1 g/ e6 |6 `% }    {& @& i- V' l& v7 {( P' ^6 ^* T, {
        result=compute();3 S( d5 v; T& C' b. r
        printf("\nThe result is:%s\n",killzero(res,result));
5 z' B; T7 J7 Z* O2 f        printf("Do you want to continue(y/n)?:") ;
: i9 x! ?4 k1 B4 C- f, v! k        ch=getch();
8 Z' h, H9 D# O5 B        putchar(ch);' W1 t, I. y" @5 o
        if(ch=='n'||ch=='N'); J, c. ]" }& `/ n; x6 j* K
            break;
/ x+ G$ S1 X4 c8 G( ^" X# U8 w        else
- d' `, h( y! R: b2 q$ K1 }            system("cls");
% s: i$ g" r, y, Y$ I, g& ^    }& f$ }3 ?! ]; u. j; t& y1 o! |+ z) Y# ^
    return 0;
% H& A0 f6 L; |* W3 t2 X}

% A; ^3 L  `( W. r! j! f" E! d8 y9 ?; ?- T/ n3 R5 I& r1 o. d' ]/ y
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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