返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.- F: J" [" a) R$ O- v# A. e; }
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
. X, z' F0 u/ j' y7 p/**************表达式计算器************/! D- v0 k6 d4 o- `3 M7 s7 X
#include <stdio.h>
% i4 F; Z& @8 `4 {! P#include <stdlib.h>
+ u/ s5 i4 N$ }: f: y: f7 o#include <string.h>- ]3 ]' D3 }4 _& X0 q3 Y
#include <conio.h>$ \) u  x' z; i: @
#include <malloc.h>; N5 X# f; u9 R% k* h% k. P

8 `' F* d% J8 P6 o#define STACK_SIZE 100' |2 O0 M4 A2 l! p' m
#define APPEND_SIZE 10
! {3 p  T8 J) f. x* G% ~
: g* o% z- N8 f. |0 _struct SNode{
% G; p* x7 e) m3 \    float data; /*存放操作数或者计算结果*/" S6 F1 f, G4 x# E0 U9 p
    char ch; /*存放运算符*/
3 c6 ~7 Z( K2 y};
1 Y' g% F% G/ t/ x7 i/ Q7 U" \2 H  i# Z/ o6 ?( P9 w
struct Stack{
0 ^+ X2 i; L+ A    SNode *top;5 A' G: h9 l, _& w$ [- D; L- B
    SNode *base;
& J, C0 N4 A* X4 ~6 R; i" g0 M    int size;, W: `& Q" @" }# `) e$ h: K
};
' w' g# Z0 f, K6 K: G. c# f7 f! M) K0 m
/*栈操作函数*/
" a6 |% c' j* M, R3 j& {  Tint InitStack(Stack &S); /*创建栈*/9 q3 _  F! k1 U- P9 A
int DestroyStack(Stack &S); /*销毁栈*/# a3 w; v2 m  s) S% P, `
int ClearStack(Stack &S); /*清空栈*/
3 C2 |) U2 F4 H! d% E! Aint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/" \. n' ^: e: `- U! m- n7 J
int Push(Stack &S,SNode e); /*将结点e压入栈*/
4 a' ^( G4 o, E9 A, p0 x6 Lint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ \8 @( {" K0 _. G7 C) ?/ v- a5 z4 v
/*表达式计算器相关函数*/# W0 [5 |/ k/ P0 X1 l1 N3 P8 h
char get_precede(char s,char c); /*判断运算符s和c的优先级*/5 X; j& s% I$ F: ~, a
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/# z' ?* f5 J: A' n, {
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
0 l5 n5 C" H4 x  B" Rfloat compute(); /*表达式结算器主函数*/
. e  d+ j( d7 e6 o; C5 O/ Cchar *killzero(float result); /*去掉结果后面的0*/ # ~0 N6 J$ f: l4 w" Y5 R
) p0 g% d; [, [$ {' v+ h. F
int InitStack(Stack &S); F: `! T, c" Z4 l4 q9 h- d
{, [4 X5 y3 P5 N3 L1 _% V* o
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+ m6 X- ~  H( @0 z) j    if(S.base==NULL)
4 V* j; e+ g4 }. z4 ~! M    {
  m" P' r' u" @* F) D( P        printf("动态分配内存失败!");* s: h! J7 S9 |; B. }4 Z2 E& G
        return -1;. I6 D& T) h. G
    }
6 S* n0 ^2 z9 v( q3 ^0 O* R    S.top=S.base;3 l5 R) M3 S7 A: r# f
    S.size=STACK_SIZE;) m  \: v  H' L* ]3 l
    return 0;) G1 l2 j$ S: @! ?7 f8 p
}
7 K6 A. v* N, S% W$ \3 J
8 O! L; }/ w# M1 J' h  {7 @int DestroyStack(Stack &S)1 T) ?" i* d  y! W8 ]' d2 C
{
, K4 }" i2 x* ^! c7 r    free(S.base);
! F6 F! S6 v. E8 U# [    return 0;
! M9 X' v* [( G' }/ p6 z) I}
  D0 q2 T8 m  P4 M) N% [6 h) O8 o9 a: p. V1 m; @% z* W  M( [
int ClearStack(Stack &S)6 V5 X; l' i6 n; R( x
{0 s/ E0 S# b. @6 {
    S.top=S.base;) H7 a+ o9 P/ e; k# Y
    return 0;
  x% U: h" f4 W( r8 b1 o; h7 R}6 P3 w; |) A" b2 C' s
9 ?# b8 g& }1 c# {7 l: g2 R
int GetTop(Stack S,SNode &e)
  ~& G. }8 p- N% L: o{
: S& g3 j4 M/ h/ M% `5 @" I7 e    if(S.top==S.base)
  X( `4 m. n; z. x7 G9 a; X    {
; f. b% m- G: R0 r" R" a) T        printf("栈以为空!");
! P9 w  h6 J# J+ G        return -1;
( Q$ A( f9 t9 b, Z7 L" U. c    }
- D. ^; b- ~% J6 ^$ O; e$ s6 r    e=*(S.top-1);- h8 {; `* _1 `& Q* M' ~9 r
    return 0;
" q9 r' `0 e, A& Y}5 D) D) \, |0 F( ]: Z

: c! `9 m) y) ^int Push(Stack &S,SNode e)+ K' ^/ c4 u2 k4 O1 Q0 O, I
{0 z; B6 c$ [0 @' O2 |
    if(S.top-S.base>=S.size)
, l9 P; Q5 w1 R/ _    {$ D0 P/ s  t9 t' \5 W1 x# \
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));' z6 i3 K0 J* S; o7 \# i
        if(S.base==NULL)3 T: R' U5 L# }; p2 S
        {- s+ d- V; ]( ?! L) W
            printf("动态分配内存失败!");0 k; \0 i8 X' ]* Y
            return -1;  u5 Y4 T  ]! v4 q1 ?( ^
        }. J3 q4 R0 T- e
        S.top=S.base+S.size;1 z: ]9 P9 P# J/ o, C
        S.size+=APPEND_SIZE;+ z! p4 B0 k$ R  t' i1 t' Q
    }
$ X1 t9 ~$ j) e, j    *S.top=e;- L3 D0 _- m( K
    S.top++;
7 J& E. E9 e1 c) ?9 Z    return 0;* q4 ]/ `2 l' J6 F" u0 e
}
+ @* D# [" C' l* i4 U# _% M/ {9 v) V, H* w' L% N0 z
int Pop(Stack &S,SNode &e)4 A/ ~9 K& i7 I8 c% E3 f& H8 D' H
{
' b; ~3 p4 I( G& [    if(S.top==S.base). I# z: ^8 U/ C- E# I
    {
( \! J4 R# X' O7 A" H4 D5 v  u) M        printf("栈为空!");* i4 m1 `5 S  Y; }$ M. F$ }/ w  v
        return -1;
3 a3 k& C" K- _# O' c) M+ l    }
& ]" k& n3 w3 c7 J5 {3 o( |    e=*(S.top-1);
% Y$ P9 j# g# T; l    S.top--;0 l8 Z, {' q. D% y( e$ O
    return 0;  Q' }& i4 y0 u$ ]6 G# K
}
# t2 K3 H% a5 i' T# v9 V6 Q  E7 Q$ A6 W/ j
char get_precede(char s,char c)
9 _; E' N+ X9 D3 G5 ^4 h' K{
6 E5 l/ H9 }1 S5 D% h- f    switch(s)  H. n* L6 f' f! G& X6 z
    {+ \: I. A+ F9 {& Y0 B1 }
        case '+':                 
) {# L2 ~4 x' Z. q! l( [6 n& {        case '-':
' i, A- J. b; ]; J% w# a             if(c=='+'||c=='-')
! {0 U% k  F0 Q6 I3 B                 return '>';% R3 \' j1 w' B  ~0 _9 q
             else if(c=='*'||c=='/')
: |6 x! }% l* v1 a                 return '<';
; X5 _% q  I; ^' M- s/ b' U             else if(c=='(')6 {! J$ ]+ g' T! C( E1 [
                 return '<';$ t' N$ n( Y8 q. n
             else if(c==')')
  Z( `: f. i4 O( R' l                 return '>';
9 ^; X  P7 \9 L- F1 P             else
' f0 P% H) b2 L3 t2 P, O2 ]9 d                 return '>';$ z7 f' J% u& v) \& t7 l/ T4 q
        case '*':
  `; u  n3 z$ `  q+ z$ t9 M; ?; ^; h        case '/':
( V3 E# p: K  z$ D+ L$ s2 B+ z) S  z             if(c=='+'||c=='-')
4 j' A" |# Q! h. v; G/ ^                 return '>';
( `/ o; N8 E! G) U: S! B5 h             else if(c=='*'||c=='/')
( P7 a6 ?3 ]) X2 {$ _# j! A! ^- I                 return '>';) A" a  m0 {' N4 ^- [& m: f8 x
             else if(c=='('), \$ x  [7 `. A6 }. p
                 return '<';) c: O' z2 O: A$ V4 a
             else if(c==')')
4 G/ Z5 N5 M/ N# b" y                 return '>';
* V7 x) `' R1 K. W) c& z             else2 S2 K# U# ?- D3 ?3 a7 ~! e
                 return '>';' a' U% B" M- [7 @0 C* F7 ~
        case '(':3 o+ j5 v  n: L) x
             if(c=='+'||c=='-')7 X5 d6 z6 j! l- ^/ O4 V
                 return '<';
/ J% J; K8 G3 B0 V0 S             else if(c=='*'||c=='/'). x6 l% K2 p6 r6 W# q8 r% [
                 return '<';
. ?5 R2 U: ]4 v5 P" v  k* E6 u3 }             else if(c=='(')0 X  V9 G+ g$ k+ p5 z$ N
                 return '<';  t9 r, O& p9 s/ n1 T; `
             else if(c==')')' Y  J: l  V" k; q. I1 u
                 return '=';
% p) E; [0 h, \/ A( T9 S5 t6 M$ R             else" u" f4 e- ]4 E+ i; p1 x" Y4 o+ h
                 return 'E';
* H1 M7 g4 ]+ r1 M0 e        case ')':
+ p: j( P( \0 Y$ E5 q" a7 d9 ^             if(c=='+'||c=='-')
6 w9 O) g, U3 Q                 return '>';
  S& c1 T; @- I2 @# [             else if(c=='*'||c=='/')
6 m$ r3 n+ `: ^# J3 B                 return '>';0 e! p* Y9 f/ H* k+ s0 u; z+ s, E" k
             else if(c=='(')
4 D# ?! s8 y0 D                 return 'E';
$ e  Y% P0 @9 d4 o$ {3 a             else if(c==')')
) J6 R2 r: r- T* e) U                 return '>';  `, K: [4 ]" h
             else- e8 a8 c# G: H) z
                 return '>';) i) D9 e' i2 n# E) c1 a' A/ e
        case '#':
: i! C' Q1 ]; \             if(c=='+'||c=='-')) @0 {. d; Z2 C$ z8 z
                 return '<';
" `/ I( n" k3 V7 Q             else if(c=='*'||c=='/')+ [4 o$ s% U+ l% D% `
                 return '<';7 P  G+ V% l# v7 T$ z
             else if(c=='(')
: _+ L- k' f% S9 S                 return '<';0 @; F9 k( ]. y' c/ Y1 Y5 M5 H
             else if(c==')')
( L1 }1 S: [) p% Y2 \                 return 'E';& u/ r% ~% C1 P' w0 g, z
             else" u7 E* @$ n3 ~  N7 V
                 return '=';
6 u  ~9 Z9 D( c' d8 @* r        default:1 R) b# Z% f( J5 O9 j
             break;
/ {$ D: p7 g( o: H8 S! A8 n    }$ P4 z/ @: z* ~* x  z8 E/ |8 A
    return 0;   
9 Y5 T. b1 i5 _2 _/ n, a}
! K5 I, j& Y+ Z3 F0 y  W& B; ]' C8 x" u8 Q  e2 s
int isOpr(char c)5 ^/ {8 A3 R8 \& k7 g+ v' ^" f
{
& w7 e+ ^2 p- }& Q: }    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')1 }; V. G9 ~( |. L( H, E
        return 0;
9 K! x: t; v, k/ v/ t    else 8 T% j) b+ H1 x, Y" \
        return 1;
6 X' l/ |2 \4 ]}+ y( ~0 o6 s1 f* o

1 t4 m1 X2 H' V$ Pfloat operate(float x, char opr, float y): p' H0 N7 _% e7 \  y; t
{7 \) |+ r  p! Z6 r/ n
    float result;0 X- l; v) k  C) T/ A% b4 z
    switch (opr)$ S# |9 D( n. q- Q
    {- `. K! x9 E& m) w4 r( d
        case '+': / B6 J$ Z# ]' y2 ?( S
             result = x + y;2 U' Z* `" q5 `/ l% f9 C4 _) {
             break;
9 u! F2 S. m+ s( f8 X7 k        case '-':
/ G8 A9 M- \- H" t1 ~3 ?! D             result = x - y;
$ x; ]' @) m4 u2 |/ @$ x             break;' G  |4 o/ B$ U7 F
        case '*': " |9 h1 K5 X; Z2 v+ N
             result = x * y;
4 F2 l/ X' C8 Q, C* y5 p( k' @; }             break;7 N6 ?$ N2 l8 X" F3 L! b7 A
        case '/':
0 E8 u( y" g$ g& o             if (y == 0)
6 y4 T) \" A) f" J6 d& ^8 r             {# {, G" `& i$ ]# Z. ^. b( m
                printf("Divided by zero!\n");
4 f8 W# t1 x3 R9 y- {7 W8 L' B                return 0;
# y7 v+ u# w* m& I             }
( Q1 k0 I& R9 @             else4 v1 D) \9 V2 ~7 T9 A
             {
2 `# b  h! ~, I, ]. g: R. R; m                 result = x / y;
* {0 H* |: \- f2 E                 break;
4 E. T* H3 A" l: }1 L4 j, A1 G. d0 B             }
0 f! T8 q) y% G6 ~2 s* O0 d" o       default:
4 H' _" b6 `- Q4 |. o             printf("Bad Input.\n");
: }/ ^6 R3 o# }4 C0 D             return 0;2 _& o! W0 b# h4 m
    }
3 A( ~6 b+ p/ f6 r    return result;5 @. T7 z8 m6 E8 f
}   
" c. d" |  i4 S" t; J" I* E3 X. O' x% v2 y2 V7 P$ w, C
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/+ v7 \# Q7 N5 l5 z+ C  l
{* n' x( s  T2 H2 w
    Stack optr,opnd;0 r4 v( w- l1 R  ]  i" a3 |, Q
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
' c; w* t/ A! J) a    char c;: m! S7 _$ Z( h/ l* X" K
    char buf[16];5 E( P- e( i9 ?) {
    int i=0;9 ^* B5 x/ r: t: \- S8 M( x
    , s( I3 e6 I1 m# I0 f( X
    InitStack(optr); /*用于寄存运算符*/
: e5 i! U- t* D; W2 h) \0 c* \8 O7 D    InitStack(opnd); /*用于寄存操作数和计算结果*/' l9 S( m' ?, [% O1 r
    memset(buf,0,sizeof(buf));
0 d) Y- @2 A6 q   
) ]3 m' e' X) }    printf("Enter your expression:");
6 B4 k  ?+ C( F' D        ( U4 ]% g4 O) a, Y7 B
    opr_in.ch='#';: Y# D' K. v% V
    Push(optr,opr_in); /*'#'入栈*/
( ?& \. a) @; g* q# z! E1 i. s    GetTop(optr,opr_top);
3 Y0 f5 X8 U) [  x5 U$ G    c=getchar();/ u8 z+ X% A2 ?' u% f9 `6 |/ _
    while(c!='='||opr_top.ch!='#')
5 E# X; Z3 B6 ?/ [9 m/ }    {, f! w  V1 S0 g+ Z. _  {
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
; a2 N# G/ Z9 v        {
9 X  i/ T, G( n9 c; \            buf=c;
& j# L# @3 `+ Q1 B& l8 z/ G            i++;
5 t! n6 M6 L$ q" H( y            c=getchar();3 U1 T8 I$ K9 A9 M8 v, W
        }6 S3 i" ^7 `% U: R& k) w* Y  L
        else /*是运算符*/
5 l) m( Y8 L( b  {        {
; _& v  o" p6 Q2 p            buf='\0';
: w3 ^' T4 Y: n! G* J            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8 L( `! i1 H$ F0 o+ V            {& M, e6 ]+ w) {$ O1 A
                 opn_in.data=(float)atof(buf);
0 I. F; T3 m8 ?4 o0 l# ~1 l                 Push(opnd,opn_in);+ S% P4 A. A9 M; X0 p8 s
                 printf("opnd入栈:[%f]\n",opn_in.data);% S0 K* W2 y$ c. ?
                 i=0;0 ^3 B& I! ^$ C/ v- Z
                 memset(buf,0,sizeof(buf));
( t4 p; u6 }6 s+ j% S1 B            }
7 i! I; s- V1 r6 Y& N            opr_in.ch=c;0 v8 J# i4 Y) Z/ A4 U
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/' T# Z- M) c$ k/ _& s
            {" u1 p% N# N5 t0 y
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
" G. H& [4 r/ S: k- w, h' }                     Push(optr,opr_in);1 i6 l  a5 K, O9 F+ l2 [' J
                     printf("optr入栈:[%c]\n",opr_in.ch);) G5 |- v( x. j7 \! g: K+ [
                     c=getchar();3 }; g/ X- ~$ P! a& S# @
                     break;; n, m% R( r* X
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/% N2 F, J3 P& y6 m. l
                     Pop(optr,e);
2 g0 K" g  n- ?5 m9 N                     printf("optr出栈:去掉括号\n");3 K6 l5 P0 v2 H9 x5 A& K4 H- O
                     c=getchar();
4 {! Q1 Z& @7 U$ W" u# Z                     break;
5 e7 S, [- p4 R5 S* g                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
( w* @1 T/ o& ]4 W3 ]$ j: d8 j                     Pop(optr,opr_t);
$ [; @7 X3 R: M                     printf("optr出栈:[%c]\n",opr_t.ch);
( n* X( N$ \& f) F/ s! ?7 j; b                     if(Pop(opnd,b)<0)
! u/ R9 u3 A' b                     {, X. r- v# C% Z
                         printf("Bad Input!\n");
4 L" Q' [& a( N  r: T2 o) k" Q                         fflush(stdin);; |: R9 W4 x  d+ W
                         return -1;8 ?* e+ e( b1 K- E3 V3 y
                     }% a5 I1 W5 x, X6 a1 H7 w
                     printf("opnd出栈:[%f]\n",b.data);2 j" @( G3 O4 d8 w& y
                     if(Pop(opnd,a)<0)" n6 t* G8 x) M+ w5 ^
                     {
0 Y! F3 U- }# W                         printf("Bad Input!\n");
* B7 v, Y! B; i% R1 u                         fflush(stdin);
; @3 v! z; c' l1 b: |                         return -1;7 F/ p; f$ d& s- s% {
                     }, l+ R( R0 J) y( O
                     printf("opnd出栈:[%f]\n",a.data);% w5 Y4 j; S, u! P
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
4 D8 F. h; Y: {8 R8 {" G+ U  N) [& m                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/" z) E( W% e8 Y! V- }
                     printf("结果入栈:[%f]\n",opn_tmp.data);, z7 _1 [" w* B  n7 o: N
                     break;
# Y+ d" a; p8 Q1 g- b  N1 n            }
; v8 `. V. u1 G' q7 K; N        }
8 X' b/ v' f: K$ T1 A        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                $ `1 X6 k5 W' q1 A* v7 H
    }4 q9 O" s: Z( `
    GetTop(opnd,opn_tmp);
- U6 u0 @1 r& v6 N) W" x6 q* s/ G    DestroyStack(optr);
5 W% F& f0 I/ H! d" p) h8 K    DestroyStack(opnd);7 B! l4 y+ r8 L' G. @, {2 I+ Q
    return opn_tmp.data;
/ g4 c5 c. K; w0 Z3 r0 M( K9 p% ~. u}. f; ]3 n, K( J& H& g6 a

$ W6 z' a, M! Y4 K2 Uchar *killzero(char *res,float result)3 i0 p7 V5 N7 G+ o
{; q- o4 e! O: B
    int i;& X6 |- E: T$ {( `6 n. _

9 F% j* [" U( v1 x5 {    sprintf(res,"%f",result);0 w! q. h$ V5 B1 @
    i=(int)strlen(res)-1;
  N2 r! l# `, u" _9 `7 n* W    while(i&&res=='0'). p+ T- [( l& Z* C# W
    {! c1 c5 A1 J' Q
        res='\0';
3 ~4 z1 n- X, M        i--;0 [, M: ?/ y0 u
    }( p. i' P3 ^% }7 W# K+ _& x
    if(res=='.')9 ?! Q& c# k: m5 N1 T
        res='\0';
6 [: {% d) G. `. g    return res;! a* R) m, J4 B$ o( v& n
}% z% p3 V$ T* ~

  R8 Z5 [# B5 _2 ?int main()
2 G9 L% |# P' C) j# i9 _  g{
4 h% `; G$ M3 v$ c. u4 p    char ch;" h- x' J1 K9 \# E5 m/ P0 G. ^
    char res[64];
1 X% f! ~/ t2 i1 i$ A- W5 @4 L    float result;& d  t, Z7 [) [8 t- c8 c
    while(1)
% \: H$ M3 r/ p, _. A  t3 O    {
* i4 q; T" M2 w6 n, F        result=compute();3 A/ N' h, @6 Q3 I
        printf("\nThe result is:%s\n",killzero(res,result));- a2 z/ _, l3 i- z+ {8 X
        printf("Do you want to continue(y/n)?:") ;" |2 {: V" O! P; {9 Q
        ch=getch();
6 ]0 o% I9 x' n, |/ g, i1 K        putchar(ch);& h' g% X" `4 _# \
        if(ch=='n'||ch=='N')
4 h. y7 s$ x* W! Y, q! J$ t! m            break;
2 L6 M0 }& D) ?$ F        else0 ~2 ?. T  i* V3 e8 s" v
            system("cls");
4 Z: F  j8 j& Z$ h4 l+ ?    }6 G" W% R5 y6 ~) m
    return 0;
% _/ c2 e4 M0 E- i}
! Z4 P6 B" b+ [$ I% ^) D  C

% V* _# d* L% F2 R0 t. ^[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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