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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.4 {  ?  q8 x3 }
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=8 @5 t, m( [" t5 ^7 @
/**************表达式计算器************/) n1 b: x6 S$ W* j8 W, M' T( @3 a& ?, H
#include <stdio.h>
2 }* `* A4 d# E/ @#include <stdlib.h>8 _- W) l5 }6 \; I
#include <string.h>) i! N" L2 @) _- p$ r( ]$ x1 A
#include <conio.h>
; u5 C' C. y! ^# ?3 r#include <malloc.h>
. ]1 T  v4 A" T. k4 ^
6 k* K- s! k! I) m' y$ b#define STACK_SIZE 100; Q8 r1 p+ k4 g2 Y
#define APPEND_SIZE 10% t- z+ t# G6 ~8 D
. i; ~( Q' F2 ~, {4 c! V
struct SNode{
/ j& x  W7 \6 U4 C. M7 @    float data; /*存放操作数或者计算结果*/
( O8 ?/ R0 i0 |- U& M    char ch; /*存放运算符*/
7 b; z5 W4 f9 x! i. R  ^};
* K. S: `- {5 D
% E8 f, h% x, Zstruct Stack{
( E) L1 p2 D% C& W& v* B8 s- Y    SNode *top;6 [5 P0 H, |- x8 q" K9 @+ ?
    SNode *base;: w. b  O, n& e
    int size;% f5 v- D! y! T3 S
};
. |2 L. \, ]# n$ m0 E/ i4 q$ n8 e, U' u9 Q* x, d3 G$ z
/*栈操作函数*/) J% U% O- V! G( c8 Q* \
int InitStack(Stack &S); /*创建栈*/$ l1 c) d5 _! R/ f" h) A4 F
int DestroyStack(Stack &S); /*销毁栈*/
& C3 t' E; k1 N  e/ j5 a5 Yint ClearStack(Stack &S); /*清空栈*/
0 H' ]6 J7 G5 }. vint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
* W' Z6 N7 K: b9 G, X+ Q6 Qint Push(Stack &S,SNode e); /*将结点e压入栈*/
: e7 h" e/ D% a9 X. w* Y+ Gint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/5 N" m5 [# ^# ~" I: g3 A

+ j' `, [" p# n* `* h/*表达式计算器相关函数*/  h) n* w5 U* o) {; k# U' P" Y
char get_precede(char s,char c); /*判断运算符s和c的优先级*/7 {( v0 [$ q8 o9 G
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
& w& j7 T1 B, K* x* a  Qfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/: }; Y5 E6 J  f" A: |$ Z+ L* b
float compute(); /*表达式结算器主函数*/6 J$ o3 V" \3 X; N/ i# l$ ~; R
char *killzero(float result); /*去掉结果后面的0*/ 1 C3 ?! t0 w3 _8 j8 n. L
( j9 B3 \" i$ C' W! w# m4 i
int InitStack(Stack &S)
2 g) I1 d) n8 H& W! Z{  w5 Q. k+ y, I; V( u
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
( h2 y* i2 t0 J" T" Y+ d' g1 R    if(S.base==NULL)5 Z+ M: ]( D3 w; `
    {0 C4 u0 x6 ~* ^/ w
        printf("动态分配内存失败!");
9 i& i+ @, T0 C* e3 f1 C! I, S- Z: l        return -1;
9 u/ G/ x- y; \$ x$ y    }
/ g/ b# V' X1 t8 ~, h' p    S.top=S.base;2 _+ X1 o# \. e" m" U
    S.size=STACK_SIZE;7 e; J$ o1 C' t! f
    return 0;. I* Y  ~2 j' b7 o2 v
}
3 a5 @, s1 [2 ?2 Q% c
# L" L1 B, j5 J  pint DestroyStack(Stack &S)
# W6 U/ j+ R/ Q" t+ _{
. F  x+ Q% n7 Z* {    free(S.base);
1 L3 G/ _$ Z* ?0 \    return 0;
9 g$ Y" R; D- |6 I% |; K" v/ d}% _2 x( H; |% p+ E. D- G
, L3 H* H( E3 z( p% O& v( x# z9 A- p
int ClearStack(Stack &S)  R) ?0 h: B  t& r( l
{0 m% z$ T. p$ x* A: O, u2 A
    S.top=S.base;% t/ U2 ]( D8 H+ S
    return 0;+ w& Y2 k1 }- D0 R9 j! X+ h
}: q( Z' x* {! I4 W+ j
* @# v+ K$ n, D& a: i# Q. M
int GetTop(Stack S,SNode &e)
+ M. N! g% D' P# _8 o3 W' ^( u5 j{
& f- Y2 v4 q- [6 |* H4 s; V9 W( Q    if(S.top==S.base)- z- ^- H! _* ~% H& Y
    {
5 J* s' N7 a; O- L' X% O+ j        printf("栈以为空!");
( T9 G$ l4 g' v% @" g5 w+ d        return -1;4 _; [; @, }; {! J2 G5 V6 W: H
    }
# x: `- C9 N6 [" y) w' q" e8 R    e=*(S.top-1);; D: u1 K& m- l: `: V/ F
    return 0;
) Z" Y- E% n, o) I/ \}* I2 e5 ~* u0 R- F
9 y" t' u' R; J, y& C
int Push(Stack &S,SNode e); s8 N- B+ _& G0 m2 e
{* a; N+ {" ?0 F  F+ T
    if(S.top-S.base>=S.size)
4 O0 n+ f4 f2 a    {- d' b1 ^2 p9 c" M0 k9 j9 z
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));( C: l1 n4 D( T. j0 @) L; t
        if(S.base==NULL)
3 w$ [' o+ q9 ~$ D) ?        {
: Y5 I, {( ]( L5 N            printf("动态分配内存失败!");
* ^8 j& i! V0 Y4 P0 t! h            return -1;$ [& C% N, q( _  {+ ^- M; h7 z
        }
: x# Y; h& q& O        S.top=S.base+S.size;  w0 y( \( K' a& |/ p
        S.size+=APPEND_SIZE;
( N' {( l% B) n; @; i9 }    }& A, p" i* ~+ X* D, _, P
    *S.top=e;# N0 z: S7 }; V3 N" D
    S.top++;
9 L, F8 a( u2 g# |, {    return 0;
, X' r& y0 }8 b1 t}
, M/ G1 ^. n7 I" X( p& ~. N2 s1 b! M7 Y
int Pop(Stack &S,SNode &e)$ P8 Q; u1 I2 l- n8 ~
{6 F  Y4 }' A* I
    if(S.top==S.base)2 [! G) N7 M' N1 W' Z- L
    {; J) Z/ C! Y( E3 r" E& S3 c* C
        printf("栈为空!");
" H+ E2 N. I. T1 T; B  k' w        return -1;/ y9 l* O  R2 a- s, R
    }
- w$ i) t/ F; ]+ E7 t    e=*(S.top-1);$ k" G5 s* f" H8 t5 T9 z$ C
    S.top--;! L5 f8 l" H- f0 O
    return 0;% O4 y9 r! B( G& o6 H
}
! A' D+ ]6 @4 Z: d3 ~6 g- ?% j3 y% |3 ?( c  x4 x0 q; d( b/ X
char get_precede(char s,char c)+ O% n7 M+ m8 n) i+ k8 D5 H* {
{2 z- ^& G4 s0 S% V/ w& H. d
    switch(s)
' c0 X" Z3 I+ a9 `3 l+ z    {8 D4 L4 J- L: c
        case '+':                 * y1 X6 ~+ `, x2 y7 J, x
        case '-':
# \) K) ~5 @0 K             if(c=='+'||c=='-')+ N4 y: ?! I, ]/ }6 g- `
                 return '>';
$ ~; n0 \4 Q( g+ f, E7 C             else if(c=='*'||c=='/')/ n; ~, d$ {# n( ~2 P6 A3 i
                 return '<';
8 A; F0 Q' o, `1 N& C& R4 S             else if(c=='(')
: R) r+ P9 B9 f/ k1 o* [# Y) K                 return '<';
7 _- ?% x( r. \1 p6 c3 @4 l             else if(c==')')
  ?$ R# V: A# z3 q                 return '>';9 _0 m2 h# E7 t' A
             else
2 [; w" N5 `) L7 e                 return '>';
  X2 @, N, G6 w. l# Q- O& _        case '*':
- \1 m/ x6 M* r# J. t( m  @        case '/':
. R9 i7 P+ j0 {. x2 d6 h) [1 k             if(c=='+'||c=='-')
$ `( \# ^1 c* M- i$ v$ O- o                 return '>';
; ?, x6 r0 l3 c; E             else if(c=='*'||c=='/')7 W1 C( z' T/ x1 R3 t
                 return '>';. M, U- Y+ l" t' w
             else if(c=='(')7 n/ w) A8 d- l0 w
                 return '<';
$ I7 S( A: Y: I3 R6 q$ g             else if(c==')')
( p2 N+ y, v6 T                 return '>';4 H/ J: X* N* [
             else2 |) S5 t: G5 g: ^* O" ]- U
                 return '>';; E' M% v! v8 ~- k) ?1 X, W0 M  K, n
        case '(':, ~( t+ }' z8 ?, C, V, N( y- o+ `5 Q
             if(c=='+'||c=='-')
8 G7 W+ L. {3 t( t$ W                 return '<';3 z2 G$ }9 Y: S0 t" y
             else if(c=='*'||c=='/')6 D% q4 {) i9 G6 X! y- v8 \
                 return '<';
3 L; M' C$ w6 D/ |+ k& l" ]* g& F             else if(c=='(')
$ p5 X( y; ~" q2 Z6 V                 return '<';" [% d( @$ T8 _+ H
             else if(c==')')2 P/ ~+ R  Q: @$ [
                 return '=';
2 o( ?, N7 D0 \. `* ]# X$ {. a             else
& S3 R7 p8 K8 V; R8 y7 G0 s2 R+ p                 return 'E';3 F2 s0 d0 i3 b( c) ]( R" Y
        case ')':
7 R! {' W9 Y$ ?) B: O. ]* f$ L             if(c=='+'||c=='-'); {' I% Y8 U0 _$ i% N# y1 E
                 return '>';4 G7 Z3 v0 k! ?' E0 c+ j% x
             else if(c=='*'||c=='/')+ l3 g, m5 P. E' n
                 return '>';9 p9 E9 W% q( N/ ~% ]' T& \
             else if(c=='(')
' Y% E% N7 t$ X7 o/ D                 return 'E';
7 y$ D, @  w; B) K0 H0 ]* I             else if(c==')')
$ t  t3 ^' `. L8 j* w4 X' T                 return '>';
/ S3 f: A! Q  O( E$ r* X/ h8 i/ @) Y- r2 C             else
  s& r3 d. I8 j- X( s' P) b. k                 return '>';, K4 _) F& ^( n
        case '#':$ ]' M- `$ p3 x) R, ~
             if(c=='+'||c=='-')8 R. x$ m1 z. r' u* {3 l
                 return '<';
& Q- I. g: z6 Y- F! E             else if(c=='*'||c=='/')
: U0 W9 S2 C# A, t4 @; F5 `# i7 z7 E                 return '<';6 F3 t2 ]. s3 y/ Q8 v
             else if(c=='(')
# Z( K' G3 }4 F$ [( v* O# P5 [  G                 return '<';
4 ^# |: g! @  m4 C1 `+ ?             else if(c==')')3 H: ]1 c9 A4 j( }
                 return 'E';
# N, W2 N3 K7 A- l7 R  Z             else5 J1 O! k9 C  O5 O/ z6 J. g
                 return '=';
1 ~0 Y7 x9 U" s        default:6 }6 E" _1 H% _  t: `
             break;; I4 _3 h4 g6 R9 Q
    }, B$ p7 o5 N5 J& l. f, J
    return 0;   
" z- C' a+ P3 p8 x* M}. M5 q9 A, l  n2 y9 y. U  i3 w

8 N9 `3 V$ {$ [' Hint isOpr(char c)
  Y3 x6 s! N# ~$ t5 U; @3 Z{
6 o8 _. z8 f$ |0 [    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='), s0 _  W7 A. J# @0 g% j0 A
        return 0;6 g: d9 d) {$ R. j. g8 {9 j( X
    else " j" x' g7 q4 r: Z! A
        return 1;* @- e9 s3 M* {" ^/ a
}# a4 R2 V6 N$ H- a5 A

* P/ l6 j$ \, W. H% i" ]float operate(float x, char opr, float y)
* T2 n: t( [( _: r; T{7 l1 X7 _9 E+ i# i9 s! [  b; u
    float result;! d% U( S" q1 g+ x. s2 l3 N
    switch (opr)
5 c1 \$ U7 X: n- }' x0 n) |    {
# @. b6 t5 t: f8 h/ V  s        case '+':
  Q8 _* \3 t% ]* f9 }7 u* l: J9 a             result = x + y;8 w) p* d0 e5 |5 }# n
             break;4 w* {5 t% G9 F& P$ y, j* ^
        case '-': ! W1 Y2 P5 @9 l7 b8 G/ o
             result = x - y;
9 ^& [8 q* w4 `; j! \             break;
/ A6 H8 X# p$ O        case '*':
6 e$ w! ?+ t; `4 v. o' k2 p9 N             result = x * y;
% h2 u8 Z7 k2 {/ @             break;
. s: @+ D6 i7 R8 p0 T) _( F' Z        case '/':
  F- [1 w7 g/ m' Q             if (y == 0)3 L7 A8 ~5 c8 `7 r% W! l
             {
. j! Y- j- D( b2 G) K                printf("Divided by zero!\n");5 b  g+ r0 N9 @! P1 \% d! t5 H
                return 0;  K5 H7 J. k- u* f6 F
             }
2 A& Q  ~( Z% \; q# O9 ^             else
0 |9 w1 L# U$ ]" ^# @8 g             {
5 g7 o( _4 I" D6 c. l1 {                 result = x / y;
# a4 M2 S6 J/ w( e' U9 l                 break;
3 R- u) s$ x. s/ y% O, M  h             }
% z+ X  n8 I! \" @7 A1 F0 C. T       default: 6 `, a0 ~* ]0 Y, H! H8 l) y2 ?
             printf("Bad Input.\n");
0 F  T9 L8 f# S8 I" L: w             return 0;. y5 K8 o, X3 a  }
    }
4 N* Z$ v. V$ O% X% m) W4 h( ~3 f7 j  w    return result;
3 o1 T9 N% i" b' J$ p- T; ]}   
( |  H  P1 n: a4 v/ o' r( _, P2 ]! q% N% i( w
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 r% @1 I" v$ E- ~{
2 B  K- C( T1 M    Stack optr,opnd;" x2 f9 v1 E+ ^4 k1 l
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;. H9 W8 y: U! z; y' Q! N
    char c;/ o/ Q6 A3 x) r* ?9 @
    char buf[16];/ L; F: F3 k; @4 ]* X
    int i=0;
# `* v7 d( y0 z. }( V  ^" O7 f3 d4 s   
  C6 u# a9 C7 \6 X+ j    InitStack(optr); /*用于寄存运算符*/
2 ~; F. H* t2 H! T- Y    InitStack(opnd); /*用于寄存操作数和计算结果*/
1 w0 o: ~, t# S  s! J2 U; ?* [    memset(buf,0,sizeof(buf));; }( l8 ]' ~- n# d7 q
   
  K9 D+ m* q! h3 D/ `( h+ c    printf("Enter your expression:");
  e; N& A4 @$ k  d# d9 u+ W        
* h& m: u' |% h/ o0 ?  k- t0 `, |    opr_in.ch='#';% H5 k& [, _& v7 I7 L  R$ L: U" I! j
    Push(optr,opr_in); /*'#'入栈*/
6 C% B* L* j4 Q, p( a7 _    GetTop(optr,opr_top);- c8 v* {% T" N' s; ^0 W. @
    c=getchar();- y# B+ e# w. U$ I. f5 A3 M! C
    while(c!='='||opr_top.ch!='#')
! q4 @# B: `- _5 ]1 d8 T$ o% C' s    {
- k4 g: \: |) B) ]: }9 i  r" J; ~        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' H( J& |6 Q/ z. M        {7 z* f+ q9 P4 m# e7 C7 Y
            buf=c;
2 s. l$ r( ^( J3 U- P1 ^, |( [2 }            i++;9 x5 F4 l% X8 X1 \% {$ ]
            c=getchar();$ q# i* T/ z; ]# t5 Q! D
        }
! j4 a* w+ f4 b/ |$ F; w        else /*是运算符*/
! O5 r0 M# j  P% I/ |+ ^        {6 P- R2 {* ]( ^1 a
            buf='\0';+ x4 ]/ M) Z3 v% h' `
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3 c5 Q- M7 f7 J# g% q
            {/ ]( C3 {% E) {/ f& ]
                 opn_in.data=(float)atof(buf);; D" @& o, U( z( _6 ^  ], Q
                 Push(opnd,opn_in);* T4 Q* K' Y4 L! C2 x5 u! J
                 printf("opnd入栈:[%f]\n",opn_in.data);: K4 V; u9 I6 g" A: R
                 i=0;# i/ h, z) z1 }$ A# }  r( o$ ]
                 memset(buf,0,sizeof(buf));9 v0 Y5 R  ^( l; B5 M" p
            }
8 V  C- X! g" U/ [0 Y' x& W2 _" D$ W            opr_in.ch=c;- _% ^: p* j, X5 c; m# q
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
# `  Q. ?- k' a( f  K2 B& ?8 n            {9 H' S; Q6 n+ Q# P0 b% z
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
* z! Y. x6 R, q0 I. b5 K( ~                     Push(optr,opr_in);
% q7 n9 b: Z, r9 C* U0 j, T                     printf("optr入栈:[%c]\n",opr_in.ch);2 I7 O2 A; }- `+ h
                     c=getchar();
- O$ u2 S$ ~0 y# ]                     break;4 j0 b4 g: A8 g3 S
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
) A6 r) P7 f8 y" Z. N% Z& T                     Pop(optr,e);
+ u% J, r8 D7 S1 E                     printf("optr出栈:去掉括号\n");
+ }- E& W  t$ P# w5 b/ _                     c=getchar();- l' M" T. k' u$ R
                     break;
0 g: d+ Y4 Q$ v6 k+ I2 V                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5 }3 _0 i8 k: I4 N; `- ~
                     Pop(optr,opr_t);
9 j% ^8 }- W; B2 w) x, Q                     printf("optr出栈:[%c]\n",opr_t.ch);
6 t; E% b& M) }0 L' z                     if(Pop(opnd,b)<0)
& C8 R  F. t' _( h                     {5 r/ y9 Y; Q3 Z/ V, M
                         printf("Bad Input!\n");
" v, ]- O4 K5 A& [6 Y                         fflush(stdin);
5 _1 e5 j& D9 N- O  v                         return -1;5 t0 `$ {4 J/ G; t
                     }# |, t  {' t; F6 H
                     printf("opnd出栈:[%f]\n",b.data);
- t  F) s% n! U7 h; F1 E. |& B$ Q                     if(Pop(opnd,a)<0)
( t/ `4 W  _0 w. B9 ^- G                     {7 M' B  }5 k7 |/ n
                         printf("Bad Input!\n");
# {' k* z5 X1 ?( [, Y% m3 Z5 F; g                         fflush(stdin);5 l$ Z6 q! C4 A. c% Q1 H
                         return -1;
& Q) ~4 ~, Y0 W) ]8 b( W/ d' h                     }
. r  c# T9 ]4 v! s9 S                     printf("opnd出栈:[%f]\n",a.data);
5 A: S! Q4 ]% M1 r                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/( y4 d. ?- o5 o/ H  V6 n  F" Z
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( \$ i& g) L& \' ?4 _6 I6 V                     printf("结果入栈:[%f]\n",opn_tmp.data);0 A8 @3 M# w3 j: p8 _
                     break;& T/ I9 U% G: l: ]
            }
$ w3 k! S/ H8 e        }
. x/ ]! r' A) r. g        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
% F4 X6 n- f: c0 I8 Q) p    }2 F3 c4 e& u0 M; i( v) Q9 q
    GetTop(opnd,opn_tmp);
0 j; P+ E( ~4 S0 m    DestroyStack(optr);9 j' @+ Y) j, v% M: f$ {2 p
    DestroyStack(opnd);3 s4 J5 p$ U/ V( `3 v
    return opn_tmp.data;3 T( J7 t# a* I. Z. ?
}
7 c* R9 D/ L2 H2 }& D8 u' U; p9 ~7 j$ P3 z' U
char *killzero(char *res,float result)% D$ j' L! B% A1 a8 i
{
, `% z' C6 _& k8 K' E- Y    int i;
* m1 l  j6 n" d' r1 o2 n% x; n, F- E) M) {7 B
    sprintf(res,"%f",result);: |" F7 V7 y+ r* X' [4 d
    i=(int)strlen(res)-1;1 L" r" j* r! A$ U9 R
    while(i&&res=='0')% l. U4 }! o% {9 |9 u' H# V# `7 |
    {# m2 V+ q" r. w9 H5 I
        res='\0';
) f8 [3 w) b0 q' n  D        i--;. _9 n: y; }, J% I
    }; z3 b7 O; A$ D4 o# |9 I
    if(res=='.')6 P5 z( z, n0 b+ M8 s. @
        res='\0';
  s* ]3 b3 v3 t$ Z4 Q    return res;; D: F& t- B9 S
}
4 v5 }5 E; g* ^: U" r# p
& l& C+ G: U- z9 `int main()( \# r$ q# |$ C: {  G) i3 M3 f0 ]
{" |/ T% _6 b3 k% |3 a
    char ch;: `3 f2 I4 [0 H/ E, ^0 W8 M
    char res[64];
* h" d3 j( f7 X: n0 J# A    float result;' x% `3 a; n  A2 N: @
    while(1)% X" ~9 I* a! |5 o& ^) N% H) A
    {4 L9 O+ I# h  L& V
        result=compute();
* ^$ L6 |+ Q3 U% E        printf("\nThe result is:%s\n",killzero(res,result));( f8 Z1 e# l# h. X
        printf("Do you want to continue(y/n)?:") ;
7 Z: h' I3 S7 v  P        ch=getch();
: d" ]. Y4 G/ o+ }/ e" P6 r. B        putchar(ch);
' S6 ~# g' c/ r5 `9 j        if(ch=='n'||ch=='N')
& ]* R3 _' c# o& C4 l* r            break;7 M, n. d) i! k8 M0 z2 g! z3 F# X
        else& ]. S2 o- a. R1 N! \" i+ D6 i/ T
            system("cls");. H+ ]( i9 L& \
    }
; P$ n! _. k# h! l    return 0;
' Z# a' _) r! E- L- `}

# G. B. V( U5 Q+ e: e/ C3 m1 ]* i9 U- `* r
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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