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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
$ u! d. d1 H4 n7 s程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! }3 q. Y! A; |/**************表达式计算器************/
  [5 A0 i8 V- c#include <stdio.h>3 a- Z! q# p* Y
#include <stdlib.h>9 q% t$ G; h* O, k9 p' g" j9 E
#include <string.h>
1 m$ k6 q$ z, E) W- _1 m& N* O( A#include <conio.h>, G0 c& V+ u  |7 y( C! n0 [% K. e
#include <malloc.h>
8 W6 a8 R: }4 _6 d. a, X3 q3 S7 ~* r, }" R
#define STACK_SIZE 100
9 M% k9 N/ p' v) C/ a#define APPEND_SIZE 10( ?2 z( w7 c/ m6 i5 M( t2 A, C3 H
' W6 `8 X+ H" }4 ]
struct SNode{
; g: K/ v5 Y3 @' T9 d1 q    float data; /*存放操作数或者计算结果*/7 j" V! n# r& I  k  l# Y
    char ch; /*存放运算符*/! D0 Z2 o# @1 y3 T9 r! b" h+ C
};
! k2 Z$ v( R9 h0 O% ?, U- L- i7 i; P, b
struct Stack{( X& k; N+ }) j/ Z$ S; B
    SNode *top;9 R5 _. X: D' J+ Q& Z
    SNode *base;0 [2 x9 i2 W; L& Z1 o9 O5 I) k
    int size;1 E% |: q7 [0 m0 C% ^/ n
};
: w& v' a; J3 F# N+ `- L( v" U+ a5 x6 E- J" B% d8 D
/*栈操作函数*/4 ^( t0 q3 X6 ?5 A
int InitStack(Stack &S); /*创建栈*/
$ y' m3 W% C3 F' fint DestroyStack(Stack &S); /*销毁栈*/
! o4 J9 @/ L, L. O. wint ClearStack(Stack &S); /*清空栈*/
/ i! k) j5 u, _5 Q2 d# Uint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
/ f0 G$ \( O. k+ V, ?+ a7 {6 {int Push(Stack &S,SNode e); /*将结点e压入栈*/
9 l& J6 a' X0 D* F8 fint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
( w1 U: n5 T  m+ ?3 I) z- K+ @) E8 v9 X& Z5 I% @
/*表达式计算器相关函数*/3 ?1 {6 S! V. L
char get_precede(char s,char c); /*判断运算符s和c的优先级*/( s! F  ^9 v# o
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
& p2 l1 C/ t& U8 Wfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
2 m" z. F, }% V2 Bfloat compute(); /*表达式结算器主函数*/
0 I) n& H& M- U% {0 C. Z( J  qchar *killzero(float result); /*去掉结果后面的0*/
# N  X, [0 b7 s- z7 g6 w- G" o0 \+ U) y* k; f
int InitStack(Stack &S)' o& J* g- M8 ~0 Z  V% A5 R
{+ w( n/ _7 y1 N) u4 c% w
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));5 [( e  [1 V  x" n) v
    if(S.base==NULL)
. O, L/ F% j2 D    {
- f0 @3 e3 k$ c/ z6 A: B9 n1 i        printf("动态分配内存失败!");
% p: p) K5 K, ]5 ~% ?  A        return -1;
" n8 z' \/ u( |0 [    }
! l; u) _& _& O% O  E    S.top=S.base;( Z5 _* E7 P( w; ]- c
    S.size=STACK_SIZE;3 L6 j7 h$ C0 B6 ~7 g4 S( ~
    return 0;
% _# `% A: H) |9 `5 f' `7 E5 Z+ l: n}
/ l2 n- B7 k/ H& t- r9 C) ?+ O2 B# \+ n# Y& K
int DestroyStack(Stack &S)
1 |8 |& W3 _7 o* b{/ |' B; n) i: t: `
    free(S.base);- `4 ]( o* j3 I4 a5 O7 B/ a( u5 F3 ~
    return 0;- j- J* @0 ~2 b7 f9 P# h
}1 t+ r  n% A1 H3 s
! e* X# z$ P( m4 T  ?7 V3 F2 T
int ClearStack(Stack &S)
& R) L. {; \( y{
6 `; `3 g" `! J$ n/ o6 e/ v    S.top=S.base;
0 j1 W) S' b' T* N, c    return 0;
2 {+ Q, A. F* J+ C. Q3 c}& D, A1 C1 y$ s( ~+ [
. x2 f  m+ A2 u9 \  X  _
int GetTop(Stack S,SNode &e)
- _9 s6 w9 j) _# B2 A# j  U% z{
1 A0 f* u5 F+ S" z4 ]2 r    if(S.top==S.base)
# e' O! p1 z0 M$ D# J% ?* \    {
) q/ [, M* C# [2 k0 q" l: _6 O        printf("栈以为空!");
- ~6 k1 n! }8 u+ [) H" I        return -1;' Q1 I$ L5 e8 ?3 q/ M$ L: y
    }$ b" e7 h8 v5 g4 C0 Q
    e=*(S.top-1);
+ Q: S! c. x% s    return 0;
% X/ [+ I6 b6 R( B6 T}
% H0 S" `2 Z6 O. n, S+ W) f. R" m9 Y$ \( J' n
int Push(Stack &S,SNode e)
: E& Q- L4 J" W6 f: M9 X1 D{0 g: }! o) R+ ]( y+ G1 i) M0 Q) ]3 |
    if(S.top-S.base>=S.size); d1 Q' w: D4 N3 Y" S+ ~
    {* t' t+ I( g" R0 o, q: G
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
2 z8 u9 H$ h& n* s: Y4 Y$ p% ]        if(S.base==NULL)8 {6 S' Y) G( t8 ^1 P$ O* b: `
        {# z; @" v9 P$ i. J" J: \3 Z+ z# }
            printf("动态分配内存失败!");
  G, ]6 \4 _3 l) b6 }            return -1;; V" D# u- Z8 Q6 [, o# W
        }9 `( n/ T! y4 X! I8 D$ w# y; J
        S.top=S.base+S.size;, Z0 ?. P$ P9 D1 s0 ~
        S.size+=APPEND_SIZE;% V* V, j5 F7 l5 d! c" e
    }
' H1 B5 L9 h7 |8 e4 x    *S.top=e;
/ }. T# P* i/ x. f/ t; `    S.top++;
/ E$ _: Y+ i, Z    return 0;! [& n9 H" y8 o) b1 |' d
}
) J! c' I! P/ b8 i1 k1 r( j
3 A5 z) W2 F- Y' `: @int Pop(Stack &S,SNode &e)7 ~' i8 d. w' H5 E! H( Y
{
0 l. u& R$ j) N- ?    if(S.top==S.base)
) B7 f8 S  ~% _4 r) |    {
$ s- y: j$ J5 h- ^9 Y        printf("栈为空!");% n; h' H9 O1 Q) z9 T  e
        return -1;5 @  M, v2 W) t$ `$ n# {$ Q7 X
    }
/ z3 G2 C$ ^* w5 x6 v9 z    e=*(S.top-1);5 F! p) t& V% Y) E/ [" B
    S.top--;
% T( N: A9 H! I+ k; K8 `/ ^    return 0;$ T: ^$ w1 L' N: x3 d9 a1 ^! J
}
& C- C1 L3 f  x. W# R3 r2 t! s9 v) J, M% [4 S
char get_precede(char s,char c)
1 D$ R, d$ R% C$ [3 I1 X{
7 Z/ C# H5 V/ F# \. \4 i; x    switch(s)! }! [& }! x" n/ P" @
    {
9 d) R7 \$ Y) [+ M        case '+':                 ! H, r- ?& V* i" F. O  d- w* y1 M
        case '-':9 P5 v( ]% t, Z& U  c, L, v4 q
             if(c=='+'||c=='-')3 F1 F9 u2 J: k! @* J4 Z
                 return '>';
! O; O# O, r* N  h             else if(c=='*'||c=='/')+ T# T  P5 w  `  G( N
                 return '<';
  l" l! F6 E1 m7 `: O0 N             else if(c=='(')
6 g; S" h& x% W                 return '<';
4 @# p4 d4 z/ ^6 I; @             else if(c==')')2 M0 e# o3 `+ C* @, u3 f1 U
                 return '>';
# ~+ ~3 _! g+ T) |/ P) j+ |             else
9 J# n4 w$ [4 v( O% B                 return '>';! m8 q, }$ a  s" T
        case '*':
8 g& t' c# T, R6 H. M        case '/':( m8 P  A5 `! Q; p
             if(c=='+'||c=='-')2 c4 e0 t- u  e1 {, U+ P
                 return '>';, }! q/ p4 C" c2 p* q% J" @
             else if(c=='*'||c=='/')
  U, O: s, d4 J% f: ?                 return '>';4 u2 t/ k& o% J) {1 |8 Q- G
             else if(c=='(')2 A: D6 ?7 M5 E
                 return '<';6 o+ M, J) c7 {3 {9 N2 a1 y+ V: c
             else if(c==')')
4 f9 x. A. _! T6 w7 q6 h                 return '>';
; L2 A7 u2 W) Q& q             else( n* G- V$ G2 S9 L
                 return '>';
3 H* K* e7 m5 c; \- `" {        case '(':
7 S( }' s- G$ r+ c+ |             if(c=='+'||c=='-')
. F% L1 ~& q6 ?( K- ^% B8 F                 return '<';
5 m. v" N; j2 V. ^5 O) K/ |             else if(c=='*'||c=='/')/ g  T& M" L3 N& T# ?" G
                 return '<';
0 C- A, I4 \( Q% b& X! r             else if(c=='(')7 z+ M9 v& e& w( U. c9 q
                 return '<';4 g' L, g. G9 L" f
             else if(c==')')" d  X0 l, p/ l' X* c
                 return '=';
  \' ?8 |  C' g5 h) {. M2 g" P             else
3 b# D+ v0 w8 ~% y2 _" X                 return 'E';
. N. Q; x1 y4 `1 n        case ')':$ M$ T5 d+ w' Y, f
             if(c=='+'||c=='-')5 s$ C2 j8 J% y* _  r7 w
                 return '>';( X- r% \; _& N" v) R
             else if(c=='*'||c=='/')
+ L4 y+ y7 Z. _$ Y# r0 K                 return '>';1 W9 y7 w& v( D
             else if(c=='(')" `( J, R* q: ~% v; _, `3 ?
                 return 'E';
* ]' Q3 j4 c& T             else if(c==')')1 N" q' A1 H3 l" M: c
                 return '>';9 V* H* K0 Q) w2 H4 q4 ~
             else. f! c( \& y' `% o- O) l, K5 }2 V
                 return '>';
6 G" q* I$ `, V' u. d        case '#':: N/ C: M3 j7 J+ `* F
             if(c=='+'||c=='-')2 r7 O2 P$ _+ T
                 return '<';
/ b* R0 ]' @" P( I8 J( ~: p# o, Z% w             else if(c=='*'||c=='/')( t/ f) A. J! d% |, t
                 return '<';5 G7 ?. [( {8 x# V- E- {8 E
             else if(c=='(')
# f7 P" F, g5 q3 k! T. P; T                 return '<';* C6 g- q& u+ y  h( j
             else if(c==')')0 J$ Y9 H. ~* I1 U
                 return 'E';
: v4 a& j9 N2 h; O+ o' k* l$ Y) ~9 w             else
7 N. Y/ r. k  k, W" P/ L' b                 return '=';+ h; {1 B; w7 R4 }: `
        default:3 a+ J# r' \3 r7 [
             break;$ k/ A' R; u7 |1 f( D4 g
    }
& |' Z$ A4 t: w! q7 y+ Z    return 0;   
& o2 [  E, t2 ?& q1 m, J8 I6 i}
" E) F7 P0 _, N" A6 G4 p3 `9 m7 C8 A
: H6 E& }# n1 d$ h9 T5 Lint isOpr(char c)! i& f1 y# G" y  ~
{3 @) Y' }0 ~- U3 C6 }7 m, {4 ]
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')) P) I3 {9 B! y  U1 m# x6 u2 [
        return 0;7 S9 A; E. S5 C1 M2 a/ _4 C8 m
    else 3 m+ t: j' a' o: o$ a) n0 U& {
        return 1;
; I" C/ N0 ?5 C& |: G1 S8 l  S5 z8 C}& ^8 o, {, x% B9 I2 _/ o
" N2 c2 S2 n' R9 S
float operate(float x, char opr, float y)
: O& r* s  \% K9 \5 d{
) f) N" k8 p6 J, |1 _% R    float result;4 ~5 O1 G' e( Z2 L8 g- t
    switch (opr)3 ?, [: V: I7 G+ H2 N: ^; E$ k' F7 [
    {
: B! L% Y% c. L- \1 |! |        case '+': & D2 N+ W9 z/ U) @
             result = x + y;- F9 X3 z+ w( p9 n
             break;
( e& D, Y% O( `! D* Z        case '-':
7 n7 m- B! U; u) }: e             result = x - y;
) {5 N/ b: |6 r0 K( A             break;
  {) ?/ A9 m: m        case '*':
+ W* p/ B0 d+ w9 M& T0 G             result = x * y;. f/ `5 n1 ?. X4 b# _* h0 C+ O
             break;9 |' Q* i  i; o& J  h
        case '/': , Q# x9 ]7 n* r8 ?5 {: i, E
             if (y == 0)
! P* L" A5 C; D/ B             {- O6 \' f: j5 v7 ]9 H5 L. Z) g
                printf("Divided by zero!\n");0 w8 H1 J! b( u9 a7 h1 Z
                return 0;
, h, F: l2 |& F: D2 K             }
& \9 N; z$ m, X             else
- Z6 a. f. ^5 h# v9 j! B6 E! b             {
' P& D2 v/ L2 ^" C8 \                 result = x / y;+ p9 }/ `" _) {( r2 Z+ v2 o
                 break;
7 g! `7 U% w  R; `2 ~& |             }( N6 z/ q! N& _2 Z$ q3 |) Z3 G' }
       default: + Y2 ~$ c# K" B1 D, T& K+ R( t
             printf("Bad Input.\n"); * v8 d9 P' N- D  B( E8 h
             return 0;$ C! p# T1 B4 W# k) t6 n; M
    }$ H/ Q5 D" i! N7 M- f
    return result;
; y* j, I( q; R. d}   
2 i* _* @% }+ |% h8 h
; Q* ?* e6 U9 U  A# Afloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/, P4 c6 }% K6 G
{
$ w: R8 Z& e1 h! Y8 ?# y: b+ J    Stack optr,opnd;
1 D! U& Y' `7 E3 Q0 h" W+ `# B/ y: u    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;# J- Y9 z! m. p' H
    char c;6 W! I  ?7 v! q4 q
    char buf[16];' M  \/ c: w: n. t; ~: N
    int i=0;
8 x, f/ ^) [, J$ u% \3 ]0 q   
" J+ |# j4 t. z$ P7 ]3 s    InitStack(optr); /*用于寄存运算符*/9 D1 k1 H' u  V( d# ~5 m, D
    InitStack(opnd); /*用于寄存操作数和计算结果*/+ W. m5 o# L; G( A5 H! z
    memset(buf,0,sizeof(buf));; z; ^, L# P( X/ k
   
1 |/ r3 g" @8 k/ W( I6 I# i! g    printf("Enter your expression:");
* [. V( L6 ^: L: `        
, U* L2 S) C- w* O1 J    opr_in.ch='#';2 f% V/ R  B# M  R" B" J
    Push(optr,opr_in); /*'#'入栈*/  C3 p- [! B/ o) x) Y5 T
    GetTop(optr,opr_top);, f& a6 Y$ i$ g4 l* ^9 q& [
    c=getchar();6 o7 g" j# H+ M' r0 N
    while(c!='='||opr_top.ch!='#')
# J" x# H  A+ h1 X: l    {6 M  a& x2 l( t6 B* c5 w
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/9 y) Z$ w! |# b# Z) Y% t
        {
/ p  V: ~' O" Q2 Z+ N            buf=c;
, n) X! m6 g" I; z: v% X            i++;
8 R( _6 g( g5 B9 G) X9 v2 ~- V9 u            c=getchar();6 j8 k2 s! m: f) C0 A6 t" M( ]' E
        }
: D9 G# `7 e. b, K5 W1 G        else /*是运算符*/% Q2 ]) M1 a$ T' Z, V- \  u& d
        {/ X0 z& B% @1 j8 D. W
            buf='\0';
  V+ F' x* o6 s% i* A! Q            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
+ c# J, g! u; \; L            {
# Y, {/ d7 _. x: c" I3 D                 opn_in.data=(float)atof(buf);
9 W- ]1 Y9 B; X) [9 w                 Push(opnd,opn_in);; x2 u1 s0 t  e3 L0 Z( q
                 printf("opnd入栈:[%f]\n",opn_in.data);; R4 }" J' c8 Y* L! d* J
                 i=0;* y. O! |" P3 N
                 memset(buf,0,sizeof(buf));+ a7 v- ?) x. {6 N( x
            }
" \  d- r6 Y2 ]1 j6 \0 [: {+ e            opr_in.ch=c;% c. I& i) x& r- }) Y/ A: _& z
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/, A! N) j/ a/ q% f, I. [1 ~
            {
: y8 P1 D/ k8 U% n4 g2 B% X' Y                case '<': /*优先级小于栈顶结点,则运算符入栈*/
) R" e8 t. z( x: v8 x' g" A9 x                     Push(optr,opr_in);: X0 ?+ ]. B" t/ P* z
                     printf("optr入栈:[%c]\n",opr_in.ch);
% L) u! h( u+ g2 |( ?( C7 M1 U                     c=getchar();
: U6 B) }% I. C* Q) Q& R. [                     break;
" f$ r6 Z( `$ @' }0 X9 p( m                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: s: x% m# k. j( ~" s3 H' j                     Pop(optr,e);# M( H- ]/ E( _" t7 g
                     printf("optr出栈:去掉括号\n");& R" H( f& s4 P2 I3 w- r2 `+ V
                     c=getchar();+ }) ~& ^( M( ]: C/ B1 }7 i
                     break;
, m% t8 ^, r/ U$ ~                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
# N8 J9 C3 X% R0 E# ~& J9 ~                     Pop(optr,opr_t);& m) m. o0 q1 G. Q$ H. \, G$ d& M
                     printf("optr出栈:[%c]\n",opr_t.ch);
. ]+ D) H3 @4 [1 l4 e* w                     if(Pop(opnd,b)<0)
- W: Z; M. ]4 \$ B8 `                     {
+ x! k7 B4 M( f% c2 l3 l                         printf("Bad Input!\n");% a' l! {5 C& |/ Z6 ]) \6 _
                         fflush(stdin);
8 g7 Z$ Z% _8 a$ }5 a7 {7 N+ G4 V                         return -1;
3 V" @! G/ F7 y; m, f, T  W                     }
6 n- r# u4 A: g8 B5 x                     printf("opnd出栈:[%f]\n",b.data);. ^& J3 f% Y# e1 P
                     if(Pop(opnd,a)<0)/ ]& ^* \' X2 x  c6 E7 r
                     {  m* O: D8 D" g+ s
                         printf("Bad Input!\n");
! r( W# k, }* r: C" R! j" e                         fflush(stdin);' u/ ~! z  Q! X4 U, ~; u
                         return -1;
' f! a; H' l3 i# S8 K                     }- T' C5 `* V' t7 W4 D: A( Q
                     printf("opnd出栈:[%f]\n",a.data);
  _; N% w# `2 H/ d+ V/ J! \( z) J% D* o                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
0 I0 I2 r9 |8 u                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/. `' M9 p7 f) w7 K% g
                     printf("结果入栈:[%f]\n",opn_tmp.data);
3 ?, p. a2 h- E9 B& T: L                     break;
; y2 c" `3 j# E5 T& p1 T            }* T) @1 x/ J2 K6 H( C( c; {1 v8 _0 [1 n
        }, T1 t3 ^  @( I
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                + Y) S' V* w' c, x5 P. h; D
    }/ Z/ _# n2 n2 `$ p
    GetTop(opnd,opn_tmp);( _; X1 K8 W/ W7 v0 ~! u
    DestroyStack(optr);
5 v2 ~+ N  \( }; l* L) h    DestroyStack(opnd);
5 F. f, ]* x4 B% P# x; l% i% b    return opn_tmp.data;7 ~: t( O. l8 n5 Z* V- a, N2 U' m
}" T& Z' ]" j9 \( W  s1 U* I
& O, ?6 l( B4 G5 a  `# T
char *killzero(char *res,float result)
! r1 k3 ]1 e" ^9 y4 z) ]{7 C9 {/ P* D4 s3 S8 m2 Y0 ?
    int i;* Y1 y4 Z% h% @* T) w+ ?: D3 N# A
: p8 \" w; O* O+ [6 |" D. ~7 ]) Q
    sprintf(res,"%f",result);
7 n# X% d) Y7 X( Z* U* v( U    i=(int)strlen(res)-1;% A  ~7 D2 D* I# Z
    while(i&&res=='0')
. L) o  O, o2 c# \; J# f    {
( A" \. {; V1 ?0 v0 |        res='\0';0 m9 f7 S6 o& X# V' V, P3 E
        i--;
/ u6 m4 t2 p# V/ P8 Y    }& a- |; F6 d: s* A4 ~
    if(res=='.')
0 Q% L( F2 Z6 L6 ^" |        res='\0';
8 C' O) b6 {( u, U# y8 o  v    return res;) ]( X; a0 }1 t
}9 e$ V; h( w( P4 T

! b% ]+ W, q: N3 q4 E, d2 v% P& y2 ^int main()% n6 I& G/ E- D" `6 Y9 i9 z1 u5 N
{
/ \3 a* Z9 r% u4 @1 Z: i    char ch;
8 k; N# r/ ^! @8 n; v) H. ~    char res[64];
" Z+ J! U$ e. g" f6 L' q    float result;; D* r0 p( y) Q  P& w  x; o
    while(1)
2 A) ~# ~( E; d    {& d6 f6 e' w- ~. A. f
        result=compute();5 O6 S/ W8 {' L' R0 {6 l' o
        printf("\nThe result is:%s\n",killzero(res,result));0 H9 J" n) `4 D6 v- U0 l% _
        printf("Do you want to continue(y/n)?:") ;7 Y! b9 y1 h6 N# n) T
        ch=getch();2 \; S/ ~* Q" Q: A+ _
        putchar(ch);
- O0 b5 f* \8 {- h7 u0 U+ q% i7 y        if(ch=='n'||ch=='N')
; }% Y& ^6 A6 j  f8 [: n: J4 `            break;
8 K/ o9 T! P( U. ~2 u4 m, z        else
5 |& `% f$ K( c9 x            system("cls");
* I; V: m" k, N' `    }
) H; E! N1 j" r: V$ Q, Z$ Z: W/ W    return 0;
0 F: e3 k" I$ |1 @( W8 [}

$ G' Q6 o" ]% b2 U5 z4 W9 Q" y% ]$ D7 L: V% r: v2 r
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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