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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.  V( V$ q+ n# Y, C
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=* P( N6 L1 l3 h; C0 K
/**************表达式计算器************/0 M9 Q# e3 i/ l" u- v, U
#include <stdio.h>
8 n. H- ]  i- P: [5 U! W, U1 K#include <stdlib.h>
* M. U0 w8 c- g1 Y8 d#include <string.h>/ t$ G5 Y' p7 G0 v4 G) ^2 `
#include <conio.h>
2 T  u4 U! j: b1 L+ s; }6 @#include <malloc.h>% [9 G! p6 ~; [  O  e3 I% s

  W0 h, a3 ^% {) d#define STACK_SIZE 1003 H& r$ L2 I; n* P7 r
#define APPEND_SIZE 10
4 O5 t7 z4 L/ v0 S1 Y9 B+ |; w3 x, B
struct SNode{
* k1 L; T9 c' a, r    float data; /*存放操作数或者计算结果*/! P, @/ O% [7 R3 @% p
    char ch; /*存放运算符*/* G$ r& v1 p7 Z3 r
};5 `. T: t- m& g8 c2 I, m
# {2 F5 n" R4 N* _
struct Stack{
1 v7 V: z$ w3 Z8 E# T2 d    SNode *top;
) b& u9 Q1 v& k7 M2 |1 h' t9 ]7 j    SNode *base;
# {, c) N! T4 d8 ?) b, K    int size;
- @+ _" P8 c7 u6 p};
: F% d$ n9 v+ z% ]/ k% ]- P2 ^' X. R0 ?/ h  |8 {. [
/*栈操作函数*/, l- A: K! c! V3 ~6 Y
int InitStack(Stack &S); /*创建栈*/
" J6 \( _/ v+ M# f, Aint DestroyStack(Stack &S); /*销毁栈*/# m4 r6 o8 u/ a  q3 R# L, w
int ClearStack(Stack &S); /*清空栈*/4 g6 V: m1 ^8 l
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 x- B* f! M. ~* z- P3 Lint Push(Stack &S,SNode e); /*将结点e压入栈*/& H. M5 @" e/ g* o' X2 X. j
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2 J% b* A/ q, T/ R! U+ @; S
5 F6 V* i- W  [/*表达式计算器相关函数*/
8 ~4 V* c1 T" c) e4 b' V+ i* wchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
" C3 V( ~+ W$ y" Vint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/4 n& H  K9 a# `
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 u. K' {8 \  m" |6 S6 @% Xfloat compute(); /*表达式结算器主函数*/$ s" G6 J2 b% y, S  ]7 w  g+ B7 w
char *killzero(float result); /*去掉结果后面的0*/ 1 {( i" f1 @8 c: b$ [% W
0 W, f7 r" T0 r* I3 p/ q
int InitStack(Stack &S)
* Q% N' S6 Y: J{
5 Y+ m! Q: E$ w    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));/ R- Q6 F' m: v3 l# ~% X5 X
    if(S.base==NULL)8 _8 d* B- p$ l+ @! U
    {  J6 G# x& v5 b5 O% x
        printf("动态分配内存失败!");! _3 v0 {- A8 Z* n
        return -1;
7 t/ [; V! }. j: }* w    }
4 f( x3 E  B! \5 {" f    S.top=S.base;' e6 Q0 ^* W# @/ _* ?8 }- a$ g, V
    S.size=STACK_SIZE;
4 ~! r$ u6 a8 W6 _    return 0;0 S0 j; s7 k0 y. H3 j, s6 {2 ]2 i
}
, \  v/ O! }1 C% @7 I8 u" }% t! n* X0 `* \# K- N! ~: m+ G
int DestroyStack(Stack &S)
2 M; L/ I4 |2 g. E3 i- D) O  G1 ~  p{
4 i  H3 {1 H) O9 G    free(S.base);, y4 y0 \; Y8 y% U  C3 E
    return 0;( }4 g$ S$ k5 N- h: H& t  P6 b# S
}  W; i" Z0 \" V
: h4 N/ P) R1 J2 M5 F
int ClearStack(Stack &S)% s8 N# ]# t1 Y4 i
{
: W; @4 Y* D$ L$ ^- ?7 {    S.top=S.base;  y8 W% p$ x* ]7 j- \0 V: j6 z
    return 0;6 D6 z" u: i1 y+ l8 w# ]: [
}
5 R1 L6 S! ?- X5 e
2 E, ~" Y  P8 tint GetTop(Stack S,SNode &e)5 }7 S9 l6 M$ Q9 B0 @
{. Z, f/ i. s* i; Y0 i! N( h9 i, {
    if(S.top==S.base)
) L5 s* ]1 p# x    {
+ B$ X% q& H, I# ]        printf("栈以为空!");4 u7 \5 {+ M( r) U1 y  w
        return -1;
3 T/ G9 H1 ?6 Q9 b/ ~    }
. R8 }( G8 J4 T" i8 O. {0 [    e=*(S.top-1);2 {0 P; g. V! K% u& F( v
    return 0;
& o* `$ Y4 Y3 D* e" _& Z4 o}
* ~; s; ?) Z0 \2 m: b; a+ L+ e/ F: S, K+ Y2 H+ T
int Push(Stack &S,SNode e)" d) L7 V9 N; I1 X: ]4 [: O
{
/ l2 ^, X; h5 j, m0 C    if(S.top-S.base>=S.size)
8 M; T. A8 l4 @+ s- [. E    {
( y1 l4 q# }4 B; e  a        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));0 V- W: m9 k2 k
        if(S.base==NULL); {+ H& W5 ^/ i2 |
        {
) T/ P9 \: I" Z* e" b( }7 f            printf("动态分配内存失败!");5 ]: {, u9 E% c# o8 ^, g- a
            return -1;" I, J0 l" m, e# M/ H
        }- k& E7 |2 M3 {- e
        S.top=S.base+S.size;
; c+ f4 z" J  ?$ }  a% F- f- j        S.size+=APPEND_SIZE;" B( c2 }1 Q7 G9 I3 _
    }2 ?; O$ \& o1 g4 k
    *S.top=e;6 [5 t! g/ L$ m+ o3 o: A
    S.top++;! H9 @% t  S. w9 e, ^5 \% l
    return 0;
" w$ l" W& j" j2 r" y; t% u5 {}
# b7 J+ D- N7 I7 B1 G2 Q0 H; ]( q0 K7 i2 n) s
int Pop(Stack &S,SNode &e)
; D: H$ S5 c$ t8 v$ p$ W/ s{
* h- ^' |+ n9 a% S1 ?% r( r    if(S.top==S.base)
0 H9 s- l0 d. R5 \- k$ ~, [    {, E  ?- |# e4 }  ~
        printf("栈为空!");/ Q3 c0 s" R( L' R" P) e& u- j0 E
        return -1;2 n! |( A- c- A: Y- l
    }
  ]2 k: O4 I; \$ L5 B6 T- M6 G1 S( g    e=*(S.top-1);
. W) J  `/ @. J  q) C7 k    S.top--;
( b/ u2 c) c4 B( g    return 0;: h9 }8 k- ]5 j. B! p2 @
}
5 k' {4 C' ]- |- c( ?
! F; u$ ^! G- f$ }7 qchar get_precede(char s,char c)8 Q3 e+ `- ?* `/ F8 W
{1 i9 D; d, l% u4 q2 r7 h4 e% U
    switch(s)
- v9 I2 X8 s: j( Z0 l) f    {3 L! I5 `& K! H, q% @" p
        case '+':                 9 u  C. S$ t# H" q0 F1 k3 ^  J
        case '-':
/ L- M8 z9 G' l             if(c=='+'||c=='-')
+ o9 H5 o, w. I                 return '>';& h3 B( `1 ^; w: T: |: v3 I8 [
             else if(c=='*'||c=='/')
( [! A$ s( `- _                 return '<';
; d" y7 y/ D2 F. G2 I/ H( o- @6 G6 {             else if(c=='(')
, F4 C) r" h3 T: r+ p. d6 O                 return '<';
4 Q8 ^# [! Y, Y- |. i6 x             else if(c==')')
5 F) w! x# }; l* t( U' V                 return '>';
) m& G8 O, D  i# n  X  f             else
1 E0 H1 ?% ]) O. `                 return '>';
. M  V8 R0 b) f- M, B        case '*':
3 a) p% s5 y% k7 k- ^5 U        case '/':
+ E) N1 ?/ c# E2 y             if(c=='+'||c=='-')
" R; b6 M% k' K1 x5 {                 return '>';
8 D9 `; p  s, C! ~. C             else if(c=='*'||c=='/')
0 L+ N) v' r/ D8 Z# `8 c: B3 f  T5 c' i                 return '>';
6 S1 y" |: m' h! A- k             else if(c=='(')9 g+ x' S8 ~2 D0 ]
                 return '<';7 e/ i" q  h8 g% f
             else if(c==')')
8 W6 l. D) H. q  x7 `+ M4 h6 p  I% Y                 return '>';- f8 _0 m8 H' _6 `: y
             else
- U! v0 d$ `  i1 [) w* @# g; V# Q                 return '>';$ s7 a% u& n" C2 S* k3 b
        case '(':
; U% j. G5 j* F' E8 [4 z+ r             if(c=='+'||c=='-')8 ^0 J+ P, F3 Q# t; b5 P
                 return '<';
9 {$ ?& ~) c" z8 I( j" n$ u  u4 |             else if(c=='*'||c=='/')% M9 n+ K' R0 L7 e" w
                 return '<';" W; g- Q' p# _7 C* y& D& z
             else if(c=='(')
2 V- S/ ^1 r+ A- P$ {+ E" G                 return '<';
( H2 g. G2 s. w5 k$ U, F             else if(c==')')
& E3 I2 ~1 r+ y2 F                 return '=';
$ X& L. l& `$ t3 E             else$ Z6 C" C/ P; r
                 return 'E';
+ f9 d) [* v- F, C9 L& f        case ')':
8 B2 N$ e, l; d0 a- @             if(c=='+'||c=='-')
7 F. n5 m8 y5 z) }3 Z* d8 f                 return '>';# D7 t2 G7 p8 V5 }
             else if(c=='*'||c=='/')
7 U. k1 v6 w9 G                 return '>';
$ _5 y- b& w* }1 b' G5 d, ^             else if(c=='(')" c7 F! d& c3 Z' s* j
                 return 'E';
: T8 D2 W# A- c8 I, F# u             else if(c==')')
8 G! K% X$ j; b" D                 return '>';! M- ^' w4 P$ G
             else
3 E2 P6 K' C4 f5 v" ^% Z                 return '>';. M+ ?& l1 A0 a- f! A) `* v
        case '#':" ?9 A- N+ u3 j1 \4 ^) F
             if(c=='+'||c=='-')
1 u% e1 t- U% C) M" l. x                 return '<';* }) y, y" y3 A
             else if(c=='*'||c=='/')3 ^3 {  d6 R- |3 F- P" k1 P" ^+ d
                 return '<';
- Y5 N8 f. y0 W* \* g' O2 D             else if(c=='(')
, G& {/ K( C+ y# j0 O' P                 return '<';. l0 X; @: z2 [" E$ A5 _2 ]% J
             else if(c==')')
# r. i. Q+ z) t& n                 return 'E';
7 m% e3 T& l* R             else* K9 {8 k) ~) u3 j8 g# W) K' d
                 return '=';
4 }& W3 w; w; {: T$ S0 S, u        default:9 S) _4 H' \4 b0 c4 g  X4 o
             break;
! l2 [1 S) g( f$ J+ B/ W, G7 \    }
( Y$ P+ m% }; F& J# B    return 0;    # I8 U/ \# l- O. V5 X' d
}! O! v9 z, O- e# L# r" P! ]

' G& V3 L/ \7 U+ f$ o" ~int isOpr(char c)1 y0 e& ]; t" \) p$ j1 @8 P4 t
{% s8 g7 r: c% M* X+ R
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')* Q: {& M" }1 Z
        return 0;9 h( O9 p  t4 Q5 }8 J6 e+ v% m
    else
7 J0 Y1 l7 |% @        return 1;2 q# t+ U8 V; N. z
}9 r( b3 c2 k1 A. q" c- q

: n1 M6 ?) i* U# m, D2 k1 N9 Kfloat operate(float x, char opr, float y)$ I* P+ {! k3 ?
{% D$ q% S- k: D/ v1 y
    float result;  N* @0 Z' j% g8 i+ H- h% C
    switch (opr)6 F9 p+ x" L0 V/ o! z( m& y3 i
    {
# P, r1 [7 T; ?1 _' I, S! q        case '+':
' H/ a) C8 b0 N* d  p" P3 q4 z) }# P             result = x + y;2 O2 A* ]; W0 m* h( Q8 \. Z
             break;0 f7 H, n! Z5 q2 h7 _
        case '-': % o, R5 n9 T; a& T$ w/ T
             result = x - y;7 Y+ }! W, U1 ]/ z( N7 T1 w
             break;& A8 Z2 T- I- ]2 O7 h2 N! F
        case '*': 0 r# P+ J% t+ [7 c0 R% K! c
             result = x * y;, [6 D0 E, P$ B6 o
             break;
2 c2 Q* x( P. W+ F. b5 x        case '/':
6 d$ ]0 T) ?* ~# w# O             if (y == 0)
' T7 E* `& a- Q2 h  b- n- f             {
. N- [% S2 i; |, v& @+ s                printf("Divided by zero!\n");
$ D0 D' v( U3 A" L/ y/ e! U                return 0;
9 o  j! q3 m7 x             }8 p. F1 y1 n- U, O$ S* o
             else
: u8 V0 d+ g5 J& ~             {  r+ w' i5 y4 a4 G8 n7 [6 e& E5 l/ A
                 result = x / y;+ K6 A) R; R1 D# R" H3 Z( k' ^
                 break;
* x* m3 g% u5 _3 [& S* J! I* f- N             }
. @* c) ~' s9 G       default:
; I' C; J& t, P# S5 l) I             printf("Bad Input.\n"); $ y3 U* j# ?- C/ t; [
             return 0;1 R6 }9 s! |4 R3 k7 j1 `* u
    }4 m* [. i4 C1 H9 |* N
    return result;7 t( f: ^( Z" d3 ~2 r. |
}   
6 {. }2 r# m( O4 B2 u6 `( Q! W; B7 L5 g% S1 w+ y3 j- u
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 ?% `. d! p! O8 t4 c" y1 T: f9 F{
9 b0 l1 Y' Y6 L3 d    Stack optr,opnd;* S4 t+ q" O7 m  P) f
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$ S3 s1 u) `3 |/ g
    char c;
1 s8 i3 N, x+ J* v* k6 F! t    char buf[16];
* {! E( r0 @4 U; b  c* A    int i=0;
# Q) I/ |/ K% Z+ f   
2 p9 q2 f+ `1 s, K/ G    InitStack(optr); /*用于寄存运算符*/
, F$ q  e, c$ C1 w( v& Q+ b3 k1 C    InitStack(opnd); /*用于寄存操作数和计算结果*/
0 Q; z; p1 T0 [- n4 R- C    memset(buf,0,sizeof(buf));: S& l" X( P! E  G+ [6 v* i
    5 u5 @( A$ a) e9 L+ E/ J
    printf("Enter your expression:");
5 W8 `* O1 m- @% o        
& F5 f; L0 i- x4 m9 t+ H- k6 c    opr_in.ch='#';6 Z9 o3 n; g% M% I, J. w
    Push(optr,opr_in); /*'#'入栈*/) m, a: o$ @5 r' R+ R
    GetTop(optr,opr_top);0 h9 m+ Q) h6 N/ G  t0 \
    c=getchar();
$ }2 W8 V! T9 v) {    while(c!='='||opr_top.ch!='#')( ~* D5 C0 ~4 A! s6 z% S0 H
    {& F7 G( U( l/ _! Q+ `' |
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ {$ X3 d& b0 V" K9 _& Y, s  x9 {        {
7 s$ @# E, {* S' l; z/ ^            buf=c;
* e$ g/ E, U7 h; b            i++;
# m+ r2 I4 h3 z+ \4 U            c=getchar();
( T" a/ y% r- M: m! N        }
% c0 i3 c' I, U7 p# M5 v        else /*是运算符*/
+ \4 C# T. J6 A  @- O- J8 i7 _        {
8 b$ ?7 G0 P, F1 i3 X' Z; s            buf='\0';* j. g# F- D" r
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/7 ^; c) O# `# Z  j- q
            {
7 ^2 v# v/ T% P( q/ V1 c                 opn_in.data=(float)atof(buf);$ @' h( M+ `: T
                 Push(opnd,opn_in);2 j; X& n2 |3 s/ q
                 printf("opnd入栈:[%f]\n",opn_in.data);/ q, c# [! p& W  w' g
                 i=0;! X! o+ S, O$ ]6 \& a
                 memset(buf,0,sizeof(buf));/ O+ ]6 U: V- E9 P* L" y0 v; W& [: Q
            }- x" G* o% ^  V
            opr_in.ch=c;
( ^3 H, f* v) E+ i2 Z            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
$ i9 I8 M* \: u4 o& k            {, Z9 {( \. n; U, C
                case '<': /*优先级小于栈顶结点,则运算符入栈*/) W5 Y  U' N  }0 u  k
                     Push(optr,opr_in);
3 S2 r  H$ P/ p5 v% v                     printf("optr入栈:[%c]\n",opr_in.ch);
( L$ g+ N& s  k, @$ h/ k, o4 x                     c=getchar();
5 \8 |( _" `0 N) _' Q4 A                     break;# A0 Y& X7 S: c
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
8 l! |( F; T. w                     Pop(optr,e);
/ c2 _/ L7 _# }& u1 ~4 g                     printf("optr出栈:去掉括号\n");' d3 u8 {+ G1 R1 J
                     c=getchar();6 x! M0 y0 ^  z( _8 L0 [" g, N
                     break;5 n; S# ^& T, |0 b
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/$ H8 z& U/ `0 R
                     Pop(optr,opr_t);0 ^: e# H; R3 d8 B7 R; d) A
                     printf("optr出栈:[%c]\n",opr_t.ch);
: ]7 ?, U6 [4 `3 r! [( ?                     if(Pop(opnd,b)<0)/ {1 }* l. s% `8 G( U
                     {6 O. k7 `% B: g1 T
                         printf("Bad Input!\n");5 _' }  q- R2 I. ^# J% Q
                         fflush(stdin);' I. K1 P( D2 z8 B
                         return -1;
8 ^, |* \- u1 ^9 e* H  f& }3 ^                     }
4 c6 o5 D9 u7 X3 j                     printf("opnd出栈:[%f]\n",b.data);) l8 u$ ?6 B, a& K
                     if(Pop(opnd,a)<0)2 E4 f7 o9 y$ J' w) X. f9 s
                     {8 u5 r1 q4 I7 M# a+ ~8 }
                         printf("Bad Input!\n");3 Q: q7 s: e" f1 t
                         fflush(stdin);5 [  V8 X4 W, w; p& Y! f
                         return -1;& X# M+ g7 @0 {/ C
                     }/ e- I  l3 p$ l, F
                     printf("opnd出栈:[%f]\n",a.data);+ ^7 U! @' w6 }$ K, X6 p
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/. m% R* ?$ U0 T5 ?! `$ _
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
/ o! U3 [: r( Y) F2 f; t5 ~5 y2 W                     printf("结果入栈:[%f]\n",opn_tmp.data);! f( s! h: ~- c$ f6 b( k: j
                     break;
7 ]1 G* R8 ?9 \8 u8 {/ z4 L            }
& [$ p+ K! b4 N  J4 w/ h9 H2 q1 R        }8 q3 ^1 [- I6 i  z- ?5 T
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                , a; m  y3 d, v2 R0 h# l  x
    }- T% {# \" R& u, x9 v  R
    GetTop(opnd,opn_tmp);# |7 `4 z' S$ X( k; K4 D' s
    DestroyStack(optr);
; j$ h! l. D/ l: W$ X    DestroyStack(opnd);* u6 i( @5 f  T
    return opn_tmp.data;
/ B- p) j8 n9 K) B5 b3 g}) L. q: L/ `/ V* j) ?8 L2 y4 _. Q) l

& k! B$ G/ K7 ]8 ichar *killzero(char *res,float result)
. y( u# O- m2 h4 y9 h{
6 w9 @* \2 B. b8 X' S( ?    int i;  T' x) X! I$ u# C1 z5 E- e: a) L7 u
( R5 @6 n9 p8 F" ]  y
    sprintf(res,"%f",result);* b; {% Y$ Y/ k6 Z0 y5 y  W8 p. }
    i=(int)strlen(res)-1;: C) o4 V/ X8 v2 E- l! H- P$ B
    while(i&&res=='0')
% u5 I1 c) C0 w3 D/ _/ V3 O6 X    {, W3 T) n+ o$ X
        res='\0';
, }! m' h0 c7 \        i--;* I: A$ H5 C3 H: @
    }& o3 I/ j, k% ?: f' o2 ]" U
    if(res=='.'), v# t8 Q% D* }4 N  ?
        res='\0';, c! A6 T4 ]6 m* w: U
    return res;9 \4 F8 W8 b# I
}8 u9 Q# l$ S: S& F4 h

9 z$ g( U7 Y8 O* E4 F; U: x$ fint main()6 O7 j' O; j; G" |" g- o4 x$ j9 C
{
, Y4 x: r. R9 @$ i5 x/ C+ ~, g* A    char ch;
$ Q7 [) I" b6 S7 S5 k7 l    char res[64];9 r3 s9 f/ ^& s, J
    float result;) H9 N/ D2 i5 ]6 M
    while(1)" p$ \1 b8 I& ~5 P
    {# c  x+ A1 ]4 I4 Y* ]- @4 Y; l5 g
        result=compute();
6 e" n0 D6 n+ S" J; ^" A        printf("\nThe result is:%s\n",killzero(res,result));
1 W$ s$ f! d7 b8 Z        printf("Do you want to continue(y/n)?:") ;
* _! F+ q: A% S( E) Z5 P        ch=getch();: I9 D; f/ n! R7 D, q
        putchar(ch);
; Y% |; [/ g# \+ C1 u4 c: o        if(ch=='n'||ch=='N')  ^* \1 m9 j+ d
            break;% b' s( A( k" E. e* w) p
        else
: c$ r8 q4 y2 g2 a            system("cls");- n% P5 `- v# u& v% A$ A1 u" a% h
    }4 `. m# Y& c9 w+ q) F4 m
    return 0;
2 p& l# f" L# b( K2 l1 _}
! [5 A6 M9 J1 @: y" M5 E! a
& c) a0 R" A5 P% p5 _3 J* y4 s
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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