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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.0 c& N1 k. S2 y1 }5 _' g
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
& V' s/ B& x$ h, ]5 Y/**************表达式计算器************/8 f; l3 l( e# c4 @
#include <stdio.h>
1 ^3 T2 I" f$ Q, U#include <stdlib.h>
2 w# r# S; a3 K#include <string.h>: h6 ?& m3 a' a; U7 l
#include <conio.h>" `8 Y, V$ a- y6 j7 O
#include <malloc.h>
! f( z$ K4 i. X9 C" \. l6 d$ z+ a" g: W0 }8 |* k! C
#define STACK_SIZE 100
& K( T% M8 L, L5 T#define APPEND_SIZE 10% O8 n" n  o$ J. M8 I% q! G

: `+ J3 {& Y! i/ d5 k' @struct SNode{
4 \+ }# ^! ]1 z1 N6 [/ O4 t! m    float data; /*存放操作数或者计算结果*/" Q% \. |3 K5 j6 Y/ G' J
    char ch; /*存放运算符*/. i# z, Z/ u0 C) w
};9 P8 d% [- l0 b

! w" M& P7 V' G; o9 cstruct Stack{
7 x! x5 {! ^+ k% a, i    SNode *top;
9 Z9 F; r+ l7 z/ T9 m% g    SNode *base;# Y) ]4 o9 [6 M3 W) R1 q& }( x
    int size;
/ Q. r/ t7 [" b) r) u4 F2 i};
( f6 D( |" p% V+ X! w- P' s
% T9 t6 t3 `! H# V" a9 Y: V/*栈操作函数*/
' _" R1 {) D# ]% cint InitStack(Stack &S); /*创建栈*/+ D+ S# Y- \+ r/ C/ z+ _
int DestroyStack(Stack &S); /*销毁栈*/' Q8 ~9 \) |4 _' x
int ClearStack(Stack &S); /*清空栈*/" U: A" x; P9 D1 S) y
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/1 \  _7 r1 A. s) t- V2 i
int Push(Stack &S,SNode e); /*将结点e压入栈*/4 t3 s; v$ b, U1 k
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/, t+ O/ D4 Q5 i: z$ \9 z

' L! M7 m4 ~2 Y  F/*表达式计算器相关函数*/" W$ Q) Q/ Y2 t+ V$ k+ m& V
char get_precede(char s,char c); /*判断运算符s和c的优先级*/! c( u4 a" @6 p& S: B: x* |4 T
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/- B) Z( x" j! a
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
  c8 B4 Q+ t& \0 ~# ^& Cfloat compute(); /*表达式结算器主函数*/# T- N5 r4 t. ?$ T8 B, W
char *killzero(float result); /*去掉结果后面的0*/
' x. I6 S2 R+ w! ^: z8 l$ L2 L* b' z) Q; @: o8 k- l9 R
int InitStack(Stack &S)" n' T' q: |. ~9 b
{
& ~$ v; g/ I, [% ]; I; S    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));- d2 M5 k: P) b" H
    if(S.base==NULL)
  ~3 w$ l3 I/ x. U6 [$ |+ `    {
4 b0 J9 @0 N' A9 d        printf("动态分配内存失败!");; w6 X! N- b3 v( x
        return -1;6 ]% n/ P+ E- \# y% u6 {* R; T
    }
; s9 N& Q( t; o3 N" w0 k    S.top=S.base;
6 x- Y5 p3 p) n: \+ z' o    S.size=STACK_SIZE;' A/ r+ ]; S7 u1 {1 W$ v
    return 0;
5 L# B9 t% e) X/ q, I- P" l}
8 h' h9 @. Q! @& a0 I% ]& ?5 O- X+ Z0 k) F
int DestroyStack(Stack &S)
) n$ b  A% t/ U{
1 s$ Z0 c2 v: P/ F    free(S.base);; b% w. V0 Q: ^. F  |
    return 0;
- A4 ]0 O7 Q  s% p% _- Y}
9 L) y% d8 y7 \- j) n: I' b' ~2 E
0 C" }1 h9 L6 G! w/ b) ?  m! x7 Rint ClearStack(Stack &S)2 `2 F1 {. T' S9 @  P
{
8 J2 x* w7 W- T9 O( c. S    S.top=S.base;: w. ]4 ^! P5 o# ?  w% W
    return 0;
- Y% x' m) b7 r3 c* w}
7 a0 Q0 g  w9 f0 }
& r# V$ C5 v7 O3 {, }- b( Vint GetTop(Stack S,SNode &e)
  v" r6 C0 @; z; i0 R% x, ?{
* a7 S; D; @# c" E4 S1 r, U    if(S.top==S.base)% t' K- m5 F/ c9 t
    {- c" _- M5 z" Q1 |3 X; Z7 R& U0 d
        printf("栈以为空!");
  x. r; i* S6 U* z. n        return -1;* C+ X  o5 @! y; R
    }1 n" x$ ?7 _& t* n8 d' p
    e=*(S.top-1);
: R- k) c/ C4 |8 U9 M/ c6 R  ~  h    return 0;
; j  ]/ C# l1 q; x}. b) Z/ Z4 X0 s8 U9 a
' P4 M& w; b3 ]* C7 J  v0 h3 K
int Push(Stack &S,SNode e)" G! C6 q6 a7 G# C$ |
{
# U# a7 V( W4 [, I+ r& G$ n    if(S.top-S.base>=S.size)
4 f( v- O" u) P( ?" z: f/ @: H! r: C    {
" @) E3 X( S- _) w        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));! O- k* K" I( K" ]( O9 G
        if(S.base==NULL)* U( P6 [& z+ B2 L
        {, ]# Q, n( z* O/ A7 O
            printf("动态分配内存失败!");+ J* a5 i& m8 j2 G
            return -1;
3 F1 k: ]+ p8 r# \/ `        }
- b7 M5 m' c+ U- o" s        S.top=S.base+S.size;3 N, E* K# {) c4 o
        S.size+=APPEND_SIZE;
% r5 o) x$ D6 {* T8 z    }( B! v2 x& y6 t: j- t: K+ t* n
    *S.top=e;9 n) e+ D& _! @( J% u+ x7 a
    S.top++;$ ^% x3 K6 p: d( A. f/ w3 Y
    return 0;4 a) }& y2 `& J+ u% b( e6 Z
}
7 }5 I6 d$ Q4 e& u6 A7 R; K3 i' ]$ [/ p4 Y3 J) [: m
int Pop(Stack &S,SNode &e)
7 I* P# r- B7 ^, k{: d7 y) O/ \# R1 ]+ A
    if(S.top==S.base)! t. {" C: p5 f  d7 u
    {
7 K+ b6 X! o+ U# K0 f5 k( l        printf("栈为空!");
) z4 Q9 ]& z( L" j: L        return -1;" f! _! x) R, q3 q- v" M' U1 S  z. f+ }
    }% Y$ T) G7 S& V" p
    e=*(S.top-1);
/ ^( v* a( k, ]    S.top--;
3 ^$ D2 K0 R- j! `, O    return 0;+ k1 f0 N7 f& X
}9 L. }3 u1 j0 }4 E, ~( y9 @

0 B' l, E( @4 c, tchar get_precede(char s,char c)
. A" p: z) C" F4 B{
# T" ~+ z* R" w/ G0 v) w    switch(s)- m1 n/ \! Z0 r" ^
    {
" l: C' E/ r3 I6 U2 S        case '+':                 
; R$ G1 r9 t' F# \# ?  Y( Z        case '-':
$ X% |. u7 b8 J) m/ U             if(c=='+'||c=='-')6 b4 J1 `  {) u+ [& Z3 e0 v
                 return '>';5 a( ^# {! {: R- W$ Y1 C7 `
             else if(c=='*'||c=='/')
2 r: b$ d5 J$ }$ D1 n! t                 return '<';
6 ?9 C  b' l+ L) o' v/ r( h             else if(c=='(')8 ]* ]1 c! w% I, Y5 v
                 return '<';" M+ O/ y5 k- P6 q: U( e( _
             else if(c==')')
+ ?) H# |0 i2 F                 return '>';) x" S! _" ?2 a' T; k6 }! A( R% v+ w
             else 2 l0 k" p* a# d
                 return '>';
0 m- a' `/ r- R; }2 q0 `        case '*':. t' q; m  W6 _' Q7 [  x
        case '/':: V) I4 }) }4 T$ p/ j$ w
             if(c=='+'||c=='-')
( M0 X* g. J: G0 V; a9 E                 return '>';) ]8 A, @+ X# b' k
             else if(c=='*'||c=='/')- h- |, L  S9 q* D! f# d' @  u
                 return '>';; _$ [' h& `  c3 \6 ~& ^8 E- h
             else if(c=='(')
- M: |- G* z1 Y0 B, G; B' c, F                 return '<';
& I- N4 o5 _" }/ l             else if(c==')')
$ d+ w! v2 H4 L9 Z5 v. f1 j                 return '>';! b+ I) E( q4 e3 ^
             else
8 i0 h! |7 X% K: F$ o1 X                 return '>';
5 T' }3 W! e/ {3 y0 X5 O        case '(':. T# L' ^1 B* p& p8 J
             if(c=='+'||c=='-')
1 o# E7 q$ K- @5 C                 return '<';3 n9 p1 P, `3 w: q% t/ D: f
             else if(c=='*'||c=='/')  Y/ @1 ^9 }& C
                 return '<';
$ B; t: n! \3 Q9 Y' R: A" K3 Q             else if(c=='(')
8 Z9 `; h- y! S/ \: W                 return '<';
( A2 Z1 z" o; G7 n) @# v             else if(c==')')2 L3 @6 T" n  p, s! y3 W
                 return '=';
; o$ X5 Q  M+ Q! H( J! q$ c$ K( u             else
* U( m2 {5 Z7 n                 return 'E';
8 Y( _4 |. ^/ X0 ]" Y; o  L% I" X, W        case ')':
$ f6 n3 e: c+ S, x+ H             if(c=='+'||c=='-')+ m0 L& O5 A, b( m4 u' D' t
                 return '>';
5 Y* R# ^: n0 b             else if(c=='*'||c=='/')
) @9 `1 z/ I5 h) J4 C2 u# z                 return '>';
3 u2 h1 j; a2 Z0 c             else if(c=='(')
2 I. q+ H% e, R8 F! G' n                 return 'E';
/ e0 z2 x6 k% G$ P7 f0 w* u; G9 b) ^9 u             else if(c==')'): h- z+ J1 K  S% s
                 return '>';
- r, G2 q2 r5 V1 m  T3 i' S  D             else# r0 z& K7 j* O( f
                 return '>';! Z- |7 s2 C/ x' y( l$ y
        case '#':  ~2 @% ^  F$ N* R5 `' k* d
             if(c=='+'||c=='-')* b2 h. o: j% n& ^2 a8 P
                 return '<';
% Q$ s/ R) h/ L% K! O+ Y             else if(c=='*'||c=='/')
% }5 m8 B1 t0 E! n  u) b. A4 \; @                 return '<';; D% T9 `4 S% ?. I7 P, l! I6 z" ^6 M
             else if(c=='(')
# P6 k$ f& ]' [1 o; }                 return '<';
9 A, u, G! ~) o# Q$ y             else if(c==')')! e. x5 t0 q$ Z8 _3 k
                 return 'E';
* y: Q1 B( v$ [! @, a3 B4 b& r% h             else) t$ V/ `* o2 M0 `6 Q
                 return '=';* v! [9 N! C9 ]4 m+ P, r; X; U: `- n
        default:. E+ t# W/ T/ ]- K  N$ ~
             break;3 {1 [& u' V& ?- M. ], d  S
    }
3 u( l! f8 q6 P* j    return 0;    # H+ u3 w7 d" `  ^+ p* J: [
}+ H! Z# w8 M$ P; O+ \

% ~9 t8 o. s4 B0 L; r" j" Mint isOpr(char c)
/ L& Z1 U% @* c0 w{
9 m1 Q' ]- @4 T; }: b    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')& W2 S3 Z; \3 j5 {* M+ F
        return 0;
) Q% ?6 L1 l5 ?    else
) L5 b( J  k0 G4 E        return 1;
2 N8 O( K& X' Z: L}8 S' ]8 d, ^3 A

- s% [' @% H! }3 wfloat operate(float x, char opr, float y)
, o( y" B: g- I6 f) j  ^{0 Z: n, i9 W; s- L6 [: b, c& x
    float result;
+ H3 h1 F# f: r3 }& \4 b3 h    switch (opr)
' L" E  `8 T/ |. t! W: e. g: {    {
" \4 _9 k% x' q  q0 B        case '+': * Z8 t: H/ L. H) [0 W& w$ d
             result = x + y;( d2 g0 @, p/ I8 L5 T
             break;% u0 Q# y' ^. e5 u
        case '-': 0 K& A1 E/ Z# x! V: Z9 Y, u
             result = x - y;
# Y' n. J8 ]( k0 t& a" @             break;
) g& Z/ ~1 K9 s. u2 a- m* m% O0 x        case '*':
  K9 H0 ^" Z) ~/ J# I& B             result = x * y;
  w  d, S" k7 j1 k& j9 T: d& H             break;7 z3 i' ?. r- N- ~
        case '/':
3 r, ^& f0 w' g             if (y == 0)
$ W6 \8 V% I$ x" `0 y# _; s" V  B             {
2 Z1 w& z( }% w9 q  R& J( h; K                printf("Divided by zero!\n");
/ r7 o- Y: j) d# c7 H# {                return 0;, H( H- m: a5 o0 T/ x% p
             }
. X/ S2 H  a, I             else1 [6 y% i! A3 Q. u# m. o
             {
# Q4 k6 y# l7 E                 result = x / y;( Q+ }) q. }( l/ [7 B& J4 E* A
                 break;& p2 o  G# H+ R; W
             }3 O  c/ b" J  |8 k2 b0 Q. k$ }4 y
       default:
$ N) s: n! C: C! N$ r+ @6 t             printf("Bad Input.\n");
" ]  b0 r$ b) `0 D5 t' I             return 0;  z8 @0 U: R. E
    }
1 ?, j3 f+ P2 C, G1 `, ]* l3 K    return result;
; J) J( K/ r8 z; {9 m3 N}    3 j$ |* p( v" y" l" M4 ?

& n& j2 ~' }- L+ `9 M6 gfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/- g! }; K5 b. e( z0 c
{
% J; H) l6 _' P8 d% u    Stack optr,opnd;
& k" T. Z+ W4 b4 E" i. _( _0 s0 t3 w3 _    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;1 ]0 K% Q9 r8 D1 f$ y+ {$ b+ B; b
    char c;* e  E1 s; i* ]; A  t
    char buf[16];2 w0 h5 |  D9 Z% c
    int i=0;6 O( M; e. a( O8 T  z* w6 g" O
   
$ d& s2 e0 @9 {    InitStack(optr); /*用于寄存运算符*/0 ]' C8 u2 E4 z
    InitStack(opnd); /*用于寄存操作数和计算结果*/3 g/ s& [* J+ q- p: N* m
    memset(buf,0,sizeof(buf));
$ R3 f" r( R( C3 ?5 X, D   
+ _6 }8 L9 X- F* R$ x3 }! F0 N) g" O    printf("Enter your expression:");
. n6 B% J# J, f6 g' ~4 e        
* Q  m, w6 }; Y    opr_in.ch='#';/ P; k/ i5 o' Q4 U' A* G6 e: B
    Push(optr,opr_in); /*'#'入栈*// z  ~6 h  Q7 c$ }5 M6 {# [
    GetTop(optr,opr_top);& O7 L) Z8 L+ c! E2 B6 d9 C/ V
    c=getchar();
2 L% I5 L$ u/ j5 K# i) U1 f2 F    while(c!='='||opr_top.ch!='#'). u2 o& _( \& `3 F+ W- C
    {. S5 P% A' k; a  _/ D( y0 `
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/0 x+ e, J5 Y4 j  X% B$ n
        {
/ l' v- w% Z  Q6 g            buf=c;% ]$ v  y, }- j$ G
            i++;( z. J. X3 d( M
            c=getchar();
' o0 e1 ^, r% w8 j& s8 [' D4 q        }+ l' h( X$ [2 E4 I* u- W
        else /*是运算符*/* H6 F2 n  h! S3 i# ^6 U# N( d
        {
: d% o! p/ J+ {" k            buf='\0';
% ^; e1 m, b9 a7 P+ a3 P            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/2 F8 d4 T  F: g/ E# b
            {3 U" ~! F( P* D% w
                 opn_in.data=(float)atof(buf);# ~1 z& `! J% ?$ U" s' Q/ N
                 Push(opnd,opn_in);* u1 r- i' I( M3 G. }$ e
                 printf("opnd入栈:[%f]\n",opn_in.data);
6 a  F" }3 p) L. S$ M0 S: o& ^6 f                 i=0;
; w; [) ]3 J" `* D1 Y( s8 m                 memset(buf,0,sizeof(buf));4 K$ w' N$ z+ E! Q# k
            }* p. }: |. l$ W% T* k3 y
            opr_in.ch=c;2 q5 L% _9 H9 j( ~0 {' I+ b" [/ n
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/& K- t6 p! j( {+ c7 m5 \! j
            {0 N1 H  g& t4 [* y. P) N0 K$ T
                case '<': /*优先级小于栈顶结点,则运算符入栈*/4 Z% l7 w, t6 j/ h
                     Push(optr,opr_in);
* G& \- \, q# O* _' v6 n                     printf("optr入栈:[%c]\n",opr_in.ch);3 o: K" j/ o% Z7 z, \3 ?
                     c=getchar();
7 B  b) X/ l. u9 J( v                     break;$ U5 G8 R4 T+ S8 D8 \: m
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
+ ~8 T9 }/ C( w4 O$ T6 y, b! r8 X                     Pop(optr,e);
# R8 V4 E, ]" B, v; l                     printf("optr出栈:去掉括号\n");2 ]9 r" o% @, t4 i0 B
                     c=getchar();
+ l  @! _+ _+ Y                     break;9 k/ \7 d* K5 L0 `7 r% U" x
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/6 t( l4 m: o5 X# E  f+ L- Z' s/ P
                     Pop(optr,opr_t);
3 Y# f3 S; [. {# i# b1 S8 N                     printf("optr出栈:[%c]\n",opr_t.ch);
4 {: L. t. D, y$ O: o$ Z1 G                     if(Pop(opnd,b)<0)
& E; ?  \3 E  @                     {3 s7 a; m& }2 n! j% b6 n
                         printf("Bad Input!\n");+ E4 F3 V5 |( d, K
                         fflush(stdin);" q$ c$ R& v- J8 v) ?" v
                         return -1;* p1 \* _2 c- D, U/ ]5 q
                     }
, l6 u# u8 x/ I( [9 D0 q                     printf("opnd出栈:[%f]\n",b.data);" p4 Q! A& H( c; I
                     if(Pop(opnd,a)<0)
4 L- d# j  I6 t) K  H                     {
  w% w* @% _" W; r0 Z                         printf("Bad Input!\n");
  V) J; O5 O9 z8 M: K                         fflush(stdin);
" m" T: y" [; n4 f( {' @9 w                         return -1;. b7 |8 u/ p+ V  q* O2 i6 }. g! j+ |
                     }
; w/ a3 A) [% z' n6 s* H) l/ y                     printf("opnd出栈:[%f]\n",a.data);4 i0 d! k/ b3 L( o7 u$ F. ^" x
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/. h2 O) H4 ^7 p: |( w
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; T3 m$ q6 X/ R# W                     printf("结果入栈:[%f]\n",opn_tmp.data);, u& S6 e3 W5 g
                     break;
1 p  M8 B( @" A6 C! |0 ?& r# h            }! t9 J7 |7 Q# |
        }
& p4 C3 z+ r' @7 U: `- j/ r        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
, r2 }6 F2 R. |" T    }
: ^; q5 D) |2 }$ C    GetTop(opnd,opn_tmp);
$ y( g; s* E7 I9 C6 k* ^    DestroyStack(optr);
: y7 l1 k! X! S    DestroyStack(opnd);6 K' y; i" O2 p! L( @
    return opn_tmp.data;* D( |' S' B+ y0 x% j7 w: I
}( B; q, X/ ~5 T: p. i9 A8 S: s
2 U' `, Q/ n9 [: I( y" D
char *killzero(char *res,float result)9 N4 Q- j/ M. j- }/ W$ o0 z
{, l* ]# ?9 t  K( e8 i
    int i;' f0 t% e- T$ f* ?' t4 w

. l; K3 j2 V( W8 r- s1 f( @    sprintf(res,"%f",result);
1 f% o7 w" {8 u- n+ ^# x    i=(int)strlen(res)-1;1 i  q8 g" n- W6 \
    while(i&&res=='0')# z- D! F) c2 X/ g  d9 S, R
    {
* D4 j8 F- E& ?2 H        res='\0';
) b$ k) t) F; J, S) B9 ^        i--;- r0 |3 K. z4 D% J3 y# k
    }
+ X) k% U! d. Z1 P; N' G    if(res=='.')2 ]6 t- ~2 g6 w  N1 {) i9 U& K
        res='\0';+ g, l$ h. L  K4 T8 F; A5 n" Y& x+ V
    return res;, }; W* Z. J' l9 K
}
  j4 O: n5 d" s5 C. W. i7 ]# [8 K; O9 H7 ^
int main()
( k' r2 y9 i/ p6 G' \{. X) h3 Z( K3 P3 g
    char ch;& l! M' }7 y% C# v; c
    char res[64];
) I  s* r9 {9 f  g    float result;& |8 U3 t& h5 k& b  H) c: d
    while(1)
3 _- h: X5 W9 r3 y- X    {4 L: [0 L* W7 O3 G/ O
        result=compute();
3 `; J6 @" d0 g: A( X- i        printf("\nThe result is:%s\n",killzero(res,result));) A3 o6 M8 R2 B& t4 O
        printf("Do you want to continue(y/n)?:") ;
/ g5 {* V: N; F$ U9 |- l        ch=getch();
5 w1 v# S+ E  W8 |" h7 w4 Y4 ~        putchar(ch);( @  m+ T0 k. G; j
        if(ch=='n'||ch=='N')
  [$ y2 \8 Y- c! e) i            break;9 ]. O" @7 ~3 P8 ^; z
        else
* C8 |5 \( z6 o' k: {8 q5 O) J            system("cls");1 Z* v- ?- p: N# f
    }4 T# c1 i5 a7 a" K
    return 0;3 y+ F7 B8 f' ^) {' [2 K* b8 J
}
4 ~7 G+ U5 l8 w% ^, r% W+ B* {; G

# |" k5 l  ?: ~[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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