获得本站免费赞助空间请点这里
返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.* `& ]4 c+ L' V+ w8 x  K5 S. ~
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=+ }% [4 O' G$ {' Z
/**************表达式计算器************/) f' j2 X" L! O' \
#include <stdio.h>6 S/ P; A( ]. ?% h
#include <stdlib.h>6 T  n5 Y/ c) Q+ M, Q$ N  b
#include <string.h>
" D1 n1 m3 a$ Y/ ?9 s#include <conio.h>
$ s$ v# D' ?: U: B( {4 f$ h/ z" c#include <malloc.h>0 f4 X0 W$ c0 y: Z

# o: t  E9 ~- d' O3 L8 F#define STACK_SIZE 100, F6 }0 j  Z( }: V5 m* M+ q9 _
#define APPEND_SIZE 10/ F5 j4 u& f8 }* g) e, g

$ h: R* O+ k- estruct SNode{
+ I9 z  p8 p; b6 ?    float data; /*存放操作数或者计算结果*/
$ X# A8 Y' z  w2 G# Y0 b- I    char ch; /*存放运算符*/- L; q/ @" f6 H& P' F1 F! P. m0 J
};
4 S) ?; u! k2 x$ B% f1 S
; W+ B- Y7 z2 D7 R, d  Estruct Stack{' O- v- q7 L' Y0 k( b$ s+ \; [; V
    SNode *top;
/ t' P  c7 [* M    SNode *base;
* i* v4 N( B6 q; e    int size;* V# z/ N- {* d
};
% p+ \# m4 p8 P* o
" c, I: O% V- N0 L- f/*栈操作函数*/9 T8 `' s* X4 H0 m& k
int InitStack(Stack &S); /*创建栈*/
! _6 X% ~/ H( z9 \0 w4 P0 G* Bint DestroyStack(Stack &S); /*销毁栈*/
8 {! H* d  C$ k- c5 dint ClearStack(Stack &S); /*清空栈*/8 o0 J4 Z4 R9 C( e3 E$ \
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
9 R& S8 u) g8 d4 O3 n+ Uint Push(Stack &S,SNode e); /*将结点e压入栈*/  j( B% i4 k1 s) `  M* R
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6 Z8 A" K% p: D- \4 ]1 n9 I
& q6 s) U, @* }. R( x% \/*表达式计算器相关函数*/
) S; n7 F' W8 ~7 {0 gchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
) H" x, O+ O$ J( H$ c2 L% |: ~int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
3 i2 C, U0 V, e5 G2 Ffloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! K' i% }% [8 {) P; wfloat compute(); /*表达式结算器主函数*/
2 R" K8 c% t7 T$ ]9 p8 N4 Lchar *killzero(float result); /*去掉结果后面的0*/ " p$ z- y2 @; k$ X; Q
" {7 [+ G1 s  o: c; D, I
int InitStack(Stack &S)0 f9 l# m$ p. B% {' o
{% A+ Q1 y+ l$ `! {# [
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+ d3 Y. S; W7 e- C% {9 o    if(S.base==NULL)
1 ~3 q1 M6 B# w' P    {) G9 [6 c) M1 K' L$ j3 S# Y& S
        printf("动态分配内存失败!");
) n& U5 \2 x, H' S4 e        return -1;% `2 z3 N% c6 N) b# q, L) k
    }; U+ A; P; N& R/ Q! B
    S.top=S.base;
2 S6 G+ p; Z" B    S.size=STACK_SIZE;5 u9 J# ?7 ]' o- t# S7 l: ]: X
    return 0;
! x. @0 m+ ]# f/ M, u}; [6 t! j5 s! m' R6 S2 a- `$ h; h
- r4 Q! E" D6 |3 R4 u; z! H
int DestroyStack(Stack &S)* k% o$ a& B- U( N" g
{
( Z5 {2 j5 w, {" ]$ C    free(S.base);1 g; v4 b5 ]* O: v! V" _2 j/ Z- Y
    return 0;7 U# t  i8 d) Q2 T6 [
}7 u; M( D- w" g5 ]' ?6 B6 i
8 t/ Z* w7 i$ G" j4 M0 e9 z
int ClearStack(Stack &S)
1 I# ~7 s, M( V, }4 R- W, R* G{7 n' G4 l- a. R! w
    S.top=S.base;
6 Q0 y2 Q" W" @3 e    return 0;, l* {% Y1 G2 v. p8 a& }8 S3 ~; o6 Q& ]
}
- M2 |9 {( J, M& X$ E7 v
5 U. C8 n0 Q8 F) p# D, ^int GetTop(Stack S,SNode &e): j' y6 y, o5 k
{
+ k7 {. `2 J  r9 M' }) ^    if(S.top==S.base)
' a- o- P8 A* U" y( ^3 K' i    {
* ?+ I7 }4 M% I7 @7 {        printf("栈以为空!");. D. V3 ]! p' p' w) Q6 O; }0 h
        return -1;7 }* \) b* O# K& W$ w, b& {+ H
    }  [8 ~+ v7 u# K, t
    e=*(S.top-1);
% L* M$ |+ X/ d    return 0;
* }- T' H. v9 e7 ]* P}) z' t( ]" \# {, D
! v) A1 ~4 _; T" B
int Push(Stack &S,SNode e)8 D7 T! y: a$ I5 j. h( ?
{
0 F* M  W: v) E; p/ U    if(S.top-S.base>=S.size)5 ]+ {& {8 e( m& R. {0 G2 @
    {7 H  K, ?: |: L
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));$ ]$ U! `4 g3 n- B( E
        if(S.base==NULL)0 V4 G2 J7 ?5 r( ~1 ^; e$ t  n
        {
# s" `4 T" ?8 H9 ^4 H7 q            printf("动态分配内存失败!");3 m# ^( `$ [5 u! k8 q2 k- L
            return -1;# ?" w" W" l3 w5 `0 y6 k% a
        }
$ ]9 W- n+ c2 G        S.top=S.base+S.size;% L2 X8 r: b. A' ^& O6 C! E
        S.size+=APPEND_SIZE;1 h4 U% l+ c5 J" s! T1 q; n7 n
    }$ h$ l! w/ l# \
    *S.top=e;% D# `% f: ?9 r
    S.top++;
- y9 I0 ~6 e/ e1 r9 q# U    return 0;
+ l: g" W6 P4 u}
9 V3 x0 ~( ~# ?' U2 [: ?4 H
6 I) Q$ r# f$ `# |int Pop(Stack &S,SNode &e)
( R4 l7 C, ?  L, O( T{
! ?* l/ g( ~# r  O    if(S.top==S.base)/ X! }6 a/ V+ V+ p, S
    {/ y6 R) ^; b/ e* T
        printf("栈为空!");& n) c5 ~# D5 G% y" A/ _
        return -1;
, G  X$ w5 {! o2 H2 d* {    }
1 @4 O* U7 [( C3 y* ~; O* A    e=*(S.top-1);1 L( f, u1 A0 S/ t
    S.top--;
( ]* d( ]6 y$ r% E1 e8 Z2 }+ A    return 0;
9 U! O% p1 S3 Y) y+ M0 n}5 t4 _+ X( E; T& q+ t0 f* O

, j. [$ E, E2 U3 a* }5 P" {char get_precede(char s,char c)1 b5 B* O7 J. ^% g! V4 J
{
* ]* x& k/ s$ X! J    switch(s)6 F( Z" u9 r4 }  b1 C
    {
0 a2 E" n- I# v- u9 T6 Z9 L        case '+':                 
0 j  M1 i7 K# F) K6 L        case '-':! y! R- Y! R% ^( w
             if(c=='+'||c=='-')
) z& |$ {5 U. Z% v0 m- q' Y                 return '>';
& w* R0 a9 F9 x/ \3 O) _: o             else if(c=='*'||c=='/')
% K: K. T+ z2 Z( r4 K                 return '<';1 r  P4 [/ U3 s+ K" P
             else if(c=='(')
" G1 }' D/ H" U                 return '<';
% C# n  y+ P3 z             else if(c==')')4 h$ A' B: b0 |0 w1 n  b+ z
                 return '>';
4 [! m! k$ M. H$ ?( c0 z* U             else 7 I/ G* B: f( u1 a2 b
                 return '>';
# O4 J; i; D: z3 x        case '*':
# p; \2 C' m% G' M4 [4 L6 J8 g+ N. n& ?        case '/':' k1 ^7 ~% K- h$ x; u
             if(c=='+'||c=='-')6 w4 d7 b/ j. v5 X
                 return '>';  B; d& B; ~1 I+ I
             else if(c=='*'||c=='/')4 Y8 s9 l, X0 O: M0 E- q2 s* V
                 return '>';$ D& d* _3 }; p+ d
             else if(c=='(')8 k8 g( W4 s& z0 B5 X" `: O
                 return '<';
' Z! {: s9 Z6 e2 k+ j* V  X! D- T             else if(c==')')
- ^( ]6 O" U- \9 |, _                 return '>';
2 V9 F( l. C" t. a0 e             else+ m; `- F6 f$ ]
                 return '>';( ~" K, M+ P# K6 g1 B& _
        case '(':5 E! }  N, b2 s9 P' \* a
             if(c=='+'||c=='-'). F; K/ I/ V. }0 t
                 return '<';
2 L+ H2 P6 B. p7 _0 z7 J6 c             else if(c=='*'||c=='/')0 P% R# o7 y( p' v- I+ E9 x! U
                 return '<';
1 u# G$ {$ n9 h8 G2 d2 }# W             else if(c=='(')9 H, N4 o; s8 k
                 return '<';3 G7 T, T5 M/ q; ^* ~7 M: n
             else if(c==')')
9 a8 c- N' y# o7 _& o3 r                 return '=';5 k" b( C* y1 @/ L& M7 D! `' {% C
             else
& }  i$ W$ t2 B9 P/ ?, r                 return 'E';( Q6 m; T4 s& A; r- R
        case ')':
% @8 o: |4 N, o  V             if(c=='+'||c=='-')& h' x# h7 Q+ p6 ~1 u/ _8 E. E
                 return '>';1 L3 ^: W4 r4 {8 I$ }2 Q( M
             else if(c=='*'||c=='/')
, K. [; M& P& H# G                 return '>';
" a2 e- ~$ Y$ g             else if(c=='(')
3 V! }8 l& R& o( M% u2 {                 return 'E';% p8 K0 Z: ^3 g4 b
             else if(c==')')
" `2 f- P2 k) a8 Z+ A                 return '>';
! h) X- Q( i4 R& J! c6 `% X0 j) M             else' A2 W( C. W3 s$ o/ U
                 return '>';! \8 q+ ^* v7 Q2 ~8 u: c9 T( v5 w
        case '#':8 Q+ p) e+ N( j+ w* e$ a
             if(c=='+'||c=='-')0 c- t& t6 j% B# Q
                 return '<';
2 H3 \( Z  M% t             else if(c=='*'||c=='/')
0 h) }' j: B- e0 M                 return '<';) T/ f5 G: |; J0 @
             else if(c=='(')
# H0 Q' o9 t. z                 return '<';) Z) v. V3 H+ P: \9 U% Z. }& y
             else if(c==')')
9 ]& S8 `* Z! W: W% j                 return 'E';% Z# f4 {2 A& y0 y8 U# A! p+ T
             else
- y6 A+ ~. U4 [0 G; O/ r                 return '=';- F1 V# f! T% W
        default:: \: V7 V9 l  {; d; v9 M5 V- g
             break;
' H1 L) Y9 f, v3 S0 E- W    }
8 }+ W( k' ?' B. A/ x8 y    return 0;      x5 Z7 ^1 B7 G9 ^
}
6 F2 L3 O, B  F, y
- t7 T9 i* T" S6 ]int isOpr(char c)
8 A/ v% X! R- t, z" ]( y8 k{
! ~6 {2 d0 T0 j" L* W, ^    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')# r8 o& G9 Q# k9 \. I) C
        return 0;/ r' D7 [" T+ b& F  x: B
    else % s5 P) |% I# D! V9 B8 m
        return 1;; Z  \$ I  z& x) C
}/ r+ N7 w( O! B. L% P: X
$ i5 K# V0 E9 M& g
float operate(float x, char opr, float y)! f6 e: ?* q# p: i
{
1 Q" K' y0 g0 Q" V2 T# r    float result;5 \, m: N* S3 B* T+ p9 w1 `3 s
    switch (opr)' U2 p5 O" n3 t; y9 X1 I6 g( |
    {. a( |, o0 a* @( j
        case '+':
. E+ k* ]' i: _5 T. F3 \' t+ W             result = x + y;
! K$ ?* f- L5 @* m. z( k; k             break;+ C& T8 n1 W( A0 r6 e! C! q
        case '-': 4 J! M! \" M; B
             result = x - y;( {5 ?/ n' i0 }* Y% }0 z
             break;
0 P# ^9 k3 c7 y! `1 _        case '*': & p- S+ N# b8 ~) J$ B& ^
             result = x * y;, p4 E5 H: w  E7 i& W1 n
             break;$ g& t- O! k! E; i5 q$ J  ~( `
        case '/': / S  F1 G6 s; K, [
             if (y == 0)
+ v/ p+ P, L( v9 V! i: Z2 A# o! U             {
' N2 b& P/ B! ?* |/ w6 T                printf("Divided by zero!\n");
2 n2 A8 f4 I5 V9 _                return 0;0 w) Q; O  ]9 h8 u( h" g! u
             }, {: \) G/ g+ x% D  b+ |& e
             else
) d3 J9 k# p1 U. q" A! M: ^: i             {: c. `* p8 _; G1 O
                 result = x / y;1 p; u, |3 F0 L6 w
                 break;6 e6 K( w, Y* R1 X
             }
. G& ]- {; |1 B6 _  M' C       default:
8 ?  b5 g& z$ z1 `1 H) g) A% }: M             printf("Bad Input.\n"); ' Q9 h& X" U& F
             return 0;% ?! w' ^* u7 ^
    }) K. o* _% F! e
    return result;# I' L; I5 N# N& V7 Q  s. ^+ t
}   
; d9 T* j& o; ^" P
. S+ b1 X  s$ I. Rfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/$ B+ V" ?* ?( r" J3 ?
{. `& }- j, p( g6 @* h
    Stack optr,opnd;4 l- b  j) M3 f4 ]9 V/ A
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$ x9 e" }* Q6 e) n, m' w: G
    char c;' R* N1 O: Z- Y: A
    char buf[16];
7 i& g" ~, w/ k- L" X" @    int i=0;* Z( l) W6 ~/ ?
    # E3 ]" D% Y) |! I/ n3 ~
    InitStack(optr); /*用于寄存运算符*/
' @9 V4 L5 {9 D" A! e    InitStack(opnd); /*用于寄存操作数和计算结果*/+ y/ b% m" l0 O
    memset(buf,0,sizeof(buf));
2 T5 R- `8 l8 A3 r1 s  p   
* ?' T7 f6 i+ l    printf("Enter your expression:");: V4 h  j. s8 _* [' P( F
        
/ Z0 F2 s* x7 \, w4 B% i! e    opr_in.ch='#';
/ n' j: {/ l7 M6 s! Q    Push(optr,opr_in); /*'#'入栈*/
+ p5 j2 Z7 e+ U6 Y  N    GetTop(optr,opr_top);5 ]' t. P0 E& _* d% T
    c=getchar();( f6 I# V2 ]( T' x. u
    while(c!='='||opr_top.ch!='#')
  M6 t0 s$ d7 S9 ~7 h% O  T1 e+ H    {- q- ], v/ v; ]- m+ |: [( n
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/: i$ L' Q' k2 g
        {/ U2 o8 X9 {2 V  R
            buf=c;
0 m% n0 \7 {) T1 B% ?& W. s            i++;
8 i+ W% a* `9 B. G. b+ E" s2 g! L( {+ Y            c=getchar();) \( \- c! y6 {8 o2 g/ c) U- _* a
        }
( ?- [+ A2 N( E5 q        else /*是运算符*/1 H2 [8 _4 h7 K" M) z- Q: \
        {. f+ c* i3 Y2 l# T
            buf='\0';7 c/ l$ H# x; z1 L9 f
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
; {" a" P/ B( s2 @8 S6 a            {1 ?$ l, Y/ |- T* A4 y) ~' `8 P
                 opn_in.data=(float)atof(buf);
* H7 M$ p/ q4 E4 l                 Push(opnd,opn_in);5 J6 n  ^, p# g+ N& e" q! o
                 printf("opnd入栈:[%f]\n",opn_in.data);
: @3 o; b% R& k+ T5 E! M  N! D                 i=0;. p0 l! F/ D( Q. x9 x9 J% ~
                 memset(buf,0,sizeof(buf));' [1 A, F: [8 \4 m7 E
            }
+ T7 S. I% f8 k7 c7 p5 Z6 m: c2 J, p            opr_in.ch=c;2 ~8 U8 `. @8 _1 Z6 S6 q, C" x
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
$ u2 m; Y4 T) J& j! g% a8 W4 @( J            {
; B  D: [. i) D( F' i, n* b1 `                case '<': /*优先级小于栈顶结点,则运算符入栈*/
4 R5 D/ T9 U# B2 V7 B6 Y                     Push(optr,opr_in);
: I  M4 ~" y& s1 W                     printf("optr入栈:[%c]\n",opr_in.ch);
6 ~8 H: i' w& W0 z5 Y& W                     c=getchar();
) @  g" ^9 q- P' N1 W) f" t+ H                     break;
+ }7 U) q# |" V( n( R7 b8 v                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
/ g" K# \# u7 X1 K                     Pop(optr,e);
. U# T$ A  P* [" g( m7 W                     printf("optr出栈:去掉括号\n");
, \: z  H. w3 b- X" N. O& ^                     c=getchar();
- U/ o/ B3 i7 X                     break;# y+ }' \  d. W" ^
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/- x4 d2 n1 J  o( O. E! d$ ?0 t. p
                     Pop(optr,opr_t);% }& D/ h- l& T0 J7 K1 \
                     printf("optr出栈:[%c]\n",opr_t.ch);
! ^# l: n' a" L' W: S/ Q: d                     if(Pop(opnd,b)<0)
* u! k) {. ~8 p7 e4 r                     {; j. V: H, J, ?; p# z2 s
                         printf("Bad Input!\n");
; K4 a  e6 P3 C% H; t                         fflush(stdin);" H) r# l% J0 }6 m, x4 G" Y+ G
                         return -1;6 r8 D2 {2 o  W9 r* o; I, I
                     }4 W4 r. Y5 D  r, j9 c
                     printf("opnd出栈:[%f]\n",b.data);: `" P5 u2 x9 |3 L0 |6 |$ U; p1 k+ r7 @
                     if(Pop(opnd,a)<0)! N+ \2 W  D# T
                     {9 {6 `" e# b, J. c/ l0 h
                         printf("Bad Input!\n");1 W9 j% Z' L+ D* e- W% r; D1 Z+ Y
                         fflush(stdin);* v3 O4 ]2 r: p0 e7 T* B
                         return -1;
& m* s: F: ~1 t, @8 B                     }' G& o9 L) r' M; m7 \& G/ U9 |
                     printf("opnd出栈:[%f]\n",a.data);2 i+ `( i1 L9 y% T
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
* Y. `& T' ]6 U                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
) A* Y& O6 u3 C. U  g3 g+ _$ A+ c                     printf("结果入栈:[%f]\n",opn_tmp.data);0 w( ~7 |: B3 z8 v( k
                     break;) f2 x8 a: e* z" }' N( V" M7 y
            }
/ g- P% J% u0 Y' u        }# J/ d: y  r7 t
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                8 |5 t$ {" b9 i% ?8 F; a& U
    }; k' F) i% a2 [% I4 f9 w' b
    GetTop(opnd,opn_tmp);, F4 U; |4 `. v+ U! P( ^  D2 Q0 b
    DestroyStack(optr);
* C4 A4 j: E" F. E    DestroyStack(opnd);
) V7 Z0 h% V( Q# v+ J( P$ c    return opn_tmp.data;6 R8 z$ i" q* j- C; g, O
}" y4 g/ q  \  u! O9 U# T

% m" }; D5 k5 Pchar *killzero(char *res,float result)6 o  D$ }% s. r# s, J2 Q6 p/ f$ F2 t
{' G) j5 S+ O+ b9 d
    int i;$ `; u' F( ^0 T5 }3 Q: U
8 k; j4 S8 h/ d) M+ T
    sprintf(res,"%f",result);$ Q- `+ Z6 J+ C- b) Y3 u
    i=(int)strlen(res)-1;9 \! A' N* h& {
    while(i&&res=='0')
: k# C  S8 g7 ^/ h) L    {
7 t9 D3 x4 v$ I( D- u        res='\0';# K0 U7 M" C) ^! @5 e1 J9 Z9 [
        i--;
8 ?( b' s; r! ~. y7 k6 w    }
; z1 m* k; w, C2 M    if(res=='.')
; x9 v! m4 C$ }5 R        res='\0';
1 k  ^# e/ v3 R    return res;
, k- k& o; ~9 r/ |6 t: D( g}
8 H! `# g& m2 r, j
0 k% i" S/ |( \) E3 [% K5 Mint main()& `. {! d: o/ W8 @# _
{
" T  k) v' p6 b; P) P7 K, t    char ch;
% {* a3 V$ a5 q4 r' b( S+ t    char res[64];" |/ a) M" r3 J7 Z( f
    float result;
2 B6 v! ~3 a2 J% X5 t* @    while(1)
6 z, V# @( \! X* T% ?    {
! a# S+ F5 }2 z% a  F! G# N. \+ ~        result=compute();! x% k8 I4 c, z, T; Y
        printf("\nThe result is:%s\n",killzero(res,result));- D" A, R3 M; ^/ P( Q
        printf("Do you want to continue(y/n)?:") ;
) {( Q3 O8 D1 ?        ch=getch();- J% B. L# f' }# a2 _0 W8 X* n# }# I# d
        putchar(ch);
+ M, M) W' B3 x        if(ch=='n'||ch=='N')
7 j/ ]" v, {5 L: K' C            break;) b4 z; U! _+ [! H  ^5 P
        else% f" R, Y* y$ M% U4 w" S5 X# U
            system("cls");' R* _9 r  u6 J( }6 s/ |
    }/ K/ X; S: m7 L' O% M
    return 0;
0 M. ?* l7 o- w7 z0 `; r5 N: H}

, [1 k+ A2 `) d6 \, a  y0 o) }# p+ Y2 S
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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