返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
! l+ Z4 W$ ?) W# \# e; Q: l程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=  t: d8 `5 ~8 \1 m3 u( \
/**************表达式计算器************/
, o9 J/ }6 s8 Y! ?/ w#include <stdio.h>
4 S9 ]% u+ C3 E* W#include <stdlib.h>& E/ X4 |: M( L+ v* Y' Z4 S& t
#include <string.h>5 _1 b+ l6 S3 B( @2 j
#include <conio.h>+ t( Z5 z9 _% l+ \
#include <malloc.h>
% b( |) v, i& R2 N
" `2 @+ K( ~, ?0 t. E#define STACK_SIZE 100
% f% B, V1 X7 U& Q+ u#define APPEND_SIZE 10
2 ]2 q. Q' A5 h! }' L
* M3 P3 }5 Y4 o# l  Istruct SNode{; X7 P2 l3 y9 }6 M$ L# h9 ]  f  s, D
    float data; /*存放操作数或者计算结果*/
1 X5 u/ H1 d. P- p0 ~: `/ |    char ch; /*存放运算符*/6 x) ~- Q, g2 B: C: H
};
! B, g0 S; s* X% }; q* U7 s( i% D' D2 r2 ~# g
struct Stack{9 b2 M6 C. w2 a' N
    SNode *top;/ \  a5 n& E- e- B. Q
    SNode *base;* Z/ @5 z3 G4 _8 c6 z- M
    int size;, U4 e- w% _1 Z6 K0 W+ c0 _
};
1 N- n* E# Y& K1 N8 h& B2 }! S+ b% o% L1 u; n
/*栈操作函数*/, i. E4 J5 W- t' E" {7 y
int InitStack(Stack &S); /*创建栈*/
$ w6 [* {/ ?- ?  aint DestroyStack(Stack &S); /*销毁栈*/6 n; x) h  c$ G/ O
int ClearStack(Stack &S); /*清空栈*/
) V, n6 N* Y- A5 Yint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
- B$ c7 \* ?2 |' I/ f/ U( wint Push(Stack &S,SNode e); /*将结点e压入栈*/
* ]; z' K" \) g6 p/ ~, q1 q7 Xint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ j6 E: }! u2 G- g
0 Y- \- _& Y# i) F+ C+ Z; a' y/*表达式计算器相关函数*/# ^9 |: f# Y4 }: Y. V- P% v
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
' e" G% f7 S0 @5 y& gint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/; K1 S$ L9 N" o0 v8 L9 T% [
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 H; n8 T- l8 _$ @  yfloat compute(); /*表达式结算器主函数*/& i7 B' Q6 T" l9 U6 e
char *killzero(float result); /*去掉结果后面的0*/
" z; V% J$ Z0 ]- v4 e$ V1 G5 i/ \8 a$ h! A) i, ?  z, x) }
int InitStack(Stack &S)
/ x2 j. C8 Z7 T, Z{2 z: Y! |) r7 G- w/ K' i& t
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));- l' X% }0 N5 d' ]- z( t
    if(S.base==NULL)
. N2 B  X! M5 `, o  a" S    {
  Q$ o8 ]3 o5 @8 q) `0 \6 C+ j        printf("动态分配内存失败!");
# W8 L4 G, F4 w* l" _  p( l  y5 w        return -1;5 d* ?$ s& \  i& @, |# B/ u
    }6 N. p3 [/ l% ]2 R
    S.top=S.base;
; K" R) _# [1 Z    S.size=STACK_SIZE;
' z2 f, G9 j6 I( O. b6 w3 z    return 0;
6 A' [3 F7 p* Q* I5 y}
" {: Q& n* g. [' [. d: D( _2 K6 d& q  F
int DestroyStack(Stack &S). s! ~( s& W& @2 I, F% z
{
" J0 ~: r" O- j1 I( \, g+ ~; F    free(S.base);) ^) h( b( A7 K  p3 X; C2 ~
    return 0;7 ?6 m9 x4 X1 f2 \( G1 ]
}
& J- O1 Z4 k) S0 I7 w2 t% j5 T
4 N# b3 r( N+ j. n+ u; u" F2 Q- uint ClearStack(Stack &S)- v" {' L  `) P. n! L
{" \4 k9 l, {( e# Z" u+ m; Z, N
    S.top=S.base;
* z& w1 F0 W+ c+ c    return 0;
8 ]5 d) {& b0 v& _}  S% R4 m, X. P0 ^0 W
& r# t9 M) q: Y- \9 a! z4 T
int GetTop(Stack S,SNode &e)" P3 K! ^% f$ F$ D2 L3 I& K% @
{
7 Z( }5 `3 \; Z; Y    if(S.top==S.base); Y3 D; D% Q- P) W* t* u
    {
/ W% r; Z6 F& `$ M7 {/ Z        printf("栈以为空!");
4 B7 u# Y, Y/ H; d2 V6 a        return -1;2 f  i5 J! n1 b' b' L
    }* e4 }+ B7 z- W# z/ U# n! @
    e=*(S.top-1);
& i; X) ?! N- M8 h" {7 \    return 0;
, z9 j3 c6 N: l1 i7 Z/ f9 O  N7 Q}
' y* g& x$ p$ i
+ I, C' b, B& R1 p" Mint Push(Stack &S,SNode e)' r. K0 K( p4 K
{9 _/ _4 \9 n6 S3 M+ s7 O1 O
    if(S.top-S.base>=S.size)
, @" ~5 b7 T; c' s- J    {
$ v3 e* a; Z6 k. Y- `        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));  m' ^8 n  j* \4 f6 U  t# Y
        if(S.base==NULL)+ S" b# b" Q4 h- f9 L+ ?  a# p% e
        {
- B* z% k7 b+ L$ v" }2 Z' ]            printf("动态分配内存失败!");  i% m4 p* a0 J8 k- _
            return -1;! a9 ]3 `( @% r
        }% ^" b$ N5 S! n6 w
        S.top=S.base+S.size;. L8 e0 y/ U9 ?# Z. r, F
        S.size+=APPEND_SIZE;
" O0 G; K7 e: f4 [    }
2 ?) U- g; l( S# L& y4 |1 ?    *S.top=e;
0 O: x/ L2 f" p( G    S.top++;
! x+ z) B+ G' s* L4 K) V( `+ [    return 0;0 [7 f8 `3 b5 D- Q; y2 f  z8 d
}) K3 f$ |, a4 X
, X: V( [# ?" w, X8 x
int Pop(Stack &S,SNode &e)
+ t! }/ `3 D- Z1 p7 q{
0 Y+ [' H) e9 E$ x    if(S.top==S.base): U- u' {! T( `9 b& R' R
    {3 z; r* g* l8 Y4 q; v( M
        printf("栈为空!");
5 p8 i) V( k; l( Y3 C  Z        return -1;
4 ?; i* o5 c$ P4 H8 v% M$ Z4 v    }
  {$ }: F: a& }    e=*(S.top-1);
& K  y  }; |: ^; I8 F( m6 u    S.top--;
! a/ A9 f% \" m- Q9 g! p" ?3 Z" i    return 0;
; w/ M8 J2 A* n% J& L: _7 r- ~}
9 Y* Z; b; S3 f( |& G) M. M2 T' `
char get_precede(char s,char c)! r+ w* P" [2 Y" ~$ ?# i, t
{
  M1 ], T( N, z1 Q4 ?: O& B    switch(s)* D' }$ A6 A2 q8 Z4 k( g4 Z
    {, U; J$ `0 ]7 j9 Q' ?
        case '+':                 ( q2 m  ~9 u6 a; R9 z
        case '-':" G7 `  q" i, J1 {/ \
             if(c=='+'||c=='-')
& P, t' d1 O7 n+ E8 H2 R, C                 return '>';2 q$ f6 V5 R& ?; k3 H' L
             else if(c=='*'||c=='/')
( M8 L1 K" b& }: w" E4 [9 K                 return '<';
9 s& d& q" a4 l) m. ?% P& \             else if(c=='(')2 l. ^9 k8 h7 L1 i. X. Z! t2 w
                 return '<';
5 d8 _( K0 A) f& P  k; z0 E             else if(c==')')
% n) R* [5 A/ |. e% [                 return '>';* {7 W) j( V/ V! x: v5 E7 u
             else
6 W/ L9 V1 Q, d# J: R, q                 return '>';
' e: i; `$ x1 @+ k' \3 d8 q  N        case '*':
8 @  D; D6 h" i. c9 {% T        case '/':
  K" N4 O& t4 m1 y& i) W             if(c=='+'||c=='-')  K, p$ Y+ E  k4 P9 o5 v1 v
                 return '>';
8 \% V' v) B  }' v! u- \             else if(c=='*'||c=='/')$ Q2 L& C3 A3 i. A  F% _- ]
                 return '>';' y6 E. O/ L. ?0 I& T
             else if(c=='(')
; t) H8 O" j3 Z" X                 return '<';% R6 q3 G3 h) P6 k8 G$ x1 `
             else if(c==')')% C4 H4 v) o$ @2 T( L
                 return '>';
3 E* t7 b# D. {% `" s9 o0 X             else
% A) S  S' j  v                 return '>';
! x' ?5 I( i' a        case '(':
9 }" P% A' A' Y  A, Y3 {             if(c=='+'||c=='-')
( g0 f2 W. ]( _3 L; M1 |, @                 return '<';1 Z( T, }( c* H+ V* \8 y7 [" N
             else if(c=='*'||c=='/')+ q' A( U. N5 ?4 D2 b8 R1 R% t
                 return '<';! ?2 T5 J+ f; Y8 E0 W' R
             else if(c=='(')
9 g% E5 P9 _- P* M0 Y- l! |6 h                 return '<';8 H7 g( w% F! |0 ?1 h; J8 O: n
             else if(c==')'). [: Y6 ~# f! Z6 g
                 return '=';: F  C1 S5 ?2 Z( g  x& m
             else
9 U, a& c' {+ r* n5 t2 ]                 return 'E';
. t. V' o* D" C        case ')':
: H6 S5 R; [& ^6 K             if(c=='+'||c=='-')% a  h) D- @  J
                 return '>';. B# D0 s/ C( Q- e
             else if(c=='*'||c=='/'); w+ H% e1 A( L# Y
                 return '>';
; A9 \3 ~  \0 T% u             else if(c=='(')
/ `/ J/ a& R& O+ Z$ H; X                 return 'E';, S. a$ `5 m, r
             else if(c==')')  `) q+ m' d- h0 p8 [4 g9 N! U
                 return '>';
7 Z/ p; s/ `% h2 Z0 t/ t             else& a% h4 T6 \# r: t6 d
                 return '>';, ^) j; W2 F$ Z# D- ]
        case '#':: n7 l' ^# w& Y
             if(c=='+'||c=='-')1 P7 M- _& E7 f4 p. |( v! |/ w: w
                 return '<';
5 I8 Z5 r; B3 x* e# L* W# U             else if(c=='*'||c=='/')
! b. A8 z3 Z5 A0 `                 return '<';( Y4 r4 W: G, R1 t' M8 i4 C: S7 g
             else if(c=='('): O# {; A  N& a- g  T' Z
                 return '<';! G! o/ o9 D; m9 Z5 O  H% \7 @
             else if(c==')')$ l% w+ m* z! w. p5 p$ A
                 return 'E';
/ R& v  q7 s& x             else3 q3 V. ^9 ^: P$ T  `3 Q( W
                 return '=';3 d1 o/ T; U; n6 K" s
        default:
% ~+ {# F- }- F             break;
, C1 Q! P9 e" R  e4 J2 P7 V# e    }+ S: s1 }" z9 m$ P! t
    return 0;   
$ A; X3 P  n7 g$ @, A}
" F, v4 j8 y* S3 V( l, V, n& _$ `3 K; M' L. V; n& c2 @4 m
int isOpr(char c)
* i1 W% n# V( Z9 O4 i% @0 i# [1 n+ e{1 g0 a0 Z- C" c5 [! S
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 i) s+ p+ x. J1 R
        return 0;# G4 |+ Q  A" w' f% A
    else ( ?' {8 d! a/ b6 B) u5 b
        return 1;+ N7 v  X. B3 Q6 ]4 p( k
}
3 V) Z$ F3 q# l7 O5 d% j; V: S( @* x) l/ d
float operate(float x, char opr, float y)4 n% J4 C/ T1 ^: P' p8 d0 O6 k" O
{8 G: {4 ]1 Y: r; H% {
    float result;& U# @+ t. j: u$ E
    switch (opr)' O5 t4 X/ A$ v/ l8 P5 d! m- i9 ^
    {
& a4 ^( l: U3 W& P        case '+':
) Y+ L0 d5 Y& E& o8 H7 F5 \# e6 M             result = x + y;4 x  D0 s6 p  K7 M
             break;
% w- ^' h3 A: A8 C# l        case '-': . Z& q6 t' H4 w/ j
             result = x - y;
" J0 g; F; I! q' a! G             break;
5 A; i+ \" U& N4 ^: T5 u        case '*': 9 K  [4 v! w. [1 Y( M
             result = x * y;
- A) ~; M1 ?( {  b5 g7 y' W, p" I             break;
$ o1 N3 O" L4 ^0 M        case '/':
* E" |8 Z7 u# y4 z             if (y == 0)! m* Q8 N9 d7 U7 k# L: I
             {% H+ p( X! r% ?/ h7 L! W9 x4 Q0 Y
                printf("Divided by zero!\n");0 W' z0 F" O8 X) q' u, D
                return 0;$ g- f6 Q  a! p' L8 g: j
             }2 r% U- o- R* O. J
             else" d; m8 c" w8 T* _
             {1 }4 w3 V1 E( n" i/ A
                 result = x / y;
( o( s9 H; I5 d0 @. k# q2 d                 break;# V5 a0 w0 F9 L- t" H' c. B
             }  g# \- ?% G! b+ {/ Z; S! i& a
       default:
$ w/ Z) k1 `4 L& }. z! ~             printf("Bad Input.\n");
. @* f8 f  Y9 X7 A0 B: D             return 0;
9 F1 J# w& V1 O8 P6 z* ^6 |7 S* `    }2 X  P4 p0 F# w- u
    return result;. |* f4 ^/ L- |; \$ h3 w
}   
$ X8 l+ ~* J  l6 H) r/ \4 p( g! ?& R9 m3 p+ `
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/' W3 ?8 y) N* s' D  ?! e" X
{
0 ^$ m& q4 B9 u$ U$ p6 U    Stack optr,opnd;+ C2 d% F" A0 J/ R4 R
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
. A' V) h( r' a- ]0 y$ O$ j    char c;; G; y) T/ f# ]2 _. z  W
    char buf[16];
" ]% c% @! ?. R5 U3 t, X% X( |- l+ r9 r' Q    int i=0;: i6 J: ^. l5 r  Q' \, R0 X" L$ S
    ; K: e/ a# y$ @
    InitStack(optr); /*用于寄存运算符*/, `6 M" W  Y) M# Z
    InitStack(opnd); /*用于寄存操作数和计算结果*/# P. v3 z8 F' F! h6 S1 W
    memset(buf,0,sizeof(buf));" m9 [7 q0 |+ U3 C3 J- M' r
    & M# Q# i3 L( z& o+ T
    printf("Enter your expression:");: Q/ w7 R$ K# ~7 o2 m! L
        & `8 q9 O" {( L
    opr_in.ch='#';/ X; |9 l( j0 s
    Push(optr,opr_in); /*'#'入栈*/4 Q) J9 ]5 m) x! a* w
    GetTop(optr,opr_top);
1 I. ^; I0 f) I1 a- Y% f    c=getchar();0 P6 N9 S- U6 [4 y3 y- |
    while(c!='='||opr_top.ch!='#'), n) m+ }8 Y4 p& N
    {% d5 k% ^- {$ G
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/) Z2 F, N& W4 q4 {3 y  Q- y) ]
        {
, B$ G& D9 V/ u, G7 \            buf=c;$ G, [+ d4 B6 ^% y7 x# R6 @3 w7 g
            i++;% ~- z6 Z$ W- j/ e
            c=getchar();/ v$ E2 x5 x! P
        }7 ]9 \( z& c8 {, ?- t# w, N6 C# t
        else /*是运算符*/
' J6 X$ N# {1 ~' S1 j0 t& m        {
* z! S/ @5 _. b; O            buf='\0';2 T" G; ^9 [* K" }
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/- w1 y: j; T5 Q  l7 |6 C
            {
4 Q9 l$ J2 S6 {6 G" V6 H                 opn_in.data=(float)atof(buf);
$ W8 v. ]9 r7 v: A                 Push(opnd,opn_in);2 T  ~; r6 g, m( m( c
                 printf("opnd入栈:[%f]\n",opn_in.data);$ P! U2 H7 D; i' r
                 i=0;
' _7 }$ S. M* [" l8 s                 memset(buf,0,sizeof(buf));& T2 o; t4 G$ }! c
            }
% l, y* W* T/ }7 a2 S8 Z5 [* p7 {            opr_in.ch=c;* f, |/ B7 F, s: V0 \- \* T
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/; t" A6 K" E4 u, ?5 f
            {
9 E+ n+ {3 I, I                case '<': /*优先级小于栈顶结点,则运算符入栈*/5 H+ {2 m: R  F* @! u
                     Push(optr,opr_in);
; {1 i, S& e# i# j5 ~3 R                     printf("optr入栈:[%c]\n",opr_in.ch);
7 c3 P4 }( A+ r+ a8 }" s- @0 m1 p" {                     c=getchar();0 V: q& w6 p8 y
                     break;; r8 M, V9 z& J2 x4 s9 G* l4 _: b
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/7 @7 ?  W: s6 o
                     Pop(optr,e);
7 |) \, a7 J) q$ X, S                     printf("optr出栈:去掉括号\n");7 n' r+ u: q9 m1 g
                     c=getchar();
, [7 a( S: e* }, ?6 n/ ^, A                     break;
9 x0 w* b9 A5 v+ ]: D                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/+ R% h2 _5 b$ i5 _( O
                     Pop(optr,opr_t);
3 ~3 U' s4 d1 A0 p- }7 I3 q$ K: v. D/ Q                     printf("optr出栈:[%c]\n",opr_t.ch);
. {' N' c3 D  q0 i8 W0 d& D                     if(Pop(opnd,b)<0)4 s6 U7 R7 P) w5 r. o; O$ `
                     {
0 x5 Z/ L0 N# a                         printf("Bad Input!\n");
6 }& F/ L. M0 N3 N& E4 e3 \                         fflush(stdin);& u6 r' s4 M' p2 ^( g, H
                         return -1;
  u0 h' ^, s( F- S                     }/ ?7 x0 f# \, L8 ^7 f9 ^
                     printf("opnd出栈:[%f]\n",b.data);
3 y/ \) |5 f# ~) x5 a$ q                     if(Pop(opnd,a)<0)$ l! f- H# p% z
                     {
0 A- A& |9 \9 X( w& p1 j                         printf("Bad Input!\n");
6 z; M8 N# ?- j& t                         fflush(stdin);
( ]. M# s2 Q; o1 U                         return -1;$ s5 O8 {7 }7 m+ s
                     }
3 A0 h& R, [- h; {                     printf("opnd出栈:[%f]\n",a.data);
9 ^! ~( l4 q) B2 Z; C  W( d                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/4 K9 b, A! G/ q. O
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
& g5 G' }4 J0 L0 ]                     printf("结果入栈:[%f]\n",opn_tmp.data);  a4 ]  X/ c) S3 |6 g: w
                     break;
! `. V$ v7 r4 p6 `            }+ f, m9 K2 D# O) Z% }* s: [
        }
2 }' {3 Z) b4 H1 b+ f! G# R        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                  q# S5 {! d* h3 Y% _  C
    }0 ?8 J& v+ W; c& R; X- v0 ]1 |
    GetTop(opnd,opn_tmp);
* t- w5 `3 G: A% q- W0 P$ f! N. N    DestroyStack(optr);
9 Y% f: l" j; K2 E: ^9 Y    DestroyStack(opnd);
3 r% R# q) }7 T2 K; |0 o9 q    return opn_tmp.data;5 D- D+ |0 i/ A6 O& n( F4 ~8 q6 R$ D
}9 A3 f9 m4 v  p1 m, u
7 q: s8 H0 Z0 _4 p3 l" I3 ?
char *killzero(char *res,float result)
: e5 T- ^3 ?& g# \{
! A! s- n3 b; j* W+ Y- f6 _% w    int i;, z/ ~  r: a8 i9 N) Y

6 P6 q" s% u/ L* M- p+ {+ ]+ b    sprintf(res,"%f",result);
* h: @: J; g  ?    i=(int)strlen(res)-1;
8 c8 L4 a1 d0 ~" _    while(i&&res=='0')
9 p. [  O6 i: ?* V    {- J7 I) E8 Q" P
        res='\0';
; h, f3 P, d" r! m, C. [6 Y; a8 c        i--;
! A1 ~2 b; N8 n& T8 \    }" e  h; F" _- b8 o6 o
    if(res=='.')
  ~' K+ |* t8 G9 o: @/ g        res='\0';
  Q/ f- E& l8 X9 W7 w3 ]7 j    return res;
8 U- m0 ]1 S, q2 i; g9 Z( R}: [& R/ k" e9 u2 J) z, n0 z6 O/ i
; I) u% u! o1 V' j
int main()
8 p% f9 D8 K5 J8 @- G4 U{
3 E4 ~& i& ]! }) d    char ch;
. F3 I! A! b' B8 [    char res[64];
: q, k1 U$ A0 C/ b. R    float result;
: L' T' D7 q8 O0 Y0 Y" F( \7 D8 A    while(1)3 y2 V+ b; Q2 W, U; O
    {6 m6 B$ l- Y6 m
        result=compute();
* f# l' p" t! ]- O: P# N        printf("\nThe result is:%s\n",killzero(res,result));( ^  r3 @/ F. U; g
        printf("Do you want to continue(y/n)?:") ;6 M. z: S9 O% k& V6 l
        ch=getch();4 Z! V/ s+ s8 h# E( ?
        putchar(ch);
. {! V0 a) `) g, O- `/ C- q        if(ch=='n'||ch=='N')' s. l# W. @" ]" G9 l
            break;) d5 h, D* c6 `- r# q
        else* {9 s) Y/ w7 P6 D, B& e
            system("cls");
" j, z" l2 \0 A9 p! x* L$ D    }
5 k! F0 v: E0 V+ ]  }9 g2 M5 o    return 0;
# f( I6 E( Q/ i, E- g; n}

  f; Q0 _  T& ^# g. f' X6 A2 w/ T! v4 Q
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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