返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.; V- m. H( j9 g2 A( w
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=. M' ?7 a9 w0 z' b: O) z9 t
/**************表达式计算器************/. h! s/ F; X+ @8 f/ e0 D$ T1 g
#include <stdio.h>
3 w% P2 Z4 ~4 k& S4 s#include <stdlib.h>
  ?$ k1 a0 x$ ]& p7 o" L! k#include <string.h>& f) J7 W! Q/ d0 @( z
#include <conio.h>
8 M) ?2 {; s5 s( i, ?2 X4 j#include <malloc.h>
( c' J: M9 I: ~) _) l6 i+ y" A6 b7 X8 `& c; S% h; j
#define STACK_SIZE 100" i0 i2 d9 |* }. \) A5 M
#define APPEND_SIZE 10( V  q; R% W& g8 K2 t% X

# Z7 _( [$ W" s/ h* P" s! xstruct SNode{1 K" Y" t9 y- \# J, J
    float data; /*存放操作数或者计算结果*/
( t0 \/ S/ y! K7 _; t    char ch; /*存放运算符*// g1 v, @# X1 v" I: U
};
- s# L1 z3 A2 F7 \2 t$ i1 ]3 V: M. N, o+ Y0 k
struct Stack{
$ ~# L" X  ^6 g- I# m    SNode *top;- a4 E% x  ?4 C$ {# ~* V9 W
    SNode *base;
1 {1 p8 t# |5 W2 j+ c/ u. S    int size;7 {7 [9 j  Q8 s  P1 G6 ]
};
) N9 K/ \& f  _/ u( A# `$ \
/ Q7 Y7 }, N4 S* ^0 c* L/*栈操作函数*/
  O# q, n; {% x! v* ]5 k# mint InitStack(Stack &S); /*创建栈*/. X4 A8 O: Y+ D, z) F
int DestroyStack(Stack &S); /*销毁栈*/
! f) X; x% N" p7 oint ClearStack(Stack &S); /*清空栈*/7 k+ `- t( X' J4 k% b" T
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/2 w% K) p; R/ W; f# |& O
int Push(Stack &S,SNode e); /*将结点e压入栈*/
- w2 s& l6 }5 r# W* Yint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
) O# c! G& ], h
6 I  n3 S' a- {. \1 o+ h5 G/*表达式计算器相关函数*/
7 q+ d% z, |) v2 e- c# _char get_precede(char s,char c); /*判断运算符s和c的优先级*/9 b1 [: L+ f8 n$ q% ^  n1 K
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
; I. s* Y/ h! ]float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/: Z: ]" @- O( ?6 V% Z
float compute(); /*表达式结算器主函数*/
5 i  E  ?* Q* G7 m+ V2 r( _char *killzero(float result); /*去掉结果后面的0*/
* U+ ?' |6 S! F2 m* a
9 k" e- S( r, {$ P5 x- mint InitStack(Stack &S). s! j) X! P. ?0 a
{
0 s+ s7 M/ ~; g. H! Q# V4 [/ u    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
) [7 l) B& s. G* f6 ]    if(S.base==NULL)
& X# S( {3 ?0 z    {
' Z, ?5 h- \7 S, x+ g        printf("动态分配内存失败!");, k# h: n' ?& W, \4 l9 R! R4 u( O
        return -1;
5 l% s9 Q& d1 L% x, r' c, Z/ p; A    }6 W. v' z3 D! O4 O( V; a! H5 }2 l+ t
    S.top=S.base;
. h/ g0 y) Q& u3 g% K( y    S.size=STACK_SIZE;0 F/ f( t9 f5 H1 ^! I: w
    return 0;' I$ ?- q' L* p# h
}
! A& D. p# F' ~+ D0 f& @6 l5 j" ~- q6 u+ O: D# C4 h2 h( f
int DestroyStack(Stack &S)
/ C' @$ l& S$ _4 n* e6 k{7 [' E6 e4 v# M
    free(S.base);
6 h1 z) K' X# X& u    return 0;
% ^. [) n6 G, m0 G}6 O% E5 B5 I* `; v

7 n" I9 y- R4 [& Zint ClearStack(Stack &S)( P5 T9 ?1 m3 W( p) p
{3 J2 d) t5 O' K& _, B6 I
    S.top=S.base;
% _; D$ U/ f2 d# B/ K0 g    return 0;$ q, v9 h6 ?8 _9 O( z' V( y# ]
}
" f! y5 q' T9 a# e
6 H) m7 K2 G- oint GetTop(Stack S,SNode &e)
' z% _: x# d6 o" a{3 ^3 q9 d/ {4 ?8 A
    if(S.top==S.base)3 g4 H' ?1 u0 ~  h8 C! i
    {6 A$ a8 S0 t3 j4 k5 d, I8 X
        printf("栈以为空!");1 e6 |6 U6 ?* E4 g
        return -1;
5 U6 n& ^0 y! ^* @    }2 G( ^2 W" r/ b% X  Q
    e=*(S.top-1);
0 g' B* Z% n$ @7 {4 ?" J1 v' M( I    return 0;/ U: R1 ?% f4 M- U  K
}
7 M: l! x. \8 N# _5 i1 Z7 {' T; v1 Z$ }2 `7 c* [
int Push(Stack &S,SNode e)
$ J. c1 J. r$ t# b# v8 s7 ?{: r6 k& p2 O. _7 `* A  H) u1 D
    if(S.top-S.base>=S.size)6 q6 q0 p7 z; [& l8 B* |: @* y
    {
+ P( J2 ]5 z0 k1 f9 t! z# U        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ L/ P7 B1 q: D% w+ u
        if(S.base==NULL), D( j/ \+ v6 g
        {$ c' E' u8 f& u7 n
            printf("动态分配内存失败!");2 P1 S$ Q* X, M+ J' g1 N2 P& v
            return -1;: L4 W& X4 S9 I0 w0 |- U& f. J
        }
0 M8 J4 V% `/ m5 T+ _, d& T/ N        S.top=S.base+S.size;
! Q% t5 a' E6 |3 q  r        S.size+=APPEND_SIZE;+ o8 D3 k  P. i) v
    }
+ U. z" ]  [- A8 T& v" L    *S.top=e;
! s2 C8 b8 q2 ~9 a" l* e    S.top++;
* O: w( ~# s% j: \    return 0;: V0 h1 x# S" F5 |- `
}# M. u2 A1 M! r# i+ C1 O
5 O0 E) Q4 s! x1 ^9 ~
int Pop(Stack &S,SNode &e)
( i" S+ }* ~  a" O- L0 K' F{% ^, N& S* ^' `6 y3 }& O% b
    if(S.top==S.base)! t$ h+ i- H! ]8 s7 D7 {+ P- R# _
    {) X0 I9 @' M& O1 v* p3 ]
        printf("栈为空!");: O" e% N: ^- s! l" Q8 N
        return -1;7 F+ m; a2 k& q; t# A6 C
    }$ m  a4 ^( B( ~: Q
    e=*(S.top-1);
8 ~0 M1 ^  `' h( T0 I. C: z    S.top--;
2 Z& D9 _1 C9 L; d    return 0;6 I5 U7 `2 U7 b# ?% y" l( L$ z
}3 s4 I' Q  N" h8 k

# k. X$ p, f% i( `5 I+ Ichar get_precede(char s,char c)
, R5 G: L% E' }, o4 x& c* A{& h* L* D2 F1 V, K2 ^+ G
    switch(s)
% {& [" A8 ^7 \3 f    {
& F6 R/ L; B0 o8 [        case '+':                 
8 X7 a+ f: z& v8 h' A. T1 H        case '-':6 q3 l0 }9 \& t! R% p8 j3 h. A, S
             if(c=='+'||c=='-')
( Y" F& D( C* |% X5 n                 return '>';9 {6 l4 K" |, ]( B" B# C
             else if(c=='*'||c=='/')- ^: S3 N$ v% \5 W
                 return '<';- ^6 L6 L6 ?. B- C, ]+ g, a
             else if(c=='(')0 }  v* \- H. ?4 P, O
                 return '<';
  [' ]- e/ m& O+ ]$ X/ |, y             else if(c==')')
2 S/ H) R8 |: A' E                 return '>';
' F; k( W& ]0 L! T5 x3 c             else
+ @; M" U) r  p3 V; f                 return '>';
, E: j( |; F3 s4 H& b, _& n        case '*':7 u) j( x3 G. g$ v  ~  ~
        case '/':# O1 r# `' }# @5 j& y$ o
             if(c=='+'||c=='-')- k# ^* t5 Y. g
                 return '>';5 y3 l( d1 ]2 R1 P% l  ?7 M' `
             else if(c=='*'||c=='/')
# M1 z1 x; k. Y                 return '>';$ p9 Q$ z" s4 f, F, k
             else if(c=='(')
) S/ n6 w8 [5 d8 }# O! c; y                 return '<';
3 \" K8 y, y: F; c             else if(c==')')
7 q7 }- J4 O8 Z/ d0 C                 return '>';3 P- O; b! W+ v2 e7 h
             else
% H' v9 q. K7 w% S8 ?& b                 return '>';
  Q& l2 r( C( e1 _) }        case '(':) N( Q( x: o2 v; N
             if(c=='+'||c=='-')# N) w3 u2 ]8 z! `+ G
                 return '<';9 O1 ]  H1 @: Y6 W& c( D
             else if(c=='*'||c=='/')' I; S" R3 ]. {- P
                 return '<';/ r: |  [4 g' G4 a3 n1 C1 G
             else if(c=='(')* d: J0 _) f: p* e
                 return '<';# @" g; z7 G- n1 |2 d( `8 Z
             else if(c==')')
) b( j" H1 j" ^                 return '=';) E' c: _7 S; c: u/ f" u
             else9 j& f, c" `, z6 a1 f3 \
                 return 'E';
6 @1 Y: B) m( B$ ]" [        case ')':
; ~" g! a0 _- g$ A5 W& w2 `4 z             if(c=='+'||c=='-')2 Q) C- Q4 g8 b3 E9 [
                 return '>';5 a- V' W& M4 a/ s) B
             else if(c=='*'||c=='/')
/ Q, v- ]# X6 L                 return '>';: W+ s! V$ @, @; K4 x
             else if(c=='(')6 c5 f/ ~+ C% n
                 return 'E';, x  B6 l2 e# v$ j) Z' `
             else if(c==')')& }; S! L, G% u5 j% }/ {
                 return '>';
! \$ O. n/ E! E$ F             else) o$ c/ y7 n' b$ m1 o
                 return '>';) o; H" G6 _: x, T4 ]: y
        case '#':
1 R$ y" i7 r% s             if(c=='+'||c=='-')
' m8 j% V6 Y: g, t7 T& {; W                 return '<';
6 z$ m; r  o' b& I6 A& X             else if(c=='*'||c=='/')
6 ~2 w2 I- E( c' d/ ^1 J( J5 }- W                 return '<';7 d3 }3 z- R8 i9 Y3 \: `; l) ~) H
             else if(c=='(')  Z5 Q1 l+ v* H' r# f1 Z
                 return '<';* k4 e, U" Q- ]0 w( W+ W
             else if(c==')')! Y4 h7 o8 O% _# R* t8 \% c. T4 x
                 return 'E';8 n% l+ X, N% o9 M7 u
             else
7 {' L  t% \# f% ]5 t. G  f: i: z                 return '=';4 u+ ~, p1 O: {% P: R. U
        default:, y* h7 P& D, C/ j' z( U
             break;4 v- z, t' o: O6 ^0 \' R1 m. r
    }+ }) a/ {0 e; ~5 s+ w7 a. e: m
    return 0;   
; @) T  S5 a+ a6 K5 V}
1 p8 u3 G$ i0 [- U
5 W8 m$ S9 `, qint isOpr(char c); j$ F, d5 ^' K/ s% Q" a$ f/ F6 k
{% o' Q4 r/ Y7 k4 o3 x4 }1 u
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
  s  o$ t3 q" ~) z( f        return 0;( w+ Y+ v" p8 h1 p% k8 @' L6 C5 ?/ c
    else
, P- o+ l2 ^; Z  e9 P        return 1;
; c" O1 L( z* E) s0 m}
; o/ d2 T' g: ?# G0 K# e, V. m( R6 O; L" @$ j$ ~* a9 d/ t% e
float operate(float x, char opr, float y)
6 D/ a7 ?+ h3 N) M4 n. f" I) u{  K& Z9 U1 L& Z9 h! B
    float result;
1 U5 M7 R. I: l& G( S* _# ?    switch (opr)
8 P9 M5 V. q; R. [    {) L+ M# G6 D" n4 d
        case '+':
; t4 n" F, J( `4 _& F$ v             result = x + y;
( F3 N6 @2 ?: K             break;
% U3 R- M* z5 a( n; S9 f        case '-':
* v8 {! B: s% Z( c8 z) [" \             result = x - y;
8 F- t4 T4 j: H9 A0 d7 p9 L# {- ?2 F             break;
7 i, Z5 W3 k5 @0 w* G. C        case '*':
# R$ j  H+ r  y; M4 h: r7 I             result = x * y;
. |4 \0 v) j: `  G( \' B- K             break;
' I6 D- ^; p; T) L  z+ O5 q! N4 C        case '/':
# E( X  x9 ?8 Z5 @0 b& v             if (y == 0)7 e: g( K. y, K" R! o% _' s% e
             {: P" ~' n" c/ e) ]; j9 e: L' x
                printf("Divided by zero!\n");/ V) q5 `2 K% C
                return 0;4 `  Z! w: ~# L8 }4 {' h6 d
             }" w3 u) e7 p4 d
             else! O  Z; c- i2 n- U" l, H9 _' ^+ y6 o
             {
* ^, N0 m6 {" U7 E' K, C                 result = x / y;
% J8 T) N9 y, Z7 s, \8 y                 break;
$ L4 y& L+ W' H/ a6 o& _             }
0 V% K* h$ f+ d3 o+ x) r       default: ; J  K" V% ?) |
             printf("Bad Input.\n");
7 F- x% A# ]# w9 d( j2 l/ b             return 0;7 @, _  \1 V" c+ Q) d* I- I" a+ {. q
    }
( `% @* I# d* i; x/ f8 U3 g    return result;
! I$ a/ a7 n2 O" H}   
5 R4 T' S' }7 W
" _: [1 N, H4 U* i' Y$ Qfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
2 B4 L& c$ E+ F{3 T. y( [9 }! W8 ]2 I/ Z5 N
    Stack optr,opnd;
6 {, y& p0 ~/ }+ ]  ~" b    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;+ W# \4 C9 t- q6 c8 E- d
    char c;
( y6 H* \& g& e' v. [    char buf[16];& j. ]& z7 C$ I) \+ c
    int i=0;
. D9 Q( Z9 d/ P2 @* d" k    9 h; k! m, J" ~1 C- P" y
    InitStack(optr); /*用于寄存运算符*/
4 U5 h  i  c& @1 C: [- l    InitStack(opnd); /*用于寄存操作数和计算结果*/
. H( I. P$ C$ Y' o! n& ?$ e    memset(buf,0,sizeof(buf));
9 ]0 R. b! `6 v( H$ ]9 J; l! ^    0 c3 n% a6 x7 q# H  E! |1 Z0 A9 N
    printf("Enter your expression:");* u) {1 V# D0 m* n+ e. x! d
        
; `; z5 I7 Y- I% N3 Z: X" l& L    opr_in.ch='#';
, V0 Y, X- ]( e; T2 D    Push(optr,opr_in); /*'#'入栈*/( R+ d; _2 k. U9 _5 ]4 g! [6 I8 k) y! X% R
    GetTop(optr,opr_top);+ C9 X6 h9 c2 ~' [2 [6 v' y) E
    c=getchar();
" [! z* \  f+ f. M; \6 C2 b    while(c!='='||opr_top.ch!='#')
$ I# l! g& u; `0 Q- t$ i    {; y: G3 [2 I/ h, Q; W
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
5 e9 q3 @0 Z$ Q: w# {4 n        {! o" z# A/ c( L. f
            buf=c;
6 {# B: M" g8 K& [" s  W% w) O, S$ Z            i++;
: [( q  D" l$ _) u, J9 X: ~            c=getchar();
9 l5 Z; w/ M9 X/ P4 [3 R        }
% M: R, ]4 V4 E        else /*是运算符*/7 R7 i  a. C/ D" g
        {
/ y8 E1 N# W! k' C5 G8 F            buf='\0';
1 l+ p2 O) e+ [- }( H            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0 c8 w' [7 n, m2 ?# B
            {4 ?5 i4 o2 `; @8 n+ Y8 s
                 opn_in.data=(float)atof(buf);  v+ Y- I9 I/ o0 q# T; o0 k
                 Push(opnd,opn_in);
; }9 h. ?$ W+ q! x- J                 printf("opnd入栈:[%f]\n",opn_in.data);
# g9 j$ u8 ~  e                 i=0;
% H: f- a7 T+ f4 x                 memset(buf,0,sizeof(buf));
0 a7 u1 j( r: P* |$ M            }
6 w# W; P8 }8 x' |6 K1 Y0 I            opr_in.ch=c;
8 X4 _2 z/ N& |5 G  @7 z+ c            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/4 b/ C9 M" O; T9 y
            {; \# K4 _/ e2 c  k7 ^( X) M
                case '<': /*优先级小于栈顶结点,则运算符入栈*/4 K2 o0 P. ~* M4 \: y  P4 B
                     Push(optr,opr_in);: y- G* H' }& t: }& K1 o
                     printf("optr入栈:[%c]\n",opr_in.ch);
6 @3 e3 e& O7 J% Q% S" s0 _; N& H                     c=getchar();
4 O( h) l% S2 C( w, Z. g# [                     break;
0 I1 H, Q) ?# ^% e* [4 l% Q                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
' J" `0 p1 b3 H* M- V: o4 ?# M                     Pop(optr,e);
' ?: F8 A  _$ P* [                     printf("optr出栈:去掉括号\n");
$ ?1 X/ O, H! q9 h) U% ~( |                     c=getchar();
9 m# I% Q! c& X9 j% z$ \- ^                     break;
& f0 U8 P% q+ ]# l1 g                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/) r1 h0 N7 Q+ m
                     Pop(optr,opr_t);
+ n2 `' _( x4 w6 {" G) {( N                     printf("optr出栈:[%c]\n",opr_t.ch);/ S/ k' R6 \3 Y
                     if(Pop(opnd,b)<0)1 Q/ l8 w4 P" ?( e
                     {
* B) q# R' D  ?3 F( h: ?                         printf("Bad Input!\n");
% u7 t' F# Q1 g) \$ ^* Q1 q  w$ p                         fflush(stdin);
8 M& R( ]: }3 v! F: g                         return -1;" }, z# {' f% H
                     }+ d. M/ [2 w- l3 c0 ^' c6 F
                     printf("opnd出栈:[%f]\n",b.data);: f$ S$ V( n! `  b
                     if(Pop(opnd,a)<0)
7 p& o  v1 ?' Y0 E! S* W( B                     {) T0 R" x" g6 F7 ]0 j& A: N+ V
                         printf("Bad Input!\n");
- G, U; m8 j' v3 ?                         fflush(stdin);
, Z4 J: u0 w: ^9 j, e3 [# l: ^                         return -1;
  E. F/ {+ N% w) ~                     }/ \; H6 N/ ?; q1 u+ e' O
                     printf("opnd出栈:[%f]\n",a.data);5 |" _% G' _+ e3 E
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/, }$ f7 J$ z8 a" Q' j6 c; L
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/- X8 u+ @- G! s4 l
                     printf("结果入栈:[%f]\n",opn_tmp.data);; n# c* |7 T- B) X% n9 Q: x" e0 B$ A, p
                     break;5 N9 l* G7 j; Y  J5 W
            }* g  M; C( U* O! s
        }9 l' U9 y* h4 S8 I
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
8 U9 x( a8 H; _! Q& {- J    }% p  g& d$ w  q5 S
    GetTop(opnd,opn_tmp);7 v0 V* O" e+ C3 e3 |- x
    DestroyStack(optr);
. n8 @3 n+ f: @' S3 l4 v7 [/ `    DestroyStack(opnd);5 G8 r/ T8 G- G: i  N& R5 y
    return opn_tmp.data;
: G: O7 K! _* h* g. w) G}
* S1 y0 W9 @/ f2 ^- t' b# V; T# A. b" `3 f9 |- k
char *killzero(char *res,float result)
. W) U6 a3 O- ~8 p" k) s0 o" y{
5 `: B- i0 Z5 B7 a1 h    int i;, J8 n6 I4 V: Z* t+ n

2 L5 [  p) U* D" _$ m    sprintf(res,"%f",result);% S; ~0 n+ X' |; I& G) z1 e
    i=(int)strlen(res)-1;
- |- E3 c4 o" o' u  }8 q7 N" k    while(i&&res=='0')
' l" I3 ]* f) K# r% j    {6 q, V; {9 u+ r  C% F3 Z3 T7 E
        res='\0';7 d3 N' F# @; h$ \$ m: U
        i--;/ h1 d$ ]9 s. F: S2 l" Z9 Z
    }
2 L5 c, h# ^3 M$ ^# e    if(res=='.')
0 b* n& h* T0 D, h8 P# i  r        res='\0';
8 W, a! f/ S* ~+ [6 L    return res;- e4 M* @  m' j* c- b
}
! A9 \% T. V& a: p, f4 U
  ?) y) e6 `5 iint main()
" G) ]0 Y' U' q, N! E{$ w: f& s: k, O- n
    char ch;' _$ m! p& J( ?: h  ?
    char res[64];' r2 i. O% w3 l8 ]3 v2 O% K  l) Y! i
    float result;* M- O. d7 w: }" k' v$ S# ]
    while(1)
& ], T7 b: X$ C+ x* l    {1 N9 J/ n4 u) M, ^' r( N
        result=compute();* `6 m8 \; f' p! |/ [) m
        printf("\nThe result is:%s\n",killzero(res,result));
# |4 E. O9 V' q2 ?( D& m        printf("Do you want to continue(y/n)?:") ;
3 P/ i1 P* i7 q* u; y' z9 T7 g! r        ch=getch();0 s- a& c2 a: r5 q( A2 Q
        putchar(ch);0 w* t) e" w! I3 D- _, s9 [% \
        if(ch=='n'||ch=='N')
" R! G9 ^2 W7 a            break;
: T, W6 W& U" u; C! S9 ?4 X        else
2 v7 C- n: {- z0 f5 D% Z6 Q% d5 ~            system("cls");
9 F- H1 I5 N2 O7 a! P( Q; i    }
- k' g7 {8 H8 r9 D9 ]/ k    return 0;
& }* L; ?0 M3 ^7 |* l  Q. G}

9 i. w4 W5 C7 G) D7 K* t/ q4 p4 s5 I/ ]/ L2 @: A
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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