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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
" `$ Y" ~: z+ P& ^程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
: w# V2 I4 [: h1 N/**************表达式计算器************/9 s# i8 t' G* F
#include <stdio.h>
; |# V4 E* f6 J3 y7 a#include <stdlib.h># ^2 ~7 S; r) b, O6 J6 g
#include <string.h>
) s7 a5 @2 h: l4 r& P: J3 P* P0 G1 J#include <conio.h>& o& l4 V0 Y+ P, D0 Z! l; _
#include <malloc.h>( K# l8 A. T% R# s7 M
8 o* A. N: g; M. e5 }; }
#define STACK_SIZE 100
2 G" e1 K5 n' B4 E#define APPEND_SIZE 10
7 [9 g# }/ X6 ~
; ?" z7 k; W; e* W0 a3 zstruct SNode{2 K$ C, I; v& n$ {2 l  \
    float data; /*存放操作数或者计算结果*/: R8 K0 D* c7 e: q/ ]' v# ^  z
    char ch; /*存放运算符*/
" y& h( m2 N* p" I9 I3 U+ X/ J8 y6 y};' o) H) L, y2 o# O: u  a
/ e( j/ _7 x' A& Y; X  k+ K
struct Stack{
9 `# w1 ~2 Z1 _% z  G    SNode *top;$ ^7 q6 `: Y6 B% S
    SNode *base;( d; l# d* X1 y3 D$ o0 h
    int size;
" j6 R3 b; q! B: D+ I& C6 S" @};  e1 ^9 }1 m+ L, x2 b1 o
1 i2 H1 o% F# t* q
/*栈操作函数*/% @* K5 l1 F9 _
int InitStack(Stack &S); /*创建栈*/
; |2 H: M3 ]9 u: O# mint DestroyStack(Stack &S); /*销毁栈*/
3 b$ A' z+ d9 V) x1 Hint ClearStack(Stack &S); /*清空栈*/9 w4 R8 |) K1 d" [! m& T
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
" q& n/ d, D9 C  A# q6 tint Push(Stack &S,SNode e); /*将结点e压入栈*/5 n1 v& `& `9 D% ~9 o% i
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
; K, b6 B2 K2 {. u! y. O0 w2 X5 x/ h# Z3 ]* ?
/*表达式计算器相关函数*/
. `1 m) F/ N1 Schar get_precede(char s,char c); /*判断运算符s和c的优先级*/$ @$ l. D9 r( W/ ]& x
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
: A2 k/ c# n- y. u6 m2 Wfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1 z* v2 x! q! N% X* |! I- {float compute(); /*表达式结算器主函数*/* ?  H* a0 ~, h$ S: Q, t
char *killzero(float result); /*去掉结果后面的0*/ ! a* p/ i7 d7 @+ K
) v- s9 c! ?8 u# |0 r! t
int InitStack(Stack &S)
3 @4 Q: z  V/ ?$ ~{
( l# g- y+ b0 G/ V/ z4 U    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
! f& A- q* c4 f9 `0 o7 W0 W    if(S.base==NULL)
3 f. f/ s: P' Z, T9 O1 b, A- Y$ S# \    {/ l0 a! k4 E4 u& b
        printf("动态分配内存失败!");1 h' z8 i3 n- V8 A
        return -1;+ b4 C$ a/ |  r2 T( P# x
    }9 W+ e  u+ d' L
    S.top=S.base;/ m+ p  O7 J/ _  g0 z- E1 r2 O2 [
    S.size=STACK_SIZE;
2 g: b5 m6 B6 h# M: V    return 0;
; m8 Z% q0 ~7 j+ K}
2 M: _! n1 k$ v: m+ h( O. H9 N
; [" e8 X# g4 D8 f5 K  iint DestroyStack(Stack &S)0 y5 Y! \, I% f; ^; @
{
0 U0 l$ V  P. x- n9 z8 m    free(S.base);
( a5 j6 w' M- O$ F$ J3 j. D% a    return 0;
* {; ^8 @) I+ p}2 C+ b, i3 ?- E; N

, J- e, A7 O0 qint ClearStack(Stack &S)
3 H4 g4 E% Y: E7 A{
$ ~2 D; W' c& w/ c% l    S.top=S.base;6 l( D+ b$ S* t
    return 0;; d7 h7 r) y- F0 W( m
}1 {6 }  H) T, t% U. h0 R
# X0 A. b+ g& X. M# Y& _
int GetTop(Stack S,SNode &e)
- K) G0 X, M1 c: l) Y7 b9 ^{. a! |, S+ l% m" z* W3 z8 \
    if(S.top==S.base)
, ]+ Q! I7 y3 |+ r- X( D  H7 Z    {2 x; c: l$ E' i4 {6 \+ A/ j
        printf("栈以为空!");
! ?; m4 G8 M( t! m7 k7 r        return -1;
1 D1 U+ _0 ^, w) O7 r    }- l" O* x' r7 w
    e=*(S.top-1);/ _4 f! s% X+ u& \) F- c
    return 0;+ ?3 ~) N( H1 d# T9 |7 Y% _$ L1 S6 s
}- N% E( s, X5 \; k; w

  W. Z; t- w; r( I, Jint Push(Stack &S,SNode e)! y$ v% J% }2 u9 C. l/ T
{
5 S3 @$ A/ f4 L& ?2 r, [    if(S.top-S.base>=S.size)
/ |# {( [3 H. i( O+ ^6 x( u* ]- i    {% U7 D4 h+ L% x( Z( N+ x6 B
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));6 E3 s( a/ R- n1 |. ?4 D7 }, Z
        if(S.base==NULL)( U4 ]6 c2 U' y. i
        {
, s0 ?& q" J2 @9 Z0 N' ?            printf("动态分配内存失败!");0 d' e; j7 o; e& B
            return -1;3 M% z4 F$ t3 X- n. b
        }+ P: o1 W* p) L5 Z/ [  H
        S.top=S.base+S.size;) D7 `' n6 S" u; Y# L
        S.size+=APPEND_SIZE;
& f1 ]+ f4 z" i( A1 [+ n: H    }
8 P* ^, X. [$ B+ c$ T* F    *S.top=e;
  F" X( V$ ?% W1 d3 s    S.top++;) y. Y5 L3 \* F/ T
    return 0;& Y, b( d& r0 e0 `" i
}
# o8 O+ m1 E2 u
. M6 _/ ?3 g6 i- ~, i0 fint Pop(Stack &S,SNode &e)
9 m8 w2 o5 P% J3 `+ @{* b, {; J# u( p$ S% |5 J
    if(S.top==S.base)
/ f  k- {* }) D    {( U* Q2 K$ U, _' V7 P4 p; m6 T
        printf("栈为空!");1 \3 o* c! q$ j# F( g% b* w! u
        return -1;8 e' l' v0 ~. [6 S: H/ p% X
    }$ I' o+ y6 i6 U; r/ F  h( d* @& U
    e=*(S.top-1);
9 G3 K" r, j+ a! A. ^* y1 K    S.top--;
( U2 a6 g- C7 U) o7 t    return 0;
1 V1 g( D8 B+ b) {1 V) s, |}
& m8 g7 V: |0 t3 G0 D% P( F% w: U
8 k0 H; t: w0 f, j0 h% o5 A/ wchar get_precede(char s,char c)) k5 Q+ N7 z) p
{
* _' c! a7 p8 I' I, t7 i    switch(s): Z4 P+ a( {5 s% `4 c
    {& z  {# X+ V5 L, w/ D
        case '+':                 9 u: V0 x0 S  S) H, L
        case '-':
  Q$ m0 T3 i; r4 J             if(c=='+'||c=='-'); C& g5 Y) c# e, E) y' z; `; D
                 return '>';5 S% K1 n3 B2 M4 r+ |
             else if(c=='*'||c=='/')
+ I/ [0 E6 T' d% {6 C                 return '<';
1 v/ v- i# p& w4 t/ a/ t             else if(c=='(')
  g/ R8 e5 i2 Z- M: n, v, L+ t                 return '<';
( n$ y# o& U* k/ G' w' G0 u" |! {, W2 q             else if(c==')')
8 n- i+ @$ m& Z! D' J                 return '>';
5 o* Y; c- L- m* k3 G$ C             else 5 _+ X" P' H! R
                 return '>';6 A7 P! r+ t' T+ ~* O8 w
        case '*':6 e% \+ V7 k2 b; e  I
        case '/':
8 f2 T; ^4 o+ q4 O             if(c=='+'||c=='-')
3 f/ F, ?6 B4 B                 return '>';
3 W7 A: R( [" d# j             else if(c=='*'||c=='/')
* E, W0 E0 Y( ]                 return '>';8 q  B7 E9 _" R9 ?$ |3 S, L1 ^
             else if(c=='(')
  k9 w+ ~$ [. C6 d                 return '<';" v. f3 e% ]8 e& Q$ @
             else if(c==')')0 I. R9 y( P- I, r
                 return '>';
. E+ e; r. r) ^5 J5 q3 u- L5 n             else) K7 r' D, x% B4 E/ a+ H$ L2 ^
                 return '>';
6 [; b+ j/ v* W) i5 g1 `1 X        case '(':
! r5 V/ j# I, r7 B             if(c=='+'||c=='-')
# \# T, E+ t- Y5 ~                 return '<';  Y8 t/ j- K" T' P' r) i+ T  |& ?1 s
             else if(c=='*'||c=='/')
) M( q9 i4 \8 A1 |# c* t, x                 return '<';
- e' S0 h: `4 q+ y  `0 c             else if(c=='(')1 s6 D! u4 n0 ]7 x, r: ~6 ~
                 return '<';5 d' u9 ?9 @' R) S/ w9 s! z: x
             else if(c==')')0 M# i+ ^1 |& M9 v  E
                 return '=';/ q: {1 E& U- g5 R5 Q1 B4 e! j$ S
             else# j5 Q" d8 b& ^* t7 A# b& d
                 return 'E';  G/ Q# i4 ]# l+ f) X  W' E# f
        case ')':
/ d. C: F3 ~2 I2 \4 t             if(c=='+'||c=='-')
$ T9 ?, t  T1 B+ l! w* V3 h) r                 return '>';
; Y/ l9 g0 `  S; d$ m  f' Z/ Q4 }             else if(c=='*'||c=='/')
6 \5 B  ?! u6 w. G9 M6 }                 return '>';" l# d* D5 [) k1 i; p
             else if(c=='(')
: ]6 I% |, t" S/ d, ?                 return 'E';
5 x! u! O5 P; b$ o% G             else if(c==')')2 \$ q1 d3 |" i4 }0 o
                 return '>';
- L4 g4 [5 n$ J" \; c2 E0 U             else2 Q' Y7 }* ^+ D. G
                 return '>';* Y' n( ~' |# W0 O
        case '#':
" _: J4 r1 K% J5 a7 U             if(c=='+'||c=='-')6 K6 ]' z5 P& [8 J3 d
                 return '<';
0 e4 M9 g/ f- U5 W( T/ V* \8 f             else if(c=='*'||c=='/')! w: F! t8 L: j1 K& y6 D% O$ R
                 return '<';
. V7 t% F; u7 n% h) Q( B+ ^, O1 t             else if(c=='(')
7 t4 x" m$ u/ m( R, \- c3 v                 return '<';
4 q" @7 l+ ]" Q* {6 H0 J" K             else if(c==')')
8 p8 T+ C( w% R6 u0 R' I' p                 return 'E';
! r5 T8 p  r$ i  G6 h3 w& _% M             else
* o1 v& g7 e4 l- _8 O                 return '=';! A; t+ L  R( ]7 {9 ?
        default:# {3 w- R$ \7 X' e5 ?! h0 E
             break;
9 c1 g7 v% m( }    }
9 O1 F0 y& m" g; J! t    return 0;    5 @, X0 u  v" F- o& ?
}* q& v) J* O4 W. P9 ^
5 Q  g8 ?( }2 N* S" ?9 O
int isOpr(char c)5 O7 n+ E4 W: |8 t- R& J: q
{0 q3 }" v# v; G4 g8 {& W, M: @
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
+ D7 o1 i4 q, y( [        return 0;3 p% J5 ^' r$ w2 w' }1 Q3 |3 d
    else
8 X  X2 J; j/ d/ a$ N8 ~7 x        return 1;9 S6 n. {. k( I8 r
}
, y8 L+ x- Z3 @! G5 }* `( d* G4 V& h) e- R1 ^0 m3 y
float operate(float x, char opr, float y)& P( I5 ^4 V1 h. P- x
{
; Z% d; ?0 l) Z7 h- p/ a    float result;7 w8 }5 A1 `& ]2 M& N+ r/ L9 |
    switch (opr)
7 z! s! P: \$ ^! z    {
3 V, ~) V( u2 e' E3 I        case '+':
2 _1 L1 I- H/ M9 \0 ~             result = x + y;9 c( \% O' [  P5 D9 a. O
             break;
8 e9 n' o2 @" C        case '-':
% |) F- S: e* L) N/ [7 k, j             result = x - y;
* e  A* {) e2 u- F4 E             break;
2 f# q! B6 k: f* L5 c* A        case '*': 9 [( O8 K8 d- P2 |- c5 E, @0 v
             result = x * y;
% x8 q5 u* P: w( o             break;
4 f- w2 v. |+ e2 B; y8 _4 m        case '/': ; Q! Y. B* L; u, C$ U% u5 E
             if (y == 0)
5 E, A/ V0 E, x9 Q             {' d2 Z' F. r/ Z3 U/ G1 i+ N
                printf("Divided by zero!\n");
7 T+ r( B; M% o  ?6 X                return 0;2 D8 d% x, x6 X( j2 G& M
             }) Q$ n$ o2 H6 g
             else
: T1 O7 T+ _; b+ w1 T) c. f             {
6 J! \% n1 S( R8 n                 result = x / y;: ]; o! m( n2 i, x$ J* u2 b
                 break;
  v# S$ n' {4 r4 y5 A# J( W             }
7 ]4 F+ y& x& K       default: 3 F; i: R4 J9 P# F( `* i7 x, @
             printf("Bad Input.\n"); % q5 X4 Y) L5 K( R9 B
             return 0;
% Y" B9 E+ F1 B3 Q: f& r8 p    }7 X1 l2 Q6 ^5 m
    return result;
" x6 P9 N0 x" g! v}   
# k! [: Y( ]  x0 ]0 `
% F* J6 w+ u4 H& |0 O% u5 r" Hfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
  K  ]# \8 l$ S3 Y: ?: ?{
  _! E6 Q% }7 U$ t2 g4 l& ]    Stack optr,opnd;
$ z3 ?: m' o; q, Y- B- d    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;6 V7 A" z9 ?: _9 Y
    char c;
8 t# u* S2 b# C0 K( c4 l2 K) G    char buf[16];
1 C# J0 X( Q0 A& g$ @' c& ]    int i=0;2 m9 g* _1 l' h; a8 c$ o* [0 f8 d+ r+ h
   
: A9 A! ^- A2 B: a    InitStack(optr); /*用于寄存运算符*/6 q4 Z4 W7 z' H0 _* y
    InitStack(opnd); /*用于寄存操作数和计算结果*/2 A" P- _3 l" Q# n# L- ]( e/ W3 {
    memset(buf,0,sizeof(buf));
$ c, w8 F) z0 z2 h9 `+ r   
  p2 }9 J6 l( d$ G  C( R/ A    printf("Enter your expression:");
8 C$ I4 B; ?0 g; u        
( y! g. u8 L" G    opr_in.ch='#';
. Y, P2 o; e7 t: J) I    Push(optr,opr_in); /*'#'入栈*/% s8 H5 P9 E2 }) n$ E- k
    GetTop(optr,opr_top);$ p. n8 ?/ v6 a8 `5 M" H; p" j! ^5 ?- j
    c=getchar();
6 u6 @% L$ M% e+ q1 R3 c    while(c!='='||opr_top.ch!='#')
# \$ M9 G6 w6 m; u* q    {
3 d- B1 M0 P; N' r( a        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
& R" L( r0 B7 y        {5 Y' [4 \: S3 K
            buf=c;, [7 b7 O/ P0 t8 H/ f; v" x
            i++;
8 L6 q5 j* }. _            c=getchar();4 Q6 U  W6 @3 g- y! I7 V4 A
        }4 j% b* O9 @" i
        else /*是运算符*/- _& U9 p3 E: N3 {
        {" q% n% O3 x# t  U$ t* r
            buf='\0';9 _: w* M& j+ f9 w6 E& H0 g) H
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8 e4 g% w' o8 P; o* I            {3 k. q) k; o$ l& G% Z$ H% W
                 opn_in.data=(float)atof(buf);
9 G2 Z, v1 j- {7 H. h! o, d                 Push(opnd,opn_in);
& [1 Q- E4 K- q1 z" d2 u2 ?# _3 t                 printf("opnd入栈:[%f]\n",opn_in.data);
6 F; u9 ?6 ^, X0 _                 i=0;9 h, P; ~3 }; p8 x
                 memset(buf,0,sizeof(buf));( ~7 I+ Y  M5 u, K2 f" @
            }
1 n% \7 o9 I7 j- u6 T            opr_in.ch=c;" W, A# S& f0 x( G
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/; ^* g2 L0 g" r+ @3 |% i0 K- z
            {
+ \5 s! ?6 Q4 _6 p) |  o                case '<': /*优先级小于栈顶结点,则运算符入栈*/
  t. ?0 Q0 Y- {3 ^6 H3 e+ F                     Push(optr,opr_in);5 u. o$ x- K6 ]4 u& i, n9 k9 [
                     printf("optr入栈:[%c]\n",opr_in.ch);
9 T8 {" X1 [$ J+ l9 a- t                     c=getchar();( G: ]1 T$ X# J4 n. X' {
                     break;
% f/ t$ W% s  M& B+ U9 m                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/  W# l! w/ r, }1 v: B6 E  o
                     Pop(optr,e);: m2 R! u  D/ @& z1 x
                     printf("optr出栈:去掉括号\n");, T7 q7 T4 H9 ?" a  V( F" ^
                     c=getchar();
: m9 M2 `% k* p( |                     break;7 Y, g7 Z3 B- ~7 J
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/0 s/ _& p& e7 K2 p& b- }, Q
                     Pop(optr,opr_t);
4 b5 b( _* L5 @! |7 r                     printf("optr出栈:[%c]\n",opr_t.ch);' J* U0 [  w9 T8 _! f
                     if(Pop(opnd,b)<0)) H1 U/ s3 Q( Z2 o# y
                     {" M1 {5 F, t+ m8 i1 U4 C- M3 x
                         printf("Bad Input!\n");' u) `5 T$ Q' r, V
                         fflush(stdin);
  r) m* W. A+ e) u                         return -1;4 z) M( T' _7 D2 X8 N% e
                     }2 }: R$ f+ F7 a- _* s# ?
                     printf("opnd出栈:[%f]\n",b.data);/ Y6 E+ ?: g7 X& z3 {
                     if(Pop(opnd,a)<0)
3 d+ J; J  h2 l) I$ P                     {* O" z4 f5 i8 _4 t, h  [
                         printf("Bad Input!\n");% I# g# `* x7 t6 i- {1 W' N
                         fflush(stdin);- E$ y2 B# v0 M2 E! t! l
                         return -1;
+ a' K; K* J. r% Y                     }
/ M5 v# A7 i" L7 N                     printf("opnd出栈:[%f]\n",a.data);" x: I9 R2 t  I  b" U3 N
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 R7 j1 R% P' `% {7 F. K% }                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/, e3 a. N! x* a6 k
                     printf("结果入栈:[%f]\n",opn_tmp.data);0 r$ C0 D" m7 v, K+ `$ v1 H5 b* D8 S
                     break;& {5 q2 {" Q4 X4 r* A  A
            }
. W; o" v. T% {6 z4 t! b8 N        }
; U! d% V: z# A3 s$ e        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
, S2 r# i6 B7 o- f' e    }& G* S0 A; s$ x! ~2 @% o% u6 ^
    GetTop(opnd,opn_tmp);$ }! `7 @/ \4 F4 _' S1 {8 j
    DestroyStack(optr);0 I: P' \; a7 s0 q- {7 j. T
    DestroyStack(opnd);9 w5 e9 S* G8 @  s4 u! @& P& d! P
    return opn_tmp.data;
1 @! ^& P/ S* l0 R}: h9 W& Z3 Z$ u5 p% N' n

8 r6 p9 w8 e0 b7 a8 Y3 c& Wchar *killzero(char *res,float result)8 m2 t0 p6 l$ M8 h, \
{
* h9 z: B1 w- o& \& W& Q+ X    int i;
' _9 N5 c* k$ r; G; [3 L6 X
' i% f& N. [. H+ v/ e; K) m3 V    sprintf(res,"%f",result);
0 K" b% H: C# `. ?    i=(int)strlen(res)-1;; {8 x; b. V+ v$ ^" X4 S
    while(i&&res=='0')
/ t- r, ]' f& p4 D5 ^1 `    {7 H/ N) ~/ O1 }9 ~: m) f
        res='\0';5 L/ H) b+ u1 o- d9 k  `) ~, W
        i--;7 m2 Y0 J- o  p" m, P) `+ |( s9 H
    }
- v5 b6 B: r( z/ C$ W* @: q& L4 p    if(res=='.')4 B: c0 @; V4 s* t
        res='\0';; U0 f+ S" T$ p1 e7 ?& {* M+ p
    return res;4 F3 a. k3 a; D. P# |, v
}
3 l+ J3 }- u3 x# A% b" y$ `+ h. @
int main()
$ C2 l, A. z, F$ D- \0 T8 G{0 L& |; F: p7 t' l& y; h; J. {
    char ch;$ ?9 j% ^9 q5 Z" H! k
    char res[64];& S) I; r3 Z' R) a
    float result;1 C+ a0 c" k: D0 A6 d6 i) z
    while(1)
7 @; k0 d5 E9 z* V4 b; ^    {
$ L! x: H" t2 W        result=compute();
4 I5 J4 F- F& x! E( J        printf("\nThe result is:%s\n",killzero(res,result));
/ T. t& p8 Q+ a1 Z: H7 }: h        printf("Do you want to continue(y/n)?:") ;1 z" l# z6 r" U; }! _
        ch=getch();
8 T7 [! H8 n; Z* p) @- S7 {        putchar(ch);' t" k$ {9 |9 k6 |
        if(ch=='n'||ch=='N')
; w4 V, }, d- j- Y/ v            break;
  U/ h; H' a% l0 G# U1 e        else3 G. N: r5 S( T% V- Z9 I6 v* c
            system("cls");
1 A) j. ~5 ]0 Q    }
4 D( E& e. u4 ~7 {    return 0;9 p' Z1 v* ?& K; G5 [) U
}
# @1 [7 ^2 ]! l) Z2 ~0 U8 K! d
- o% i9 L  ~) r3 k
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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