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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
; T7 t8 x. I0 ]6 P程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
# ]0 y- T6 e( b( s' }2 Y& y* }" V/**************表达式计算器************/; w( p. }* E: Q3 J( s4 r) ~8 {
#include <stdio.h>
. _. |/ N+ x2 s: U2 x; Z# U#include <stdlib.h>, ?: O# {" m3 m4 v' q4 P/ ~
#include <string.h>/ m* s' @# ?% X/ [5 z
#include <conio.h>+ g* C6 i% q- X2 b
#include <malloc.h>
4 ?5 S, d' r6 j1 a9 a8 t9 l- l0 k; y
  ]& Z; ]& ?7 |" D9 R, T$ l#define STACK_SIZE 100$ ^9 l4 [, E0 C4 |$ j
#define APPEND_SIZE 10. y1 {. x5 E, E) f# P% T, U
* u' l/ h' O5 E! o# t; a. A
struct SNode{
& o! I6 u! {. A3 u    float data; /*存放操作数或者计算结果*/+ s; _! f, A9 C9 v; _4 `" w
    char ch; /*存放运算符*/6 |0 D2 o. b3 A& C3 U: Z: t
};
; T% A  u9 V3 u7 V) i$ C* c$ w$ v# u: b4 F* D: }& i' V) d9 ~
struct Stack{/ d  P9 T2 [0 `2 w
    SNode *top;
6 y% Z' t% K0 ^    SNode *base;/ R, g4 N+ _  q2 e
    int size;
5 \& ?; _: p  g1 Y) e2 z/ Z};+ z, y8 p: @+ n+ q7 C' B
; t( T1 _' G+ W$ X' Z. W2 t2 O. ?& T
/*栈操作函数*/
! L6 L1 Z4 X+ r/ C! ^int InitStack(Stack &S); /*创建栈*/2 S9 S" A$ N# A" R% Q& V
int DestroyStack(Stack &S); /*销毁栈*/
. o$ p. t, @( b7 J. f- A! oint ClearStack(Stack &S); /*清空栈*/
0 n# g! x  ~) `: @2 a( {int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/1 O5 h  t, J6 e9 G: ?3 v" J  F1 w8 h
int Push(Stack &S,SNode e); /*将结点e压入栈*/) h/ a) r! }: s& ]3 Y
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/( A1 c; L4 L5 I) D5 ?0 n# G

6 q! W! _/ _1 w+ T/*表达式计算器相关函数*/% C- M/ @5 ~5 d6 g$ q
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
1 W5 P2 T" A) @: Mint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
1 W* M: \0 F2 N& w/ D( Sfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/* ]. v- z: S' M: E- y% _% @( ~6 T
float compute(); /*表达式结算器主函数*/' i) I- N+ }, g- T! ?
char *killzero(float result); /*去掉结果后面的0*/ / w' @- t( \( F# y4 K. }9 S# k
! g( v$ o* d6 R+ f0 q+ Q1 z
int InitStack(Stack &S)( K% P( @! b9 m5 o0 r) U
{
. K7 s9 K) G% _+ B4 a    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));( t6 v( {' m+ M( f, A
    if(S.base==NULL)
. ^. O; y( Y: D' u% T* g    {! J1 F8 B! ?6 D
        printf("动态分配内存失败!");
8 M+ ~: ]0 o- J! B" M  ~/ U7 [# l        return -1;
: P5 W! C: C2 ^0 `    }
( S* c$ X6 ?$ k- u- l    S.top=S.base;8 r0 B# u) j& K8 V3 J- M
    S.size=STACK_SIZE;
6 g3 K& G+ G4 m' K4 M" l, Y    return 0;( Y  c/ L5 F- K8 b& _# y: `
}
2 J) P4 w: b# \9 `; |! U/ s( V7 Y- f7 [7 F: l# p
int DestroyStack(Stack &S)
. ]) F' m, m  d" C( c{
, p  h6 g. n, q' `    free(S.base);
( u# r/ P3 g! t3 L    return 0;
4 O0 @2 r- s) x( Z9 D2 C}
# ?  E- Q5 g, u" ?0 S- i  `8 W4 _: @
- [- W  z3 p; S- [, c: t+ i; {int ClearStack(Stack &S): a5 e6 L0 p3 u8 w* ], r% _
{+ ?7 ?2 E8 Z5 X' \+ ?, I) _
    S.top=S.base;
+ U6 m: T4 i5 z: m) D; {    return 0;
5 C; a6 [8 Y# w# y4 k0 u}% N( A2 ?# L4 y1 I
4 s9 ~) t* |# Q# B
int GetTop(Stack S,SNode &e)
0 H# J; o" w0 X2 K. r, |" K$ X{* D  d) {' r2 S( f
    if(S.top==S.base)
* W7 f- b$ l8 X: q: W2 r    {* J. T  T+ A& e7 u  d7 s
        printf("栈以为空!");' n6 ~. ^8 T5 ?. n: l) y
        return -1;
# a/ x7 e1 [5 M    }% `# V* M. s0 T, Y# y) Y1 ~4 W4 @
    e=*(S.top-1);6 e9 s- F' ^0 X) r
    return 0;
8 o( Z7 c7 _9 e# J+ d}3 z- y+ ^2 o" B( @' K

- _# J8 m) B% ]" C5 wint Push(Stack &S,SNode e)1 N: e+ i4 G; J$ t
{
0 ?% f7 _( }. i+ h3 ?, Z1 p1 L( i    if(S.top-S.base>=S.size)
; p" L' q& y9 z2 y8 |7 m    {' F' J: }0 w6 {
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
& H3 `% R1 x+ ?: Z  x        if(S.base==NULL)
2 G% K0 ~0 i0 }, f( f, o        {
0 o# t( t! }/ q1 X            printf("动态分配内存失败!");
/ ^5 x; f" C/ b5 Z" k# x% A0 [, h            return -1;2 m( E) b: f# T' A; @
        }6 m# z9 ~6 |- I
        S.top=S.base+S.size;
( w: p' ?) G1 v. [" O+ ^        S.size+=APPEND_SIZE;
! h- M* ~/ c1 ^1 N9 I    }* K" |  I5 R/ k5 L+ S4 y* {
    *S.top=e;
4 V2 Q+ f2 V+ D+ O( u* p    S.top++;4 {% p( U& N& m; G( ^
    return 0;  \1 W+ q+ D5 h" [% A
}% O% n2 e  f8 ^( Q. k
$ `; x( C% b: B! P# X
int Pop(Stack &S,SNode &e)0 Q8 g  P/ j& t+ P) h5 s5 g
{
% B/ U( Z/ q! r4 |3 e) P    if(S.top==S.base)
# p4 c7 ^3 R5 G( g* b: P8 T! V7 h    {
, }2 Q- Y2 N1 d7 C3 d  ]. x        printf("栈为空!");, `; _2 L* N' U! N. U5 {* s
        return -1;: ?6 ?& V% Q) ~- J+ p
    }  ?5 l6 y, H+ F9 q& G
    e=*(S.top-1);: L) a# h% ~. _* W5 p( O* d- M0 S. y
    S.top--;
. r8 i8 w- t2 z# a4 J; _! K/ Z    return 0;6 \4 r6 f9 g8 @% Y3 @
}9 U1 G& j7 X/ c4 s2 X
& i& R6 Q: X: A
char get_precede(char s,char c)$ \; V7 }6 c& M1 ]5 P+ @
{
- E0 m+ b9 \: ^5 k    switch(s)
$ J( b. ^+ F% C& Z+ ^) T2 G; M    {: W; k2 T3 u  M: `
        case '+':                 " c0 U0 K  ^% Z  l
        case '-':
. M( u. @  o' L. {. W# B             if(c=='+'||c=='-')0 P& x% E& D; Q5 E- D: Y3 X# }
                 return '>';% R" }& U, K5 w$ [( j- E, a
             else if(c=='*'||c=='/')
8 H; s% @- ?' A8 N1 k1 {1 G                 return '<';. D; g. G9 n8 n' k8 Q# s% \
             else if(c=='(')
4 Q( c0 r" ~* b& s" [! s' V; J+ t- L                 return '<';
) d) V" u* H. N0 `0 ]+ I, L5 z, C' N2 Y             else if(c==')')
# e% y4 ?; P$ u+ S+ i; U5 Y$ D" o7 A                 return '>';& S8 ]$ u4 T: b% t, [
             else
$ Y; M  r; x  |* k                 return '>';6 R1 k! _# E1 T0 y4 h; U9 R
        case '*':
1 _9 n2 G2 n' C! `* F+ y        case '/':
! Z" b+ b& ]6 T" h) a             if(c=='+'||c=='-')" e' s! z3 `) b& P
                 return '>';
2 W! _" S% u5 T7 }/ w" W             else if(c=='*'||c=='/')8 Y7 F! w* g  q$ u4 g1 w' N
                 return '>';( Z5 Z( N  j: z1 I- C' g  q
             else if(c=='(')8 l; o: @1 r( R; a5 g
                 return '<';3 C5 r( p+ d8 {! B6 f2 c6 S
             else if(c==')')
- o3 l& H* Y; P! \                 return '>';" [1 ]2 ?# l; }: Q
             else
0 Q0 E* H/ P# [' |1 T) ]                 return '>';
6 u" G* E3 x+ k0 s2 ]- B! B        case '(':
+ g/ V4 x: z) a! ^% a, Z* L             if(c=='+'||c=='-')
9 I+ S6 T) ?: H5 |                 return '<';. h5 J1 z3 @7 i; w4 I5 @3 O  e
             else if(c=='*'||c=='/')
  }1 a* {5 @; z4 Z+ ]8 n                 return '<';- d$ D6 g. n' [9 F, E+ Y) l. p
             else if(c=='(')' X. o! W; k4 |$ ~7 W: |
                 return '<';! s$ c4 Y( `, k2 H
             else if(c==')')
+ h7 o$ }! r3 p2 b, c                 return '=';
$ L" z2 ^# I: T. w             else) ~1 e' }& W4 m% p  U! z1 n# E
                 return 'E';
8 v$ _( L9 _" Q8 w4 S# A        case ')':& u. B( ]- g! e1 j% I* d% H
             if(c=='+'||c=='-')
& \3 i9 p5 L9 a9 p                 return '>';
$ T/ O) l# Q5 v9 \& {1 ^; Z9 W             else if(c=='*'||c=='/')
. a; g8 @) y) F* T1 L% x0 R                 return '>';* L. Q4 n( e# w/ E8 Q3 V, B" a
             else if(c=='(')# d" _8 L2 s# j4 p+ ]
                 return 'E';+ b3 D4 j' t" z0 p  M7 L) E
             else if(c==')')4 `) y4 C. j7 D2 V* }
                 return '>';
! \/ L: b3 b' G* q  U             else
" ^( ^: |( u) D5 `                 return '>';) g- @8 n6 Y2 \$ }' o& S" b' S
        case '#':: u  ?# j1 o  _
             if(c=='+'||c=='-')
  t8 b5 B  }$ y+ S* W+ A                 return '<';
$ L6 b  T; a2 S; w% _             else if(c=='*'||c=='/')4 q9 {! ^8 b& y5 C' f. Z
                 return '<';  r! Y) q; \2 y
             else if(c=='(')- H" O" U8 T8 l) a
                 return '<';
0 D' ^' n+ a) w. C' q. @             else if(c==')')# r; H" c0 f, O, e9 r  [
                 return 'E';* a; g5 X, ~7 v2 U
             else
; R$ G- ^& Y. a& e2 d8 w# ]7 B                 return '=';
% [9 c/ P- A1 C+ J- D" C" P8 N        default:
7 k# L+ i; J5 q0 M             break;6 i3 _; X0 G- D
    }8 D0 c" b8 J( k- w
    return 0;   
( v9 R4 R5 w% T& l- a}. f+ s8 I! H  o0 l& l. ^

/ ]' x! `0 F6 L: ?int isOpr(char c)9 G) f/ n9 J8 h- V* x
{/ N0 i4 Y2 i& ?) e# X
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')( |5 Q' |6 U  s/ F
        return 0;( n0 }7 h4 Z+ [& _' N5 H' @* e8 @3 X
    else ; \" T2 D! E7 h2 \! n+ x8 Y4 T
        return 1;
7 j% T5 n& _) l9 [4 T}
* h5 c" c" J$ L/ S, D+ r* F+ \/ {. A2 Y7 \; r: a8 X
float operate(float x, char opr, float y)
: V* c4 m8 u- }' R/ f" y+ s{0 z: Y/ u2 {8 V) ?: i
    float result;
6 l6 {; ^1 B# p8 N0 \    switch (opr)
( |( g$ i: W3 A1 ?( P) ^0 l+ d! z  Z    {
- v' z1 Z2 a7 X4 v+ y1 F) u        case '+': 4 K9 e0 _1 j# `% ^
             result = x + y;
, z# [: z8 n9 \5 {* e3 d4 N             break;
" E* L4 [4 [$ X  Y6 {- ]        case '-': 4 C! X, d7 S* z. ]
             result = x - y;7 y/ Z7 S' F7 U' _
             break;# E# B- D: o$ I4 [
        case '*': 3 T) O/ b5 k) J, x$ _
             result = x * y;
/ D5 C) C: b2 G  o             break;
1 s' b% K7 S' W6 F$ C& }$ i" {+ N/ k        case '/':
8 [. j" q2 j: ?             if (y == 0)
2 X, j6 J# e3 D0 a! q$ j             {2 o0 E0 v* Y( |( J
                printf("Divided by zero!\n");
5 C- i) \3 C% L7 e3 b) H5 v9 n0 l! m                return 0;
5 t- R1 u' b" `$ O6 ^, g' B) x8 e             }; g2 J3 h8 X& d) y+ E' G
             else& Q: y1 G0 R' {
             {) w% V. h3 u7 v% Y
                 result = x / y;
# c, y; v/ \4 @# |' E# ?                 break;; B: }2 I4 v* V0 u
             }; }* [3 A* k7 S5 m; ~+ X/ I; M/ d
       default: , R4 M7 D& Q1 T' \# I& ?
             printf("Bad Input.\n"); , }0 S2 C2 n  r4 @, m- K
             return 0;
; S" w3 f# `9 q8 h3 Z+ N    }, i; K# ^3 Y! G+ u& }
    return result;9 b$ N" M8 `8 `" d
}   
8 D+ ?6 Z' H7 A: [& u1 a, c4 d# |( g& G" c0 Z6 ]
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/. D$ z. {7 ^: W5 }: W: _9 i  V5 n4 ^
{& z! e. E1 ]$ {  [' f1 ~, q
    Stack optr,opnd;
; p( h( ^6 a1 j+ J    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;" _/ Q+ v% B% J* g7 N% X' q
    char c;3 m; }) |- A0 }  `1 G3 c# R3 p( \
    char buf[16];+ q' U9 S& D- N/ S1 @+ l+ o
    int i=0;
* v) D3 L1 q8 \" k   
0 [( ?' r7 \5 A5 ^# p0 I/ r  T    InitStack(optr); /*用于寄存运算符*/
  Q: v5 y" K9 w# Z    InitStack(opnd); /*用于寄存操作数和计算结果*/
1 a3 I7 M9 H- Z: ]/ Q: x1 F    memset(buf,0,sizeof(buf));
/ \# c0 Z4 C8 b; l( m   
2 E2 N# O) u& @7 T  P) U! O9 @) {    printf("Enter your expression:");( b- r1 a* l$ s% K
        
4 ?$ w5 E6 O6 [8 E1 x: M    opr_in.ch='#';
) s6 s( n' ~6 p* H$ }% X- n    Push(optr,opr_in); /*'#'入栈*/* X5 }0 S1 Z' b3 s( Q- ?: B- q( C
    GetTop(optr,opr_top);3 V3 B0 X  b! e5 k4 K9 H2 ]1 Z
    c=getchar();6 @7 [; G$ u8 G- H' c
    while(c!='='||opr_top.ch!='#')
9 _; X$ l: B& S: i. J% l0 e6 Q, J    {  `. j1 ^+ W# }
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/- D6 x- |" z; a; ^
        {8 z* k) y, l5 J1 l7 i, Z3 z
            buf=c;
" D$ M' j- K: Z: Z, N' F            i++;, n5 ~( [& t- e% b# g5 P
            c=getchar();
& Y# c) J/ D2 g! Y% [$ o$ z        }2 a1 b" K- m3 [9 B5 [" }4 w
        else /*是运算符*/
5 |% X; r7 i! v( o        {2 J$ X! y4 A, |& k) p% h) p! ^
            buf='\0';
% J+ f! H- t! \' f            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
* `  K. j9 _, F3 a            {
, T' U: F6 ^6 Y1 {                 opn_in.data=(float)atof(buf);
  l* R$ f$ o7 e- ^; ]" x                 Push(opnd,opn_in);
: g& T: v4 ?* c! m2 b; ^0 S                 printf("opnd入栈:[%f]\n",opn_in.data);$ N, N4 E" a& F. i
                 i=0;/ G+ B7 r1 f& M6 _* \
                 memset(buf,0,sizeof(buf));2 y% W8 `7 X, g: G) }% m
            }. i/ }4 Z- S' ^% N" S  q/ m
            opr_in.ch=c;0 b% \. ]3 b) {6 v3 T
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/+ N5 F0 S. Q5 J) ?
            {; m: X% H4 B) u% C3 Y
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
0 e' i! I8 m& A7 x9 K6 Z) e1 G( [                     Push(optr,opr_in);
7 j0 f/ ~/ w* \# A2 I2 {                     printf("optr入栈:[%c]\n",opr_in.ch);9 d( Z. `; Z- U/ P
                     c=getchar();
: M& S% {, d3 H- j5 j' X* e+ Z                     break;
* t' @* o* J' U0 r# W  j                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1 B- r, j+ {; B+ \+ q+ e6 |                     Pop(optr,e);
& k8 t9 \$ J6 Z/ ~                     printf("optr出栈:去掉括号\n");
0 L1 b% \, ?8 ?$ R                     c=getchar();' g/ l8 @: t: V8 |2 T
                     break;
" ]2 `$ c$ ]0 j4 s5 _( z, ^* e                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/- Z, X5 @( F! t
                     Pop(optr,opr_t);4 t' V' N" j! @  u- n
                     printf("optr出栈:[%c]\n",opr_t.ch);+ \! M$ n* ?! {9 E. K
                     if(Pop(opnd,b)<0)' q, }8 v) |! \8 s0 ?* Y0 I
                     {
! p& _$ E( D& u                         printf("Bad Input!\n");# |' N4 b$ r6 m
                         fflush(stdin);
1 Q3 b( \# ?2 w                         return -1;
6 ]+ O6 e: o# ]" h" v                     }+ ^9 S- I4 R# ~% q! r. i0 z- Y- L
                     printf("opnd出栈:[%f]\n",b.data);  Y6 P# P. L; l& D2 C
                     if(Pop(opnd,a)<0)8 y1 B( u/ z( [' Z
                     {# C9 r: P1 P1 V; z- C: ~1 v* z2 C
                         printf("Bad Input!\n");* D/ N) A- j6 C+ T2 @  u
                         fflush(stdin);2 Z8 o0 i+ A- Y6 G0 Q
                         return -1;
6 |' \/ F) K* Y                     }" b0 Q, q7 H+ `4 c
                     printf("opnd出栈:[%f]\n",a.data);
; v# [" L" S% @1 C. J                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 M! y! b. ?5 u  r. _1 ]+ W% ?7 d6 X                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
) t2 X) i' F* {' g                     printf("结果入栈:[%f]\n",opn_tmp.data);
2 U- L' \) j7 E9 r                     break;
  e1 Q# e$ v5 u, B            }
+ C9 h' h; u& |4 H; m- C        }4 f& b& Q6 f. ^
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
$ u$ S: n9 S3 A4 |* x3 x    }
! R0 f0 A" e3 ?" d    GetTop(opnd,opn_tmp);
( Z: y: T2 B3 \! V    DestroyStack(optr);! ?' h! x7 m  @  P7 N+ M9 D
    DestroyStack(opnd);
' s$ q+ x+ f$ B" q4 ?/ m    return opn_tmp.data;: D9 D+ f8 V& ~! d  Z
}
4 A. X& f+ k* ~+ h. e
2 C- x; h8 X0 ^4 t# f# a) Z  H/ M2 hchar *killzero(char *res,float result)% ^5 F8 M( j  ^9 R
{
# S, D: K  x- w+ o  N, ^/ f    int i;
1 S- f/ j8 o1 Y) P7 S
* @' a- A" k2 i9 q    sprintf(res,"%f",result);+ {) \! f1 h4 k! T" U
    i=(int)strlen(res)-1;2 ^" b& C3 P/ u0 a% S) h/ s
    while(i&&res=='0')$ q% s; j" J) f, q  v
    {+ j: v- c$ A" j/ m4 N4 p. r
        res='\0';
% e- f6 I  g3 a. S) @0 G" Y& L8 p        i--;
- m; A/ i* u1 e1 Y2 M0 a    }
% i3 w5 {8 b% v# g5 v+ P    if(res=='.')8 K- o' {9 H* O* A1 D+ d4 K: d
        res='\0';+ s, h+ ]& h+ [. H9 U% L
    return res;1 @2 z* O1 ^+ L2 U8 |1 R: @" X
}
# u3 G, U2 {3 C# j$ c
& y7 \8 s: ]$ U5 w/ ~" [  A) kint main()
! y5 C9 ^9 ]  k: ?( x" t{
1 h: m" ^: j0 ?    char ch;
* j/ `1 J# p6 B$ L6 I    char res[64];+ H% k, \* |! F
    float result;$ U1 s; P* g! |' i+ p' a6 a
    while(1)0 W) a$ J2 p  l8 L* `4 x$ I
    {
/ k" j4 H, ^/ {        result=compute();
3 M% M2 V% C, b3 Y4 t0 b        printf("\nThe result is:%s\n",killzero(res,result));  F7 h7 C9 D8 r1 ]9 s
        printf("Do you want to continue(y/n)?:") ;
, G- ]( s$ ]9 I        ch=getch();8 G4 E8 U8 S; ?. k1 @' J8 r$ r
        putchar(ch);4 \) j5 G: R) y3 c3 N, l- w% [
        if(ch=='n'||ch=='N')! N& ]0 n. J: O7 {0 `! |
            break;6 \# I7 O- w. N# ~5 S; p+ y2 e; _, ^
        else
7 ?! s, ?9 s$ I6 G# L! \$ h7 r            system("cls");5 @& F( a$ d& m8 K
    }! C& Y( U, j7 D& S
    return 0;
1 v$ e5 x3 W; ^0 j$ N/ l% _& T}
* Y. Z. t! C+ S+ j- @) |
" o5 i0 d$ a5 {$ B! F
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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