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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
! e2 \  h, N6 o6 O+ r0 Y程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=& i. i- y5 ]! I
/**************表达式计算器************/& b( x" B; Q2 [0 u3 Y
#include <stdio.h>
$ O3 {9 {$ |2 s4 W2 P8 C3 U#include <stdlib.h>1 q) }1 c1 {0 p! O
#include <string.h>
" Z3 \* x4 c+ y- o0 n3 A#include <conio.h>4 T! u1 V: D+ K4 \1 t: O
#include <malloc.h>
6 Z, c# v2 @0 P4 ^4 H1 Q; g- C, n; H8 ^' e0 s* u8 x' V
#define STACK_SIZE 100
4 \% E. n8 Q! ]* l#define APPEND_SIZE 10
' O8 d  w  v8 t* t) ^( z2 {7 y3 c$ J3 M" A) B1 F# j- O
struct SNode{: o( V' F8 v) }# z: r1 [1 o
    float data; /*存放操作数或者计算结果*/
& e6 {( H7 r3 ?. h# f4 t' V3 H; E" I    char ch; /*存放运算符*/
( E  e# C9 g  q1 B- I$ S};8 [& j8 R/ f3 L" V4 D" U6 f5 O

/ ~5 e0 P" ?/ j0 @; f6 _$ s5 i$ [struct Stack{+ ^, V) T/ w1 {5 p
    SNode *top;
4 w7 [0 j/ Z3 n$ x' l    SNode *base;
; [4 S: W3 B8 x. F, g' p; H    int size;
: f) b/ d4 Q) h0 N4 Z};
" L" i5 V& ~) k% b# l) y8 j% P6 u( t; u8 |0 e1 M% g
/*栈操作函数*/
4 T6 u/ a9 m$ X" K! ~int InitStack(Stack &S); /*创建栈*/9 u2 S5 U2 }7 V  _2 b
int DestroyStack(Stack &S); /*销毁栈*/
  }8 E4 f, M- L" r4 Kint ClearStack(Stack &S); /*清空栈*/4 X0 A0 }% S& d0 a# D6 k  ]2 ]
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/9 h3 P, K$ q* A/ o
int Push(Stack &S,SNode e); /*将结点e压入栈*/
3 Q1 @! n( i7 s  }0 oint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/- C9 ~3 }7 N  [

' o; G6 z7 ^3 y6 w" O: s/*表达式计算器相关函数*/
5 g6 V- F7 d. Z/ T" @4 P1 zchar get_precede(char s,char c); /*判断运算符s和c的优先级*/4 ?( ~  M% t9 i3 e) ]* b& b9 P: z
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
: a* u7 r+ [# Ffloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/. _, v% F& k/ o) N
float compute(); /*表达式结算器主函数*/  s( o$ t3 [/ w( _1 c9 w) U/ U
char *killzero(float result); /*去掉结果后面的0*/
& S; W) N' t$ y; c# P1 T7 `' o6 [
9 Q& v( h  O" f/ I4 A9 O. jint InitStack(Stack &S)* e' K- P4 {2 q, z4 ^, V5 v
{
, q. n- B" ^+ y7 X    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));" `+ O1 Z' _' m  [  l
    if(S.base==NULL)
$ d' p8 a! \& Z    {. C- j" N- w# h& }6 F
        printf("动态分配内存失败!");
/ F& _9 \  P. H8 X+ N  J% i+ W" b6 y3 j        return -1;
, l  Q* K6 a: i    }! Z: ~# Q" s5 F. V
    S.top=S.base;1 ?0 S0 M8 B) M: d: S
    S.size=STACK_SIZE;
+ |) }/ C/ a2 S' M8 Q    return 0;
# s; A1 A" r  t0 Y: ]0 l}; C: e" r2 b# U( J5 m; j. E  P3 E

) |. z0 r9 G6 U/ @int DestroyStack(Stack &S)
0 W  j5 e  m( n) Q8 z  X  q{
+ }; _% d# J. ]& b+ ]( r7 U' F    free(S.base);
4 @" E$ I6 a- k5 ^2 d% i7 m0 e4 g/ [    return 0;
" [3 \" r/ T/ b; d$ s}0 o4 h  c* w6 |5 w; h3 N8 Y0 M
4 ]  {! p  @. P  g& u! E
int ClearStack(Stack &S)5 [$ a" E9 R! J# x8 |$ U/ j$ W
{) ?. q/ |4 x- X1 I4 g. P
    S.top=S.base;: p* i1 W9 W  j9 f
    return 0;# x5 t  @* d5 n8 d7 P  \
}
' ?; c1 T* N8 k# N+ Z0 `
- g/ E( ~4 `. t% A. hint GetTop(Stack S,SNode &e)/ Q0 e8 N! q, Y
{
0 z% I( X6 q5 D8 q    if(S.top==S.base)8 e( U( U4 {  _0 U0 w, m4 {
    {) p: @) R* B5 z: t
        printf("栈以为空!");
: u' Z  ^) m, M2 c4 H        return -1;# @; L% F3 T5 w. A3 u! |2 t0 _
    }
/ y# q- E5 Q% \$ Q; o/ j    e=*(S.top-1);) Q7 y+ Y) o% |, J, U* p! h) Q
    return 0;7 }/ t' `. J) F/ |; [* D8 {$ ?
}6 P  U, [! J/ I( M

, C# S: G8 W2 s% w0 X. ^int Push(Stack &S,SNode e)
2 {$ n% \% g7 W6 h. y1 {{  j) [$ M2 x' k4 G* g
    if(S.top-S.base>=S.size)
. B7 S2 V) s. e5 T9 I. r    {
4 l7 z; W  h: B        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
+ O  S0 h& o" D! `9 _0 V; c        if(S.base==NULL)
( r9 w7 W3 E5 f* ^8 k        {
0 ^7 ]8 v0 g0 Z; o: y7 w            printf("动态分配内存失败!");1 _$ m5 t7 w! Z. F. M
            return -1;7 ~3 x/ X4 }! l6 T8 F6 k
        }
) U2 p  }  J3 c/ Z! H  O% V( c        S.top=S.base+S.size;
; v& S5 p$ n" [7 {. Y3 I* b        S.size+=APPEND_SIZE;
' ?7 S! F! K. M7 L    }
! Z+ }9 H& E$ o    *S.top=e;4 O4 G1 Z2 X! b) j; p- O" u2 P
    S.top++;- {. }4 \9 h- ~, f
    return 0;1 s! a- [2 n& \; v- m! ^$ h- s
}6 U, ~2 m; T- D+ e9 Q
/ |) S; S8 i% F3 @  k5 s
int Pop(Stack &S,SNode &e)
/ b+ H$ a1 d0 }; ^) M7 p- y{% X% f6 W% D) o; d4 b7 S
    if(S.top==S.base)
* q% ]4 }5 U5 z! q# V8 X5 U    {9 F( _3 f0 U: S& N+ b0 _7 G: ^# J
        printf("栈为空!");
1 @1 m5 D3 l; B  h" z! T% f! @        return -1;3 t6 K& Z1 t6 a/ U5 R9 V" Q4 d
    }( T4 h5 ?6 j1 U, r& U; @' q) d* D
    e=*(S.top-1);
6 o8 }- H' W7 }$ K" T! O$ A    S.top--;
5 b8 d; t% L' T3 ^2 a/ a- a8 E8 A1 ~    return 0;
" G  j& N5 w( [0 A) A$ ?- I}8 \% v2 f8 K; `# z
5 j6 n$ C1 R5 N/ ~- B
char get_precede(char s,char c)
3 L% o* U+ T8 F8 E* u7 Z{
7 j1 L2 C. _9 r2 u    switch(s), u; p5 r7 n1 Z1 S2 _- p
    {
' A1 J; p! [, r        case '+':                 $ d& s9 b, v+ `% ~  ^3 U' L
        case '-':$ E9 \4 v9 |) G
             if(c=='+'||c=='-')
. n2 X0 X# e8 `, H4 g1 E; U                 return '>';! \* F  h9 e" M' p
             else if(c=='*'||c=='/')& J# E, Z' E& m/ E) Z& p
                 return '<';6 j8 K$ v# @3 x
             else if(c=='(')" D3 I1 L2 J  S/ n
                 return '<';
4 ]! Y6 q+ Q9 F# n9 X5 b             else if(c==')')
0 n+ {# @/ R/ U                 return '>';/ D, A4 }4 G& d* L6 z
             else 3 i7 [6 D( I+ y5 ?  M. G2 }7 M
                 return '>';
5 ~+ \9 h% v! O% ^        case '*':
5 t% t! a' B/ R        case '/':
( t, f/ B) l8 v% O* P( W' O             if(c=='+'||c=='-'); k* u& p/ y  D3 O* ~- ~
                 return '>';0 C1 H) V3 e1 j8 j& W" F& D& I
             else if(c=='*'||c=='/')
# x4 A# n" F" V% t) l1 o: @                 return '>';% u1 K8 {; h$ o
             else if(c=='(')
: {( W' z) h( q  ]                 return '<';% u  j7 e9 y0 j5 i8 O# E8 b
             else if(c==')')+ C0 P$ t! `2 a; D
                 return '>';; [5 |, o5 J- x, W- s( A
             else
9 ?5 v' h2 L. W1 @( Z- u                 return '>';8 ~3 G' d9 w4 `$ \, Y$ s* j1 i
        case '(':8 p. c( Q; |( N% h
             if(c=='+'||c=='-')
  B+ V, C. l3 `, ^: C( [                 return '<';
3 H0 B9 [* q/ ~5 V( \" o( h             else if(c=='*'||c=='/')
, b5 L% A3 y% U5 Q- K5 ]5 z+ C                 return '<';  R; A" m8 a6 c7 ?4 P1 g
             else if(c=='(')% W* o0 q) Y  ?
                 return '<';
; b, T/ ^% f) n& W+ N; s7 P4 Q: C8 N             else if(c==')')
9 }7 m, p  y, D4 q- H+ j' R                 return '=';
% K( }& Y! P  C  H0 i8 `* r1 L# \% F             else
4 C: d7 u( F9 g1 i; ?$ M7 {2 }% @                 return 'E';; w. m) `3 Y' r% [6 n  X  c
        case ')':
) G/ Y% u1 O! @) l% H9 D  [             if(c=='+'||c=='-')4 R. G7 c) y# t( m/ `
                 return '>';
' a1 a# P% Y! g7 `             else if(c=='*'||c=='/')% M8 d& W' L0 c9 E7 c
                 return '>';3 }8 s" t# |7 R5 G2 x
             else if(c=='(')# H6 t/ ^$ E" N
                 return 'E';1 o% C0 k( _5 _" f( ^
             else if(c==')')
1 K7 q. @" h6 ?! n( F                 return '>';0 C  E7 q/ P! y$ X; V( K& I8 g
             else* E: e. I6 N) ^( A  T
                 return '>';7 y: w9 A1 D& X
        case '#':
3 {+ H$ \$ M( |* Q) F5 x             if(c=='+'||c=='-')
$ ?# ]& |8 E& _$ D$ z. c                 return '<';6 a( v( _) T: @/ J5 @1 N
             else if(c=='*'||c=='/')+ P( F4 O$ Q% i0 [4 i2 j( ]" k1 D
                 return '<';
6 ~9 t6 V1 k2 A  ^1 x4 ]( `             else if(c=='(')+ t. h$ s' u) K8 H, \
                 return '<';9 x7 p" ^) w8 b" @) v  d
             else if(c==')')
$ m6 z  c4 Q! D* v) n) p                 return 'E';! N  v+ U+ l9 G; |6 r7 }
             else4 w9 ]) M4 x7 k0 p) v8 Z) D5 ~9 r8 Z
                 return '=';
% L$ R7 B, s: Y  E- x7 R" A        default:
( V! C/ I% ~+ w; B9 T             break;
; ]* Y6 C- f2 S3 r    }
% y% c+ c$ S# a2 z$ o/ R0 ]    return 0;   
, E; J* m' h, D" m, W. n}1 G& e/ K% w9 ~8 P" k
* P( {+ x/ ~, z, s( K: Z
int isOpr(char c)( \8 X& m0 H, p* C  i6 S
{
$ W5 a7 f2 q2 q3 U; B% D! l    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')5 y, k9 ]+ H2 l4 @
        return 0;% z* j% n5 K! `" r
    else 2 W- ?, ^( v0 l8 B
        return 1;
/ r% V8 B. u' w6 V2 Z3 T, I}
. d+ m' l; T" C0 D$ n( Z0 a9 w. L$ \6 O" y' [
float operate(float x, char opr, float y); `$ \% G. ]6 j
{
) Y6 w! ^8 V4 }& `    float result;& A) P! x3 `  ]7 q3 M: s9 C6 V6 @
    switch (opr)
6 Y  V4 x/ W5 @0 a7 y# [& V9 E    {6 w! i$ n( a$ a/ T2 v
        case '+': / y' \1 W; f1 @. i
             result = x + y;. X3 I% R" T2 ]! w! M
             break;
- s+ L' i. U% f8 G% R        case '-':
, g7 [) Y5 T5 L             result = x - y;
. a1 y6 l2 I4 S& e" _# X6 B& J             break;% D+ {0 T' v7 h
        case '*':
0 k, A+ M, s* h( f* i; m+ j             result = x * y;
. |# t+ N4 l6 I. c( E' o             break;
( o: z  f( R7 e* Y( `        case '/':
4 J% S9 J+ W7 c2 C# A             if (y == 0)3 z. m+ C% X* b* G; x6 V: G( z: I6 w
             {& @3 K5 {: D8 ]% i/ l9 `
                printf("Divided by zero!\n");$ {6 y1 @  C% `5 I. m+ K
                return 0;
) ?) c9 G& n  ?, D+ `% J+ S             }
8 c9 ~! p: l0 F3 O             else
! l: A5 z, d0 T             {9 _4 F1 L+ n/ e- G8 r2 y
                 result = x / y;
) N; k  g: B. T7 S. F& ^1 q) r                 break;
, F3 n. F+ d* N5 U             }# ]1 D0 Y) B* s
       default:
  O* a9 B+ m% B: B             printf("Bad Input.\n");
# r, h! X5 V, o; w1 k: I0 X9 s             return 0;/ h3 P7 S) W8 Q" b; @2 d' D4 g; z
    }4 P5 d8 M+ a  h' @% G
    return result;; E# A- u) X+ t0 f$ u3 H- Y8 P
}    : F8 ^& t, Y3 Z7 L8 r$ _- V
5 t+ O2 O6 I+ e5 @
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/; I& D0 P% |) O/ a& g" u
{; F( D; e; ?9 y9 R0 V" }4 V3 J* k8 e
    Stack optr,opnd;7 i/ P' ^6 a9 j3 B5 L& V8 x  u
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
( k4 b) {$ I* j  M8 u8 z" d# O% r    char c;
- B/ u# Q1 K/ R2 i  {    char buf[16];% F( k5 y: G7 |5 V
    int i=0;
, U/ q4 K& r/ O( c. m# N# Q3 _    3 m8 k" M9 u& |& ~
    InitStack(optr); /*用于寄存运算符*/
! Y$ O$ |2 n0 i! Z: t. N    InitStack(opnd); /*用于寄存操作数和计算结果*/
1 j9 O: {9 Q5 Q( F3 p" z* l- N/ l  {    memset(buf,0,sizeof(buf));0 y9 s. @, O& o6 B
   
' t. x1 @3 [& M, c    printf("Enter your expression:");( @* L3 l: u& c6 {- w
        3 a% z) f5 w4 Y4 Z, M
    opr_in.ch='#';
; L4 Y6 p- t0 z) L: }3 E  A    Push(optr,opr_in); /*'#'入栈*/
: u& P! U( Y3 z+ L$ K6 x    GetTop(optr,opr_top);' {, ?$ G. k: T
    c=getchar();9 d" G8 P- A4 F. t# j
    while(c!='='||opr_top.ch!='#')( b4 p* f; \* q% ]6 p0 m$ _
    {8 C  T4 j, r1 ]+ y! q
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
) ~  O- o) W2 ]: z9 B) O- O        {
4 {9 Y+ q: ^# s8 e' s            buf=c;) U9 Y( [+ {& w2 T/ f
            i++;$ a8 d3 s$ h2 ~! T: B
            c=getchar();
4 N7 M5 w% e8 V9 B% ]        }
: u+ O$ B5 D7 f9 j        else /*是运算符*/
' b4 ^6 ?5 ]# Z& a) l. K6 k        {- _& ]) g) N0 [/ W. H
            buf='\0';
: g2 {+ \4 [- x0 H- c% E9 C            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
: K% r" s, j$ ?; P) O            {! {0 O  `4 m3 H! n8 p
                 opn_in.data=(float)atof(buf);
/ w3 D# s7 C- k: ]# w                 Push(opnd,opn_in);6 Q  t, o2 U) R  y
                 printf("opnd入栈:[%f]\n",opn_in.data);+ ]! H& M6 b& H- |# }
                 i=0;: o/ H* I; G$ h- Q! ~- K) C
                 memset(buf,0,sizeof(buf));& U8 e9 }; K, ^% y" z7 q6 C9 B8 W
            }4 T2 F2 j- ]( b. S% q- O
            opr_in.ch=c;
0 V/ x* ]$ c; s8 \            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/: y3 w; ~( }0 G& }2 [5 H
            {
. @/ _0 u' _9 |0 r/ }* q. |                case '<': /*优先级小于栈顶结点,则运算符入栈*/
5 y. Q. Z" L- a3 v5 a) i2 N& X                     Push(optr,opr_in);$ g2 u* X: C6 Y+ ^1 q6 V* Z
                     printf("optr入栈:[%c]\n",opr_in.ch);
5 c# F# [) u$ j                     c=getchar();1 L* |5 j. q) w' i0 G0 S+ ~
                     break;! t& V9 o/ z( `$ W9 `: g9 U! J" p  `
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
+ h' L6 t4 h# C                     Pop(optr,e);
) n+ y1 W1 [5 j) |8 f/ D                     printf("optr出栈:去掉括号\n");- N/ z0 ]% Q/ {$ Q! W5 }+ B
                     c=getchar();; E' I: @& q- G" A& ]
                     break;
1 Y  O, E3 I1 U( `                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8 y9 X8 z  }- v7 p; H; W1 w* r/ [
                     Pop(optr,opr_t);) H4 S# P* }& j, C+ d- T
                     printf("optr出栈:[%c]\n",opr_t.ch);4 X5 B4 a% M& }5 |1 b4 Y
                     if(Pop(opnd,b)<0)
0 g( e& G9 y3 U. [) f2 Z# X% j3 i                     {( o$ g4 q5 k! g9 o: w
                         printf("Bad Input!\n");
- \2 T+ |+ |  X" O5 l                         fflush(stdin);" ^2 f; i8 s3 I" c7 c( u2 N
                         return -1;
" u: m' I( J0 ~1 Q% a* {                     }) |- Z  p& S+ k9 ]1 p# F! T6 }6 G
                     printf("opnd出栈:[%f]\n",b.data);
- t  [! A3 r- ?: T# s- v* [                     if(Pop(opnd,a)<0)3 }. d1 E- Y& ^9 m
                     {
6 e# x( D. h) b0 |, {) T; _                         printf("Bad Input!\n");
0 _# m* [- A! B* q6 x                         fflush(stdin);( x8 H4 Z. ~, w
                         return -1;7 P  Y9 x6 S0 T8 i
                     }
) c+ v; G& x1 j+ E& Y% Q% s5 c1 E  U                     printf("opnd出栈:[%f]\n",a.data);' g8 F8 D' W0 T& U8 w+ o
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
  S% n- b8 i) T& D3 K                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/8 e5 q  N( W6 ^' ?' W1 l
                     printf("结果入栈:[%f]\n",opn_tmp.data);4 s4 ]# f1 [# l
                     break;/ f4 e) d6 T* }+ ]7 t2 P* `" |
            }7 s( N/ m" b/ B
        }& m% x) B4 d9 x1 V
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
) n$ v5 b9 b9 l: h: ^4 x    }* |$ Z/ t' n1 Q& Y! M0 t
    GetTop(opnd,opn_tmp);
( G7 f- x' W3 I# _: T    DestroyStack(optr);
8 H7 |" M1 Q! c7 q# |; D; C    DestroyStack(opnd);3 r' J; g& S' r
    return opn_tmp.data;# [& T/ w( L% T6 d/ K
}! q! Y, d* ^( t4 z) n: ]6 T

  ~" m$ {. R3 x- y/ ^: h1 Echar *killzero(char *res,float result)
6 U. b0 S8 I7 F% \: D{
* T. a+ @. K. k9 C0 k# ^! G& H6 Q    int i;
9 z" e$ q3 z1 Q# U, D* L$ v! z* {' U; \5 p- A4 g9 H2 U: O( g
    sprintf(res,"%f",result);
, e) O0 M0 v/ F* f2 Z9 C    i=(int)strlen(res)-1;1 Y' ]6 ~! M- x0 U
    while(i&&res=='0')
0 a- C  a4 l8 p4 V8 E: D    {7 @' y: H- p0 S1 o1 r$ V( u! g: ~# ^
        res='\0';/ h8 e- O4 _4 p7 z$ c! O
        i--;
" n" U" j$ d5 n    }
& u% A9 W" Y9 o" ]    if(res=='.')
/ l; I- b, G$ h. G! V        res='\0';. Y9 N( u, [5 r, M' i# T. l
    return res;
, f; l7 |+ @* E9 r/ ~}
0 e/ c' G2 N: o/ a7 J( `- L  _+ O6 k. @9 `( F
int main()2 V$ ?; M; I2 n) l8 `  F! R& I* B& T
{
1 I- m2 i& @  j* r5 u* H    char ch;  T5 n' p  L" F
    char res[64];
" T+ G& I  W# k4 ]    float result;; S4 T$ N+ x0 I( E  G, D5 l# O
    while(1)
0 I1 h1 v5 r; X9 }1 A8 b    {
: m6 I8 {; e; h" b5 ~        result=compute();1 W% d2 h6 U- Z* p4 G( S/ Z- ~3 S) J
        printf("\nThe result is:%s\n",killzero(res,result));& g5 m) Z: p# ^% j0 @
        printf("Do you want to continue(y/n)?:") ;
* k  _- G6 R  T        ch=getch();
1 W- w0 A9 u, G        putchar(ch);" `+ V3 n/ }3 D1 v' f
        if(ch=='n'||ch=='N')
( u' h' B, G: R3 A/ a5 w            break;
. s$ d" D% f- n+ m. m0 R        else
! a, _* H1 H- v# R            system("cls");, T, j4 ]; t( x% X0 S- Y: G& O
    }. p+ z2 Y2 q3 r! U8 }, J# A
    return 0;
) y7 P" ~: Z3 U, X+ s1 R& d}

. h/ T2 y# L* g6 d7 s1 V
9 K# L) s8 I6 N7 l0 f[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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