返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
1 c6 o* f+ u3 P. k: d( `0 Q) e& ?程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=7 W- p  F- `7 r, F3 I# j7 |
/**************表达式计算器************/
' Z/ k  H: a; z# J+ T#include <stdio.h>& B0 P1 ]9 i' S+ P6 E$ h: G% h6 D% {' h
#include <stdlib.h>
; N, \$ T9 P1 T5 o0 K; Q#include <string.h>
7 ]5 B( V7 J: @8 f9 q$ \#include <conio.h>7 I( ?6 v6 ?- u0 F# E
#include <malloc.h>. n' N, J7 C  |, o& _  b

1 I) f6 r3 C9 R0 `1 t$ y1 p#define STACK_SIZE 100
/ @4 T1 F; p0 m' D2 U3 K: O#define APPEND_SIZE 10, s' [0 B2 k1 S! @4 F3 I* B

; f1 [( ?8 f2 A; \struct SNode{9 B8 r$ y2 f+ `
    float data; /*存放操作数或者计算结果*/
  \0 V4 f  j$ I4 O5 `" h% [    char ch; /*存放运算符*/9 ]6 G3 Z1 m8 J2 E4 l6 K
};$ @% `: V6 _8 o
# X: n- j1 K% n
struct Stack{+ y! }5 ?; J+ P0 L% d1 M
    SNode *top;- N; P, k2 A$ j) N) s) Z  R" h
    SNode *base;
8 |4 {; c1 X0 @8 \* q2 g    int size;0 i; v& ?# G* j) b* P
};1 r1 g* s1 T0 ~  I1 h2 Q. ~) o
. H" r; i4 B0 |% ~& K
/*栈操作函数*/( _, H. x8 b- e$ \0 a! S5 ^
int InitStack(Stack &S); /*创建栈*/
, t0 h. y8 B4 u* D. E# q- lint DestroyStack(Stack &S); /*销毁栈*/( J$ M/ L6 V8 j3 Z: b; _7 L5 {0 t
int ClearStack(Stack &S); /*清空栈*/7 P1 [7 e7 s; D: A5 w8 E* f; S
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( n/ O  U9 F  P, h; u0 ]int Push(Stack &S,SNode e); /*将结点e压入栈*/0 [; ^- W( s; M0 z2 O8 _
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/9 D2 ~/ ]' H" l1 k" b

3 q- }4 c' G# K$ Y& L& a  ]/*表达式计算器相关函数*/' w$ Y# Y; J0 s1 z1 O* p/ P
char get_precede(char s,char c); /*判断运算符s和c的优先级*/0 S" R+ @1 H, V6 g
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
& [! l* T" s5 g8 ^# T3 `& M3 I6 Zfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
, b! B4 q* ]: i& Q2 D. rfloat compute(); /*表达式结算器主函数*/
( x. h- j5 S4 O; ?char *killzero(float result); /*去掉结果后面的0*/ + Y% L" z. v+ T, \+ E/ f% {5 [- W
' t" |0 u, }* F$ G/ ~6 W
int InitStack(Stack &S)
  i3 E$ Z" Z) D. ]" q{8 m/ L; x; i- u
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));' x6 Z! G! o8 i9 d  p! |
    if(S.base==NULL)
9 c+ G  Q# X" z* g2 `( i( f7 s    {
; I+ ]9 e* h4 l# S        printf("动态分配内存失败!");! ~: E% L6 M6 s% E4 A' S% Y# T7 r
        return -1;! J( X' k3 p5 h9 K
    }
9 {5 [7 r" p$ G/ ^    S.top=S.base;
3 R# z, D' D% w; y0 G    S.size=STACK_SIZE;
' `  I# C% O8 x  K% \! F    return 0;
2 I: l2 B0 S5 F( j2 w8 `! ]}- y+ D' v- V0 U/ g* e7 N  O

: Z4 P. b8 m6 }$ ]int DestroyStack(Stack &S)
6 S& v1 o/ k6 g2 {# Y- _" M$ W{/ l& [0 a# |6 d' R  k9 _
    free(S.base);
1 |+ y. r7 C8 \, c    return 0;0 h$ s! j% h- v) e& X6 a" ?7 ^
}: ]) A  J7 d7 i1 S/ r, @, K5 G0 _
% ^5 Q' P& m* p  r& o7 z: U' n
int ClearStack(Stack &S)
2 e% K2 @/ v0 V& E. S{
5 Z! M) {& o7 W+ K. O2 B& t    S.top=S.base;
- w, {5 ^. ~( Y, b, ], H  u    return 0;
* w# D. _( [- v( i}9 z( f: F$ P' o6 l

' ?8 Q( K8 Z: d8 xint GetTop(Stack S,SNode &e)
( W2 u/ |3 Q2 Q; n  I{
. H( X5 `# d! N: p    if(S.top==S.base)
' }+ ]8 Y! t/ w1 V1 v5 Z: M    {
. ]7 N% A* f: O: L        printf("栈以为空!");# Y3 M+ ?3 e8 l- j
        return -1;
0 ]$ k" h  G0 f7 V+ `    }
+ \- Y: W/ X3 ?7 H    e=*(S.top-1);. ?" [& M0 v% H! @5 O
    return 0;
& j: B0 x' f, _& D}
2 t, l9 Y( R1 H% j0 ]4 U/ P; [/ ?; j  `+ M9 e7 R$ K
int Push(Stack &S,SNode e)
3 ?6 d( J9 R' K4 D0 I( n{
" P0 l1 }& F, P: u    if(S.top-S.base>=S.size)# w0 m8 o2 E- u
    {* Q5 {; }" ]; z3 R7 `
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));6 w0 S- O) X8 ?8 N' {* N; H' r
        if(S.base==NULL)# E3 D3 [; }7 [4 b8 w- \9 }
        {" a  N+ G& S9 M2 ^. I9 R
            printf("动态分配内存失败!");
7 L+ W. @" U9 ]/ Q# I( b: R            return -1;( J( n2 `. r  Z: X' U5 ^
        }0 S2 q2 Q, f  ^# ?4 T) `6 ]
        S.top=S.base+S.size;
2 N7 O* m/ b6 F6 N0 c        S.size+=APPEND_SIZE;% }/ Q& c# U& f9 O- t* a! G
    }
4 x( j8 D) B& h( N% f    *S.top=e;4 J3 ~) a7 D( u1 L7 z
    S.top++;/ [) {" H+ {1 [6 z' F8 @
    return 0;& B; S" s9 |. Q
}( l1 x; [- h8 K  v& `% X
0 B) k/ A9 s, f+ B6 G. k2 }4 E
int Pop(Stack &S,SNode &e)
+ C) S3 O, q" H{
' b4 G* J' H8 P( V1 G" j5 ?    if(S.top==S.base)# k+ }. D+ [! r1 J  F! y  V5 u$ T
    {% ^5 U7 j: }2 N! z  O" R
        printf("栈为空!");
0 h6 B$ B2 H# L; L0 m- `& R# E, U7 D3 x        return -1;
% F- }& r2 L# v5 @& C    }# w1 g! o! p! ?# p  p/ _
    e=*(S.top-1);  T" b8 P: `/ F* e6 l( h* J+ s0 Q
    S.top--;
1 G0 u/ H6 R. T/ b% W$ F- w    return 0;6 U% x+ ^7 I1 I( K! E/ T9 l' h
}
1 W, }" u  `3 q
1 b' \( E9 S3 e' L5 T0 \char get_precede(char s,char c)
# J$ ]3 M* |. L: Q  S{; Y( F" g# F4 ^% O9 Y; @
    switch(s)
, s8 T% S" G. E- A4 ~; D$ [& e+ i    {
5 X; _, n( S4 z# ]        case '+':                   ^) C2 _4 S" r7 X3 K
        case '-':  j& O8 n, ]- I3 W. F
             if(c=='+'||c=='-')4 S, y4 V* A: U" N3 u7 n3 V. _
                 return '>';
- v. ~7 |5 b4 H+ \' K& C. T             else if(c=='*'||c=='/')
; B# d6 J/ A( O% f1 Y- J9 g' _                 return '<';
2 U$ ]* o7 Y: f5 D0 v$ o             else if(c=='(')
; \* O, H+ e: Q1 u  `! M( h                 return '<';
( f% I% t8 ], k3 f             else if(c==')')
1 R3 {8 x' Z  M" e' T                 return '>';6 I$ w' |: D, L$ f# }5 Q+ u/ o
             else % X0 ?$ Q7 B2 p$ |& D2 `
                 return '>';" r, @( r* \8 V7 e
        case '*':
9 b3 v) j8 A# ]' _: D+ G* Z        case '/':! s$ |) Y! k7 I$ ]  [" p% Q. J3 a
             if(c=='+'||c=='-')1 ?+ o3 ^! _5 i1 C+ C! h, o
                 return '>';
' K% z0 ?% b6 o4 j             else if(c=='*'||c=='/')  e7 u9 H6 p, `! O6 `; X) `
                 return '>';0 H+ ?, ^4 ~% |7 \
             else if(c=='(')
" q$ \: \  M3 s' W9 e6 S                 return '<';0 u  j/ f$ m" k8 g- v
             else if(c==')')
& V  ]# _! i7 [9 j, S                 return '>';! ?" |9 e1 p) p* F, V& |
             else
2 f* p$ I' J2 t4 o& f4 \% X                 return '>';
+ z  n7 s8 D! {6 V2 v        case '(':9 P$ f: c8 {6 |2 K1 ?) O  H
             if(c=='+'||c=='-')4 ?! q+ I7 K% y2 e2 P5 x
                 return '<';
2 ~- O5 k! W/ @/ Y+ d; u             else if(c=='*'||c=='/'). T" k; u( [) O8 {- k+ R6 d
                 return '<';
; ], j7 s$ g+ P# R( G+ M2 Z8 v             else if(c=='(')2 P5 a% t& i3 V5 g+ E
                 return '<';
2 w, N/ I6 u8 L             else if(c==')')5 P2 z9 U3 F6 ?# N& ?6 z
                 return '=';  ^6 a$ \2 `  W8 I' l1 y
             else
2 F$ ^  K1 Y6 M& H7 q1 l                 return 'E';
3 {/ D% s6 |4 @. L0 X  ^# v0 {3 n        case ')':# B* E, o3 B8 B+ f) D
             if(c=='+'||c=='-')0 o# p7 d; q  j0 p- D" J) Z
                 return '>';
# h& j# ?4 }! k* U4 a4 [             else if(c=='*'||c=='/')% P$ i  q7 [4 V% B! M
                 return '>';
. v, [. u* o, `, Y             else if(c=='(')
# _2 G7 j4 }- F1 W6 B( H                 return 'E';
3 i' `7 c, A8 g, M             else if(c==')')! j1 x& _% G) ^
                 return '>';
& n0 T. ~  u* w9 r             else
6 ]* t+ S- j/ `                 return '>';( T! K% a- v: [: l$ k; }
        case '#':
4 b2 {  a/ q( i             if(c=='+'||c=='-')- Y* ^- Y7 q  t) X- n" |
                 return '<';+ F8 G' L( v1 L8 c% R% h
             else if(c=='*'||c=='/')
" Y$ ^7 S8 \( F/ R4 Y3 ]% U                 return '<';
$ i. j! V6 x# U. |5 }! r. }, _9 z* u             else if(c=='(')
& \( m* T4 n, [/ x  F                 return '<';- C* D' [" R  G* f! x
             else if(c==')')
( Y& ~  v) F7 @9 V                 return 'E';
% O9 R3 X5 M3 s; r             else
4 p( T# ]9 S0 E; [7 A                 return '=';- U) u. w. m1 R  r
        default:: R' ]) o$ b3 B3 W, p
             break;
8 p6 J2 S& v" p  `% u: L1 k    }
1 t7 u4 E- v% G1 S6 ^    return 0;   
, Q# I: {0 ^4 a8 w2 G}' ~/ Z5 e# h/ f  o- ~( T: o

* k! b3 \% ^$ _int isOpr(char c)
" o. _. \( _$ E6 g5 g9 N/ S, V{
; R" ]( g) o' P0 \3 r    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
5 k8 L2 i; c% }, ]2 D        return 0;$ r9 G+ h1 K3 V6 {5 Z' o& X6 [
    else
: g5 b+ A4 @7 p; D: w. B+ b/ Y        return 1;
6 M# x7 j- J3 U) X  Y$ K; E* J}
% H, d1 S/ M) ^2 X& a7 E- n- K# W7 v
float operate(float x, char opr, float y)* Y! U* q% }! l5 t4 c/ R
{
8 Y5 B8 N8 c4 ~  u- i% D" {    float result;" Z( t5 _& D) q# s0 \* x
    switch (opr)3 l+ C- f  Y( }
    {' v* I0 N4 Z" W) d
        case '+': . }+ _4 X4 n* @- u( |
             result = x + y;
% n# J' Q; @# `             break;5 g3 R$ i6 G3 x: j7 N
        case '-':
/ H& ^1 a0 z' S             result = x - y;
7 {; S: S2 G! j1 Z             break;
# D9 e) D  E/ O4 k( d1 D4 }/ r; G        case '*':
+ m# |+ X( {4 Q! K             result = x * y;7 G+ E+ b' D9 `  V4 `, o3 d* u
             break;
6 u- T  \6 r9 u        case '/': 1 ]" {- B9 I4 p5 y
             if (y == 0)0 ^2 V* _. H* `  ]2 i5 Q1 R
             {9 Y6 k5 B; e- z4 `* N
                printf("Divided by zero!\n");
' s' H4 f+ S; y5 D" |8 o: B( ]% S                return 0;
( [  n- Z3 H% j* b1 c             }
0 o# @+ ~/ ^6 X2 z# f6 G4 h; g; ^" r. L1 L             else
  a. @6 _- w& N3 B3 R# x             {
* N, L4 g) F, }                 result = x / y;
* O- B- i+ K" M) t+ W                 break;
' m; ?6 A2 a# J% [             }
3 d# n( D: _5 h1 X! [       default: # a- ?7 A" s+ d% o
             printf("Bad Input.\n");
) D0 P; ~+ X. s! Q             return 0;
  ?$ w  J# {/ v2 n; h0 X  ]+ P# t    }  _  [4 _5 |: b3 I6 a; F# D1 h
    return result;
$ ~- x8 Y9 l8 q  U( _% H}    ' I4 v( U8 `8 H* I( f' S' e
/ ~- s4 u* F  j  n8 |  v  Q5 N: k) a
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/: R$ N2 {. q1 x! Q5 R' Y% U; u( u
{
3 ]: a3 e$ Y' j; ~% o" W$ D    Stack optr,opnd;' P- [" M2 H& U# E) f
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
) S+ v" ~4 U- U/ V    char c;
, E  {: m3 ]5 q' b    char buf[16];- A/ |2 \% D7 b' a2 A3 `* \3 c
    int i=0;
5 T$ d; O9 Q' O! `6 |8 R: c   
; T; z3 B, _* Z0 Q    InitStack(optr); /*用于寄存运算符*/0 e9 b8 P2 U' r- u: c* L, Y4 E
    InitStack(opnd); /*用于寄存操作数和计算结果*/2 G  p2 S7 J! X1 _
    memset(buf,0,sizeof(buf));/ [$ ]7 z5 ?, r, |
    3 K$ l# p- O' h  @
    printf("Enter your expression:");: T! Y6 I/ m0 W8 P& G0 ~
        6 y0 P3 q6 Q; o' \. N2 y2 a
    opr_in.ch='#';
- a" O' u. [6 P    Push(optr,opr_in); /*'#'入栈*/
. `9 m0 n6 j2 d2 g" {2 v% M( [; `    GetTop(optr,opr_top);; _- l% K2 B5 M; f  p
    c=getchar();! g9 I  b) e3 z4 N
    while(c!='='||opr_top.ch!='#')8 S; L1 L# i( I7 G! b
    {
8 C& G. O; V1 }; J! L1 R        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
( O2 [9 D! ~0 k3 Y/ _8 v        {! ~4 q. [# r! v. m, A
            buf=c;# e: r8 U& T+ ~. S# E
            i++;( _% X6 r  n. v0 l  l* L
            c=getchar();
9 U5 q/ l' X! m: s2 U6 z        }
$ m! \6 n% @: M4 n: p4 ?+ B        else /*是运算符*/8 [$ m7 E1 ^5 G, w2 }7 z. E0 u
        {
4 k' Q8 q5 ^5 \$ _$ U; E            buf='\0';
  ?' w' l1 C7 L. Z. X. H& z; F            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
2 `1 x7 b8 j1 m' s' h* N            {9 y3 P6 |0 d/ m6 q$ C: b, }
                 opn_in.data=(float)atof(buf);4 `; e# `7 `6 y$ \
                 Push(opnd,opn_in);1 H+ z0 ~1 F9 [5 ]- F5 q& x
                 printf("opnd入栈:[%f]\n",opn_in.data);2 g+ o) g5 i) s% M7 g
                 i=0;, \: E. B3 C! p6 f# e* d, K
                 memset(buf,0,sizeof(buf));3 W1 }" x1 z& `$ u* D& Y( ]
            }- a/ S  K: g' Q4 C: z
            opr_in.ch=c;
2 U( j" ?4 }# D0 i4 K; O2 Q! h            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
) N, O1 m! Q) g/ G" w" B. Y            {
+ A7 g/ k( M" s' a' N; l- N                case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ x4 p. P. I) k: E" _                     Push(optr,opr_in);3 ]7 {  o# r" h/ B+ }. E
                     printf("optr入栈:[%c]\n",opr_in.ch);
5 V4 C0 Q4 Q* `1 {9 \1 v2 Q                     c=getchar();
# Y% s  }3 b, E6 b                     break;
" J" b, c& C  @0 l' h* x6 M0 ?                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
. U. ]7 B! u. e3 Q4 h) q                     Pop(optr,e);
, v: {9 \3 E5 w2 S$ c' b                     printf("optr出栈:去掉括号\n");# ]+ f. _$ ]4 w- I& t  b
                     c=getchar();( q, j( H9 z) J$ t$ d* N
                     break;
7 w' m+ K1 G9 W& w* e1 g4 _                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/, _" k1 b3 D3 `
                     Pop(optr,opr_t);
" {8 M& ?1 l' l6 o9 {+ N3 m                     printf("optr出栈:[%c]\n",opr_t.ch);! ^$ S) N# f' i8 |+ B' O* T5 n
                     if(Pop(opnd,b)<0)! w+ C$ J! `* ]+ M2 C
                     {, A6 t. s: w3 T/ B8 E9 J
                         printf("Bad Input!\n");
% N* R8 \! O  Q6 w/ J" J# M* n                         fflush(stdin);4 U0 V+ Q0 u% {
                         return -1;
# F. i( r0 r! w/ _$ ~                     }% D+ ?6 G3 I# K
                     printf("opnd出栈:[%f]\n",b.data);
0 r" z- r$ m, u                     if(Pop(opnd,a)<0)
0 f( x9 H/ m3 p1 c5 p                     {% I, l7 R1 w/ X
                         printf("Bad Input!\n");$ i  ^, }% }7 C
                         fflush(stdin);
- F/ P( G+ I6 v7 B7 s# F+ T$ \                         return -1;/ Y1 x4 [, J3 C/ J5 y
                     }
9 |6 |' I0 l: ]( Y                     printf("opnd出栈:[%f]\n",a.data);! |1 ^; M/ s0 s$ L1 s* P1 n! g
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
5 ]# V3 r( G0 U9 T! G/ b                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/* d' _- p: M0 ^2 l" F0 l; c  I: F
                     printf("结果入栈:[%f]\n",opn_tmp.data);
' u( i/ o  y6 z& Z* g! ^$ A5 L                     break;' T( c' z3 I6 K  b
            }
4 o* z% E# \; L) |* m- m+ H        }
. {: C+ m( D* ?: `) w" T3 n3 s        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ! t3 t  d6 H0 {0 @* E
    }
6 m& x# ]7 e. v3 h    GetTop(opnd,opn_tmp);  \; R  W2 [# x" D
    DestroyStack(optr);6 X+ @4 c* h. K" M5 {$ d# _
    DestroyStack(opnd);
, q# K3 O9 {! ]1 z$ y9 m4 @    return opn_tmp.data;: ~3 E# ~  t% ?1 K7 b
}
6 c4 `% i5 B5 F8 c* \
( H# N: }, d& @' X( t# Kchar *killzero(char *res,float result)
; L5 N, U5 K+ j% M/ a' t{* g4 a$ d/ J% `$ |# g
    int i;
' M( H& D  r: ?2 C7 [8 A  L8 i; S& P3 I, E. c) @
    sprintf(res,"%f",result);; j" O1 X$ _6 m2 ]
    i=(int)strlen(res)-1;
" |% x/ u7 q% ]! n* Z+ p, b    while(i&&res=='0')+ {2 g$ Y* @, t* h% X6 \
    {/ W& I6 |. S* \( a
        res='\0';! V! l6 V- n4 }
        i--;
$ ]0 T2 p$ M; ~    }
: ~; R9 F/ `+ o    if(res=='.')
9 f% v, ~7 P  b* `/ N        res='\0';
" q  }; ~* x) `! I$ A  b    return res;
+ n6 c* P4 H7 \3 z+ z}" T! T8 x! X& x+ i' m8 S
" x+ r9 ~3 w0 H
int main()' T8 H  Q$ ]0 B; M2 z0 a1 q$ Z8 \
{
; {7 S" y1 |6 l4 F& \4 W9 u5 C, A    char ch;
; l9 f3 d/ a" M( j6 o. U    char res[64];
/ {' V$ T9 w# K/ O( c" B+ L    float result;0 B1 N. o5 _/ J4 {
    while(1). D6 x2 ~+ `/ [  G5 f8 G. X
    {2 X/ A  d9 T1 H
        result=compute();3 N  {4 S  D2 v3 e% b7 K2 P
        printf("\nThe result is:%s\n",killzero(res,result));
2 \& o0 q% m* Z+ W; H; t3 C        printf("Do you want to continue(y/n)?:") ;
; ~5 b/ d) w, S, g* b% E- m        ch=getch();. E# n+ D% b3 ^# d
        putchar(ch);
8 u6 j1 V* h0 [        if(ch=='n'||ch=='N')/ b- |0 h6 i7 D6 S! Q0 m* g( C# n, c
            break;4 ]1 n; z4 a7 R4 b* i
        else: b: y8 }6 _0 G1 S- [: _
            system("cls");7 n% @) X* n4 o+ v" @- c" {+ `
    }
* G/ U6 I! r$ e    return 0;9 D2 p# c, f/ ?7 h2 u7 F. c
}

2 E; z! Z3 ^" n4 n4 r" k
5 X. A8 K* ^( l[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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