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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
( R! L% z2 d; T# R3 x/ c, `程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=6 q8 A( n' k" o3 f) f+ s
/**************表达式计算器************/
) r" _! Y4 Q8 I! [& ?: v1 v$ ~9 p* f#include <stdio.h>
' }; }2 ?9 r$ e7 ~* B#include <stdlib.h>
* U  }' I) ]5 K0 a' X#include <string.h>3 k7 [! f7 X  N
#include <conio.h>  R- [& U7 k; O5 }' O
#include <malloc.h>
- C9 M, W* A' S* `% s
5 ^! ]; D& p5 ~" ~6 b; r. D2 R#define STACK_SIZE 1008 _* H: }* D% \6 i2 G" ~7 [
#define APPEND_SIZE 10
) F& a. ~4 O& m$ m" w/ u' I3 Y4 ~# y: z2 R0 v
struct SNode{
! P% l, x6 S5 L' _: V    float data; /*存放操作数或者计算结果*/0 y4 C. n! x% k& J- l5 s
    char ch; /*存放运算符*/2 V  M) L7 x1 S. M9 R" T  O" }4 h
};" T6 `4 X9 b, D2 \/ U

  R4 M. H0 P/ `2 }+ Z2 ]struct Stack{8 j5 T. Y1 p4 E! p, `# F  t# O8 F
    SNode *top;
: h  B! {8 B: o$ O. D1 j    SNode *base;
1 `9 l+ e1 n8 R5 {8 K% ?- @    int size;
$ H: Y8 I% [7 C( q- d3 T2 _! O};1 Z% [+ n; ^1 v

& L* |* ^5 a7 q' f' S/*栈操作函数*/
4 J+ u' w% z# c5 H% Aint InitStack(Stack &S); /*创建栈*/
$ N3 n8 c# Y9 y0 H  c' N- yint DestroyStack(Stack &S); /*销毁栈*// Y2 r" S7 n# r
int ClearStack(Stack &S); /*清空栈*/' p, P! c; d  j0 x" L5 u/ y# ]
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/: H4 _: z( e7 B% N# Q9 q' `$ o
int Push(Stack &S,SNode e); /*将结点e压入栈*/3 w% B/ I) ^5 s1 S' C4 ]
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
9 Y( Z, C) l. ~0 b5 M' w
8 Z7 ]6 Y/ r7 }+ [- X/*表达式计算器相关函数*/. n  e9 v1 Y7 F6 U, G9 F8 ]- |& B: s
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 R1 V4 D4 _* a7 i7 g! gint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/# N) Z* `9 A+ Z) U9 v* M* u( E
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1 }5 s2 S7 v2 M9 wfloat compute(); /*表达式结算器主函数*/
3 `+ f6 \5 X' Y, F8 l! tchar *killzero(float result); /*去掉结果后面的0*/ 9 W) @$ z& h% r/ d. v6 l! d, B

9 q3 v" c9 _' K/ pint InitStack(Stack &S)
+ O# y& W2 o8 `+ V3 `{
$ Q- H9 q- M/ T8 J/ B    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
. ]  X6 W9 C( M/ x! n    if(S.base==NULL)  j" T$ J+ c3 a, F9 I
    {
0 l: Q# T9 G9 \: H5 K2 J        printf("动态分配内存失败!");
, i. M; R: ~0 S" C4 X8 A: A        return -1;
1 `$ h+ F+ G% ]9 C, ^    }
! d$ B- q4 ~6 A: F$ C! ~7 b    S.top=S.base;
0 s9 x2 g6 G! B7 L& Q7 k    S.size=STACK_SIZE;
% i1 R8 g2 k$ G. I3 Y) q    return 0;  t6 F7 P) J( R; x8 G" @$ k
}
: ^5 n9 a% O- G6 n/ n3 b- @3 ~9 D
int DestroyStack(Stack &S)  t1 ?6 D  U0 {8 z6 {: \: Y
{" S/ s/ f/ T- ]" h
    free(S.base);
  i' [# R8 h+ T$ \    return 0;6 Q8 p3 G: z8 B5 ?8 b# M: w
}
" S4 o% x  H8 J  i
2 P( Q8 f% \# {" h+ o( oint ClearStack(Stack &S)
9 G$ d+ M$ P9 q  f3 E# ^3 I{& ~; t; `6 A( G9 B% d
    S.top=S.base;& o0 z4 g& G: {- W) K8 C: W
    return 0;
: m. L: ~% N0 a0 k/ X& r/ s}
0 F# y5 m0 e0 x/ m3 V; _/ `: R0 s) X3 b" ^4 A& {! R  M
int GetTop(Stack S,SNode &e)3 u0 T+ ?5 @" i" X  a5 D
{5 K# {1 J0 f( k, U# q
    if(S.top==S.base)! |  W" C8 g+ X
    {+ |( S8 C; n" L$ P
        printf("栈以为空!");
2 L5 Z$ [' t) |7 r8 X5 X! W2 g        return -1;1 a$ k) \+ i' Z8 k5 B$ D% R0 B
    }$ |9 B# i( P1 t. S' R( W  e
    e=*(S.top-1);
  e2 w, H* k7 R: e& d& u    return 0;
. _( n' y2 m6 ^, }) \}+ k6 |" ]$ {2 N
8 Q- s' M! x$ N2 F
int Push(Stack &S,SNode e)
' _$ O+ m9 _, w2 E{
5 ~2 Y+ R- Y* p% o" n- c    if(S.top-S.base>=S.size)6 J, m) g- R1 t+ {" ?
    {4 Q& }. ]2 _2 g
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
7 D5 }5 b: h, @' e# O        if(S.base==NULL)" g" J( J# a# s3 a5 b' u
        {
2 q- j* g5 ~8 q, X            printf("动态分配内存失败!");* y$ Q7 g/ q: S/ L) l( R# N; B# T
            return -1;. [3 N' q! m7 x  `
        }9 l' t0 O: w( |  ?  @
        S.top=S.base+S.size;
' F7 h! o) k9 U        S.size+=APPEND_SIZE;! e0 N% X1 g% r- [. k8 b- {
    }+ g* q) ]5 f3 {3 V3 U0 ^* g  I. M
    *S.top=e;
, M( z7 o* R6 _    S.top++;
& M9 a) n; z- p& D    return 0;! _; X$ ]" D- A
}2 O- M! g$ w1 B8 T
5 Z) v# r6 D- [+ {1 y
int Pop(Stack &S,SNode &e): D: s1 G! I% ]$ h. U
{
- A! _1 Q  o4 ~! B8 Y    if(S.top==S.base)3 h+ l! f, M! S& }
    {. O7 t0 u# [/ G$ i  y8 p# O
        printf("栈为空!");$ R+ P# q* O# z* e8 V4 j2 K
        return -1;
4 O3 ~6 K% j+ K* ?" U) a) R" |    }
6 v4 M8 G* ^, r7 b+ s    e=*(S.top-1);
& Y6 z! q# t0 q% O% A& i    S.top--;; s( @5 N  N7 j
    return 0;2 M+ j, Y, j% J6 d
}- Y: b$ ~: |% W" |; m/ v

! f, `9 ]. E7 schar get_precede(char s,char c)
3 |% Z% ]* p& S, H& b2 H  l{
6 t! U1 K# N% s# C  U# b5 g1 h    switch(s)$ o5 w  l' U% [4 C- f1 e' W2 x6 P
    {
7 ?, [: {+ M+ e; k9 Q3 I: X) o        case '+':                 
8 t: d9 `( h+ o9 o, C- D. F3 b" N        case '-':
0 p3 J4 C; \* o% y; U$ @6 V             if(c=='+'||c=='-')
* [* W3 z$ v' |  Q. b! j8 Z                 return '>';
1 U$ Y3 [3 E- j. @             else if(c=='*'||c=='/')0 H* g7 N! y8 y( J
                 return '<';/ {3 I; K8 J! ]0 Z( s
             else if(c=='(')
7 q0 J. l9 h# t! t                 return '<';
1 E) `. i8 T" D; ]) u: `, e             else if(c==')')
1 m6 m! {2 W) X' d                 return '>';3 Z" P7 v* E3 Q, |/ x; e0 _
             else # p' J$ j* \9 a
                 return '>';* y2 j/ m7 b( Y# W! w- P/ Y; l; u
        case '*':
9 d5 B3 A5 X) a# u; ~, K3 b" W        case '/':. n  v$ F/ @+ m( K! B8 w' v' R
             if(c=='+'||c=='-')! C2 b5 A: l: I( i* X
                 return '>';, }/ T( b" k9 L6 j# {
             else if(c=='*'||c=='/')
; H* d, I6 F8 d1 [9 k5 f1 D                 return '>';& X( ~7 S" a  l; b* H; K" r
             else if(c=='(')
. ~% H4 e+ g5 q' s, O7 C                 return '<';
) H8 u8 M$ S. H  l. s; O3 ^             else if(c==')')! m# V) h; B  R' W# N* f
                 return '>';
& v2 }* J/ X2 @& `$ r+ A8 x             else# N+ r8 C/ d& S+ w: c- U
                 return '>';
! G3 M% D% S! }; v( l4 b        case '(':
, g% ]  R! o$ t) m' ?             if(c=='+'||c=='-')9 y- S7 q& O0 F- @- _" Y$ Q- c
                 return '<';3 }7 @' ?* H4 B6 J) ?2 W1 z  W" S! Z+ P
             else if(c=='*'||c=='/')/ u  Z5 F+ Q0 h( V& {# ]  W" E4 R
                 return '<';
; F( A) U" h! H             else if(c=='('); `* U( H/ {; S. F" p6 _
                 return '<';
" Z5 D% r- e- {9 v( a" M             else if(c==')'): z9 i2 A5 ?8 ?# Z; y1 t: Q
                 return '=';
) v& M$ ?  M8 M             else
0 R4 Y/ X/ B0 }- ?, R$ R% X4 r                 return 'E';4 Q+ k+ e* `$ e) b0 `# m' m% a! s* s
        case ')':0 p$ t1 H+ [) }9 @7 r9 ~
             if(c=='+'||c=='-')
( {9 a" }* Z; h8 {# W* [                 return '>';
1 W2 w4 [; n7 s  Q             else if(c=='*'||c=='/')
! }1 ]* \. r1 `2 t+ H4 R                 return '>';' f* B8 o- H0 H3 T' b
             else if(c=='(')/ b- E# m4 @' T1 ^9 v, }( S2 u
                 return 'E';( y- F; @" }+ S
             else if(c==')')% @2 Y# c- M1 A. P; s& s1 J* m
                 return '>';
, o3 x  _! t8 Q1 \: P3 k; p             else
$ u8 G" q( ^; g                 return '>';
4 R# I) e& t) |1 O        case '#':0 _$ p  s+ R$ |  u* s. r5 |
             if(c=='+'||c=='-')! f# e/ }5 f) x+ J4 g9 X# `
                 return '<';, x- {  _  k8 b$ G, D/ A6 U: n* `; d
             else if(c=='*'||c=='/')
! E1 Q0 W& l: l                 return '<';: l# e1 Y8 [; @. s6 H
             else if(c=='(')& B3 A) C0 f% h! F
                 return '<';3 o1 J6 Z+ g6 B2 a# A% m
             else if(c==')')# Z# q2 s$ {' i0 o( }! i& X
                 return 'E';# A, k& }5 D' L, W, `& P
             else
# p, p' g6 B# v2 z; l& o1 a8 S                 return '=';7 Z6 g4 H! y4 J
        default:$ R9 k* z# Q3 H" X
             break;
1 j  u7 b7 x8 Q6 q4 w5 N! V    }
: q4 P1 V" h( `! N0 N    return 0;   
3 G: ?4 n+ ^! d& Q# o2 n" _}
  w3 C0 W7 w8 r' Q: a- O6 p; Z9 x* ]8 D
int isOpr(char c)
4 L( z5 a6 d& W' Z4 A{
; [& i; a1 N# K) P' j: C7 X    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
  N% ?5 M. a3 q9 Q4 W6 ~: |        return 0;" h6 s( Y8 e" E$ u" ]* \+ T
    else & U, Z! t. f( \* G5 ~
        return 1;! Q$ F* ?4 E! v' w& q0 ?
}: l% o4 \+ U9 ^" J* B3 }" m
' W. y% }6 J' n' `
float operate(float x, char opr, float y)& e2 k& z% M8 I% z2 ]
{# |, d* [7 l3 ]: b* D9 U
    float result;9 q0 d/ {' F2 {" L0 |( {
    switch (opr), E* {- p, p( g$ `
    {1 M. A5 M! f: u3 {
        case '+': % s' D; J  ]( V" _) C* \
             result = x + y;' u4 c' o8 B; X/ F, G: p' s
             break;' o, Y" d9 ]) c6 H; w  \
        case '-':
) ^8 S6 v4 S% ]' K             result = x - y;
* k' m+ ]. G3 O9 Z0 R             break;
, G( a) Z1 s  M        case '*': 5 y" h- w7 t& N5 T, L3 w2 l
             result = x * y;1 m8 e+ Z( K" |; e* E$ a; P. S; F
             break;
( e# W% E4 Z7 o. N# G4 f        case '/': 1 {. V* K7 u: q0 p! e( A7 l
             if (y == 0)
  h8 D( L1 @/ v7 I             {
) t2 N3 U% `: ^; ^, K" f                printf("Divided by zero!\n");
9 ^4 J( ~- C2 A8 [. G4 t                return 0;
( w7 u) w( z) k, Y; q% M             }. f: j9 O) k/ ~
             else
, M) I+ L% G+ Z& t6 _- N8 B$ b$ B             {6 _& O% ~0 l" H: @# W7 z
                 result = x / y;
( b$ G8 w+ s" X; f! B* u                 break;
5 q9 ^9 E5 V7 J: [7 b             }
' O$ d6 [; E7 m. g2 Y& P9 H       default: * H6 [5 D1 o7 o# t8 y0 I; o5 J
             printf("Bad Input.\n"); 8 M) z+ K/ K8 _+ Y/ `' @' t5 g: O
             return 0;) T3 ^, w$ K& [4 u$ q6 R) a
    }
: a8 T/ o  L, Q: [# H    return result;
7 {5 v3 g+ ]: v$ l}    9 N) R+ `7 G& G' |

% b! ]  X! K# I/ X8 \, D4 X5 K; z# tfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 g, A: R& W) s# i5 h. n" b2 s3 i{
& j4 [! j% L, N7 W1 X    Stack optr,opnd;
( ?  t  T2 `$ U4 ?- ?    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
# c( O- Z6 w" T; q/ }' I    char c;( z4 r0 q  k8 D  D& U7 c
    char buf[16];
  F+ @% o$ L9 ?8 o- V$ f5 C    int i=0;
! P7 v6 h8 y* p% \+ q3 j   
' y8 F0 j, w( C  u0 s    InitStack(optr); /*用于寄存运算符*/
1 l6 p" ]* a0 X" ?7 K; z" ~! I    InitStack(opnd); /*用于寄存操作数和计算结果*/7 _, T: _# _, B# A1 _
    memset(buf,0,sizeof(buf));
6 ?7 q' w6 C/ \- e, @' [    - T' M  \. p0 l3 z/ ]
    printf("Enter your expression:");5 E+ j3 e& m: }3 A; O! [1 p9 a# Y
        ( |6 }, e4 j" D, b+ Z
    opr_in.ch='#';
* G, s' O& k* L; ^$ Y: f4 W    Push(optr,opr_in); /*'#'入栈*/
5 u* d1 \# P6 I& h' Y: Y) D    GetTop(optr,opr_top);
' D$ [! C# n) y    c=getchar();- [( f6 J7 w+ k! y- V; @0 E) I
    while(c!='='||opr_top.ch!='#')6 C1 b1 _- @9 I8 K4 O6 `
    {
% b% F% G$ m/ t% ~! D7 r( b* K        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
/ K- N; J8 X  T# _# j1 R        {' b+ |: K( y6 n9 a) }3 p! m9 U
            buf=c;/ C3 ^8 {* S* b8 G8 R
            i++;
3 z7 |1 S% [; Q5 [: ?4 p            c=getchar();2 r2 g( F: e. g# \* Z
        }( |2 D' p2 Y, Z1 D$ e2 H- C7 _! }- ]5 Q2 U
        else /*是运算符*/% b" y# Y: k( t6 r
        {
6 V: B  b7 ?  q% j7 w8 ~1 R/ Q" K            buf='\0';
  L3 w7 R% Y: ]. u6 s# V( d            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
' \: R( [% v* Q0 O. H& A6 G8 q            {& d/ e6 j6 S5 F- H5 g* S7 a
                 opn_in.data=(float)atof(buf);. x& {2 t; g' w9 ]$ \! n# O
                 Push(opnd,opn_in);7 U4 Q0 c1 Q8 k# P
                 printf("opnd入栈:[%f]\n",opn_in.data);
( L, X/ G/ Q( z7 }- C( Z4 f                 i=0;
; k# K8 m/ O: Y% [                 memset(buf,0,sizeof(buf));! @4 A! @& ?8 s! b0 b5 l
            }+ k- ?; `/ b; O/ E4 i4 c
            opr_in.ch=c;
- l( t2 L' C: B: j9 |6 S            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/7 k* j% Q+ g; H
            {/ s4 O) Q' f' D% \
                case '<': /*优先级小于栈顶结点,则运算符入栈*/( x+ Y  F  `6 O: v5 Z+ u
                     Push(optr,opr_in);) U. _4 |5 G) P- c
                     printf("optr入栈:[%c]\n",opr_in.ch);! B/ K& T0 U9 `1 Y. ]2 s! {
                     c=getchar();7 P5 S  H1 A9 V- a7 A! l- J. O& y+ c
                     break;- ~9 u6 ?1 m6 T
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
5 ]" h3 G  T4 S4 F) M, i6 h                     Pop(optr,e);9 D0 C: J. a5 M2 i& n
                     printf("optr出栈:去掉括号\n");* d5 g9 t1 j1 A! z. b2 Y! n
                     c=getchar();
. i: u: I5 S6 @5 E9 S                     break;- F# G9 d& f" j+ }
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
3 J! w/ F; ]; m4 ^) v* M8 ~                     Pop(optr,opr_t);: e. ~7 d5 y  D" q* @! G
                     printf("optr出栈:[%c]\n",opr_t.ch);+ N) v0 Y9 ~% v/ l: G
                     if(Pop(opnd,b)<0)
4 y6 ?* W# b9 z# `' S, Z                     {
1 g( {' ?# g# m4 U4 }4 `) o/ a                         printf("Bad Input!\n");2 M& D( t+ @: i7 o' p& k2 [- s5 F
                         fflush(stdin);
  g8 Z; f/ B" `                         return -1;. M0 t) ~, D, Z% M
                     }: j* X) f, X& H. h
                     printf("opnd出栈:[%f]\n",b.data);
/ v! ]' N# ?9 G& k- L& N                     if(Pop(opnd,a)<0)
1 f. U6 C' h& \2 B                     {
% G4 i* j! G9 E  J% T% K                         printf("Bad Input!\n");4 J3 g3 S' E7 @0 y' l3 q3 L
                         fflush(stdin);+ g2 ]/ E4 \6 q8 \
                         return -1;# e5 h, _9 O( x
                     }+ }0 S/ F; o# u- W
                     printf("opnd出栈:[%f]\n",a.data);
- Q5 I% P) u$ ^8 s+ O+ i) p1 {$ ]                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/3 |1 ~4 K, ?! F1 X2 E: i; v& T
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/; B. I! B; l( O# q# S! W( Q
                     printf("结果入栈:[%f]\n",opn_tmp.data);
) e. K: _4 R! W# ^3 n( N) ^                     break;
4 v, [! u$ ^5 |. ]: k            }
5 U! d) q1 z" n' I2 ^; O: m        }. C3 j+ v2 ^2 _8 p9 P8 k0 ]
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                  H' U+ T# P4 V& Q
    }$ k* }4 J4 e! h2 D2 ~
    GetTop(opnd,opn_tmp);
1 a% A5 ~6 \( v& d% H$ g; s: _    DestroyStack(optr);) W$ s5 i2 V  Q, D- b9 O/ ~# X2 k
    DestroyStack(opnd);( [& D# l! f' j- N* G( ]6 {, R
    return opn_tmp.data;
- o$ ~+ L. `" m/ x$ A}* @  \5 L. }$ y5 B% X& V

' W& ?7 C  v2 s" V& k  P* xchar *killzero(char *res,float result)
- x% G9 `3 e/ y4 E* y{
" l1 T: Y! }4 T8 v, T    int i;
7 C# B3 `; a( h( f7 f7 f! E) ?
- X/ }/ M& ^( a    sprintf(res,"%f",result);
' a7 C5 v: W' S5 l/ ]5 P    i=(int)strlen(res)-1;+ C: q1 u3 d# t- m- ~9 _
    while(i&&res=='0')
7 v; l3 w( U5 t    {! o0 ]; Q, E- S7 C# ?
        res='\0';, e# k( P) ?: T- l' r
        i--;
6 X% q9 |+ w9 L$ E; @    }/ w/ r3 L" P: p5 Z% U
    if(res=='.')
' w2 a+ o2 V8 p8 `        res='\0';
8 E- c! _, ]+ t0 h+ \* B% a0 A    return res;
5 _, s* i* A' x}$ v( l6 n. N% V  K' t: o! `5 l
6 W  R1 R" |$ h: y3 i0 z
int main()/ K9 h* _, s& }  @0 U3 e" u
{
$ I# M5 D! J8 M# g9 j0 j9 [, p    char ch;
$ ?4 i5 t( W8 g. [    char res[64];
) z; b, m1 w; q; h0 Y9 o( I4 Q4 i' w' Z    float result;0 C* s& P# A* k( S" Z5 j
    while(1)
4 D& {+ T9 o; K( o, a# z/ U! t% y/ G    {0 v2 C7 v9 S  L; W, s
        result=compute();- o9 s: g% U. T+ d% Q8 T& N
        printf("\nThe result is:%s\n",killzero(res,result));4 G& [3 K5 g9 l1 G: g. |- u( c, @
        printf("Do you want to continue(y/n)?:") ;8 ^  q0 R; I2 e' L; {* i
        ch=getch();. Y' p& K; ?# K/ F. h" r1 s& K
        putchar(ch);7 e! j2 R( j$ c' r. t* d& `& |
        if(ch=='n'||ch=='N')
3 [5 K9 Q" K  }! u; r) |0 e            break;
( x7 n7 ]5 g# D3 }7 ~! z$ j; _        else) s$ U. h: c, E" i
            system("cls");5 v" y7 _+ q5 w, I7 |9 W* [1 [! R
    }# ?+ F9 a; K% Q# C5 z
    return 0;
+ [" R7 L' j" r4 H: E6 D}

3 D( C- r( \) ~- J
/ u4 j+ `2 q" m: ^5 @+ R, p[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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