返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
7 v; }  K  j0 B- `! s程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
& B# m( D; j; [; o/**************表达式计算器************/
# U( H* \# ]$ w% E/ U) X#include <stdio.h>! S4 `. T/ \) T1 t+ F- }
#include <stdlib.h>
1 J/ q0 _3 a, X3 z, @0 I#include <string.h>
$ d1 G' j6 \/ G0 O6 _: w( M, F- ]& d#include <conio.h>8 F" J0 R& d1 v$ l+ u  w
#include <malloc.h>
/ D( D' k7 V; c7 N1 _' s  M/ f, ^* w
#define STACK_SIZE 100
; R  ]3 U% W' p  S- Y0 n#define APPEND_SIZE 10, \  I+ C0 |% O  @
2 y$ ?5 b- a+ f, O0 T* `: d
struct SNode{
) a  T/ w' p' K% F8 ?    float data; /*存放操作数或者计算结果*/- @% c- H& ^- \' x7 x: n7 I
    char ch; /*存放运算符*/6 y5 K8 P/ j$ N. @+ k7 [& y
};
9 K4 w$ |1 R6 j& v/ b* ?
3 U: [. W0 Q- q- pstruct Stack{
# T: d- n3 V: n2 ^) Q    SNode *top;) G! H7 m9 E5 `& a) u( q& {
    SNode *base;5 P( M7 O/ E! f9 {
    int size;( u; x7 ?- \4 Y, l  b
};
+ j4 p5 y/ @1 U- y* E( j/ V& o5 I& P; t
/*栈操作函数*/* ]1 i! Y- S3 n4 Y9 b# O
int InitStack(Stack &S); /*创建栈*/
- n& {' e/ c8 gint DestroyStack(Stack &S); /*销毁栈*/+ X- k0 j+ V1 R! M
int ClearStack(Stack &S); /*清空栈*/+ [  D1 n: g. }; J
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
6 P" J( B" h7 @; o  M7 }3 Nint Push(Stack &S,SNode e); /*将结点e压入栈*// j  K/ C8 U8 k
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/& L6 i0 \* S) X7 m  B. R
( P0 I0 Z; g+ @/ o# `: P( \
/*表达式计算器相关函数*/5 C# I1 F3 A; V$ h3 p
char get_precede(char s,char c); /*判断运算符s和c的优先级*/3 x$ S1 V- W* Y7 W: H
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/, u4 y' k; v8 T
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
9 F  H& E- ^. U3 S' K* s% Cfloat compute(); /*表达式结算器主函数*/  _0 V0 s8 e1 N1 Z- o: g8 C4 D
char *killzero(float result); /*去掉结果后面的0*/
8 H( s" x) N! y% J* u4 r8 [) Y4 n3 g& p
int InitStack(Stack &S)
$ |3 r$ g$ \  @: f* F{8 |6 T: \- z8 t
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
: v& n: R' l' e% t  O/ i5 P9 y$ G    if(S.base==NULL)
5 q3 v$ F5 y4 l% f" z0 L- ?6 D* v    {
0 ~( h% B; J* ~+ \* K0 ~  ~' D        printf("动态分配内存失败!");( D3 j/ c8 j. r4 @' m8 Y# X) y
        return -1;% }" S9 w/ \- D6 [4 ^- W3 \
    }
# T8 L9 I1 r/ M: |: q- C% x  `    S.top=S.base;
1 U- J" B  k# H1 F+ Z    S.size=STACK_SIZE;
' T8 L2 j# S; D6 I1 E, A9 h. d! C, T    return 0;
" l! w1 I$ x: t. R}
% u4 f0 \% R( r8 u8 P
. P4 q6 t- L9 Z% s7 |5 }6 Pint DestroyStack(Stack &S)8 R" ^, {: B" h' `8 i5 z
{$ T7 h% C2 y# V3 A
    free(S.base);
% Y/ h5 u" ?1 u' B3 v' c( g. l    return 0;
, [8 s/ g2 x& Z; P  z  D+ G}  R3 S; C, w/ n. ?- u1 W; R

' S) {. \% w; x" u9 ~6 P+ ^int ClearStack(Stack &S)
5 F, |% l; ]2 l5 p: I6 V{
+ G6 u9 `( P4 N" ~3 b; d    S.top=S.base;
" L9 L' F7 O4 j2 n7 q# h2 q7 B    return 0;0 ~7 a/ k; N2 o* h* F( D' @: z
}8 `5 Q& t  v; R+ \! a  m2 I" E
. o  p, c" j, I( _6 Y1 v
int GetTop(Stack S,SNode &e)0 k( T2 G9 ~- O6 h# i
{
* I0 O. w% c1 G* f) s! e    if(S.top==S.base)3 t6 c2 J: a; X  w, L2 j3 ^+ n  E
    {
) V# D& ^0 l! t# P8 ]) I        printf("栈以为空!");: I' v8 e. v* V% j, w0 K* [+ Y" u
        return -1;
4 ]& E- A, n0 c2 M    }; }+ w0 ?5 [& `9 X4 [
    e=*(S.top-1);2 U& [6 j1 u$ J# R& X! T0 }( J% N
    return 0;  D7 h5 l' m5 k4 {. h0 E2 g, n' q1 P
}
! h  i. d, B) ^5 y5 w3 m2 ]9 H  O2 d. g6 t" U$ G: t- E. j
int Push(Stack &S,SNode e)
3 x/ x7 z2 v( }9 r( a{
7 Z# A: ^; x. `2 i, Z0 f) c    if(S.top-S.base>=S.size)
3 I* X1 C  }8 F    {( H* ^- e' w2 M
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
1 d8 Y4 ?: m) G/ X. S        if(S.base==NULL)6 O0 x  i. T, N8 h) }2 ]
        {
4 g, Q( v9 {2 r  }& r- k  N            printf("动态分配内存失败!");
5 P" P" C' y3 Z9 u+ z- e            return -1;9 u8 \3 v. U8 r* v$ @- r; d& D
        }
  v0 Q1 e2 v0 X. J( F* z, ^2 T        S.top=S.base+S.size;
. T. m! `& u, N  @        S.size+=APPEND_SIZE;( A+ k0 v* C6 N' ~
    }
2 i9 {4 A! v( Q3 x7 B0 B5 O2 P  T    *S.top=e;, o$ h6 J6 @  [/ c
    S.top++;
: R" i2 M9 H8 c9 t) y5 P9 P0 N0 r  c7 x    return 0;" V2 x9 [& O6 m- J
}
+ S" h' s( p4 x2 k- I% X/ \2 N8 A4 G1 W1 p0 |
int Pop(Stack &S,SNode &e)9 ~! h( ^3 A+ ~% b2 y4 I+ ?
{) y/ b" Q& g: p' G
    if(S.top==S.base)
! J8 i+ C: u( t$ i    {# W0 l8 D# ]2 ]# T
        printf("栈为空!");
; G6 u9 }% p4 a- s: A        return -1;6 l' ?, Q* T3 w8 I3 W
    }
/ u! ~6 g: l6 R# i    e=*(S.top-1);" z9 p$ Z' z. S9 V  G$ ~- d6 x% `
    S.top--;( P1 T. B7 E9 z% B# F* s
    return 0;& V  W) X  @! S$ ?. \' _# H
}7 v+ ~: B  _) x. A. L

5 l4 E6 ^$ i! D; ^char get_precede(char s,char c)
3 H' f: u, d* ?{
. x7 ]$ |9 f4 Q    switch(s): V+ x+ x8 }. K
    {
1 r8 y4 b/ }1 x( n) R7 S- j+ x+ _$ a: Y        case '+':                 
  T' l5 v7 c  B! w( @        case '-':
" a; k: I" Y) k( X3 T& U9 {             if(c=='+'||c=='-')
3 R/ f1 a& h$ M" w5 J                 return '>';
# k6 @9 ^5 k- I- w( R: o  W             else if(c=='*'||c=='/')- Z' C# Y; x+ H, C5 O6 [2 W3 [- m, G
                 return '<';6 [' @; U" A2 k% ~% M' [
             else if(c=='(')
8 [% ?# J$ b$ ]0 Z6 d4 H/ G                 return '<';
! y/ A% m; X( T6 T; ]$ h6 A. A             else if(c==')')
/ g1 h; L! p" e$ y2 w2 @                 return '>';
% G& }$ H2 c* T# v0 H  ^             else ' k" D; j' e2 m0 K9 L/ R! ^2 ]+ i
                 return '>';$ v' \% m7 c& L; g* ^
        case '*':
) k0 _9 d2 t# T        case '/':( t7 P( V2 L' ?8 S$ h0 Y6 H
             if(c=='+'||c=='-')
9 b( V+ ~( Z# i4 S! n                 return '>';
6 [* H# [% }# c& Y7 k             else if(c=='*'||c=='/')6 j5 H) R( r! F9 {" Q8 W
                 return '>';
+ |$ S8 ~" x. J' C3 c! V! V7 Z& n. e             else if(c=='(')- Q( y- ?8 a! F# z* m
                 return '<';
: x" a1 D' D! q* _- o             else if(c==')')
: p  g  e: h8 @+ Q& o: |                 return '>';  r# S( S$ O& c5 k
             else
' V1 l  {3 X9 P9 ?7 X* X                 return '>';/ e/ d/ e  ]$ l  a, t: _$ g* W5 Z! `
        case '(':. P. _$ t! M7 B* U5 n) i, n! R
             if(c=='+'||c=='-'); G4 w0 o& B& Q0 `5 t9 Q' ?! m
                 return '<';4 m, T2 H7 ]/ B+ R; ]" o
             else if(c=='*'||c=='/')
( b. d3 @( F8 X2 ]+ H# u                 return '<';  \4 p- o" S' k. M+ [
             else if(c=='(')! |2 |$ B$ m9 c, B2 _5 n  c; _( Z
                 return '<';5 F6 V. f* U! x
             else if(c==')')
/ D- Q' p2 t. E- S- S, ~+ x                 return '=';
6 }  b, R7 E: s             else
" L3 d7 }3 f6 }6 z7 ?                 return 'E';
" ^, n, U1 z. {9 z' l1 \2 G        case ')':
5 p: p- D2 y& {             if(c=='+'||c=='-')9 v( {1 C' [" ^9 N. T
                 return '>';
7 \" @' y) T2 _# ^. }             else if(c=='*'||c=='/')9 ~3 q2 l  H0 u
                 return '>';; Y9 h6 q+ I0 U/ O1 j
             else if(c=='(')2 P+ j) }" r6 z! X
                 return 'E';6 u8 @! _) s% b. i
             else if(c==')')6 n1 t- P2 m8 R8 k2 g
                 return '>';: [4 k1 H2 G' n" O; f7 c  L( v% f
             else8 U2 x2 z5 F6 M  _' Y3 N) F5 E
                 return '>';+ }9 y* u( Z8 P; g, A$ u7 i
        case '#':
6 h/ q1 o8 d7 H, @/ i! }: p1 ?6 \             if(c=='+'||c=='-')" R1 j4 K7 o. _* G: z
                 return '<';8 J; H: v( M& e
             else if(c=='*'||c=='/')3 j& @8 Q7 j7 K9 t. ~
                 return '<';
( o2 X& \( W7 N- S+ D             else if(c=='(')
1 v7 _; f+ ~/ K+ X                 return '<';
* o& ^+ m" s! w8 a; a6 x             else if(c==')')
. z+ q7 F1 S5 ?                 return 'E';
% Y1 {1 i: V) C) V             else
3 ~" z9 V) u0 O- o                 return '=';9 n! O5 u/ e3 ^% @
        default:
" j# B6 h6 P% D8 Q- _             break;& S- K* H3 T7 \6 q9 a! ?
    }
9 h/ A3 s" Q3 Q, f: R    return 0;   
' ?# k: T& }8 d! C3 [5 J& p# F  U}) W* N4 P$ e3 r0 g' G& t/ i# f/ D
6 O4 z& V" G, ^
int isOpr(char c)0 d8 w7 [$ }) p  R7 E
{
  I3 `( i: M3 H. K" {) c5 ^$ W) T) d    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')" x2 X, ~, D1 m& f1 l, ~+ L
        return 0;* P/ ~' p$ ~1 H# G, Q" s9 G
    else : Y! v* y4 h0 [: B+ ?
        return 1;9 X, W0 N6 x: m: r
}) D# X: d, n( q( Y& ?8 {
- q" C' _- J/ X) c
float operate(float x, char opr, float y)
7 _8 s! p7 H: [% p+ l' ^{
" q8 G$ O. `! T" F    float result;
9 K3 ^5 t. D' r3 @* S( i! s) J    switch (opr)
7 e  a1 d# l8 x9 U# q* D2 p4 R    {
. s) U0 ]8 i9 v        case '+': ' Y3 O, C6 c$ Y3 B4 r
             result = x + y;
; A6 P5 Y3 X+ E5 k3 y( r             break;
: w4 m- f+ r2 @+ e2 m( ]# f& s        case '-':
. I* W1 f& Y- F/ l2 [+ \             result = x - y;
' X# D1 X& P( `' h  y             break;
1 K" I: x3 [9 `& R$ n        case '*': & ?9 A. F- g2 V7 O
             result = x * y;
0 q1 R. |( K1 j, [& {6 K             break;7 P. l  Q* J' k. H. M6 G* G' d7 N
        case '/': 5 j: ]) |% v8 d5 g* q
             if (y == 0)! @, m. ~  k8 z6 `4 ?$ }
             {
  s/ @8 k! L! N+ b, l% D                printf("Divided by zero!\n");( @0 L+ r# j1 b- U8 q& ]
                return 0;2 w* W& O3 P5 e" m& B; U+ n
             }
5 h: |1 X5 f2 k9 `1 v( t             else
& s; q6 x, G$ x+ K/ v# f0 y( A7 x8 I. }             {' S" J- b# B7 o% B
                 result = x / y;
1 i- g+ k' F" p) t. }' T                 break;
8 l0 T  y1 {. |; q             }  E% |3 N% `3 K4 P' y+ Z5 h4 R( K) E/ l
       default: 5 G* @# d- v* `/ R4 ^) w' @& l  G
             printf("Bad Input.\n"); 9 q5 v5 @% V' o4 t
             return 0;
* U# j- y3 Q( }' V  i    }
/ |; g3 ~5 d- H    return result;
4 {+ z& H3 U: X" u}    7 U2 x# v9 f5 O8 [( k2 y
# J- [' Z. X( h- M
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 ]/ S/ _+ g; c{% `4 {$ ?+ c4 N4 B9 U
    Stack optr,opnd;1 y- I% x1 E2 r* R; E1 h/ t7 |
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
/ a; l( e* P9 s6 K: }: u    char c;
- t" E5 K* x. f0 `: Z    char buf[16];7 x* ~: n2 m2 o( o2 ^. L
    int i=0;! y* W; t9 K; K( l! ?
   
4 I$ e6 ?) Z; w# ^; D    InitStack(optr); /*用于寄存运算符*/
% P; f: C% P1 i9 i- A0 Y% E    InitStack(opnd); /*用于寄存操作数和计算结果*/
9 R/ U" N2 _: k: M    memset(buf,0,sizeof(buf));5 M8 n/ K: O9 G! y6 N
   
4 d* ~# u* B# T! U+ ], P. u    printf("Enter your expression:");
% m7 Q6 P! X9 T$ j6 v        ! S6 l" a* x1 E
    opr_in.ch='#';
7 N& R3 t9 D/ m9 q6 a1 x2 o$ s    Push(optr,opr_in); /*'#'入栈*/
4 b2 Q* Y( `9 a4 S8 Y" y+ [    GetTop(optr,opr_top);
  ?  y% n" @& ^9 _0 n0 H    c=getchar();7 u! y% T  w  i& n0 r
    while(c!='='||opr_top.ch!='#')
. j  U2 j4 K- R1 U    {6 t& }) ?& [% n3 K& T
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
4 S' S7 X$ |. [1 x7 ?6 l; y* K        {
5 |8 @) v: Z7 {            buf=c;' Q. s( i, M, k0 e* o# G
            i++;
: Y. m5 y4 ~# C, g& n: ]* q+ D, _            c=getchar();+ @  H( w" x$ ?1 L  y4 W7 ], M
        }) @: ?) ^! u- w: @4 f
        else /*是运算符*/
, v) G& O5 i5 `8 Y0 P* {1 i        {
& C8 F$ f! D) W  U7 f2 |            buf='\0';
9 q2 U% u( J* \7 b! S. D, `) i0 r6 g            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/; o$ r3 F1 [; p1 p; b: v3 o
            {1 x3 s% M* I/ v$ D
                 opn_in.data=(float)atof(buf);9 P$ Z. O4 K; \! N3 e" x  P# i$ G8 ?
                 Push(opnd,opn_in);/ N) k' }7 ?% H3 u; q5 K
                 printf("opnd入栈:[%f]\n",opn_in.data);+ \" O) Y+ T7 |3 m
                 i=0;$ E; C% U/ b: l& s  c3 V: O
                 memset(buf,0,sizeof(buf));
. U+ K& @' {' ]4 t; _: L3 J            }
# S! A$ @7 i# K* X' w' `            opr_in.ch=c;' g$ T' q9 O6 x' V/ R
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
$ [5 E6 t  g2 A/ N2 y2 Q5 l- A            {
7 P" w4 c6 F( b                case '<': /*优先级小于栈顶结点,则运算符入栈*/7 ^0 e5 f, u* X% ?& y
                     Push(optr,opr_in);
2 U- _3 R6 e9 |, K% P                     printf("optr入栈:[%c]\n",opr_in.ch);3 G4 G: `: G: d4 I: b) D
                     c=getchar();2 k; N7 p& P. N( d7 w
                     break;
/ d/ N, {& M/ S) I# E                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 O% T% |3 c7 r7 C1 o/ O2 R
                     Pop(optr,e);
6 s& s0 L) |; n# |9 V' n: m                     printf("optr出栈:去掉括号\n");, b2 E3 A7 f6 @' ?; E: J3 I
                     c=getchar();% l7 U9 l! R8 s+ m6 c. a
                     break;
+ t  e4 j. L. ^! L( n                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/) A6 S+ J( }4 a+ |
                     Pop(optr,opr_t);0 p; w7 B, |8 k# C" M* |1 {% ~
                     printf("optr出栈:[%c]\n",opr_t.ch);# b8 y& {: ?, o+ j$ \
                     if(Pop(opnd,b)<0)
+ X" j/ H3 @/ ~4 B9 l- k: B! k                     {3 P; ^) ]& V5 j) l8 R7 b+ V
                         printf("Bad Input!\n");
8 T# t. m7 \8 f6 n: |) C                         fflush(stdin);* x8 _7 D3 G1 U
                         return -1;
# M& C* _, x5 }; _7 H                     }1 \) R) S3 m" \* k& `
                     printf("opnd出栈:[%f]\n",b.data);
  F% Y, i3 b$ x' N& ^5 J& Y& V                     if(Pop(opnd,a)<0)& v. z/ e- V* t; A; ^5 I  J
                     {
) Y% X& k8 G: q                         printf("Bad Input!\n");
/ x8 b0 v% E" U! \/ e) O( Y. y                         fflush(stdin);% D( u4 K+ S. p/ T% d1 C! j: G
                         return -1;
# z. p, S  r! J. i- `. U9 o; v                     }
9 `& {3 t$ M) r1 ?- h7 I                     printf("opnd出栈:[%f]\n",a.data);; s( q0 d; V8 B; k" U; {
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
' I$ m8 b+ ~, J                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/) O* W/ `  h" _! k
                     printf("结果入栈:[%f]\n",opn_tmp.data);; v" c9 K1 |* W+ \% T
                     break;
8 f; \) d5 C8 t9 t! T            }
4 C9 _1 n# n, F( D5 m( c- e. d3 w- C        }
) k  r$ _/ f$ e( D2 R3 C        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                $ Y7 p- d" g( ?/ g  N. a3 C
    }
1 ?& q" Z  g/ A# ^; |9 N    GetTop(opnd,opn_tmp);# N  i. f# w6 v/ `
    DestroyStack(optr);- Z( B) H1 A9 M* Z
    DestroyStack(opnd);
+ c/ R$ L# H9 f. h0 g9 g3 F3 N- s    return opn_tmp.data;
$ l2 C& C! D* }3 ^" r6 U}4 s0 ?3 Y. y) ~# E+ ~( E

4 [9 @! z3 a- j. u; R; hchar *killzero(char *res,float result)
9 S- D  `! i4 t* Y9 y{
  B+ E* i+ x/ e' Y* w    int i;
8 B0 N: r! l; i5 z7 A7 n9 U6 S% V6 o1 E+ f+ s2 |) Z& W
    sprintf(res,"%f",result);: [4 Y, G* b' m; e  ?" r* @/ Z7 t1 c' G
    i=(int)strlen(res)-1;- d. [# U) y! X+ ?$ R  s
    while(i&&res=='0')
4 |* ^; m4 C" r0 G! y    {
( a# x5 W: m/ W1 a3 f" M+ N% |        res='\0';
% s- ]" `: {' {) k        i--;, d2 C/ C, B- W9 T) G0 P' K
    }
3 c8 N9 f  r. i! O8 G% [0 ~    if(res=='.')/ L) U1 p; p0 q4 X
        res='\0';
+ E3 T4 n0 l9 c4 |" {6 z$ I( R    return res;; j* g6 [; Z; C$ i8 a, E1 C( Y
}
1 U" a+ h& x  Y' D+ L
8 i/ {; [9 Y! h7 V: ~int main()+ D$ ~- l( j0 i9 ^& A% f
{' F+ T/ T2 F8 P, |% G6 C
    char ch;
8 F) F! H2 `+ b' k+ k0 b2 [    char res[64];
) I9 X0 q9 c) @6 {    float result;/ h9 `% o" t" J7 p( Y' F% C
    while(1)
$ g% c( L1 j- ?* [0 I( q" ]    {
/ |8 H* e! N5 x- ^5 X/ I3 B! [        result=compute();
- Z5 j0 d$ i  a# e2 _4 e        printf("\nThe result is:%s\n",killzero(res,result));
4 r/ @) o$ S& J  y8 ^7 b% J        printf("Do you want to continue(y/n)?:") ;
! I& I# a1 a* _        ch=getch();
# U& W, B& F' X8 Z, L        putchar(ch);
. q; U; F" z2 g& j' N% J        if(ch=='n'||ch=='N')
* P- {" r) w! A2 |: x& r            break;: {# M1 c: e6 c# y! j% _8 `
        else
# Y0 I* t9 o$ z3 k4 t) S( g5 }            system("cls");
; c9 v2 |! P/ v    }
$ N0 Q/ K, H6 D+ o/ e4 v/ C    return 0;
& T! d; a$ @; R5 S% W+ f}

4 p  }9 J0 W' J) }
+ J9 @2 m9 }8 e2 ~- n[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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