返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.1 Y& e, L, K5 [! v' T
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
+ v6 V! ~: y) q! v# d/**************表达式计算器************/1 d$ _. C6 f6 |
#include <stdio.h>% c$ Z  a8 Q# X. k9 ^# t
#include <stdlib.h>2 r. E, s8 I# ]/ ^
#include <string.h>
/ c( \; n# J: {7 F' _# J+ p#include <conio.h>& t2 w) a! u9 c) ?4 \
#include <malloc.h>5 k6 G! |1 l; I, _, s" @* B" J/ ]
+ e% Q: I/ X. l  w, j" Q; ]
#define STACK_SIZE 100
# c4 t5 K& M* D1 \- U  m0 ~4 F/ W#define APPEND_SIZE 10
" u0 y* t  U( k9 m% ~: T
- _& M! }2 A1 d1 [struct SNode{( V/ c6 A9 N) t0 k" r
    float data; /*存放操作数或者计算结果*/
" a) \% P! k8 {* k    char ch; /*存放运算符*/6 \- L' y  t* ^
};
2 A" ^8 r# g6 B2 m% S# T* k8 j/ l5 Q+ k
" J7 t1 b; \4 b* _struct Stack{
0 W. ^+ H: R% ~6 c6 P1 I    SNode *top;& w6 J. {& O5 f# ~1 k( ]
    SNode *base;* b0 v1 P' v8 X0 w
    int size;
7 y/ u' y7 I) A; c1 \};) P# m* e& x: n
1 F( X, R% e4 z% x4 Z2 d) M
/*栈操作函数*/
. _9 e, F# K4 k+ W4 N- [9 Fint InitStack(Stack &S); /*创建栈*/- E- u( K+ j6 ?- N6 n! D& ~6 S
int DestroyStack(Stack &S); /*销毁栈*/" \# F1 U/ M) c% x* d+ Z: O( k
int ClearStack(Stack &S); /*清空栈*/
& y* h6 _" o9 b1 j2 x- a) V2 aint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
2 U, l1 q- M: U$ p* N  kint Push(Stack &S,SNode e); /*将结点e压入栈*/
& b9 S/ r  ?. H) j% J# Iint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/9 J* _0 P4 b! n8 g8 e& L
7 K& ]3 p+ V# {* Z
/*表达式计算器相关函数*/
" m0 ?1 b4 {5 m6 G! dchar get_precede(char s,char c); /*判断运算符s和c的优先级*/- A& n# j1 ^& t" v/ @% s" V
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/$ J6 T5 j: b4 p. O4 _, E! s
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/7 x4 }! l3 G6 S4 U" [  [
float compute(); /*表达式结算器主函数*/7 K2 J  m0 [- R4 L7 C
char *killzero(float result); /*去掉结果后面的0*/
5 w+ Z" N" s8 a  V9 y& J7 b
- }8 g; S; u  l. ?# o% O% }int InitStack(Stack &S)' j1 s9 R6 y9 ?& [4 M3 }  ~2 T
{' a# b2 u3 d) k/ f2 r
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));* x  z1 L; n5 ?+ h) L1 v* i
    if(S.base==NULL)
4 O6 T$ R, u( d9 T( P' C    {& b4 D0 c4 A. z' z! M9 o
        printf("动态分配内存失败!");
+ H, s/ ?8 W; u; K4 i/ U( H9 j        return -1;
3 E" g' f6 y1 h" y    }
/ X2 a- C. M& Y" {9 Y3 |1 q# ^& Q    S.top=S.base;
% L1 ?4 ^& O$ O+ z8 Z. ^    S.size=STACK_SIZE;
* f5 t# m3 J3 @3 @    return 0;( H# k  l; g( n+ ~& e: M
}4 \9 C! n  \+ T' ?8 ?# s

) d) c1 q, `+ gint DestroyStack(Stack &S)
$ `4 L' c! V! Z: ^- ?{
) ?/ `: `1 E: i+ Y0 v    free(S.base);
) F6 V/ L/ ?( e    return 0;! J* ~7 z! r1 g0 w8 j7 C
}: @5 [. z0 k: N8 K  W( n+ H

' c' m( Y4 [5 K( M7 Q  Iint ClearStack(Stack &S)" K1 a0 v+ G, h7 @5 R8 k, R+ v& p, d+ j
{1 V( V# P3 }3 s+ n, R# ?# ]
    S.top=S.base;
3 E% K* D- R+ G* x4 |4 |    return 0;
8 H8 a4 s0 j1 _: B# G5 Z}
/ C2 X: |9 g& e7 K8 E5 L3 `& q0 A3 _: a& B
int GetTop(Stack S,SNode &e)2 }& z( y2 H8 J$ \* k
{
. A5 ~( z0 R, p4 i' a/ `2 r! I    if(S.top==S.base)
  E1 H4 v& a& E3 Y3 b    {/ t' ~. P( G: l! I4 {4 t
        printf("栈以为空!");
! D' s  \+ I, a2 C6 I4 {# K! A$ [        return -1;
% B2 k' G# O/ @7 e! b    }% v5 l% H* l# g8 Z8 s; H6 H* ]
    e=*(S.top-1);/ g9 u8 Z( q- d* P' J2 D
    return 0;
/ ~1 [' T, U$ B}! K. e1 i$ Z3 R2 _  y: X1 Y
1 L- x4 B& g% `" [( N
int Push(Stack &S,SNode e)
- h; r* q6 N4 X8 b' h; h" e, {{
/ V: C% H9 W# `/ S/ w    if(S.top-S.base>=S.size)
! o! m* q7 V$ H  l    {
8 W# L6 q8 V) L3 K        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));0 G) a6 q- [( z8 Y
        if(S.base==NULL)
+ o9 r1 P2 [9 F: L        {
( v. {& ]5 U* m2 U" ]1 w  v            printf("动态分配内存失败!");
6 W: @6 z9 a- p* Q+ n/ ^1 F/ N            return -1;- F6 h: X! P% c/ y# A) W4 h. k9 z
        }) @1 l) k. C9 Q
        S.top=S.base+S.size;2 g/ B6 O+ r1 y7 v
        S.size+=APPEND_SIZE;
% E0 U, b) q" @9 E6 g. d    }* h1 J$ \* `9 \; |% ~
    *S.top=e;
2 y" C* L" m! d    S.top++;6 j& s6 t7 Z/ z: L
    return 0;
% S# R% A# f* w8 F}
8 C0 J9 d" R- X  m  ?8 k" t8 I9 X1 v% u# b
int Pop(Stack &S,SNode &e): e3 r7 o# `6 d
{
& e1 |, I. p/ U4 o* Q, e' V  ?. Q; ^    if(S.top==S.base)
9 ^& K( x8 n; t) ^/ k  W5 M    {
2 G$ `1 p& Z. c! s+ Q$ q- D6 ^        printf("栈为空!");8 @0 ?5 e0 s7 }9 a8 D* \: ]; R) o' A
        return -1;  k2 t! F4 G% K' s. x) \+ [
    }. ^( u; r: R3 Y$ |; T  L% y
    e=*(S.top-1);3 Y, P8 |3 h6 v8 V% z
    S.top--;
" @: @/ u& ^: J    return 0;6 x: q; M6 P" o% I; w
}( M) p8 ^( {- j' ^2 t- X- \9 t' j: Y
5 I6 T9 _  P- @" q. M9 F( X2 ^* T
char get_precede(char s,char c)3 U8 ?1 |; U, x& o0 x
{/ h1 M4 B' W# |
    switch(s)
. s! u+ l2 r4 I! N1 W6 u, h    {
/ X% S5 }( ~: s# F/ l        case '+':                 / U- ~% k' X& \, U1 n
        case '-':5 L/ K2 \6 E, |+ c! j1 O
             if(c=='+'||c=='-')
4 K& i  s: B1 }6 r. S. s/ T                 return '>';
. n' I) k+ P7 R7 R" `             else if(c=='*'||c=='/')3 e' |! u- A# C- N# s$ u
                 return '<';
( Y  {: _! ^9 }+ A/ S             else if(c=='(')
3 ^; g. q- c/ Q                 return '<';
0 A+ V1 T) ?5 ?             else if(c==')')
1 J2 S. U( @# Z: [/ U4 |                 return '>';. s. |% l; C" [9 g+ Y
             else ' i. e" }8 |2 V; b7 w" J& C
                 return '>';& t! N' @9 T8 N: _3 E  n% H
        case '*':$ u3 Q; _2 k1 O3 o/ b, A
        case '/':3 U0 ^$ O* }# \/ S+ n% d
             if(c=='+'||c=='-')
4 `+ H& f5 I* ~+ J6 s5 H; G0 |                 return '>';& j: X; C7 Z0 [8 H
             else if(c=='*'||c=='/')9 z( a5 l7 @( X5 ^/ O( s
                 return '>';5 v7 j3 x! S/ h. H+ C) C
             else if(c=='(')
# r) v2 g  e- b                 return '<';, y: F6 g( ]- Y% y6 Z
             else if(c==')')2 I. Z6 x) A8 i; B7 J
                 return '>';* K6 \, I  x  N  t* b
             else
3 N& K6 d/ v$ C# q# f+ K2 ^                 return '>';& B9 x( _) T' f3 p
        case '(':
1 a+ v# O' X5 s# C7 [             if(c=='+'||c=='-')1 c8 k. ?$ l" l! Z+ Y6 [" ~, c
                 return '<';
4 B; d9 j9 V, u5 \( a0 o             else if(c=='*'||c=='/')+ W' P& E9 g6 c& a; V- V' ?8 l
                 return '<';
4 v# A9 c1 Q1 @0 W             else if(c=='(')7 Y) u  }# |$ j# j! O
                 return '<';
- h! b- j) o# x/ F             else if(c==')')6 a, M3 X  ?  X- W: Z+ d, l" G; e
                 return '=';
0 T( B2 @0 h' i: O5 e             else
# ~2 s9 r: c7 ?, G. h# p' R                 return 'E';
$ p: A" Y9 W" ^" M        case ')':# n! }4 ?* U- H" G. o8 Z5 ]9 A
             if(c=='+'||c=='-')+ X$ f% E) C4 }, B% Y
                 return '>';( G% m/ A" Y9 u4 t' v
             else if(c=='*'||c=='/')) {9 i: L; S, U! k( G% n
                 return '>';2 @6 U5 ]" I4 ?( S% U
             else if(c=='(')# U, ]9 O9 G, q, o3 _
                 return 'E';
  X' T% O8 J* S6 {5 k             else if(c==')')! F  B0 L- _" p  w: Y5 z$ i, v
                 return '>';- M2 q5 V, n6 J* z) [6 F0 X7 G3 Q
             else# P3 S  L; b$ H3 M3 Q) H
                 return '>';
: m5 j  k) }. R; y! {        case '#':9 T* B+ I% K: b
             if(c=='+'||c=='-')! ^6 E# q5 m5 ^; z) j
                 return '<';$ R$ k$ N$ K' s2 a8 C
             else if(c=='*'||c=='/')
3 `2 m; \  i, H4 J. `5 \0 ?+ B. N9 z                 return '<';
5 V8 D. E" r9 w) f  _8 ~             else if(c=='(')
" b( Y+ O# c1 o0 ?' L4 r                 return '<';
7 L$ Z6 U5 S# q) v5 i- j             else if(c==')')  H. [: O# Y, ~5 W
                 return 'E';
- Y* I: ?. B4 `& w( Y4 R3 J9 A             else+ o9 E' H  G: `' D+ w! O
                 return '=';
1 q, `' C6 W  w8 s  P: O6 p        default:
/ t4 Z; |3 u: b             break;
1 B! r5 a* i: K3 P4 B    }6 N- F& {) A% D- ]7 E1 r
    return 0;    - P1 Q: H! d) u
}
- q. u6 M! |, ^' Y: ]1 y7 C
" ?) D: D% k5 g  O7 H' Yint isOpr(char c)) }6 K; n% a4 g/ G% A4 |
{5 ?- {3 W9 b' C4 }- V
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
+ L3 |3 B) d' l; [  i& p        return 0;7 |+ r" V, ]0 [* y* ^
    else
0 q, q( ?4 l8 P1 `4 G        return 1;
. f. F4 P8 r, J& j+ d, G( R1 V# r}" |1 K, L$ E: X4 c& I2 b

" G2 B6 ^8 B+ S; n1 B1 }4 rfloat operate(float x, char opr, float y)/ i  A  A+ i" p( P* t- L
{
( \2 Z, r- X. D) x    float result;
" Y: R& g6 V; U: y$ o7 i* p* x    switch (opr)% q1 F3 T4 }9 a2 l. o
    {
$ r' P8 q  q9 |! f# ]9 E- n        case '+':
% T4 R& K- [2 B1 u( ]4 f3 ?             result = x + y;
$ q6 k0 y' L9 M             break;
6 o+ {/ J. K: v        case '-': 6 ?2 ]' I8 s0 Z7 |9 G
             result = x - y;+ `7 `' l) b- b
             break;5 E; I2 h, [# X2 H; w6 m
        case '*': / B9 H7 \# [1 t  Q% i
             result = x * y;/ \- a$ d6 n% M' r
             break;! }/ O3 h, C/ S. P+ a9 r
        case '/':
$ s  V! p  S! o$ X7 O7 C             if (y == 0)
7 D* e  ~- m- W& g             {9 I2 f9 ^$ i/ o
                printf("Divided by zero!\n");
. S1 {6 \5 j7 {                return 0;
0 Z7 W; B7 N4 W* {9 _4 j             }
. n5 }! X$ @; S5 `  f# B             else
# q; m9 s. c4 k5 \% L% G: F             {, O8 R% Y  l9 d
                 result = x / y;
$ L& G) O% j$ q4 c- N                 break;
9 @/ h. i/ a, e) e2 Q' P             }+ B3 W( E) J5 `+ U
       default:
9 d. X, Z! Q" `0 K5 b             printf("Bad Input.\n");
9 L0 C/ M0 p% a4 @4 C# q: S5 W             return 0;/ d8 H! ]- |) `2 v/ j4 [% @% Z
    }  Z6 {& B$ ?$ |' N7 l( `( N. e
    return result;
# M1 `% P  A/ i6 j+ |}   
- V( m: H) }9 `- ~3 l
& t5 g& N/ l5 s% d! n  S6 v2 T; A1 e5 [float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/8 V( T3 m+ Z/ i& T
{
% m; j, G# Q6 X7 g4 T    Stack optr,opnd;; m' s; u& [1 e. e1 n7 }
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;, M! g: B2 d! L7 n
    char c;
% q9 e/ ]- t* m, g: B$ {! O, Q    char buf[16];3 ^! u# T" f$ b2 a% _* v" Q5 @' K; F" z
    int i=0;/ `6 |" ]4 m/ w+ }& o
    ( }% X; ^3 s* i# Q4 a
    InitStack(optr); /*用于寄存运算符*/
2 g: b3 ^9 a5 S$ E0 {4 @% l    InitStack(opnd); /*用于寄存操作数和计算结果*/
/ Z5 J. `7 o8 q) t    memset(buf,0,sizeof(buf));
. e2 v; A  V* s- \0 T! q/ r! o   
2 C6 @! u2 o4 i' I    printf("Enter your expression:");( T1 O* D4 q9 z" I7 x; [) S
        
8 b! b5 G2 t1 o& H: \    opr_in.ch='#';% W; W, o6 x: m5 O: s8 w
    Push(optr,opr_in); /*'#'入栈*/
- _# L2 n6 |% p3 ]8 Y; n# I, w    GetTop(optr,opr_top);
3 F9 {- T5 M+ G# i. k2 t% a% |& B    c=getchar();3 O- |( E" r% Q, i- [1 T
    while(c!='='||opr_top.ch!='#')' F8 r! N) Q) ~$ o
    {  m0 Q' G& v3 ?0 p* _
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/# l3 o( p: m$ u3 t
        {
$ y! S, c+ a, [9 ~            buf=c;
1 K% G# Y' K+ e4 q8 k% E0 E9 P" b$ ?4 l            i++;! }" H' k+ [: ^
            c=getchar();& n& C( y8 y) I$ }" k
        }6 K4 i3 k8 k& d4 ^6 z  s
        else /*是运算符*/( F) T5 ?1 m4 k1 S, m
        {5 j! v; C1 D6 q/ ]2 Z. `! z
            buf='\0';/ h$ k0 {- K% Z8 [
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+ v  j5 j  W! [5 k6 ]
            {  z' d! i! \4 o# w
                 opn_in.data=(float)atof(buf);( o$ a: |7 Q5 e7 V1 J7 v* b
                 Push(opnd,opn_in);
( y6 }/ J7 t9 ?% L                 printf("opnd入栈:[%f]\n",opn_in.data);( l* ~: d) ~7 v6 A" Y  M4 V; e* a
                 i=0;
! s1 i/ X. j) O/ ~                 memset(buf,0,sizeof(buf));
' Q5 ~; ]' w! M; ^/ M5 n            }
! s3 _1 |( z  Q0 A- ^2 [            opr_in.ch=c;  X5 L- q+ q( G2 ^. }' p. ]
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
$ j9 ?0 C0 K6 I4 l+ q; J            {
( y, a5 F  |4 I& A                case '<': /*优先级小于栈顶结点,则运算符入栈*/
: `, R7 a6 Q) ^: l. L, s* v                     Push(optr,opr_in);
4 ^3 A# {7 S* z; N' G, Z; J                     printf("optr入栈:[%c]\n",opr_in.ch);5 v; \2 U  p) H" w. T
                     c=getchar();7 z5 x; s' k/ M# b( Y: n4 U
                     break;
6 [/ J* r, v) I7 C                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/& J! @+ Q4 p* V% K# v5 M
                     Pop(optr,e);5 t. \) Y. n' m! x$ J- Y
                     printf("optr出栈:去掉括号\n");
( z( a- T' H6 B5 d                     c=getchar();
; z" k! Y' E8 y: u% Q% G# n: A                     break;8 c7 t$ d7 r7 _5 t
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/2 P7 S' Z6 ~  O3 {: E
                     Pop(optr,opr_t);
: n  c8 Z% F, U& p5 K                     printf("optr出栈:[%c]\n",opr_t.ch);
7 q; d" r5 t8 Y& D) ~7 T6 p$ H                     if(Pop(opnd,b)<0)
/ L, y+ |( A0 @$ R9 e* k- J1 ^                     {8 Y9 f' v- B( M0 F/ B, ~% F
                         printf("Bad Input!\n");
, z: `5 k' R; N6 X( \) f, T1 f                         fflush(stdin);4 H% K# _! A6 U1 }& ~- J
                         return -1;& e5 F" f) Y2 X8 X/ ?
                     }6 Y1 f9 |4 T3 B- U
                     printf("opnd出栈:[%f]\n",b.data);
7 v$ i" `% F, r# ~0 Q8 ], I! P2 X% G                     if(Pop(opnd,a)<0)
7 }! m6 O7 J* ?) L1 r1 S  X                     {  H; J8 e( I% j4 k
                         printf("Bad Input!\n");
4 U6 L+ c8 q# I, f% B                         fflush(stdin);$ W7 s  d! U4 u, B& Y
                         return -1;7 W! r& f1 J2 k  o) k
                     }3 Y9 @' I; b0 `; I, z5 [
                     printf("opnd出栈:[%f]\n",a.data);
8 i$ @! p' N8 |' h9 A& @                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
) O8 S6 u5 i5 G; Z+ K9 R# S- z5 x                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/0 r+ Q% k! g$ Q. ?0 O
                     printf("结果入栈:[%f]\n",opn_tmp.data);7 O( \, ]' ^7 v' x- `( W
                     break;
2 Z3 |( c9 v. ~2 ^            }
0 J3 r4 m9 y) m, p+ P( K0 y; n        }# L& D' h+ D( I3 I
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
$ w6 Q3 H6 K! F  O5 G9 ~% Y7 K! A    }
$ _, _) `* h  q7 ~: g    GetTop(opnd,opn_tmp);0 a5 e. d- p* b5 t& N* @/ W
    DestroyStack(optr);4 }/ X0 Q- L. U  r
    DestroyStack(opnd);
  c. c4 r* H* y) }; h8 f& Z5 p5 w    return opn_tmp.data;9 T3 ]2 G$ X3 T- {2 k! A7 v
}- A/ {+ A" R: _- i# u! L

# Y) l6 z% M6 w! b( cchar *killzero(char *res,float result)
+ g. }4 ~7 _7 c: o3 ]  E( q{7 d( ^& |0 I5 e7 X+ y/ L2 f
    int i;1 T- Z. ]0 w2 k9 \. X/ x/ M0 b, J

* K4 c. p- U* ]6 c; n2 K5 |+ t    sprintf(res,"%f",result);' p* Y- B/ h7 f0 T
    i=(int)strlen(res)-1;( D2 x& X4 i# C- v( J' d
    while(i&&res=='0')) Z, u9 K$ z6 M2 |8 _7 h5 S$ J" H) K
    {. S% L) ?+ i+ C2 O" U
        res='\0';
( w- L  \, H1 m; L6 n) M        i--;
& m: E/ z/ @/ G+ d/ G    }6 m4 n* r' d: g" Z8 J! c2 P+ |
    if(res=='.')4 ^( B  _; V. I7 H
        res='\0';
* c# M' b* J+ U3 T2 _    return res;
' k6 |' w, |+ I}2 g) z8 A( M7 j  P6 U5 r8 [1 T
! C7 N: d  `  d
int main()% V' r, Y. [' y. X! R: M" G
{3 u( U: {0 I- b; S
    char ch;! B+ f* o  R' C( J3 ^2 ?6 Y7 g6 ~
    char res[64];' C; P4 `$ M# V; d
    float result;5 g2 F" H+ P9 d$ d7 B% v0 u
    while(1)8 I1 l( [3 M- x. u4 d
    {
5 g! m3 |) u' S        result=compute();
0 O" ]! f) V% u% S% M2 v9 Z4 U        printf("\nThe result is:%s\n",killzero(res,result));
. [* Z* ]' H' z. q, S% A        printf("Do you want to continue(y/n)?:") ;* @6 q4 `8 `  o+ M
        ch=getch();
5 R: N; r; }) I- @$ W        putchar(ch);
& G% i% z3 k$ q9 O7 k/ H        if(ch=='n'||ch=='N')1 w2 x# ]' W. I- t
            break;! S) N# v, ~! L5 O8 l
        else
. P$ c+ K+ [& O6 R            system("cls");0 {0 H% d, d3 J  I/ i/ }
    }- N+ H. V/ Q$ L# v/ w1 R
    return 0;
/ T! Q( [/ i+ x! b% h$ A4 X}
' O( L( y6 v+ Z4 v. [- L
: S: t. r- v& p7 [3 z
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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