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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5 j( w& }5 ]. ~* g5 ]# `) W3 r$ u/ y% Z程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
) Z/ ]* \; ?% J$ g2 Z+ M. u! l/**************表达式计算器************/
5 }% v0 P4 [1 M#include <stdio.h>5 N# U9 p0 n' S7 q3 b/ p
#include <stdlib.h>, j: N. X* Q+ J
#include <string.h>
. H4 w: B  [+ A) `1 `- v* q#include <conio.h>
8 g% R# L" b9 b1 m& D#include <malloc.h>
( q4 o- H3 f1 w$ q% I0 ~+ b, \+ |& V6 U
#define STACK_SIZE 100: _8 A# c. |, X; [3 {, c& W3 B
#define APPEND_SIZE 10
) L) q6 Y1 t2 Z3 D% m* d1 H4 z( P( x( y0 C7 a, F8 @
struct SNode{$ `$ A; ^/ Y" _/ g# `6 O
    float data; /*存放操作数或者计算结果*/
9 [3 P2 c# B$ o0 S. ~    char ch; /*存放运算符*/
" ]6 F9 S, @. y/ h- D0 o};7 X* Y! h9 m$ X& u' t

# ~  x- t% \/ T( q2 l! S$ Hstruct Stack{
6 k3 P- e/ t0 z3 d, Z    SNode *top;4 ~: Z5 ?( l1 r/ r: l2 N
    SNode *base;
) t' o% k/ m% G5 N# ]1 Y" g: J8 I; t    int size;
7 x+ Q2 x: v/ Z$ F, Z3 r. {};
/ W! h  L5 }- x
0 U1 G9 P2 ]1 F% J% j5 f% V/ e/*栈操作函数*/* H- I0 c3 Q4 i! L8 o& ^
int InitStack(Stack &S); /*创建栈*/
3 E. k( J! j* ?, w' uint DestroyStack(Stack &S); /*销毁栈*/
/ E# K0 K7 K3 \0 F3 p' `; yint ClearStack(Stack &S); /*清空栈*/
: V# c& D( P  G; t0 t. j/ aint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
7 I# I7 _1 y9 Z( t8 bint Push(Stack &S,SNode e); /*将结点e压入栈*/
: z. M9 e: U4 N( i) B0 O3 ^int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/% P/ d. a" Y) g. O! Q( I! W3 b

4 e* B+ P# s5 B) ^! r! X4 _/*表达式计算器相关函数*/
& q+ o# O7 e, ichar get_precede(char s,char c); /*判断运算符s和c的优先级*/
% o! g' H0 d6 I3 A! t1 w! uint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
; E) A- Y( r! V" f/ [/ f( Z% y) Tfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/* D4 @1 P4 o" }  N3 e: K
float compute(); /*表达式结算器主函数*/
5 u! o0 k3 v, @- x* W0 z1 o- W7 ~/ hchar *killzero(float result); /*去掉结果后面的0*/ 9 i8 d( a5 b, C* y
1 [, U' @/ y' G# {6 X8 c1 q
int InitStack(Stack &S)% |8 i# o0 {$ P* n, ~
{8 h" ^0 c, w$ @6 o2 J. I0 ~6 ^
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
% t$ p- u4 J3 B: i    if(S.base==NULL)0 ^% d  U& X: t
    {
+ _' y/ b) L# u        printf("动态分配内存失败!");6 \8 p& h0 W. ^  a- d
        return -1;
8 o" k- p+ {0 ]- o. N  O' v4 H    }
& c9 R% X$ @( \* v. @$ E! R    S.top=S.base;
6 I2 W0 V7 i! W' ?    S.size=STACK_SIZE;
, Z6 p: b# q* B  F- m0 E    return 0;, W. X4 |2 q3 t; \! ?! l
}5 k7 I0 Y& s% \2 V0 j0 V

! h3 S0 J1 _0 e0 N% ^int DestroyStack(Stack &S)
* x0 g& S' w: \' Y4 D{
0 S  n) X. i9 @    free(S.base);, h2 Y$ B0 z1 a. ?- A0 F
    return 0;# T. m' `/ X: ]
}
' m$ M( f- c% e3 L& d7 j
% D( e) @. O( q" Lint ClearStack(Stack &S)& W$ z. r: m' m: W" E+ L( |$ Z# N
{
6 J3 n, e) L1 U1 V3 ^% l    S.top=S.base;' i" N  u7 b- ]2 \5 }1 Q6 o- ?$ v
    return 0;
0 @. J7 f( ^! y}$ K( z, F2 J* @3 f

, n  ?& V1 O9 q3 Sint GetTop(Stack S,SNode &e)( o) @6 ~- J# i& ~% [: a
{
4 m7 _8 x# ~# a    if(S.top==S.base)0 w$ n$ e: \! t% `5 \
    {3 z' k+ L  b) D, F4 @
        printf("栈以为空!");
1 c7 \& @8 a5 w% p        return -1;
8 x  [8 {/ z5 s! c    }
6 ]$ t  y  m- }$ C    e=*(S.top-1);' g( V8 R2 O2 N$ `* k6 q% W
    return 0;" G! b8 {0 h8 Q( |' O/ \
}- b' `! s8 E# [5 D5 @

! ~7 a# v; }& ?) c* a. @$ ?int Push(Stack &S,SNode e)
3 ^4 g) P5 \* u. N% H{
+ e" t: j5 J% J. f$ ^    if(S.top-S.base>=S.size)) G; P2 \; A  b: B% ~
    {- C, A. L: K/ W$ J
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
+ G0 i$ W" T" D/ `0 |9 ?        if(S.base==NULL)3 H( D3 |6 E1 ]
        {
8 p% Y9 i, H9 K( a5 ?; U/ R4 D            printf("动态分配内存失败!");3 D: Y- L! n2 D/ a
            return -1;/ f* Z. }& u; w0 _
        }3 W: ?: `& [7 ?; ?7 C3 W
        S.top=S.base+S.size;
7 k/ @' {3 [2 m$ y% N; g+ N" n# @1 ?' i        S.size+=APPEND_SIZE;
; V. G0 X7 Q2 J+ e' f. F! [2 @    }! B+ s1 n/ F2 \5 X/ D( [
    *S.top=e;
8 C1 A. m% ]" r2 p, s9 f5 r: V    S.top++;
$ B; j: n8 P& {$ [0 q  q+ C8 \" A) P    return 0;1 a7 Y8 |9 R5 r
}* _- z3 Y! y( d. d, S* I- Y6 {4 Y
5 T2 E, L7 }' e* r5 R: A" _! \
int Pop(Stack &S,SNode &e)7 V" B6 z9 n( O) e
{
2 D3 `  ^' @5 q: A( I    if(S.top==S.base)
$ H0 \+ A( c6 H+ D/ J6 H    {
% M. T, Q. z) X! J0 F        printf("栈为空!");
2 O3 f* Q7 `6 Y  v        return -1;; s' x6 ^: A" ^0 u& T8 H
    }. ^4 B6 q7 K) p  l
    e=*(S.top-1);" |  q8 W3 {4 D; h0 d3 m
    S.top--;% N9 O- U( K$ b1 Z! F: Q
    return 0;5 _# Z. y5 }$ i: J3 R  E
}
/ [' w- F; D# S+ [: N/ V4 o2 i9 Q( g) H$ E  i5 M
char get_precede(char s,char c)6 x: {: W: M& n( u4 y; v) D
{
9 \# E+ C$ i# Q/ O: N# A5 v    switch(s): A$ @7 ]* A8 j- Q5 t5 x
    {% E3 }, N3 {, H
        case '+':                 . `4 N9 j/ M) l) s
        case '-':
) A: A: ?% u) [$ N5 ]; d             if(c=='+'||c=='-')
* Y% u. R& {4 [; G  A/ R6 ]                 return '>';6 t' e2 z/ F  Y/ |
             else if(c=='*'||c=='/')
" i% V, v2 @& C0 ~                 return '<';
9 Q$ s, i6 g4 q8 }+ y             else if(c=='(')* k5 G4 A3 e: m; s
                 return '<';
+ V$ }7 j0 C& B! Y- C5 u2 P             else if(c==')')$ h5 x/ }! z( @* h- u
                 return '>';( B% O, w/ h1 r4 Y
             else
/ Q3 [- o7 d* M                 return '>';: \0 V. ]# D; U" U- ]
        case '*':
' I' P: O5 M- Z$ u$ A        case '/':$ E8 @8 O9 |7 w# A. ]+ U
             if(c=='+'||c=='-')" t7 g+ I$ }; u* }( @
                 return '>';& C5 D( h% I. C( p: p% r% }
             else if(c=='*'||c=='/')) Y: G' b6 k2 _
                 return '>';
$ }3 q" P* s+ ?1 N( R) Z7 ~             else if(c=='(')
8 R8 D$ L/ D  T. I6 J. `                 return '<';
: i4 c# K" A+ U# Q5 d0 I% o             else if(c==')')
% v) I( o5 M% }' O2 d                 return '>';) Q& E" C8 x: `
             else
! [9 z) v( p; y( s" s' R                 return '>';
# m/ ~) f$ H3 `        case '(':6 Z# x' q" ]( ]  @0 l, M& G  e
             if(c=='+'||c=='-')0 X; ~* h" O  N6 d
                 return '<';/ e8 D; z$ l- F- h4 g
             else if(c=='*'||c=='/')  B/ ~. G. x. c- `& J) J  f1 O
                 return '<';) Q+ G: r0 }; k6 [2 ?
             else if(c=='(')
# e5 `; P; H, G4 g; [8 H                 return '<';
- f7 p* k( J. A0 p: T" R8 i" ?             else if(c==')')4 h5 g( b; d: w; A# p) C( Z0 v
                 return '=';
3 z' Y# A4 w# K9 n6 |, O! ^             else
$ |- m" i$ f* m  {                 return 'E';2 v8 H0 q0 I, f
        case ')':
/ E: n: j7 T$ d  B: R4 L' Q; |             if(c=='+'||c=='-')
0 I' [0 _; d4 p# S1 h                 return '>';
4 _  V: ]7 k: J! B# z+ b  e             else if(c=='*'||c=='/'); A* `. C3 Y# s: ~- p
                 return '>';) w2 M9 |1 U. R$ n1 n
             else if(c=='(')
+ x% t7 y- L& h4 e6 i4 n8 Q. ?" U                 return 'E';
: Q3 B5 n- L& g: w4 h' D5 P             else if(c==')')6 t' H2 L# F, _' _
                 return '>';% A: ~2 o$ J# G+ A: D' E2 l" v% Z, i
             else
) P* d% F4 W% n( ?/ k                 return '>';2 c6 F, E+ y& F# [# \
        case '#':
# G- g( `8 |  j$ C# _3 x* l) {             if(c=='+'||c=='-')
" a! g, m3 r- ^; f% M1 L+ k$ S5 O                 return '<';7 }7 \: M* n9 P: P5 W7 Y
             else if(c=='*'||c=='/')
% _/ f# ^% R0 b& e1 X* H                 return '<';
2 H- @" {1 ]7 w4 O0 c( Q5 m9 v1 }             else if(c=='(')
+ f" q" q5 ]0 {1 f4 \% K( Q                 return '<';$ o0 q/ f0 s6 t& _- y6 |
             else if(c==')'): z8 r# P0 ^7 J( \/ F0 s
                 return 'E';$ z. H5 o- Y5 q6 K
             else1 e! i  w$ q+ g, N6 ]+ @' W
                 return '=';, Q9 J9 E' i/ u+ Y, T* j
        default:% k" ^9 Y; E* I  J, i# ~
             break;
" A0 x) L% T  A$ `' e8 I4 a    }8 E5 ^/ q; A2 I5 U
    return 0;    , X. K6 F: e9 e
}( G/ t, J5 t0 v+ I5 M4 R

# v' h/ a/ D- ~1 Kint isOpr(char c)( {0 f( e5 Q- z2 r! s
{
7 }+ i5 G8 i% n# K- p# y9 z    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
: r, v' h2 C1 M/ Y  ^2 I% J8 o        return 0;
. H" R/ p# X) W8 m    else
# O3 n& z) b) H% t) g3 L3 n        return 1;2 N1 W8 H( Z9 y  l$ l
}
5 @4 G) b, X8 O. i" {& s
4 X* q, A4 [9 |/ X% q6 ]float operate(float x, char opr, float y)
1 `6 w& |7 h  C! g{
" ?8 g9 ?) o( v2 }- Y. {/ `    float result;. m' c3 o8 W4 r7 f8 N* D8 Z
    switch (opr)$ I2 x+ R# V: D0 }# M( @7 Z0 I
    {
6 k6 e( h3 G- X; V6 N        case '+':
8 H5 p7 v7 B3 c1 C* Y  d             result = x + y;
( `( [4 z+ k- @: D) j/ T) [             break;
; Q# w4 f" Q: B  S( A" J        case '-': " p. x# w, H  X5 U9 ?& E: {
             result = x - y;
$ ~1 p$ [, Y. D% Q- k1 b6 G( l. t1 F             break;! g% J" H$ p) Q; q2 R9 k( g3 f
        case '*':   p) p( ~; X+ O* p3 Q
             result = x * y;: ?/ O# z4 ~8 ^
             break;7 Z, q8 g+ l8 L1 ?7 B
        case '/':
& m- G" z* p$ p/ y             if (y == 0)* B- E4 O3 Q7 I( P7 B
             {: `4 x. a9 _  J4 n( s1 N! b4 ^- I
                printf("Divided by zero!\n");
" ~+ M7 ~0 P4 ^' {9 U5 b& E                return 0;! i. T& f8 _3 _' k* k* |4 V, m
             }
; r' m9 w" a: s. }2 \             else
0 e1 F# a2 P/ G* c/ J             {
2 W% d$ O& W. H& [3 S4 r" Q                 result = x / y;- r, D% I  T" W% }
                 break;
  T# s9 Y- `( G) \" G  h* b# p1 Q% E* @  J             }
1 e# _- R" L7 [# k" q/ E$ O       default: ) d: L# C/ G8 d( e" v; y
             printf("Bad Input.\n");
+ Q) M: R) u. F3 _5 U# z             return 0;/ a; G; [4 z0 ~% b( R3 g1 }
    }
" V% t6 R. s. B8 N& C- p! [& i    return result;" v6 K5 p9 W0 D- }; }! l
}    0 m7 p& Z1 ?2 K+ A( Q& I

+ n' E* y/ Q) qfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/9 |0 f9 s$ C  j
{8 E1 C# G- ~, w
    Stack optr,opnd;# s7 B/ B  r' Q& {$ D/ ~$ g; ~
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
) U( {( o% E* p% B% q    char c;& }# R+ {5 y; g8 I, Z- N% N
    char buf[16];$ U! X: g5 x8 [2 D2 c
    int i=0;
2 k$ A4 G3 c8 k! L( g& J   
7 \( S: a- a# t- a, ]: Y    InitStack(optr); /*用于寄存运算符*/) _5 r( |7 N. n7 V/ q% P5 w: D
    InitStack(opnd); /*用于寄存操作数和计算结果*// Q, z! E9 p( x$ q4 Z6 S7 f7 Q
    memset(buf,0,sizeof(buf));
( s  B5 g/ n! [' w/ k   
9 p! A% A2 E  V& X8 E% h6 s    printf("Enter your expression:");
3 c, |% h4 X) O# W3 Q4 ~) @        
% ?: W4 T* q/ K7 x1 J- B. [/ U0 U    opr_in.ch='#';
8 z  D$ h+ {& z/ F8 b1 w    Push(optr,opr_in); /*'#'入栈*/
5 M4 x0 r% m9 Y# X    GetTop(optr,opr_top);
8 i' M! m6 J' p+ C: p    c=getchar();
& ]5 i, r: }' O6 J! K- t' v: d0 j    while(c!='='||opr_top.ch!='#')# y9 U! x8 L- y6 [# S8 Q8 ?) ]) F
    {
: V" {8 \6 O& T. C2 s3 D: S; r        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/! W4 [/ I& `4 z2 v" B+ Y" P, {
        {% W+ S# X- ]/ [
            buf=c;
: A* D: E- E+ ?! W7 y            i++;
# P. w7 A& d7 j' N5 l            c=getchar();7 x( M: e1 o2 f) |6 U, g  u9 p
        }
) U* w, y8 [! M: z# {        else /*是运算符*/% B) g1 y# A2 V3 y" \
        {' V. v( T, D1 q2 |2 a! f
            buf='\0';4 r9 S2 Q5 w# m( Y) l; k
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0 S9 m# k+ t* H) ?. t
            {  j+ c, R9 F; A# e# b: w
                 opn_in.data=(float)atof(buf);3 w) C: K' I3 p; x; ^8 o, |
                 Push(opnd,opn_in);# H; \. f1 J( u+ C6 y
                 printf("opnd入栈:[%f]\n",opn_in.data);
2 T; E5 l0 m2 {                 i=0;
& y# `! N& m, _9 z- T5 ?3 A, l                 memset(buf,0,sizeof(buf));) k- Q% ^: N' x( Y4 R
            }
' b7 D8 J! D; V+ ?, z( u8 z0 Q* w            opr_in.ch=c;
% l; n1 K) T+ Q. O, i1 C8 N& ?            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
% |( U: a9 \+ t3 n            {
7 u3 q/ H2 `) ~; x                case '<': /*优先级小于栈顶结点,则运算符入栈*/$ y; n2 l+ g4 [  {! E& T1 D
                     Push(optr,opr_in);
6 G- o( ]- [6 ^, ]                     printf("optr入栈:[%c]\n",opr_in.ch);- c; r! ]# F0 ^" `
                     c=getchar();
% |* a& Q, L7 e1 p7 \, C                     break;
; ^+ f7 R. P0 f0 k+ o( X' u                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/0 L( l4 E  V. o0 {9 h
                     Pop(optr,e);
! W" m8 q& P4 N3 g                     printf("optr出栈:去掉括号\n");
9 B1 w$ X7 q. n8 Z9 ]                     c=getchar();1 U. j2 [  W6 l( i! V) a
                     break;& T+ L2 C6 G# I" [) {- h. D
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/  K1 y; Q8 S' G% u5 N1 Z
                     Pop(optr,opr_t);- C* r$ a; ~2 D0 [* h- f( h& Y# n( I
                     printf("optr出栈:[%c]\n",opr_t.ch);1 ~  G% B) j) n: Q
                     if(Pop(opnd,b)<0)
/ _& k% W1 ^8 ^, L3 n                     {' e2 h% L4 B0 K5 o6 }
                         printf("Bad Input!\n");
8 Z9 D  Y0 P3 {                         fflush(stdin);
6 _2 M6 [/ n4 v/ p, D) I" d( S                         return -1;  ^0 E  Q+ S, r" E* }5 m
                     }
5 g3 T# N6 K$ J2 D& Q& |                     printf("opnd出栈:[%f]\n",b.data);
* h4 K8 V; a- W/ L8 G* Q                     if(Pop(opnd,a)<0)
: f9 w0 |9 s2 B. P* V6 H& D                     {, |" V8 J& b, n( g- G$ U( |5 i# A
                         printf("Bad Input!\n");8 {( ]- i7 r5 w9 I
                         fflush(stdin);0 g& e" S) M, s& q7 N  C7 H
                         return -1;
$ S; N# i0 @! m                     }1 @8 C: {/ _' H5 E# R) f
                     printf("opnd出栈:[%f]\n",a.data);$ n- j+ O. ?1 @# M- M: ?
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*// B! L1 [! c8 d4 o1 T0 u2 n
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/: o$ z: s, C/ O; g( Q5 j2 q4 Y
                     printf("结果入栈:[%f]\n",opn_tmp.data);) O5 i5 A1 O* f6 Z0 {
                     break;  c7 E) X/ x8 b
            }
/ _$ ]2 i( K3 `; Q$ D, ~        }4 ?) U0 c; n0 g
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ( X2 Y5 A) r  Z* ?- G
    }- p  E# W6 \2 Y1 R  U8 s* t
    GetTop(opnd,opn_tmp);
0 @/ d: a+ P$ |0 }6 {7 Q: }1 {1 [    DestroyStack(optr);$ c8 V7 x+ _' D! j
    DestroyStack(opnd);
! n3 S" N4 @/ [: @: l1 {    return opn_tmp.data;$ |% k! v. F; d$ S
}
2 d" B$ l  @0 M& M5 _7 D& R4 P
% @3 J1 A$ a0 ~6 z6 k! fchar *killzero(char *res,float result)0 S9 D0 U# ]( Q5 ?
{
0 |. `% s2 R1 x    int i;
" y" C# |9 z8 t9 P7 h) l; n8 Z2 P( S8 `/ J# U; y  R
    sprintf(res,"%f",result);
7 z: x- k) c6 c    i=(int)strlen(res)-1;
1 \& F; f5 L* p5 J) y* X3 m8 j    while(i&&res=='0')
7 @* ^) }3 F- W  V    {
5 ?/ n8 A/ U* d        res='\0';2 D& f* S( ^# j, Z2 l
        i--;
0 u/ E# }$ N4 Y    }0 h) l1 O7 T7 I  l( t- v5 Q  B. X+ s
    if(res=='.')# P+ f; Y+ M9 d# J) G7 j. w7 y3 y
        res='\0';& ~2 r" l3 R$ O: b( t: r
    return res;
4 \# _: R# i* }$ `6 r}
' |" F$ {% x! {4 t; j  U; L4 }  j8 u! h
/ t7 k0 r0 X9 _0 L% c: nint main(). m0 U$ Y  A0 R3 G$ L6 `1 ^. C4 a
{
) ^. l) r0 {/ X: G) ?, u    char ch;
& o, o0 R5 |2 ^4 e8 n6 B    char res[64];9 Y- d' r7 I/ L$ ]- A
    float result;
, p# r1 w# V% i  S3 i" j7 Z    while(1)
+ f7 e: H  d% ~' F    {4 }) m! T2 e' u7 J9 U
        result=compute();
* C! A- f$ a! D$ m' l1 y3 [4 ]        printf("\nThe result is:%s\n",killzero(res,result));
3 v5 y- v5 U' G        printf("Do you want to continue(y/n)?:") ;
9 U: H! H$ h# s9 B' i4 {        ch=getch();
9 ^3 k0 [6 x1 s        putchar(ch);
* w% k$ W: V# `" F7 u- l        if(ch=='n'||ch=='N')
3 `7 j7 X3 Z! Z, a) g& U+ E            break;
3 p2 r2 o, e- n; @, T. V; w6 c        else& y/ N; ~& I3 L. F! M# d' I' }
            system("cls");
' s/ r! Q! r! Z$ w& v% u% E6 D. y    }) P) {7 V% [0 n! f
    return 0;
, V) \& p  L  ]  a}

/ X2 b) d4 s4 a9 E
7 v( H- A9 ]: \5 E  K[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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