返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.3 y) }/ W$ H8 ^7 |  z4 [
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
6 O+ R4 {. a/ D0 m& S6 S& t/**************表达式计算器************/
8 y! C' Y" l8 Y) k: w#include <stdio.h>: l* u; q& r4 W& {0 L# k4 O
#include <stdlib.h>
+ G% s2 _7 N4 V' ^( o; z& C5 \#include <string.h># g7 M: S0 {* A0 g! p
#include <conio.h>
- I8 l7 W5 [$ }* ~* @) F#include <malloc.h>) j% U6 p, e  Y# D( }0 h
4 s( M$ N* z" L$ ?+ V# ?9 R+ Q! ~
#define STACK_SIZE 100
/ |3 _. R. k9 e  f#define APPEND_SIZE 10
; I. C% B( f3 s( n, s9 ^
7 l" L0 y. y  v7 }, k$ G7 fstruct SNode{( W6 S% ]5 i+ V& n1 p
    float data; /*存放操作数或者计算结果*/
, P4 K) f. ~7 F, j- y% V% y    char ch; /*存放运算符*/2 c, ^3 _' C; @: Z; F% s- P% A" b
};
% W+ d) X4 @4 R& K3 B/ J# w8 J8 @# S3 C2 K0 n) z5 b( Z
struct Stack{# e: j9 j6 p7 ]' W  P
    SNode *top;& r& C0 J2 V2 V0 m0 x
    SNode *base;
6 [* J4 J7 G1 |    int size;
5 R, e2 u2 x3 P) C};
% d) h2 _! E% \: M  \+ s- U
# \5 q% k2 ^+ J- `; V/*栈操作函数*/0 Z0 y) h+ R2 ?) I6 H8 f
int InitStack(Stack &S); /*创建栈*/
' X0 s! _7 J3 W2 Dint DestroyStack(Stack &S); /*销毁栈*/- B- [( W' T4 h, n) J  n& l
int ClearStack(Stack &S); /*清空栈*/
! a' ^1 D5 Z- a5 V- `7 _8 U6 z+ Wint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 M0 N2 A* K" C$ r" E* B) ~int Push(Stack &S,SNode e); /*将结点e压入栈*/+ K2 e. R. c) O; `3 _. }
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ l) x( n- b+ i4 g
& W/ ^8 f" B" P7 r/*表达式计算器相关函数*/, S6 G7 h$ U# l+ A8 c
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
& w) ?, e7 V1 E/ x5 P' s- m" Rint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
# W* E( n$ V: v* ^9 `0 zfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
  r- X8 W5 ^2 j0 m# Gfloat compute(); /*表达式结算器主函数*/
, f+ b) ?" T" Z& Zchar *killzero(float result); /*去掉结果后面的0*/
6 p( j( S( E8 u9 a3 j7 n2 \2 |4 T
int InitStack(Stack &S)& G# g7 Q& m0 i! z3 h9 `/ }* P
{
& `5 B0 d7 U0 h2 A. F    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
/ C- ^: r5 L0 y) K7 z    if(S.base==NULL); T* B* n  i, b
    {0 \9 ^9 Q  w5 L% M: T
        printf("动态分配内存失败!");' ~% D6 [; |9 }, z+ b/ a/ a4 ]
        return -1;: m9 a9 ]1 o+ A8 I4 d
    }
7 z3 G; {! P! I+ c5 E, {    S.top=S.base;
3 O5 }: b% T8 `" O1 t' f& P" H7 m    S.size=STACK_SIZE;2 d. h, ?8 C# ?# I1 g, p) _! K& H
    return 0;% H8 A! x" {* s2 k2 Z7 I
}
* k, k( g, r5 _, }+ _2 @* s8 _! V* x# w$ ~* z2 W
int DestroyStack(Stack &S), K3 T9 H& L3 e& F+ s% K0 F$ N6 C
{. {$ x- @- W0 N0 s" t
    free(S.base);
4 \# o. h4 Q" [* }- ?6 s; i1 o    return 0;7 N3 U# u3 @( S9 b6 |
}5 k6 I( {5 J% t; ]! z6 F

) R2 V3 O/ e$ A7 A! q+ Bint ClearStack(Stack &S)
7 U  q2 M. ^6 u4 S: }9 N{4 g0 ]! s& ?" s9 ?2 h6 c
    S.top=S.base;
1 Z% l% I, C. V1 @; o    return 0;6 M" W1 v) }) [& o7 Q$ ~
}
8 @8 V. E) v$ Y, [6 F- Y* Q! c! H+ X/ S! a9 L
int GetTop(Stack S,SNode &e)! R( O* P" t6 z9 F, o% P
{
! r/ @6 e) G% H, q    if(S.top==S.base)2 d2 A( |2 |0 s. |: W
    {1 N1 H2 |4 ?7 P$ q
        printf("栈以为空!");. X+ B: T( r5 |/ h& ^! T
        return -1;7 g; z; r( D- O! z5 R
    }( E+ h5 e& }5 z2 ?3 ^
    e=*(S.top-1);" j. ]/ @* s. z
    return 0;
; I* ~% W( c* l/ _}
0 M8 `* h' ]9 t( S! w: w7 `1 q8 E. V0 T% u
int Push(Stack &S,SNode e)1 y2 V* P* x9 L, C; L3 E; r4 S! Y* \6 q
{
5 b! F0 b  a* t* m    if(S.top-S.base>=S.size). z  S$ S/ s6 u- y7 V
    {
/ V  m1 f2 }4 m) y& {6 ^        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
. R. p3 d; j4 b: {0 ~. ]        if(S.base==NULL)& R7 B, a! n9 o8 J* d, Q
        {3 A  f1 l% E2 l* D2 o
            printf("动态分配内存失败!");, z. f# A; m( I! Z; t3 ^8 k
            return -1;# f' l5 B3 F) @
        }% I/ h% r+ c$ c8 P1 P* T9 Z
        S.top=S.base+S.size;( V% ~. C/ v, \- Z
        S.size+=APPEND_SIZE;& d2 N4 h2 \* w  n- `: l' ^) A, K
    }
% R: l/ H' R, G& j; m( U  Y, G; C' q    *S.top=e;+ W2 K+ B# u4 R/ z7 Q( [
    S.top++;
1 u$ e2 l# T) p$ _  ?4 l# N    return 0;
2 F) U+ ^# c4 B$ |& Q}
& p: x8 V5 a1 `. U6 P1 V* o( s  Y' e
int Pop(Stack &S,SNode &e)6 ?! F. V% `. Z9 S" P6 K
{" n  `) Z5 q7 N1 V" t
    if(S.top==S.base)6 n  W6 G1 g6 e. x( p! B+ p4 ?
    {
1 ?/ d8 Y' Y$ D- @$ S7 J        printf("栈为空!");7 K, t9 H: ~& ~
        return -1;
+ ~" m9 U7 L8 S% [# @3 \    }  C; K8 ^6 i8 s4 ~
    e=*(S.top-1);
' t  `- P: S! g6 k+ o9 o+ Z/ ?    S.top--;1 B8 @6 f( b4 K0 O! q: k* p
    return 0;
% w1 Y- F- i; B& [9 e# `, D  m}# \5 L/ t4 `( h8 p

3 y/ H( D9 l* Y3 S* x9 qchar get_precede(char s,char c)
  V5 C: I6 i6 v- y8 Z& ~2 G. H{: O+ t' R# w& F0 v, L. j
    switch(s)
% H; w. x/ E* b+ j- L    {
- S1 j; _) t! q. i9 h% O( P        case '+':                 
3 ?& V3 r6 K2 [( L  \- z        case '-':
6 z1 [* ?, k% s  L             if(c=='+'||c=='-')
. d( T+ t; A# `' F0 _% C                 return '>';+ O; d5 z; c  h/ z
             else if(c=='*'||c=='/')
6 \; }" `$ K  I                 return '<';2 C% @  F; r+ [" d' L" v9 e5 T
             else if(c=='(')) w4 l( F- W: M
                 return '<';
8 j* O% ]0 }* ^) F8 {6 H             else if(c==')')9 D; L/ m# X! f) y# H
                 return '>';; D5 @" P' R% M0 r' g
             else
  I6 G6 C; E+ k4 ~" `                 return '>';
6 B  l) O6 _+ K! x; O; W$ U& _: ]        case '*':5 b" e5 f2 F- g- u7 _  @0 Q
        case '/':
5 U1 I( Q$ ]  \, r             if(c=='+'||c=='-')1 N/ x9 `. @. s
                 return '>';& [+ |6 r+ g! h( X
             else if(c=='*'||c=='/')
1 Q# ^% p* b* e* f3 U! A' C                 return '>';: _2 Y: p4 k1 D. E0 r
             else if(c=='(')
2 V/ K2 f9 M! C% U                 return '<';
* V: Z* }" L* U0 b7 Z7 c5 Q             else if(c==')')0 H$ o9 i$ M5 `# h, f
                 return '>';
, y+ Q; h! i1 p2 ?! j             else
3 K. T$ F* v" E: _* W0 h+ \1 C                 return '>';6 _: y. ?4 N: H6 R# P: }
        case '(':
; f" ]) O9 O' a& }' ~: n             if(c=='+'||c=='-')% f  ~, g4 k% J; ?9 \
                 return '<';4 l& J% q* N1 @- @. u2 u, B
             else if(c=='*'||c=='/')
% ^/ S9 q. n9 ~                 return '<';
5 v3 a# A/ H3 O4 X0 u) ~             else if(c=='(')3 j4 O0 }+ R; O1 P* N
                 return '<';# x4 @+ l/ J' y8 Y' n9 {2 x5 g& Q  _
             else if(c==')')
  \4 g" ?  v7 N                 return '=';
! q5 U& ?5 k: q4 U             else
3 \" `7 L+ W! R% c: {( g6 i                 return 'E';7 }, L' Z& z7 E  [
        case ')':
- [- ?% U9 V, O- ^" N, l             if(c=='+'||c=='-')
3 y) H# {, [# `! d2 Y* b                 return '>';; L6 u! C% s) _& v
             else if(c=='*'||c=='/')4 s1 i) k0 Q5 y7 S+ @& B/ K9 e& A
                 return '>';8 E8 @7 r* Z7 i- L
             else if(c=='(')4 A/ f* \0 J6 {9 m9 z* L
                 return 'E';  E$ o. H7 L, @& d# W: s+ r
             else if(c==')')
' T. x: p0 c8 ?9 V2 }! L4 |                 return '>';
6 |" `4 }% S' I3 D             else
2 f. c' b3 C* t+ M                 return '>';
+ p9 }. w5 W$ z1 E) r% B; y  v! T        case '#':6 ^' D3 Y, _( P. B, [
             if(c=='+'||c=='-')9 p+ t3 I3 X! z
                 return '<';3 K; S' X. v* S9 J6 r6 V4 x2 n
             else if(c=='*'||c=='/')
7 r& F5 X$ Q1 r/ k$ f                 return '<';! d* K% Z; v; ~) |* ^, B
             else if(c=='(')
- a6 C8 P6 T. j% w+ c. S5 J                 return '<';0 `- A. p% t/ @8 m$ m, p  g* `! o# M
             else if(c==')')' H/ k# M& f4 t' v* p& ^( ]& u7 r
                 return 'E';3 r" F( m0 ^* J. I8 W  ~6 ?
             else
/ s6 Q3 h5 l7 L) R' E4 i                 return '=';
/ \- Q* C( \; b( u8 R( G        default:
: h' b- x7 b8 n% n. B7 J8 C% G             break;
3 x% w- A- m1 J# k: E    }* v; _3 N9 ~$ I  V4 x' q
    return 0;    & U) e* y+ v2 m' j! L# x" E, ^
}
$ v: x& f5 |" e; W! p3 @" ]5 ]/ R6 i$ J
int isOpr(char c)& M  |# T8 V1 G0 K+ N" X) `
{
- }6 w' e" I5 R    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')+ _. q* }# c" G' z, K
        return 0;
" i6 B( v; A1 ~    else 0 e5 E! ]3 {7 O% c" E) J4 v5 ]
        return 1;
8 a$ j- I9 H1 ~' G' K, A}6 Z8 }. C5 E4 `! C; p- A
8 x/ F; l' K  }4 P, F1 h( c
float operate(float x, char opr, float y)
/ ?* V  L- z) \* A{
, ~5 v3 y' k1 W    float result;1 H7 q$ Z0 |5 g. P9 _  E+ H
    switch (opr)
8 r9 h5 R+ M8 X( y" O    {+ I3 a2 p7 v: \  n! a$ y+ X
        case '+': , P8 y9 x, M1 E. r3 h3 C* a6 [
             result = x + y;, F1 X. s3 u2 M% X
             break;8 O8 I1 J5 h) e: H0 z( h/ B1 F
        case '-': % W' [! F/ s. z8 v9 u- k4 R
             result = x - y;
+ l) S. v' q( ]" `. _             break;
0 R7 S. D! C) Q. `( J  j        case '*':
9 C0 ~8 E4 [" N" p  U             result = x * y;& n/ l6 b/ A( C7 T' M0 q% @
             break;
  k3 i7 H4 A1 N0 `- K/ k  K$ e+ X' h7 z        case '/':
% Z( C  y2 j) i7 ^% f             if (y == 0)0 x, T8 O1 U' s, H9 p+ y
             {& P, z) {  T5 H
                printf("Divided by zero!\n");& G6 d; f- }4 Y! [. Z0 `5 E
                return 0;% ?% Y. h/ i+ _% S$ }
             }
7 E6 }! f. S5 B  S, w1 U             else
. f' z* c8 `6 ~) W; D             {
2 ?& [6 S4 E5 t6 F' Q                 result = x / y;+ L. G7 i  `8 z( J7 a* j$ F. r
                 break;
+ R. w: y9 p% b             }9 H% k) l* e# C4 t* P4 ~
       default: , h7 o# r  A9 N: ^( M
             printf("Bad Input.\n");
$ U% a& a& [8 E             return 0;# E7 W2 b5 R2 }- {
    }7 b) z" T! j* e9 |
    return result;$ P4 j7 j5 v1 i' W. w* D+ Z
}   
3 ?3 k' j* h4 C/ G2 ^! l7 e2 B  E
+ ]3 }& E; ~1 {" v4 C2 @/ m- Yfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
, @% s$ o0 l8 L- |7 E5 ]- K{) K2 t4 Q' [' ^. q+ W7 T8 {" v1 `
    Stack optr,opnd;
! {" O$ F9 k& |& X( K' K' k5 x7 r    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;  {- J: ~5 V& H9 h2 F, p1 N  y, G6 h
    char c;
$ o: s2 c1 y9 Z. v) [1 w* Q$ B    char buf[16];
: ?  W; u; h# @& N  a. l    int i=0;
5 e3 o( a* C8 Y# W$ Z& I# B; I   
4 b# Z5 p$ A* B5 J    InitStack(optr); /*用于寄存运算符*/+ y! h9 {3 v1 m
    InitStack(opnd); /*用于寄存操作数和计算结果*/
4 G5 ~! N7 _5 N" }, ^* D    memset(buf,0,sizeof(buf));. E6 p5 g) c7 E- `% G
    $ X, R' Q1 A/ O4 [- E, H0 Q/ [
    printf("Enter your expression:");
1 [1 n! g+ o" H% ~; `& [! h/ F        
6 @) |5 Z$ n1 W. d7 h: x7 r    opr_in.ch='#';% E4 @' z# e8 y" u
    Push(optr,opr_in); /*'#'入栈*/( Q  e, n. V  l0 S) s0 ~
    GetTop(optr,opr_top);
. \- ?; ?! ?- j" A6 i    c=getchar();
6 K7 W* x! E3 H" x    while(c!='='||opr_top.ch!='#')
% g( ^4 T0 d' E4 J    {
1 U# j2 B' P  R        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
; p! {# c. r0 u' }  S9 g        {
( _7 O6 J/ b- w6 \' H) S4 G            buf=c;! l: w6 g4 ]* X1 T- Y4 b
            i++;
/ q2 p9 ?( Z. a' x  Y            c=getchar();
: ~: G; f/ g% |$ \        }
  G) P! u' U6 X1 i% l        else /*是运算符*/
9 V, M& H* e% A: R# J1 T* P! k8 V" w        {$ @% L0 e+ Y& |8 \. {' L3 j4 T
            buf='\0';# g( o; R( p1 |, b$ A2 D: V
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/  x4 b) p: g0 \0 h) M8 ~6 q1 v4 r: f
            {
- H$ s- ~% G  R( b# u                 opn_in.data=(float)atof(buf);
8 Q% q) O: X  }3 x; n" [( V                 Push(opnd,opn_in);
" {- n1 h( ~/ ~% {3 L* h                 printf("opnd入栈:[%f]\n",opn_in.data);
' U) c% W  R0 E0 t                 i=0;
  k+ R& D2 C3 H9 |1 N                 memset(buf,0,sizeof(buf));1 t0 G6 g4 o  d" s! {8 W
            }
( g: a$ v7 e, C3 K" [2 j, ~7 y            opr_in.ch=c;
9 A1 M9 x/ x% T% S8 w9 R% o' B            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
' |0 J& \; q' p! F5 M9 a* o            {5 X+ s, X7 n4 O9 J6 f
                case '<': /*优先级小于栈顶结点,则运算符入栈*/$ E" m) D/ h( W& @6 `6 E
                     Push(optr,opr_in);
3 d: y5 v* x0 Y, N8 X                     printf("optr入栈:[%c]\n",opr_in.ch);
) y) c4 P5 K' J7 Q" V8 q                     c=getchar();
! A; I" x% P( U                     break;
; i: ?: \( X4 J! [                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
# ^6 g$ o6 |  v) a' A                     Pop(optr,e);
, y' W- g5 q7 T0 A1 ~                     printf("optr出栈:去掉括号\n");
/ f- S! }" p: l& n                     c=getchar();  ?4 C6 I' \7 F' `8 a% O3 a/ {
                     break;' t+ a" \% }2 F) g
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
0 c. E% l8 Q( V2 X) Q; I" }                     Pop(optr,opr_t);
6 [/ R1 D; E/ N0 M2 {4 F                     printf("optr出栈:[%c]\n",opr_t.ch);' ^9 v, |" p: Y2 s: p6 J) M
                     if(Pop(opnd,b)<0)  t7 O+ ^" x' Z9 b: [% e% J/ y
                     {2 `5 P# v+ P2 r/ Q
                         printf("Bad Input!\n");" a  h7 E6 i- I% a- y# G- V
                         fflush(stdin);
, j& d- z$ X  y' M                         return -1;
* U% F) M$ [1 t* H9 v) \* x                     }
; Z; {2 [; v  t! s0 S- R                     printf("opnd出栈:[%f]\n",b.data);- L4 d+ M& x7 C* p9 t' x" Z9 j
                     if(Pop(opnd,a)<0)
. X+ d, ~) A' l  x9 l& ?                     {
! o7 p1 H9 g; L4 X' m                         printf("Bad Input!\n");, U9 q' _+ g: L, g+ p2 g/ C4 Q0 B
                         fflush(stdin);. d: x& {5 b8 P0 t( S( V0 K" }5 z. S
                         return -1;
/ \8 |' E# a$ F, |                     }
: O% S; k; C/ K                     printf("opnd出栈:[%f]\n",a.data);# w* |3 b, l: F$ k: ~4 L. ^
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/. H! L9 X" w8 T& R' D; `9 k
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
2 W6 V. G( g" R) ^9 E& H                     printf("结果入栈:[%f]\n",opn_tmp.data);+ i$ f0 ~3 J9 q- q0 j" J7 f
                     break;* t- n+ \: ?" H4 p0 L3 ^) x  h3 C
            }* z2 S" l4 v& w0 T* G% g
        }# P" ]/ D- }, P3 t2 }1 `. G
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                # Y8 L2 v% `9 A: H5 V+ L$ w( L5 W  o5 @
    }: J$ |! p4 b( o/ |/ H: d
    GetTop(opnd,opn_tmp);1 W" u: ]  U, ?7 |' l; q$ d# ^
    DestroyStack(optr);
6 r: C  T: h1 e- K8 X    DestroyStack(opnd);% G$ Y+ f3 h) O+ h
    return opn_tmp.data;
5 x1 w( g$ S& {+ S- t% K}
2 C6 u6 C# ~* ^' o: v7 \
% B, [9 ^: Y6 `5 pchar *killzero(char *res,float result)
6 _% d. N( U6 ~& h1 ~{2 W  s% L& w. ?. R, G
    int i;$ _# f" O8 A0 B, C4 |9 z
# p" T) Y( J) i  q7 P7 E3 j. j- ]
    sprintf(res,"%f",result);
$ O. R- R: {4 j5 f8 `- w    i=(int)strlen(res)-1;
* }4 K9 @. Q: b0 d5 D& T    while(i&&res=='0')' q  j# d/ R! k
    {8 d* c  u# `& U& a3 L+ s/ h
        res='\0';
7 e/ U8 l4 |8 u/ f2 Y        i--;
/ L# _+ @, n& R$ h$ N7 E4 ]  m( W" u    }
! |- f  J* y! V  f4 A    if(res=='.')
8 N! s! `$ h3 b2 C3 b" L        res='\0';
4 h( R! b0 E/ W8 M$ C0 c7 m    return res;. o5 d' u, y$ U6 E& \* P7 u5 C( f
}% B5 z5 n1 m- S: P% y6 C

$ o: P* b$ F+ }5 K% D/ Cint main()+ y( c4 Z& m! y' C( R1 z" s+ l
{9 }, S& E( m1 s1 n% b" {
    char ch;
5 u+ C5 c% I$ F( P+ m+ M& j' ^    char res[64];1 u8 p# }! I) P
    float result;/ g  O; M/ d4 V  s; I/ e$ L5 K  m
    while(1)
. m* s) r) @, S3 \. M! P, \    {+ I$ S9 n* K; s0 w. m$ M
        result=compute();
( Q4 d+ j  G$ S0 Q        printf("\nThe result is:%s\n",killzero(res,result));
6 A; _, f' O8 y2 k2 q        printf("Do you want to continue(y/n)?:") ;/ e& P: A, Q  Z, Z
        ch=getch();
) J( L3 W+ q- U        putchar(ch);* d4 g. X) [. u3 h: m& m( L4 o, J
        if(ch=='n'||ch=='N')) H* }( Y' L- A* w; T; k( J
            break;2 b3 [- W/ p& u# D  a% N$ p1 I
        else
7 k& }3 J6 Q+ C: z4 S, |# W            system("cls");
& L& @1 x9 r% u5 i  t1 e    }! b( ]0 d3 O6 `1 h* K* e/ c# I/ n2 T
    return 0;6 G& s; B& F% Q% M- T3 q
}
' T2 U8 V7 [& ]9 c
( n- z/ F! e3 f  e- [
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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