返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.' t) U! F/ U  [4 p! a( i7 p: Z- M, ~( x
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=$ \* E+ ]8 B5 H. l* {
/**************表达式计算器************/
8 \5 b2 U, @$ D#include <stdio.h>
" H( q/ {( m2 r1 G1 v#include <stdlib.h>
. T& m. e) I0 M3 _5 E#include <string.h>
$ |1 C8 O' p/ g$ K#include <conio.h>
7 Q( l' m; k+ ?# D* s#include <malloc.h>. {: H$ D2 `" [

: [2 f  B+ }3 y2 D1 e#define STACK_SIZE 100
+ @  x4 [! A6 G# _3 H#define APPEND_SIZE 10
  q) P; C% V. c6 D7 N/ Z( O) j( |5 S) `' V6 q) p( d: y
struct SNode{
* f: M( X- v# A0 i, A2 I    float data; /*存放操作数或者计算结果*/
' `4 \4 ]7 C' a! S3 n3 a    char ch; /*存放运算符*/; u9 [/ t- u3 `# ?
};+ u5 @6 S5 n2 M7 `0 D
! r! W4 w5 M( W( H" f6 `
struct Stack{
- N/ r$ ^. N& z& j. M2 W  o3 w" D    SNode *top;( |: o3 D. l9 R8 H' K, F; N
    SNode *base;
5 _! C/ g. @9 n. Q/ ]# L    int size;1 x9 r' ?# \. W. [/ q6 K- [/ w+ i
};
7 {: \5 b6 C# i( {: U. O* r8 E% b. [5 D* d7 R
/*栈操作函数*/
& P9 S- J" R# V5 ~int InitStack(Stack &S); /*创建栈*/
! b9 e; K( c2 a( I+ S) {int DestroyStack(Stack &S); /*销毁栈*/( j5 T- N+ G: B1 [4 f; p
int ClearStack(Stack &S); /*清空栈*/, f: `1 `* N" h' K: l" L
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 \) {/ O" J+ D( iint Push(Stack &S,SNode e); /*将结点e压入栈*/
* i* I( T! }8 h- `4 aint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
( t- a8 d$ h0 z9 U" f4 Z- u( Q! O
/ n" w3 X( o# m% E- v( I/*表达式计算器相关函数*/
' s  h3 L8 `8 e% S: wchar get_precede(char s,char c); /*判断运算符s和c的优先级*/! V+ A6 ]. {: O: G( I9 d& l! q; ^
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/9 V  b( G  z+ A; u- m8 @& b
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
0 _( [% }' u* S; Z/ L7 gfloat compute(); /*表达式结算器主函数*/
2 F5 B& F: D+ m0 f/ nchar *killzero(float result); /*去掉结果后面的0*/ 1 s7 d# Z1 s2 s4 y, _# W( J
# i& y. L1 g, r/ G0 E* G
int InitStack(Stack &S)9 E. b  F" Z+ o1 `7 |0 T) w
{
5 \6 C% l( @/ Y. t    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));2 L5 H; |; S9 @( w
    if(S.base==NULL)
6 G. h6 s5 _; `# [8 u, K    {! \6 z1 `* P. F( D6 |
        printf("动态分配内存失败!");& i' N+ @& d! S1 y# k- C' H7 D
        return -1;6 V1 a( ~+ i2 E! N0 b& T+ E
    }
1 U- u$ B. D9 |! |0 L    S.top=S.base;
" L, Q% _+ S! n5 M' @- h  O    S.size=STACK_SIZE;2 S! [, [1 T3 w$ C# s) k
    return 0;# X$ n% |3 N6 x$ B: p! t5 h
}
  |+ L  U8 x) o7 h" A, Q' L: P& y" _4 ~& B- o) h* Q6 d7 W& q
int DestroyStack(Stack &S)
5 F( a) k/ R- o5 c* Y9 i" s{* r9 `+ [  ]7 G' I( M; g
    free(S.base);4 @# ]$ ]- I! C8 \" o+ B
    return 0;" F/ G# c2 p* ^0 z- z; \
}2 e, o6 `( x7 e5 v

/ p' |# A  y" v7 uint ClearStack(Stack &S)# R& l$ S7 x- L0 u9 ?( S3 Z/ a
{
2 l% k. X( B* d! Z3 O6 R    S.top=S.base;
5 }9 ^4 }* O% L6 l    return 0;
, _- W* `. t, ?/ n4 d9 c! w5 f- I}( F3 M  E9 V* ]7 }2 P
" y! F' B5 t* G, @) E! n9 I8 P
int GetTop(Stack S,SNode &e)
9 c8 J% C5 S( N! J{
0 t) W5 a; q; y+ @+ T: w    if(S.top==S.base)9 S( n5 [: O2 n( u: I9 {4 i; B
    {
# N+ e" v) j2 V  z" Z( g# Z        printf("栈以为空!");4 V% r; ], S: c5 K5 b9 F- J
        return -1;9 z* G+ I( C9 m9 h, S
    }+ K% H  N' a4 e2 Y1 E) l6 z6 E
    e=*(S.top-1);
% D2 T& Y& ?" O4 p4 F    return 0;
7 y+ {$ P% C. {/ a7 k1 W}$ t6 d( g/ ]5 p$ v/ U
" w+ W# l. m1 K' t
int Push(Stack &S,SNode e)1 N% i3 c1 w- e: F# w1 f" c
{0 G! B* s* g9 I5 L# K+ d
    if(S.top-S.base>=S.size): H$ a$ ~9 g6 A7 z2 T7 Y" R
    {# x3 ~( {: l% a' X: I- `9 [! Z
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) C3 V' Z; v0 C        if(S.base==NULL)
# K/ T3 b( ~. p$ W# w1 n% H        {
9 N3 q2 I: s, v; w3 {            printf("动态分配内存失败!");9 ^; w8 Q2 Q- M$ W/ ?$ C  `7 s
            return -1;; {' }" v2 G9 \, w
        }8 ?: a: L) l( u) c! ~4 i; S
        S.top=S.base+S.size;
1 A+ C; n8 k# @0 \# e        S.size+=APPEND_SIZE;
1 k  ~! R' V9 {5 k9 i    }
5 o, n) }- E" j: H3 a3 p; e    *S.top=e;
$ ]: d) j# ?) Y+ e    S.top++;
' T3 W1 i% l6 F2 w0 o- I& |3 N    return 0;: D' U) x9 Z4 ?( ?) H
}. @, ~7 a" f3 N  Z6 Z& W  n; g
: h' S1 D; P5 F! F
int Pop(Stack &S,SNode &e)/ m) S# A" J/ S0 A% ^) }
{
. K+ K+ @: Z: _! Q$ ^8 B# {$ q    if(S.top==S.base)
$ @% r/ R, f  a, B    {6 [$ l, Y5 U# G3 I
        printf("栈为空!");1 l, U5 e8 C1 ~9 i
        return -1;
9 C* O" k/ R% C% y. T6 o2 }0 ~    }
* u7 N" E4 `7 L; B    e=*(S.top-1);
) w2 ]( }5 M2 L, l    S.top--;% W! W" \( h" u% V# Q! G7 [, }; d
    return 0;5 B' z1 Z7 ]! \0 J& q
}
7 f0 d0 D2 X) U! J& m( w; x/ |% v6 v4 X# x3 F
char get_precede(char s,char c)
; A$ M: B! B; c0 O) [6 m{
3 `6 v3 b  H& L' a4 R    switch(s)$ O1 R7 J+ V2 G7 e$ C2 d
    {
# e0 b: {' H4 }: f        case '+':                 
  K5 g! h8 d: t/ E' L        case '-':: `$ w9 a3 O* w4 S7 D8 u3 O3 o! ?* r
             if(c=='+'||c=='-')
/ I) @1 H+ M, A$ R9 n5 b. Y                 return '>';
! h$ ?8 u% z" b. f) `             else if(c=='*'||c=='/')9 x* r( v& U+ O: `' @' U) |
                 return '<';! ]9 h! y4 t* b- o
             else if(c=='(')
6 x. g  p0 A  w2 e8 n: v$ @0 ?                 return '<';
8 s. S* n. J* w9 }             else if(c==')')
/ D8 d0 U  c  [4 H8 y1 [  T3 j0 I                 return '>';
! `( v! _6 m& }& `             else
) H9 B( O7 P( _3 k! F! P                 return '>';' ^- a; a' n1 z) H; K7 r
        case '*':, q1 [$ X* t) a8 z1 h) D
        case '/':
7 B( C4 i4 _9 e4 ]/ e             if(c=='+'||c=='-')
' E+ r. }$ r$ r  E2 @                 return '>';9 z: Y2 q$ S2 P1 U; `) F# P
             else if(c=='*'||c=='/')
( \- [' Z5 c! q' ^( P! O" |& C                 return '>';
0 c4 J9 M. g; u. p% u  q2 J! ]$ A1 c             else if(c=='(')
5 G; F& s- P7 j3 }6 d                 return '<';  z! i- h# Z- K* ]+ g/ z
             else if(c==')')- ?/ M5 L, K- l1 E) T
                 return '>';% y- c0 @9 [+ n5 p7 B
             else
  R) R) a: h7 \& \! f- U                 return '>';- B$ L4 _6 [9 K4 B
        case '(':
# M: Z$ |2 H2 v. N9 v  s             if(c=='+'||c=='-')4 p+ d6 y9 I7 ?' b
                 return '<';1 k7 y; u6 F- J# x7 z" g3 z5 m* {
             else if(c=='*'||c=='/')
& ?0 D' {1 }1 G" L6 c                 return '<';
+ ^# G, @; o1 P. p             else if(c=='(')
2 _0 Q: G* W6 H# k; U0 t5 e3 \8 |                 return '<';; s% R+ q& p7 C2 B" q/ ^& N
             else if(c==')')7 y9 s& ~$ |+ _/ Z' {" A. Q1 |
                 return '=';
: e% @. K0 L; H5 e  t# [$ X             else
1 e2 t" @0 I$ }' \8 X1 ?                 return 'E';
8 N3 \# Z: B1 {, Z+ ]# o2 Q& u# m        case ')':
) I  m$ }) i% u  Q             if(c=='+'||c=='-')
8 L5 _' M1 L/ A! w6 P; ^                 return '>';* A) F/ \3 K' r, n1 ]1 k6 [
             else if(c=='*'||c=='/')
  {1 q( Y3 ]0 }9 @                 return '>';
4 N0 |0 P" u- H% X             else if(c=='(')
- G& |  R5 w) a; s                 return 'E';
: {% x  ~( f  y5 s: r             else if(c==')')6 h9 y3 X( q2 s; n; P) z. o0 |
                 return '>';. T" \* o3 e; i9 W; f
             else- G  I7 N9 s. T; M* n# |
                 return '>';3 N) ~5 X5 t$ E  O6 w
        case '#':. w$ `( a1 F: o% G  s, i
             if(c=='+'||c=='-')7 t- s  S) V( O$ f7 i
                 return '<';
6 C: R* T: H2 y$ r             else if(c=='*'||c=='/')/ k: q, t: h5 y0 `: s/ t
                 return '<';% X9 Y& S% k- n$ J9 @2 b
             else if(c=='(')
6 S3 K# o! n' P3 C                 return '<';
! k# x) Q) S* |$ U0 u% o             else if(c==')')9 W4 @4 v& i" }, K
                 return 'E';, O" d- k. ^( _5 }7 U( q, K
             else* x2 j" k9 F* f" Y% ~
                 return '=';
6 p& W0 W2 g- h, E        default:
9 e3 g# |- ^( ]% U* l             break;
; @: U! p4 }4 f& u5 T0 g( U! t    }
3 a0 z) L" Y6 w* I5 T2 @  c    return 0;   
+ c& u5 M( \( Y2 a7 R, L. m- h" ~}/ _0 e3 P( h! L, l

, C9 U  t- v1 y6 R3 Jint isOpr(char c)2 b) t! C1 n9 d+ ?
{
  q. {. O: U, p  d9 l. A    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
. l# J7 m. {# {! N: h/ H+ p        return 0;5 d. w* ]2 T7 ]% c- G& F9 p" E. M
    else 6 E( G! B+ \6 O' J4 u( J
        return 1;; b9 u! b3 \. ~# T4 D" v8 I
}
, ]6 j% _- U! [( S8 j& o7 x$ L" E1 A3 ~. G. v! s1 ~  t: p
float operate(float x, char opr, float y)6 b, O; y: Z* @
{. S* ^' g' w0 W1 P3 u
    float result;
; D+ M9 [6 j0 B    switch (opr)
# x1 c; J' T& J1 [    {6 X% g4 m4 U  N7 g5 w
        case '+': , g8 O( i! N" I* f
             result = x + y;0 @- Q& r4 C, N0 Z/ w
             break;
5 B; n# e+ R- {, M6 B        case '-': * G/ b: a3 E; e- n/ }( `- N
             result = x - y;
$ r2 F3 V- h! W. v             break;
1 h  Y% h6 B0 b) g/ P0 N5 Q        case '*':
+ G& ]1 n; |  j. I             result = x * y;
0 x9 ^" B( D/ u. |8 _             break;, T' @$ V" T5 L
        case '/':
. ?, k* J( I6 P: c" V- I             if (y == 0)5 C% {# d' w: u, X2 W, c# K
             {8 _  Y. f$ r. F$ U5 H1 u
                printf("Divided by zero!\n");
. N, w$ @" N: f2 a' ^& C! l                return 0;4 O9 E1 k6 C2 B4 e
             }
  n; Z. B; l8 T/ E. N! A+ l; ^             else+ @3 C( {& j: S: c
             {5 p- r! H: D: l6 s( ^' j* h5 A2 Z/ p
                 result = x / y;
4 V! n2 @+ `" Y3 y! k1 r                 break;2 J5 [# d: O+ h, Y
             }
4 ^& \1 ^7 e# p. W, s9 |       default:
! Y0 G6 `" i: J4 [             printf("Bad Input.\n"); ' q2 s. {6 R  E$ z. r3 S, t
             return 0;
  ?  |2 U. g( ]* w. B0 k5 {4 u    }7 l( n( X4 O; B; C4 G
    return result;
. b+ z' j$ W0 x, y}   
) ^9 c7 M6 g' [% w2 O, c5 O' H( \: I  D4 W" X& U$ U0 Q5 M
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/7 P2 E4 Z$ Y) V
{9 R5 f" _3 X1 Z  b1 C  ^
    Stack optr,opnd;
  N0 b, {! G+ n* |& v8 f, l; v    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;8 V  T8 t7 v& G) A' n/ u& l
    char c;
  R% ~8 j8 m9 p' G& w4 Q, t  y+ a% c    char buf[16];
  j. V+ N& u' w! S$ V    int i=0;+ N' U8 C& J+ L& t! U3 G/ W
   
' u+ G, v1 y' B    InitStack(optr); /*用于寄存运算符*/
- H) k( O; s# f% H; b    InitStack(opnd); /*用于寄存操作数和计算结果*/! g% b# j; f7 h' {3 f9 ~. J
    memset(buf,0,sizeof(buf));
+ L  ?% e* _* T4 k, ]0 l5 _% S6 }+ a  v   
1 d0 p4 R7 o& l; x$ x9 r8 o. z/ V! |    printf("Enter your expression:");$ x" T3 t: @8 _# h/ l& _
        
. x- B+ s& O# B2 l( p    opr_in.ch='#';/ W1 {! y# \& M' R
    Push(optr,opr_in); /*'#'入栈*/
5 j* q; e0 h( f( N7 R    GetTop(optr,opr_top);
! n$ h/ S1 M5 n    c=getchar();0 U% o: F0 C1 w
    while(c!='='||opr_top.ch!='#')
& t8 ]6 z- ]8 A$ n8 ?0 p    {( f) a9 }- g" x, E) d% Y8 v
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
8 _" [/ H3 k0 n4 O. S, }* s. O        {& P* T9 I: z4 b& y& I# g
            buf=c;
% X- v" z/ l" b) h- j            i++;
! t' M8 ~7 X( b; X2 j' W            c=getchar();1 |/ `% g" j9 r$ S2 V& X# Y
        }9 g# o. a. C$ ?/ K2 u8 F
        else /*是运算符*/
: ]; {5 w( n* l1 D; G6 t4 w9 J0 T        {
* l! |6 R7 x4 |            buf='\0';
2 F& q8 _: F2 D) ~) t2 [$ q4 Q            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
3 V4 s9 z* ?* H9 ]9 D$ D' y/ H            {; }2 u$ j9 f. Q( z& q; m5 k
                 opn_in.data=(float)atof(buf);' b, m! a" q3 P0 J1 D4 s* e
                 Push(opnd,opn_in);9 O7 @1 H2 {) ~
                 printf("opnd入栈:[%f]\n",opn_in.data);
$ C8 L  t( f( u. H8 @% f                 i=0;
, {9 r, i. L; |% h0 ]% i( p) g                 memset(buf,0,sizeof(buf));( l8 f7 {9 f( X
            }
4 L+ ^0 E: \# @/ |, x( f0 F            opr_in.ch=c;3 n, S! d/ H1 H7 e
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/; V# a; h& W$ h
            {. ]+ C+ K) t( P8 S  g$ D; T
                case '<': /*优先级小于栈顶结点,则运算符入栈*/$ M: O4 m7 I- n* S* p
                     Push(optr,opr_in);
; g  y( D, f5 v" s. P                     printf("optr入栈:[%c]\n",opr_in.ch);
* R/ C4 N% ]1 K$ G                     c=getchar();- y: K8 Y  g! q2 d* y
                     break;/ ]3 k# V: H9 l6 r
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/; _0 l0 P1 a: c: T1 Q2 F
                     Pop(optr,e);& z" G" _- I( Y2 q) C
                     printf("optr出栈:去掉括号\n");; d) g" y* q5 ?6 k5 |' C
                     c=getchar();% |" g, G+ _2 Y4 K* u: V' w+ S
                     break;2 {7 b  @2 B, A( R8 Z
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
. M( A0 N* p9 t) J+ Q! y                     Pop(optr,opr_t);" b) ~; \' k- G  Y
                     printf("optr出栈:[%c]\n",opr_t.ch);
5 I  ~$ |9 Q0 T/ ]! C6 R6 s) ]. D                     if(Pop(opnd,b)<0)  a/ Y! E9 ?7 q# H! {
                     {, T# Q/ T9 i9 I( |
                         printf("Bad Input!\n");
6 X. Y* J" a" k) F1 ]* s: S* n0 s                         fflush(stdin);8 ^5 s$ x! y1 U# O, a( N
                         return -1;
1 l: O: F; t$ h9 n+ @                     }
9 s# h) k; A" ]5 \- [# n- Y6 P                     printf("opnd出栈:[%f]\n",b.data);
; i+ r: @$ _2 a+ `4 \. ?                     if(Pop(opnd,a)<0)9 f* X) S% v+ O, c6 f, H' w0 e
                     {4 x7 a- Q8 g- A
                         printf("Bad Input!\n");
# E3 b2 d9 |+ z; y( \+ {                         fflush(stdin);
/ J3 f* \/ G' q4 \! X- B" f. x+ O                         return -1;8 j/ y, K0 w) q) z( }( L
                     }: h" G5 f! H5 L  z% q5 }
                     printf("opnd出栈:[%f]\n",a.data);
0 Y8 x$ [) ~& J3 ]3 G                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*// E3 O9 |2 {% @0 ~' H
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
+ [! @( ?7 u. O! g3 j2 a" n! u7 K3 ^                     printf("结果入栈:[%f]\n",opn_tmp.data);& p* V5 O4 c1 ~  s' ]
                     break;/ G7 b( Z0 j0 _, q2 r, z+ D6 p, T
            }9 P5 l+ g% C5 _" |; o
        }
9 q% x& B, m# V        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
( `! Q0 d5 v7 |0 O9 B# F* L, M  B    }; c3 N" B- G4 R
    GetTop(opnd,opn_tmp);9 D, c8 `7 n+ _$ `  l  |9 Q
    DestroyStack(optr);8 O, o* ~( W/ x( c9 a8 b6 e2 c
    DestroyStack(opnd);) M' F4 I: D5 y9 i- ~3 ~8 X1 k& j
    return opn_tmp.data;
+ q4 Y7 K  j( ~}
, j" D' g7 e9 \* ]  b' y* d
/ J0 ?" v7 s7 n/ L' o) Zchar *killzero(char *res,float result)
  F$ m. X* M2 h2 d' Q# O{
# V2 j5 n) l3 V4 R7 t0 I1 V% w    int i;
( Q/ {/ }& Q, u( V8 ~- V7 Q$ u  p# Q3 S) W  j/ J
    sprintf(res,"%f",result);0 \/ ]& T0 J6 g! G7 C
    i=(int)strlen(res)-1;
2 C  @" W  G7 @' Q. f    while(i&&res=='0')
% W; T1 z3 }6 Z3 r. B+ P7 \. p    {
; `0 N) y( g5 r/ }; H$ @2 J! e# w& m        res='\0';, ~& y2 P4 O. |1 O6 B7 A8 V/ Z
        i--;
' E8 {7 ?! W4 \4 n! Z$ e    }
: ^( E" d2 M5 S5 c  J+ H$ u    if(res=='.')7 R3 }4 C! }; _' [, B% W  ^
        res='\0';3 j5 z" ~" f$ X7 u, G& f. [
    return res;; _3 s3 r8 u' K( {- d; I5 H+ G
}. o# G- K) N( u0 u- g, y0 o
) F, x8 Q7 N; T
int main()
  c1 v( d# X" h7 P{0 @% X9 j, h2 t
    char ch;
  }& i( U5 U* {! p2 w0 {2 g    char res[64];
; r& p  D6 L: L" u& B9 g    float result;1 O9 d: P( B& U9 s; V
    while(1)6 w, T. Q4 g& n
    {
3 ]3 F! i. W+ W! t/ K- q        result=compute();: M3 K7 o2 ~2 l' V1 f8 t, D* x# }, }
        printf("\nThe result is:%s\n",killzero(res,result));8 f& O: P1 `1 d6 h6 ]# {7 e
        printf("Do you want to continue(y/n)?:") ;
$ N& W8 T/ z# m0 G8 P2 ~$ \1 ]! ^        ch=getch();- X# g9 Z' V8 B, c2 u
        putchar(ch);7 t/ N9 N$ i  }! O
        if(ch=='n'||ch=='N'). V2 x  B* Y: I* f- _1 r
            break;  w. c$ ?1 j( h% w9 i9 G8 a3 v3 [
        else( E% z! t/ A+ s0 m' z
            system("cls");& K, `8 X1 Z( y+ X$ \
    }) d' ?1 @0 }% {0 k8 V1 p8 J
    return 0;
2 o+ `- _) r8 y6 j5 j8 [}

. g8 K! f3 r7 t
7 P  `6 N  o9 j: H3 T/ H[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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