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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
; P# n& i! z! e; P2 j& ~, _程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=  w4 p. T, K; K
/**************表达式计算器************/3 u: x+ g! `# n( |9 E
#include <stdio.h>. L% Y- ]8 K. x2 o- S. c8 J
#include <stdlib.h>
) m, n* h! ?  A% D#include <string.h>8 `9 D# a/ i  g2 P
#include <conio.h>$ H$ B' L; A2 \& d$ j2 S; C
#include <malloc.h>
* k; s0 W- ~& T7 }# y9 c
1 s7 m2 [* t2 s/ R- I4 Z$ ?#define STACK_SIZE 100
  ?* l% W* E5 L. U& O; g#define APPEND_SIZE 10* f! N6 z9 w) g

* B2 Q, E) i- Wstruct SNode{
9 @, n8 I5 _" }& _    float data; /*存放操作数或者计算结果*/
5 y7 f  U) q! h0 X    char ch; /*存放运算符*/3 ~7 G* W! ^6 v* z. b7 E
};! {6 @4 O: ]8 _+ C" Y9 N4 @. R
. `0 r/ v" ?5 R% ?: w. d! G
struct Stack{
' J' H3 w3 @! ~& R& y/ S    SNode *top;
  {& ~9 N, F0 n1 }& C    SNode *base;
- g$ q; m/ {7 K( \) t7 l  ?    int size;
6 {* E2 R7 J% a2 k  T};/ T! {+ \+ D+ s: r

! C* j$ Y- ^5 G: x6 m6 @" |% F/*栈操作函数*/
) K5 [" g+ v" b5 t- t+ k0 V' Gint InitStack(Stack &S); /*创建栈*/; [& R( P! C2 n( d7 y
int DestroyStack(Stack &S); /*销毁栈*/
% `) P3 ~( A6 W  Pint ClearStack(Stack &S); /*清空栈*/
, p  S! F0 c6 p* w2 g# Pint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/2 d' b' B5 f- I  b0 k+ Q
int Push(Stack &S,SNode e); /*将结点e压入栈*/
# n& R6 @9 t+ V8 `, y; y. Dint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/  H# z' B" C: [7 Y* v
" }2 ^% e4 O+ R+ f+ U
/*表达式计算器相关函数*/
7 n4 h. Z' r5 K9 A/ }& s0 D% F1 Ychar get_precede(char s,char c); /*判断运算符s和c的优先级*/
- G' t- o- R9 e: j3 _) N2 L8 Pint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
7 ]" F: L& B' g' `# t5 C' x' xfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
$ m- r5 i8 Z# N( K. gfloat compute(); /*表达式结算器主函数*/1 R( z9 E2 v# }  r0 o; J
char *killzero(float result); /*去掉结果后面的0*/ ! |5 _% o$ {1 j4 f
& L1 F2 A8 d% d* Q6 Q, r
int InitStack(Stack &S)
6 C8 x: W" H/ w/ A{
+ E- S4 I$ ]- |; W3 D    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
/ d0 A) ]  y, _/ \' a    if(S.base==NULL)
1 l4 [! q9 B4 U4 z4 }    {6 r4 v2 W! G$ s+ i& b
        printf("动态分配内存失败!");0 J$ ^$ X; |9 I# _
        return -1;' L4 X6 r3 W' l
    }9 q4 \  |# E2 v- f- ]- Y  U
    S.top=S.base;
3 T1 x1 X% Q/ y1 w    S.size=STACK_SIZE;2 N; p3 p8 \) R7 p( n4 D" N
    return 0;8 s- h) {  W+ c
}, P, g* P* t3 I, J/ i" m* k0 q
) M) z+ _! ?$ P$ g  M. z+ ]
int DestroyStack(Stack &S)
- x& }  h4 s9 o$ N7 i. A8 y# P2 b{  B7 @9 R. t. ^/ \! k
    free(S.base);
& j1 K6 o0 \  r- _8 U6 y+ o    return 0;  @  ^5 o4 v; N" E8 ?
}5 X0 }- x5 l' I& ]

* V9 s% \" P# w$ B3 _int ClearStack(Stack &S)
- w1 X1 B" \. m( V9 X{
7 g% y6 I8 @. }4 m& }    S.top=S.base;+ [- S/ M& `: W* w
    return 0;
4 @9 n& z$ U3 `) f: w}
1 D3 S! ?0 ^9 o% b6 {/ ^3 x+ n( `' x
int GetTop(Stack S,SNode &e)
5 o5 k9 \* N' [" r+ Z- [* \! \9 F$ ?3 I{3 ^; O9 t$ I$ n# V, l. F( _: B
    if(S.top==S.base)5 n/ N  b8 L" T. L' W9 R# U
    {0 c  G; j2 g8 m3 G- [0 l2 w
        printf("栈以为空!");
: g$ ^7 H5 F: n. z+ X6 z        return -1;$ B# ~4 l1 ~4 O8 x, x, P
    }
2 b+ \3 r; A6 L+ o% {& k  V* _    e=*(S.top-1);6 f$ ?9 @7 o0 D. ^  o9 T
    return 0;2 u; A4 R6 H3 j9 t& x  L& R
}
, o& g% G  t) Z* l, _0 b& }( ~$ D& u! ]) T. `* ]* g$ ^$ l
int Push(Stack &S,SNode e)
' s8 C, y; C4 p1 q2 x6 t{
. ?, S$ F1 `# H0 ?% y0 n/ a    if(S.top-S.base>=S.size)
. n* N- N0 H; @  Y: P    {
5 Q6 z' {  |; ^6 u8 E0 @, l        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));2 I6 _7 }! s1 k. l8 \  C7 a3 e$ O
        if(S.base==NULL)6 y& F- P9 V# H# T; K5 H+ b% e
        {
' Z/ Z  k$ U# G            printf("动态分配内存失败!");- g6 H' \/ u* A
            return -1;
; L9 r8 H! `2 m& l        }% X% ?' O* E" W% j' R$ d' t* F  v
        S.top=S.base+S.size;8 n1 [8 S. S8 [
        S.size+=APPEND_SIZE;& _$ `+ l2 G  X+ j8 i4 I! N' D
    }% T% }& {! P9 M' P
    *S.top=e;7 L! g) w+ O0 r& o7 g
    S.top++;8 c. v+ P( X! j3 k' A5 S! G
    return 0;$ m2 B3 H& S) a) S+ c
}) D1 J4 p% i) F  a
" L  s7 D# t9 ?5 k
int Pop(Stack &S,SNode &e)- g8 d) E& e  E; L. _- E/ ]) y
{
/ s! }3 V/ ]: e    if(S.top==S.base)
# s  H  ~4 {) m1 u0 `    {* }; I: p, P3 U5 h1 o( c1 n
        printf("栈为空!");  x& r4 u, \# {( p2 R9 c
        return -1;
; l) o9 R* @/ x& C& R, b  U( l    }& P, b5 J: Q; S4 W3 ]# T! X" \8 j- L
    e=*(S.top-1);
1 a0 e/ D# Q, @1 F, c    S.top--;8 |9 }  }; M' v1 j) f; C. y0 q
    return 0;6 R% B* w* A8 F8 n
}+ _5 x. H/ E5 K) S
( i, t# |) }7 j0 B# y
char get_precede(char s,char c)' o. x2 ~2 d9 X0 M0 t# m
{9 ]& ]. u3 Q% Z' f
    switch(s)4 m0 Y7 ?8 c5 e: J
    {; Z/ J5 ^: }4 ~4 C/ W; J
        case '+':                 
! G6 ]& d1 U; W! v/ b5 L        case '-':
. g8 d0 F+ w" S. O' `9 [0 |             if(c=='+'||c=='-')/ Y3 i5 S4 [/ o7 D: @: U7 H
                 return '>';
. G( `8 T# {% c) O             else if(c=='*'||c=='/')9 R& W; B1 M" ]3 z$ o6 h
                 return '<';
: n" J  T( z6 \- d* U% d             else if(c=='(')8 ~% e, A: {6 h# s' `5 K8 p
                 return '<';5 |" o! {# r+ R7 W3 R; V
             else if(c==')')9 @- ^/ @4 _$ q4 C
                 return '>';: J7 ^5 ~3 a/ [$ w+ ]; k
             else
2 R- K# t3 o0 B9 m: E0 |" s                 return '>';
  t' d4 n" }! k: c& g/ I! M        case '*':
  `- s& X) z8 q* T        case '/':
8 k2 H1 b" q& H! L) Z4 l4 p             if(c=='+'||c=='-')  \( p, d5 U. A" S, S
                 return '>';  x3 A# `1 h3 L/ `- n% w& v! k! f
             else if(c=='*'||c=='/')2 K) N' [/ |3 S) H8 _
                 return '>';: |$ J+ |# D( c3 Y6 Z
             else if(c=='(')
, Z7 |! s9 ~0 d6 E                 return '<';6 x" q. m/ [8 S  L, n2 F/ Q$ U1 Z
             else if(c==')')
1 M5 Y1 Q: w" X4 r: s& M5 H                 return '>';- _/ V; k$ y" L, \' Q5 m2 F
             else
* o9 j0 ]$ ^. {: n% @0 C# W                 return '>';* l; C. Q% A2 B! t9 h) A" N
        case '(':6 f4 u; S3 X9 z# w! Q
             if(c=='+'||c=='-')  e6 @: P2 F4 q8 H" t
                 return '<';
7 Q, ]8 \! u% J; L             else if(c=='*'||c=='/')1 q! p+ c; H; D6 N% o. d
                 return '<';
5 ]5 E/ Y( W+ a' T- e& V1 B             else if(c=='(')5 X+ G7 Y+ b; y/ {3 p7 h, A" P
                 return '<';% \2 I% N8 n! e- q
             else if(c==')'), x, O! v  M6 v
                 return '=';
( A( T% B# K+ g# E& L5 ?             else
- ?/ n5 c: Z1 J                 return 'E';
$ k7 V4 O: @, O3 v3 L        case ')':
% r5 ]( U; Z- b  }4 i3 G             if(c=='+'||c=='-')% H3 [( R1 E/ n/ k7 v
                 return '>';
% X$ }) `, ~. L: x0 B             else if(c=='*'||c=='/')
% @9 }# x" n9 @+ H2 ]                 return '>';
1 o( B" d9 ~2 F- i" t. u             else if(c=='(')+ A" i' p: Y2 w) G. P# R1 v/ d/ x
                 return 'E';
( _7 g( L) Z' @1 Y- e" L8 m- p             else if(c==')'), X  y1 @' A! X7 V4 Q9 [! ^
                 return '>';
' R7 P, c+ h6 u+ t5 [1 b, s2 Y( I2 Z  g             else! g( z6 c' z, }- R4 `9 D. B# v
                 return '>';
# r2 i3 p# w3 Q5 q        case '#':6 ?. H2 S& V; e- t( X: l- Y4 v' y
             if(c=='+'||c=='-')' R" X7 j9 u0 i- L
                 return '<';/ {* V1 k, ?! w+ ?: i7 F
             else if(c=='*'||c=='/')
: ~& P$ g5 {  F7 }& e/ ]0 K                 return '<';
) U, S: `" O+ z             else if(c=='(')2 B# g; ]0 i  n
                 return '<';
+ r3 ]2 W, Q! Z' \             else if(c==')')( o5 ]3 ~- ?3 M3 R: R6 s
                 return 'E';
. ]  n, `& U( A- G* L             else
3 a/ D7 Y' k1 @; X  B. i                 return '=';
, s! B& n/ W, e8 |; d4 C        default:
: p: o, Q& l7 }6 H8 V             break;& |9 Q& |; N8 d* N
    }
6 R5 Z4 U  D$ g2 R- L/ k    return 0;   
- T# j4 {+ Y/ f( z$ G7 G3 h}
; j% x* L: R' v6 ~
; @9 d/ c) b% {int isOpr(char c)1 D/ Y7 n0 B: C& \+ R3 ^
{
+ B! g. i, ^0 {    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
) }$ I, [/ S8 a) L1 c$ I; j2 `        return 0;
9 X2 s. b0 m. |# h3 W    else
9 _; }7 m3 ^: z7 i8 ^* m        return 1;% f3 j/ d; c9 M) {1 G2 X# A+ ~" j
}
$ t+ o1 I( n' E" y9 l- s* S2 j# K8 g- R' m
float operate(float x, char opr, float y), o; a- q4 H. N2 ]
{" a$ t5 B3 ?& x, F+ X
    float result;5 N+ R  N# o, o  T' N" b( [. ~1 U+ P
    switch (opr); q: }/ [! e1 `7 r
    {2 u! M7 k& K- c, X  |( V2 K
        case '+': 1 j+ U# |, |6 j7 ^. u
             result = x + y;/ t: i* W+ o& Q$ V* {
             break;
/ [; p! K2 u, q/ w        case '-':
' v4 {9 C' A. [) j# Z4 A/ P             result = x - y;
4 R+ {( Z( m- b1 d7 E0 R: M             break;: I- q& S' N* M/ g: w& E$ a
        case '*': ' r; o" F9 |' _7 l5 A) I! \. X
             result = x * y;
! A" u3 b8 U( y. [+ o2 K             break;
6 u/ q" u9 E4 {6 h2 t: @) X% t        case '/':
2 ^2 J$ V' L. u0 M" ^8 i             if (y == 0)
7 _6 @0 W8 H* K+ @  j- q* g( j; N             {
" ^/ B( Z. f* V9 f3 K                printf("Divided by zero!\n");
& q! b1 h9 }0 I+ j% }                return 0;( [, r6 _4 T( E$ h0 j
             }
  U& c2 a5 A9 \: i/ w             else' \6 Z2 ?; I0 j7 [2 ?  K
             {
+ H% @3 @: S8 y0 e$ B5 O# S: Z  L                 result = x / y;& j2 G! p, G8 ]/ Z. f/ [
                 break;
' ~, I; J* N1 Y, D. o             }
1 H- f) z* Z$ q2 F/ s. j: o       default: 1 m# K' l+ b3 {% {" r( K' e/ W
             printf("Bad Input.\n");
5 z' |! \2 m/ c! n6 C0 d$ v3 w, h             return 0;' Z' ?; \, u8 N3 G7 M8 P/ U
    }8 C3 M- O) ^$ e! J  h0 C( g" V
    return result;& {1 t  [& n$ ]: M) O/ b; e* o2 R+ u! U
}    ; D! U& B4 Y1 E% \, z% N4 z
( Q- S6 |, O- h1 L9 b0 {
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/( q0 A# W/ T4 |) |
{! L! p  X" f$ q" j* S' [( U
    Stack optr,opnd;
- K9 L4 d6 q' c8 B5 v' F- Y    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
$ S  M6 I% L' C' ?    char c;' |2 c  J1 X9 g* }5 `& d$ a: J' v3 n
    char buf[16];) X7 y- ]) a9 [8 S# I0 L
    int i=0;
8 L# M& K$ W* ~: `" `& U8 n    " P# f2 `. V: x- d  W) Q; D
    InitStack(optr); /*用于寄存运算符*/
7 c5 A$ J  X4 P3 h9 q, W$ W. q; q    InitStack(opnd); /*用于寄存操作数和计算结果*/2 @/ p) E( w, Q1 J' E2 o# ]7 ]
    memset(buf,0,sizeof(buf));
* E3 U: Y# X( F    ! n! P  n3 h) I6 B5 S
    printf("Enter your expression:");+ x/ o+ G0 ?' K  {
        
& p6 t' S% M+ j; }) ~    opr_in.ch='#';
  a8 Q$ U2 ^' g    Push(optr,opr_in); /*'#'入栈*/
5 z& j) i9 s4 o8 H. G& i- ^7 |) z    GetTop(optr,opr_top);
9 a2 }' F5 j9 ~$ b( {4 w    c=getchar();. S% d% C6 `$ M
    while(c!='='||opr_top.ch!='#')2 i- B1 Z# L  }  y8 O
    {
4 \7 _4 J( l9 X# r0 M+ N        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/6 i, j0 s! a: W
        {. B* T9 e; u% U
            buf=c;/ N! i4 @% N8 H8 r2 V; a
            i++;/ m, L& Z& r/ `1 Y( {6 c& q% e8 V
            c=getchar();
$ w3 ^+ T0 S! y, m/ c# F        }
$ g5 a) p; |" P+ o: k4 |        else /*是运算符*/
# N' L( P' B0 L( }) P        {7 w: H- W5 e  s- X
            buf='\0';
- j+ a" u% |  r, g            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
9 B" j- z$ R( r            {. [) O# `9 B# h% I% D% _( {
                 opn_in.data=(float)atof(buf);1 K6 j* O- H5 e
                 Push(opnd,opn_in);
# e- }$ T  w2 ]8 s5 n+ b                 printf("opnd入栈:[%f]\n",opn_in.data);7 {4 d. Q" L- o% Z( Q
                 i=0;
$ {: c1 w( V2 {; b1 x                 memset(buf,0,sizeof(buf));% c- |4 ~7 ?" y7 P4 O+ f
            }2 C0 A7 n: B- \
            opr_in.ch=c;& w) ^; d/ r/ e4 t& m5 [. q
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/1 F, P$ g' r4 A# a. x
            {
. j1 t! z% h$ Z! ]                case '<': /*优先级小于栈顶结点,则运算符入栈*// D' u% {: }) ]3 q  u
                     Push(optr,opr_in);
' P& X7 I3 V- `4 F- N2 N6 M                     printf("optr入栈:[%c]\n",opr_in.ch);
1 H. m# {5 }$ D. T- G: q                     c=getchar();
6 x2 S. ]8 o; r% g2 \  O. j+ W                     break;
- Y- p# b, B1 m% L, ?! x                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/: C# \5 G6 E0 h( H# d' d
                     Pop(optr,e);
4 R6 F9 f- r& h" K                     printf("optr出栈:去掉括号\n");
0 x: @/ U- [, I: `4 r2 [4 ]7 q' M                     c=getchar();, O1 p6 g" G8 e5 ?1 V: \8 L! a
                     break;
: S" M' ]6 B1 m  p! q6 S                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/9 {+ D. w9 X$ W" D3 D
                     Pop(optr,opr_t);" r; M. W1 A0 w, e, S! w2 K
                     printf("optr出栈:[%c]\n",opr_t.ch);
5 T  k. X2 c: |% [' h( L                     if(Pop(opnd,b)<0)% U9 |( t- g; j% X
                     {( p/ e5 ?' {& l8 y0 V
                         printf("Bad Input!\n");" G+ ^( M) h3 U( I" K
                         fflush(stdin);1 `7 e' L! f7 j; X
                         return -1;  g3 d8 t1 R) N& D: a; M
                     }
3 J2 A- y0 f. K2 y8 _4 M                     printf("opnd出栈:[%f]\n",b.data);
% V/ g5 L, w/ e' O4 w                     if(Pop(opnd,a)<0)6 I" R! g- n1 A- d+ Z" w
                     {8 R1 O( Q5 K& R  [0 Y. q
                         printf("Bad Input!\n");
0 Y3 g4 ]5 R& U3 @$ d9 U                         fflush(stdin);9 p8 n3 j1 r5 H- M% Z' z& l
                         return -1;
& b* \4 R* l/ x1 e/ R. p                     }
+ d' D% y, |$ L; {$ @                     printf("opnd出栈:[%f]\n",a.data);$ l/ e* r2 [+ N' s* F
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
8 P  s+ O2 h5 P- t& c                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
: G4 R" v* D: f5 V2 Q; r! |                     printf("结果入栈:[%f]\n",opn_tmp.data);
! O& X1 T; Z6 z% U                     break;8 e5 g- s1 W* p
            }
- k1 v9 m8 j  g+ w9 @        }
. C3 }) O$ o0 C1 h8 Z        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
7 a% g! A( J5 B# u    }
! d8 T, }3 j8 I# a/ k! u. t* b$ c    GetTop(opnd,opn_tmp);
3 [, \4 Y5 [- R) `    DestroyStack(optr);
) z+ h) S; w) @7 b3 D2 i    DestroyStack(opnd);
- @5 V( b2 g" D, c1 t- m& L    return opn_tmp.data;8 W& y# E& ~7 X
}( R. d2 y5 L0 G8 ?; |8 V

% J' q" K& i. q) {4 nchar *killzero(char *res,float result)
9 w- ?4 e: |8 d; ~{. ~1 y9 G8 S' q  t! S) _8 g' q2 I
    int i;) I# H  l, k1 w/ v- c6 a, o
) X4 h7 A6 i. a& N1 C: I+ R
    sprintf(res,"%f",result);) n, s& ?9 }. C! ~; e$ A
    i=(int)strlen(res)-1;
- {* x, B+ i! w! O: ]# O- n5 c! g& @8 {    while(i&&res=='0')
' G# w" A. ~# ?    {$ h' f9 x# _  q" O1 g- u
        res='\0';) L* E) J, u; x7 B# r" N# W
        i--;
  i- P" l9 F. u8 L8 C% I* O    }0 e0 f- }) I/ V0 C
    if(res=='.')
: Q5 K% a3 i% C: @: e        res='\0';
+ t2 V8 ?$ S& Z% A    return res;
$ _( M3 p/ n! N1 D0 p: z}" C7 v* }" g, o  O4 N

$ K) @7 V% x3 s+ k: I% ^int main()
) D) u6 Q: B  F{$ O$ Q& f/ H/ C5 ~6 u; D, S
    char ch;- C0 f% e2 u- H3 p
    char res[64];% e$ Z! G  O: O! X& i2 \4 Y
    float result;' V& t1 \$ Y) t, a! @
    while(1)
. J1 E( }' I: Z9 O    {. D6 \" \8 w7 r( z& T2 c2 a& r
        result=compute();
9 v+ m6 q+ o" w# C        printf("\nThe result is:%s\n",killzero(res,result));1 M- o4 c- f2 Y/ u1 x. `
        printf("Do you want to continue(y/n)?:") ;
' v  _7 M/ w! D3 U* p% W        ch=getch();( T% |* t/ s2 U! n( ~4 K
        putchar(ch);+ ^( i2 z2 g0 d) a7 c
        if(ch=='n'||ch=='N')
! V  `/ G$ b& G3 n9 H            break;
, _. z4 W8 n: j9 p        else
5 ?' q9 K& y3 o& I2 ?            system("cls");
7 `3 w. D% j" Z$ Q& v    }
4 p  y! D$ ^- B" I    return 0;; f# Y% B# v9 S
}

9 d8 q6 E3 G9 l3 W7 t" q* E$ x
, o: z1 R& X! U! @[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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