Board logo

标题: C语言表达式计算器 [打印本页]

作者: zw2004    时间: 2008-1-21 17:17     标题: C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.  o! k0 j* u2 r
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=" h% T  G) p$ @- S
/**************表达式计算器************/
& G: _4 {: P  z1 H  [9 ~3 h#include <stdio.h>
7 O* X( w6 F: S# U% l/ v#include <stdlib.h>
- g  R7 [0 \5 C8 `) A#include <string.h>
  ]) z% [' d6 j& u/ b8 i% {#include <conio.h>
; b* ~4 |2 s8 R: a2 d#include <malloc.h>
0 B& P) {+ {! Q& F: a+ e- M9 o+ n) \% e. I% N% g) J
#define STACK_SIZE 1000 h! w, K6 E6 p. O0 [
#define APPEND_SIZE 10% |+ j6 f! L8 C

: P7 S$ Y! Q* xstruct SNode{7 [, d8 h+ n( e- D
    float data; /*存放操作数或者计算结果*/
1 a, y  t; J- Y- b% A, D" n9 e' k    char ch; /*存放运算符*/9 p/ S0 y' K8 Q% Y7 @# [
};
( `9 w4 Y0 {' L1 H0 V5 j
# h: i. s. h. ~% }8 y& V- e" istruct Stack{2 D3 f  N% G( ]1 L0 z1 z
    SNode *top;1 i- t6 b& H* W8 o$ R( `
    SNode *base;3 V0 i5 {" l0 \
    int size;5 N0 P( w) |% E
};  C- P, X; w! v4 ?9 Y. I

/ s* P: y, k) @4 I9 @/*栈操作函数*/
- T: S) z' y% S$ u  kint InitStack(Stack &S); /*创建栈*/
- a* p( H; R2 L% Y  W# Rint DestroyStack(Stack &S); /*销毁栈*/
% J% X" r( B! T" Rint ClearStack(Stack &S); /*清空栈*/3 T( P; ?6 S% I: B. ?
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/( I9 V5 ^% y0 ]0 ^
int Push(Stack &S,SNode e); /*将结点e压入栈*/
2 W! l( f( a8 M# G" f# iint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
3 O4 p( j3 _- I2 ?
- I0 [0 e7 J! x, a% K/*表达式计算器相关函数*/3 a2 E' ?# x: @1 o/ O
char get_precede(char s,char c); /*判断运算符s和c的优先级*/+ \5 V( @/ I* }
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
$ I) l$ `% v$ yfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
/ u. {& c: l* Afloat compute(); /*表达式结算器主函数*/8 _2 @; z8 D) p  k1 x# T
char *killzero(float result); /*去掉结果后面的0*/ , ?2 ]' H5 I# i$ I& |

1 d. e: L1 f' O3 f6 P9 ?1 J: gint InitStack(Stack &S)
( b' t6 |! b* k8 ?9 I{# a  G6 V$ U. t8 p) e! r# ~1 J
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
9 T$ T5 m: H  H% l1 s9 _* E( k    if(S.base==NULL)
% t. k/ i" D+ f% v; }  J& f. L    {
0 V; c8 ]# B, \8 ^0 k% @        printf("动态分配内存失败!");
6 R4 N6 P" m; j- F        return -1;: q9 C' C/ A. W% e- N
    }. S2 R  ?  n7 {# ^  P& f& N5 T
    S.top=S.base;
7 C" Q5 V4 m+ V9 K( s' ]. m& ~    S.size=STACK_SIZE;
5 }2 F" j* ]# |/ Q9 N' ?    return 0;
( n! _5 D  K; P6 c1 q. Q}
9 T1 b1 a2 [; Z! R
7 j4 i3 }3 M0 P4 O& yint DestroyStack(Stack &S)& x3 E2 _' q9 p2 g+ ^
{3 M* H# O: O5 e
    free(S.base);
0 t; J: q% \4 M. v( e5 p3 H    return 0;' h) i$ _+ [5 J) K  w! v! Q+ y
}
. ~) X$ C9 @% B: H6 j4 A, y: y3 U$ J
' q, h& d. M# {4 dint ClearStack(Stack &S)+ o# T6 e. q# Q6 V
{5 V1 O. }( e2 f* R) e
    S.top=S.base;
5 W$ M# n0 }+ X    return 0;8 x; ]1 \$ a6 Z
}8 J/ }- U, B4 R9 d( A' Z
4 W; U! }, d: d% Y6 T8 S6 x9 Q
int GetTop(Stack S,SNode &e)
6 X# m3 b9 i8 f{
5 M5 M& b% E6 c2 c$ c3 [3 E" b) b    if(S.top==S.base)
1 x$ |9 ~! a# B  k    {0 o1 j$ Z, {* b# \# m
        printf("栈以为空!");
  s* Y+ S5 Q' ~        return -1;
. A8 n1 {# U! E    }
. N) }8 q2 I; u* j; S    e=*(S.top-1);
- u/ a# |4 o7 U' P) V% r9 z" a1 G    return 0;
% n9 o, z; |+ R; ]}8 i+ P2 Q5 @/ O
8 K& [& {. H0 C6 g; y
int Push(Stack &S,SNode e), V* @0 Y* i9 @
{
0 n% M' T  |# J. x! {& S7 a8 ^! g9 x    if(S.top-S.base>=S.size)1 ]) ?1 D8 [& D1 U1 I, c) S" I6 U
    {8 h/ u: B. B! S
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));* s7 \0 J7 A( U' ], {8 H. s* W
        if(S.base==NULL)1 S$ j# J7 ]* K$ f/ B
        {, E! l1 Y2 G: B
            printf("动态分配内存失败!");
" k9 s; t( `' L( S4 {& t% R            return -1;, @. l1 v: O5 S+ {- ^" H
        }5 J# F0 L" F! p0 f: v' l  B2 h! e
        S.top=S.base+S.size;
! Y4 i/ L, y' F        S.size+=APPEND_SIZE;  S5 A" d: s( M6 E3 `8 `
    }% N" @  z; N9 A, {
    *S.top=e;
9 O8 q* F8 i# U) [+ r    S.top++;0 D7 y4 |5 }/ }+ L
    return 0;
; X* R" \$ [% v' g+ }( o+ s: Y}
  h1 D4 \/ B( m; D6 `; d  k) {' Y! w! \2 ~- r
int Pop(Stack &S,SNode &e)2 C% `" n7 F; x2 E
{- K2 g1 P' p6 y0 q6 S
    if(S.top==S.base)
8 ]9 z& b+ k, F9 G7 I8 r6 o    {  e6 U, J6 r5 ?  ]3 e
        printf("栈为空!");4 R, m( ?8 x  ]+ l; E' s
        return -1;) v: R9 R6 ]3 B, N. w# ?  Q
    }1 x$ ]. x9 V2 t5 y) K& x5 ^
    e=*(S.top-1);
: _6 n& Z( w4 B/ T$ j    S.top--;2 a$ A! [( D# a) U- V9 q1 Y
    return 0;
# }  ~. s* g% g. H}7 X7 Z$ x3 Y/ @/ S; X' L' a+ a/ k& V
. Y. n+ {1 C9 ]3 W7 H* ?0 m3 S
char get_precede(char s,char c)" U) n2 _8 g! u4 L2 G& y
{
: i- k, s0 I4 T$ a; Z    switch(s)$ V& t, r$ Y/ }+ Y  e. X8 W% G
    {4 R3 @& y; r2 S2 n) d! D( F
        case '+':                 
2 g- Y" x9 k! ]# o        case '-':0 h5 x& [) z+ C2 J
             if(c=='+'||c=='-')2 Y$ ]8 N6 ?- f: W6 S7 _
                 return '>';
" L# S5 f5 x# T  c6 `9 G* s             else if(c=='*'||c=='/'), y. F( C+ n2 _  Q/ M' S
                 return '<';
) b. }8 d# r4 f8 l  y' T             else if(c=='(')3 J; [0 M+ k2 t$ G* }
                 return '<';, Z! V3 S8 P5 ^. E7 h8 q2 V% U" a
             else if(c==')')
5 A7 H; v# G( s, ^( u4 {& p                 return '>';
; U0 R, T' I, x3 z             else
$ u. u  b* y' v$ T8 F( ^                 return '>';
3 {, ]# s8 Z& ~, u        case '*':0 \2 [( d" y* u4 J! @$ P  S
        case '/':
# @3 E* O6 j; J, n' l4 \- e( _             if(c=='+'||c=='-')  R1 D4 c8 X9 q# t+ |9 w
                 return '>';
7 `8 U5 |7 F+ q- L5 h+ w' x( U             else if(c=='*'||c=='/')
5 H! c5 o$ R0 X4 X                 return '>';2 t6 V! j/ x. x. e5 a1 I' h$ y
             else if(c=='(')
- |2 c9 L, I. _1 U! F$ x/ S                 return '<';5 _' }3 S& B$ l, ]
             else if(c==')')4 X3 o% C2 G# j2 s, A8 k
                 return '>';. P& T4 `3 A" K0 Y) E
             else9 E+ P! \; a+ Y) V( s( C, L
                 return '>';$ X% x) Y" y  w7 o; _5 V6 X' F
        case '(':( n- l  x7 I5 b$ S
             if(c=='+'||c=='-')- A+ n/ i3 O  u& \
                 return '<';8 e% ]* e8 Q+ F4 Y, _5 E# _, ?+ s% h
             else if(c=='*'||c=='/')
* ]  E9 z" I2 k# ^) v. p                 return '<';
+ T) Y0 Z! d9 T             else if(c=='(')
, i& R; R% q. m1 Z( _/ }3 \, H; ^- Y                 return '<';3 h3 R' k, {4 i& H( o3 t% Y6 G" o
             else if(c==')')
0 R. E% p5 f7 V2 e- F& A* n: R                 return '=';
- H; d9 i- T# ^. g, K8 B             else
0 |4 _8 z, N1 Y3 i7 }* h; l; g                 return 'E';( ]. T/ F8 i# a, k) i
        case ')':
6 b/ q% |; C2 I' a" Y& F' d             if(c=='+'||c=='-')
' X1 C* }- ?  S) `4 r8 s; _                 return '>';7 Y( m3 B7 ~) G/ @) M# P
             else if(c=='*'||c=='/')
8 `; J) A3 d" M7 l% l                 return '>';  g- w' P6 I/ l9 i' C  \
             else if(c=='('). S! r: _( v$ S* F: c8 v
                 return 'E';# v5 B7 g( _3 |2 @- q
             else if(c==')')# \0 E9 v- J, C8 R
                 return '>';3 b3 ^5 O! `# o' Y7 M, `
             else# b0 ?! d# Q/ X% e' ~+ R! v) `
                 return '>';
1 R5 w  g! P3 u. g* N( _& p8 }2 j        case '#':
5 C$ n' o: Z/ G0 u5 n8 C             if(c=='+'||c=='-')
9 d$ ?, t/ E, I9 y; B                 return '<';
; b* t; N& `5 @/ X/ c6 \! k1 E             else if(c=='*'||c=='/')) C, i$ g- }" b! n
                 return '<';, _1 G* E" N8 y% K+ ]! @4 @) f
             else if(c=='(')) ?5 h/ B2 I& R& j1 ?. y+ s
                 return '<';
5 O' A2 x5 S! b+ D# M+ k             else if(c==')'): i/ f6 W& T. M, V5 T% Y( p; V
                 return 'E';
& S' n1 F; A* b9 Q) ~             else
5 q4 B: V7 t9 A: ]* z                 return '=';
5 l# c, N+ F  E2 u# x& z        default:
$ h# h7 S" A7 n5 S/ m             break;
$ F2 r' Z4 i; m+ t5 p! q5 @    }
, A, R( L1 s0 k! z' d5 n. A    return 0;   
7 c5 d6 @7 W- T1 K% A}9 V' N. D5 H: r
" Z% T4 b! {9 e" A
int isOpr(char c), ?3 e  R. l3 f9 i) ~% Y
{
$ E1 Q) X) ~6 B    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
, ~1 o; f; E0 x% q/ H$ ?* ]5 h        return 0;4 A6 x. H8 V0 W; O4 q- c
    else & D4 t2 o7 X5 y
        return 1;
, K9 N6 u2 U  c# U* J}9 u6 J' ^% c4 y7 H1 u; @
- k: G0 J: A9 O2 ?; r& \
float operate(float x, char opr, float y)
9 e  ?8 C" B: h% b4 y9 w{5 M1 j% Z5 K' G. s6 j8 D. D
    float result;  H& n  \) m, T3 f, ]5 i  e3 Z
    switch (opr)
$ G1 ]" n6 ]2 A; c, ^) h3 Z    {
% y8 T4 h1 H$ D( `        case '+': ; |# r" U- B3 g
             result = x + y;: A% w9 [  U) k8 `8 W
             break;7 ~7 q7 T3 U$ Y* A$ k
        case '-': & o' y/ B8 V- d: i  S
             result = x - y;/ k- _0 Z' I7 |# S
             break;& T! R( `- w/ m7 B7 b1 I
        case '*':
3 y4 a- t% x# ^/ b: H             result = x * y;. V& s: C' b1 s" c% c+ p; a5 H
             break;
$ y, b+ `; p9 G, ^, [        case '/': . O* @. x3 o) j5 F
             if (y == 0)  _- J0 \$ h) {
             {
, E7 l6 Y0 E+ I1 m1 q3 s' {: x6 Q* j                printf("Divided by zero!\n");, Z7 d$ j( M+ n& v2 G
                return 0;
- Q: ?( {5 v' [/ h8 Y             }
1 j6 ?/ w+ ~3 a5 D             else
$ c+ X% h" I) p' K0 G             {
5 ~8 G+ W4 c  g5 o& P7 ^% H- r                 result = x / y;: i- _, z' B% D; ?7 [$ n1 `
                 break;7 G6 f& s7 D0 E( {' ~
             }
6 H/ Q4 K6 ^9 N! o( d       default: 2 ]1 g0 y, ~( e( a. W( G
             printf("Bad Input.\n"); 7 B" V! ?- b) E- U% e$ F% g
             return 0;
& [0 D7 E& G& q8 @+ ^0 |    }
7 \' \/ p; I0 H1 z+ {    return result;4 h/ l! l# }  E  {4 q2 ]
}   
/ ]2 r; G  r5 a" b6 @- U& W/ c
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
# S/ B0 z% I; J- y6 a{. A. }  P# F5 u
    Stack optr,opnd;
/ M# B$ D8 i. N$ Q    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;( |# q2 g( P! b) v
    char c;5 ]- B- h0 R" i# K" X* g5 l& P
    char buf[16];2 u5 c8 j0 T* {& }0 z: G) b
    int i=0;" ^* ^% W2 m6 v% r. ~% @: k6 j3 `
    & T4 a" ^) V4 C- {& h  g& S7 w
    InitStack(optr); /*用于寄存运算符*/2 {, f0 E0 t7 R; Q0 Q- Y; v
    InitStack(opnd); /*用于寄存操作数和计算结果*// v4 Z/ J8 j8 J9 R$ ]
    memset(buf,0,sizeof(buf));
9 v' X2 \  z# g4 P   
5 M) w0 D4 v# V) H8 F) B8 W" d    printf("Enter your expression:");
/ Q) V. f* L$ d          ?0 S( f1 b; m4 x6 a: v( t
    opr_in.ch='#';
% }# J+ y  u( n    Push(optr,opr_in); /*'#'入栈*/& K3 A9 H4 Q, h# M2 Y
    GetTop(optr,opr_top);
$ F7 M  r! h2 c9 y: w$ v0 `    c=getchar();
: W3 s* ~' L2 x. \# u6 U' k% Y! |( }    while(c!='='||opr_top.ch!='#')
; U) ^# D. s2 ^' I    {
5 I3 d; W: {9 s* M        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/" {0 G+ ~2 F. }4 @
        {
, P" E0 n" J3 V  W4 `+ j9 r4 U, m            buf=c;  |! u: J5 v6 a6 x  @# T
            i++;
, s+ ^3 y0 T" h; c. E( ~  L8 l            c=getchar();
2 y) s+ c8 g9 M7 \+ R        }8 g: x9 h# q7 w, Y6 ]5 _+ N* \: a
        else /*是运算符*/5 N* B: ^4 E# G6 _
        {
( J* i7 Y2 W( z! H0 i            buf='\0';' z$ r! \/ i  l( G& o# |
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+ u, X; V9 [/ G& F9 T, P) P
            {) L$ }5 \  B# X3 j+ Z$ C
                 opn_in.data=(float)atof(buf);
- w+ ~0 i, J& m* \+ t# ^+ Z: y                 Push(opnd,opn_in);& a; f1 M) C% T. I1 Z; T; i
                 printf("opnd入栈:[%f]\n",opn_in.data);) J2 j& v7 E4 w' R
                 i=0;
2 _1 e& [  C/ j- q                 memset(buf,0,sizeof(buf));2 S% ^: c/ {9 C2 v) I4 u- u
            }
2 ]+ y0 U0 S% `' K. l4 X            opr_in.ch=c;  I& E. s+ @1 E& n" K- r
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
8 ?8 t" ?) |! A6 W; j' c) h: U            {! K5 L) l& {% G6 F! a
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
1 u  `) j* k1 j/ X                     Push(optr,opr_in);
5 l# L* u7 x7 l: d4 r# ?                     printf("optr入栈:[%c]\n",opr_in.ch);
$ m: H& J, j, X9 k) Y) x                     c=getchar();
; y- m, Q0 L/ L9 L1 {* ?                     break;6 B+ s0 Y5 q- {2 }
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/4 E, w3 t2 K" J8 F! S. W' u# {9 E
                     Pop(optr,e);* d0 ?" T5 ]0 n6 L) A2 {
                     printf("optr出栈:去掉括号\n");
/ j! a6 @& j* w! H( u                     c=getchar();* }, g  S: I- d" t; B
                     break;  ^/ G: ?1 P0 p0 T* z0 F
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/9 E% w6 J2 v" I" t
                     Pop(optr,opr_t);3 y' s# r9 J' k, t
                     printf("optr出栈:[%c]\n",opr_t.ch);- j' n, ?2 O; y/ H9 B
                     if(Pop(opnd,b)<0)
) H/ x/ o' j% }9 k# }                     {1 g/ u- w7 Q( s' S1 J, A
                         printf("Bad Input!\n");
$ u8 ]" J' E' Z* X1 u0 f+ x                         fflush(stdin);  ?6 z$ j; h/ W9 `, j
                         return -1;" `& w, |: p+ w0 L8 q2 w: n
                     }
  {' a; n9 w9 d5 R8 J                     printf("opnd出栈:[%f]\n",b.data);+ c* A7 B, ]8 b0 e. b  T) |
                     if(Pop(opnd,a)<0)
8 }5 s0 X. S# E8 U& O6 Q                     {
* [3 q! y3 i# ?0 b0 c0 s) f                         printf("Bad Input!\n");- S0 @' g5 {. r; }6 c3 L) S# O
                         fflush(stdin);
( s! v* s9 o: W3 [9 O% i+ Z                         return -1;% j1 E& B, P7 Z" Q
                     }$ s0 \( j6 m' N) M3 ~! I% K
                     printf("opnd出栈:[%f]\n",a.data);
; n9 C. Q& p9 Y% N) `1 ~& N                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
) o& p) ~7 ?  k8 r8 ?, f                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
0 m) C- u, ]; P                     printf("结果入栈:[%f]\n",opn_tmp.data);
; \# u" s9 l1 E( u                     break;
! U$ h. ^  E, I3 y7 f* |            }+ b% j2 }! P% F1 a/ N
        }
( c  J7 Q2 H6 ]0 G  i        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
4 T8 e5 m! J# f; A. k    }
$ S) \; u- r( n" v% C5 w% s    GetTop(opnd,opn_tmp);1 d3 [( P% ~+ }; F( q# C# t5 Y8 h
    DestroyStack(optr);* J3 J$ ^7 w7 i6 }+ }. k5 t( M
    DestroyStack(opnd);6 l/ P$ F7 h6 A, r* j) j
    return opn_tmp.data;( ~2 h( B! h! A! ^/ X
}: W5 z7 ~1 ?6 b" A- ~

. f* M+ k4 {9 A8 s/ ^char *killzero(char *res,float result)
! u- }5 j1 s0 K$ d" x4 f{
3 V$ t/ q  U2 G: o* `  P1 q! b    int i;
1 S7 }7 L* g$ w( ^0 L- i4 v& o6 w! W' H2 H9 l7 c3 d
    sprintf(res,"%f",result);
% ~" F, s  s7 S, f1 ^( A    i=(int)strlen(res)-1;& r4 ?3 H5 J5 N2 ?
    while(i&&res=='0')3 d- f7 Q$ y! J0 X- |) _9 {: t0 y$ s4 {
    {- P1 r. ~. G6 _$ q# w
        res='\0';! f5 a# _) X/ S3 W
        i--;
' R& A2 m. p4 T) P+ ~    }; b- u4 I2 A4 Y" ^8 L- X
    if(res=='.')
% o5 _# L5 R0 x4 Y; Y& Z        res='\0';" ~4 c' k; v: @' _- U$ u
    return res;/ s' v+ D+ \5 ^
}
0 c2 `' [. b& F- a- A* W& Q: `$ [8 m/ K
int main()
. P! ]  t. N1 w/ m& b3 a{# E$ A) S9 ~* z0 E  K
    char ch;
% L/ t# h/ D/ |/ u+ m' i, s. N    char res[64];* N- _- L2 b( h; i  Y" }5 Q' ^
    float result;
! |6 h, f/ Q. O, \( Y- Q    while(1)
  q. w" j& J) M& m: ^/ _$ x    {; ~+ `) `9 u& R, \8 x
        result=compute();
- K/ c' ?5 ]! Z1 s+ P' `+ R        printf("\nThe result is:%s\n",killzero(res,result));  U2 Q, |* ~( V$ S# Q5 t/ m% |: Y
        printf("Do you want to continue(y/n)?:") ;
" ]( D9 i7 v* n8 ^8 H        ch=getch();/ N1 s: c: g' V$ X; h
        putchar(ch);# ~; r9 _) I) V; d8 k
        if(ch=='n'||ch=='N')
# ]/ O3 x* v' j& i            break;
- m; B& n  b6 z. J/ E        else
: ?# p8 n/ a' P$ z" Y& K6 u- U            system("cls");# h$ h0 I/ z8 ?: z4 g
    }, Z5 q/ A7 |) v6 k! B9 R" q9 G' O. p
    return 0;
& b# `, D0 p7 N- k' M: w}
9 W8 V# s- \* w/ A5 P9 g
; r9 J  \5 d0 G0 Z$ `
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




欢迎光临 捌玖网络工作室 (http://89w.org/) Powered by Discuz! 7.2