返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.* W- K  i' \+ P& c
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=- O* ]% T, K& f
/**************表达式计算器************/) d, |: p2 V& d% D4 l2 i6 V4 @& ~  d/ n
#include <stdio.h>! m7 e+ t$ q- H. E! k5 g; m
#include <stdlib.h>; o: [7 S; p3 ?: h: |
#include <string.h>* C! k: p' z) `
#include <conio.h>
+ x2 Y- J& z4 {  y  ]9 a#include <malloc.h>
! M/ Y& ^( J/ ~$ F- ^( e+ x1 N$ M3 q3 u
#define STACK_SIZE 1000 r7 W; S" k+ K. K
#define APPEND_SIZE 10) k/ B  p7 q  w+ s

& B  m$ m  [* N7 ostruct SNode{
  h+ R7 m/ g# Q    float data; /*存放操作数或者计算结果*/
* D/ W. w) F1 V; t' Q, O- Y2 s4 b    char ch; /*存放运算符*/
- ?0 c3 e$ I0 n8 N! [. {+ ~* P& I};- F# v2 d; a; y, x8 N
7 Z- a& a- s! N. s
struct Stack{! T) l5 R9 s* V7 g
    SNode *top;
7 @+ @+ u5 `& o    SNode *base;
2 y  j* C, ]8 f# Q3 R+ x! o    int size;
$ ~6 Z" p. J5 u, h* K  P# S- ]};, x" [8 o' k2 x+ f' _# e( l# o- T

1 p! K* {# L. y' S* I  C/*栈操作函数*/
5 o, E) R6 E9 Z9 Iint InitStack(Stack &S); /*创建栈*/
+ U% e' |& O( R* d& t1 `' Hint DestroyStack(Stack &S); /*销毁栈*// v/ O! W, v( C7 \+ f
int ClearStack(Stack &S); /*清空栈*/
& I6 ]2 j4 z- d4 S& U8 R% [int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
5 |! f  Q& n3 ~, K% w1 pint Push(Stack &S,SNode e); /*将结点e压入栈*/4 @; a. Q, S: |4 c7 V
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/  O9 c0 c4 f/ L7 E

  [$ o; ~" S* s6 }/ z; A4 u7 F0 W/*表达式计算器相关函数*/
# s. I( E) R7 ychar get_precede(char s,char c); /*判断运算符s和c的优先级*/
) ^$ }! ~# W& q4 C4 uint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
- y& ?9 F9 c$ E# ~# k+ P/ Nfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/, l& V( E; m& p$ Q
float compute(); /*表达式结算器主函数*/
, p3 F5 y( O$ V  f7 P) x" Uchar *killzero(float result); /*去掉结果后面的0*/
( G+ a) m1 x$ V; w1 \* x. j- g& ]( f- y3 W% @0 _4 Z
int InitStack(Stack &S)
- \& j" K. `# [{* {. p3 q6 ~; d0 }% X. s
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+ f- p: }8 X" g$ U! g
    if(S.base==NULL)9 n* q4 S) F' J5 A8 |
    {  q7 h" T+ q$ O) H/ M
        printf("动态分配内存失败!");; b  |$ l7 h+ j( X2 ?
        return -1;) j- H6 C& Y) P; K9 i+ ^
    }
; s- L9 A8 V$ y; w    S.top=S.base;
( ^  q- f* T; K' J6 `: C+ i) O+ \( j    S.size=STACK_SIZE;* x$ w+ A" W, y4 ^2 j3 k! l
    return 0;. o- z& o/ ?4 C; w
}: }) M3 W, P6 @) T/ v8 E9 G

6 h0 \! q/ n5 b) D- M$ F8 ?# y* x6 _int DestroyStack(Stack &S)5 J% u4 N' n: W0 b
{, V* d+ X1 w" W$ H/ `$ G( o4 n
    free(S.base);
" |, g+ a' g' a$ H4 n5 h    return 0;
& X. t0 O% l" V  D1 L6 u9 P4 B}
% A4 q$ R$ W3 L; N# A6 L' T0 \1 M; \% H7 q
int ClearStack(Stack &S)
7 S0 J0 f, L- _{
# ]. f. V/ C2 u' K6 F4 w( ^" f    S.top=S.base;
& b1 C! w. i# Z/ e1 d    return 0;
( l4 D( A2 F" n2 n! k. H3 t}
0 d: J$ @% w6 i: T( X# N4 D& a7 \
int GetTop(Stack S,SNode &e)
+ C# @" C3 ~+ l. B* |: I7 D{: U4 H! p4 \  j
    if(S.top==S.base); Q( M$ u: X; p4 H
    {9 {# s! n$ ^. j6 r% e- L+ p7 z2 |
        printf("栈以为空!");
( @: P/ S6 h2 Q        return -1;
' Q) h+ u1 C) Y    }
! m. t. z+ @5 B+ Q& l; D2 u' u# V    e=*(S.top-1);
( [* L5 }' F' o8 u% D/ [& B$ M    return 0;; A. P1 \* v+ O5 p% v: O
}
: E9 Q3 U! z; ~  c* @; I6 y- L$ ]( \2 Z/ Z
/ H4 C; u" \3 c& T! r8 qint Push(Stack &S,SNode e). K; A6 d; q& d- Y5 m
{
' X' j% k  t' O; D    if(S.top-S.base>=S.size)
- x) m- b, W6 n" j0 H6 N- X; R9 x    {
" y6 w1 o# t- W" |! A; q$ k( @% u        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));  C% o; c9 n# o4 p
        if(S.base==NULL)
/ K0 M+ Q! ~1 P1 K; v, G( T        {. V( \9 x( h) x2 f( s8 [/ {
            printf("动态分配内存失败!");
7 y$ |9 v8 d2 A9 }$ e8 V% t            return -1;* {7 r! O  u8 ?' U
        }9 D4 x- R+ b; T' w. `
        S.top=S.base+S.size;/ R# ?" N! R2 q, S" r
        S.size+=APPEND_SIZE;# ~' b! Y8 f- M
    }
( N4 }0 B" ~4 a- J- X6 I& Y$ {* R    *S.top=e;/ k! v; t0 L7 x2 m/ H
    S.top++;
/ A& Q2 s' N0 K7 ^    return 0;, d  o0 a* Z' U5 h) I
}
! P4 z8 K8 d( T7 u3 w+ m  w2 U2 G: m; K# y0 V" U
int Pop(Stack &S,SNode &e)
$ b. w) x- y) ?5 X{8 y  P3 A9 M" _2 }, w$ F
    if(S.top==S.base)3 |. N  ?9 h" z4 A2 b. |
    {# ?# g# b+ U( G0 r  L5 Q$ W
        printf("栈为空!");8 x  I; q5 i- D0 N8 x2 O& Y) U
        return -1;; Q" Y4 u) k. C5 t2 k3 ?" D
    }
; W, Z: x9 A1 p0 Y2 W4 R2 u5 O" x8 u    e=*(S.top-1);
" \  b+ G& k1 V. m- J    S.top--;
$ m- G; v# |% A( r8 j- ]) z( ?    return 0;
+ O8 Z. n; c0 `  m+ m' U0 `}
: t6 F7 j2 H9 A9 M0 M: w; m
  H3 n. U: w- z9 Ichar get_precede(char s,char c)7 k/ A2 X# T9 D3 S) E; b
{* j: _$ |9 O' h- B3 P9 x
    switch(s)
$ H' X0 |' t# X' q    {" R2 w$ ^7 v) H9 v' c1 k/ K% z" i; D  @
        case '+':                 4 W# n. X7 q" z8 b6 z/ d% K' B
        case '-':
% w, `% E0 U9 a9 F: c             if(c=='+'||c=='-')' P' q# M, Q. E" K& T( @
                 return '>';9 U- [0 @' T" G
             else if(c=='*'||c=='/')" v, Y- Y1 i. g7 Q
                 return '<';; s( b2 D$ E: \& r' Z0 A0 q
             else if(c=='(')6 u) m' `0 d* [9 q3 H) O
                 return '<';# J, M* r- ?" r
             else if(c==')')
4 J, o& h# f" W: T                 return '>';
5 Q3 S4 o6 a/ {8 d4 y2 G( i" j             else 1 _7 V* h1 `, h, _9 V
                 return '>';1 G; v, [1 w" a/ @, z! }- F
        case '*':& d9 t% l9 }& S, ~5 z
        case '/':
9 d3 L5 R$ r+ L/ V             if(c=='+'||c=='-')
: o' K, [* X+ A- @2 Y                 return '>';
9 M  M) o- K, e! b) C             else if(c=='*'||c=='/')5 i! x, ^1 X8 ]
                 return '>';3 i$ X$ r* j, w4 u
             else if(c=='(')- _& N$ A; y1 e
                 return '<';2 j9 v) m* h% ?, p7 ^; o
             else if(c==')')
4 J9 z& M4 Y6 n; X  b: m                 return '>';. P3 y+ I8 R5 k1 ?) p' g( ~% t. d
             else
; p: l' C4 c: G0 X2 c                 return '>';8 E5 c6 ~6 t1 ]; m2 ?5 R# c
        case '(':
( f5 p) w$ `( B9 T4 U' W4 \, n             if(c=='+'||c=='-')+ t: G' k* i/ ^8 [( _- s
                 return '<';0 M1 L0 i: Y* c+ Z8 S! v
             else if(c=='*'||c=='/')0 p2 ^9 i/ G/ l7 q; R: Z6 I8 r
                 return '<';+ e4 s1 @! H6 ~  m. o7 e! V
             else if(c=='(')
/ t9 ?* e- L7 H/ B3 `4 m) ]                 return '<';" Y) ^6 H5 |3 M* T. L
             else if(c==')')# q$ v- [% \: ]+ K" e# Q
                 return '=';
& ~2 P: |) K( d( y4 p$ S$ ?* t             else, _+ b' \- R2 d$ d
                 return 'E';
- S5 N, K% S2 R) d* L' ]) q. m$ l        case ')':
; B: l' f% k: s             if(c=='+'||c=='-')
, p! ]$ `8 A* P: V+ {, L" g                 return '>';
+ G8 {8 B! S$ o             else if(c=='*'||c=='/')9 c" B  A* R& r& o+ Y5 V
                 return '>';4 P/ w5 ^' J/ W+ y, L# {
             else if(c=='(')8 m, P, q3 [, @% O
                 return 'E';7 c* O% D4 _  o0 b( ]
             else if(c==')')3 t0 X$ Y- A" b3 H9 v
                 return '>';7 O6 K  O9 ?) Y" T7 o: l; a
             else
! x" F  u) G. G9 S* L# F- L                 return '>';
6 \( ~* T6 g+ m) I7 z. m        case '#':
5 j, e* t( _, ^; n5 g& X7 S9 U             if(c=='+'||c=='-')
1 _/ R9 n6 L, N                 return '<';
, q, N: u0 I2 C" V0 V, F" X             else if(c=='*'||c=='/')
6 I6 e2 A* A2 E% j* L  ]. D! Z* x                 return '<';
6 P& S3 J3 a' \7 w: K             else if(c=='(')( I9 a$ a& [/ l# U, U1 X4 _+ z' v
                 return '<';
& q2 b' S. ]4 q             else if(c==')')
3 R- _0 Y/ s  T  x                 return 'E';
4 [+ b6 z6 I6 a4 F6 ]$ u, X9 h) C             else8 g! L0 Z# j( L# a% t# d
                 return '=';
2 w2 y) s7 ^7 E' l& ?        default:
2 ]7 h( m+ S; V4 T% Q% `* @' V* e9 ~$ A             break;2 ?9 M* u2 X) E( Q) U3 L( x
    }
* u+ V4 _' P$ |6 ?4 K( a# v. D    return 0;    ! K9 f# |0 k1 n
}. C# m& Q1 f! V' c* j

8 u2 l- G8 |$ V/ V- p8 O' w* xint isOpr(char c)
5 \1 t' @1 a. T5 k6 [* f. `{
* X6 Y5 R7 @; D    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')  B% m1 \  r# F" p" f  A
        return 0;6 x: a7 |4 ]% R& n4 K8 d: Y9 \  {
    else 3 B8 o9 y3 ~( t, A; U' ]) i& i; q
        return 1;
6 w8 p+ _3 b8 k+ i2 ]% p}: |$ d9 k, v4 m
$ p/ q. V) t. [$ {6 T/ p0 }% U' @
float operate(float x, char opr, float y)
. S, w8 [% b% R# ^{
8 ?" {9 Y: e" M! S* Z5 h" E    float result;
6 k0 `9 P- w/ Z6 B2 B5 x, Q    switch (opr)2 h; @! [0 l; Y! M! G
    {
9 |0 \0 e0 g+ m: k0 u        case '+': 2 J7 z) h' C# t
             result = x + y;7 I, R& K0 B6 m+ m3 G" \: w+ ]! J
             break;, H' y+ X  _, |6 @5 X
        case '-': , c* H6 V" E: @3 j
             result = x - y;
1 S6 q$ i% c  v' G- [- g7 g             break;0 t% @. l$ g3 j& i
        case '*':
4 Q- k: n+ K  e2 z             result = x * y;
$ P3 j0 P; f; X8 N6 _4 @! U             break;
4 e  N* y9 e: I0 I& k, s2 w) x        case '/':
" E. \. V- l# K. Y4 G+ E) |             if (y == 0)2 Y- \. G; V  Y" Q& m1 p0 l
             {
; z: V! z& A7 o$ F1 j! e0 n                printf("Divided by zero!\n");
3 U% v0 ^2 U: y                return 0;: q1 N: T3 b* \3 h6 T/ H6 j
             }
2 Z: m+ ^) f: m9 i, M0 U. `             else( H' v+ y- q) e3 I- P' ~
             {5 ]; C3 H+ q& y* \0 @, w
                 result = x / y;
3 f2 @+ g# h/ ^9 `; ?+ V                 break;
* ^4 a4 A1 Q; M! E: ]! Y             }
6 b- E  C1 P1 k* e6 a+ Y0 ~' [8 E       default:
4 J2 |2 f0 P% r: [2 [2 z2 J& f3 H# P9 M             printf("Bad Input.\n"); 5 ^$ x! u2 O+ k2 p. ~% U8 }5 P
             return 0;6 @* h/ {3 X8 T; y
    }% {. M3 x9 n6 q: ^
    return result;
4 J8 @. q  g( h7 q( ]}    4 |2 U7 {- k6 F+ @: u; o

0 f+ L2 K; R4 g- Jfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/6 V- {7 L9 @" W. m
{3 y0 n' g+ j( \2 l# I0 v1 w
    Stack optr,opnd;' t( Q! I) b/ z# ?
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;% {, Y2 I  ^! O& n+ d3 x+ B
    char c;1 T# M' I' }! n  G, K3 b5 ^7 B, d
    char buf[16];; p7 U  g& p  h! c& a; W
    int i=0;+ l. f, {; A) p+ L4 T0 b
   
' e0 l1 W" X% P- s: N$ _/ ?2 I6 m    InitStack(optr); /*用于寄存运算符*/
& a1 L/ ^$ m. ]  p    InitStack(opnd); /*用于寄存操作数和计算结果*/
) ^& t! F$ [4 x2 B2 b. n4 @    memset(buf,0,sizeof(buf));
/ s3 _/ N, u4 f2 c2 F, l    ! [( F' @" ^7 t' t
    printf("Enter your expression:");! S: R8 t$ e6 F9 C! T$ f" x2 m
        & R) z) }% B% v5 b0 I
    opr_in.ch='#';
7 E! W+ }. V9 `" b0 z% Q    Push(optr,opr_in); /*'#'入栈*/# Z& B# m6 o6 y7 ?+ _; D
    GetTop(optr,opr_top);) L% d+ r; W* k" j) Y7 P6 g9 q3 [
    c=getchar();5 a; b  v+ a2 v6 x; k9 s! Z
    while(c!='='||opr_top.ch!='#')
5 Q. t: x9 A; i+ ]- _  q5 ?$ V* k    {- Q, X5 K1 e1 n# O- U
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/0 I9 `, ^& E! a: S/ z: u
        {: }" G" {4 R' q; l8 ~* ~. o
            buf=c;4 `9 `. ?% Q( X; @8 U  J
            i++;
7 Q& @% I$ M+ s9 s7 ^1 \2 [            c=getchar();
1 V" v0 @5 u; I; Z% [! L/ r        }
( f1 U* [9 D+ s        else /*是运算符*/
" e2 |* m5 }5 ?% U0 h        {) H6 r7 {' r6 z, M, A6 G
            buf='\0';' I3 ~5 N! Y( v) U" f  T
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/9 d# @+ D+ w1 q6 q8 ~
            {
, {& ^) U2 H7 r1 g                 opn_in.data=(float)atof(buf);
/ h6 F  _+ r" E- X& ~                 Push(opnd,opn_in);
0 F( H8 j9 @3 x* W1 C  Y0 C6 {                 printf("opnd入栈:[%f]\n",opn_in.data);7 a; B  V# J3 V1 @
                 i=0;
) M! Q4 a. J' A6 y% W1 p8 J4 g                 memset(buf,0,sizeof(buf));
  {" j# M3 ^3 ]" b+ f4 F2 P% S            }' H; a. H- a+ y7 B9 L
            opr_in.ch=c;
# g, g. m' d# S& N& T! x            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/9 x8 N( f4 M- w* r  C% c3 L6 M% |9 U
            {
2 X# j0 D& l& S                case '<': /*优先级小于栈顶结点,则运算符入栈*/) d+ n  A2 j4 [3 z# V* O
                     Push(optr,opr_in);
* o" U5 a5 W1 w3 M/ c, {                     printf("optr入栈:[%c]\n",opr_in.ch);: C! m$ ]0 a0 l- Y7 l7 @3 O8 L
                     c=getchar();" o8 @+ \  _% N: m
                     break;
7 D5 G3 c8 t2 U6 X: v9 v2 U+ d                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/2 W/ S3 U. V, s4 X+ G/ U1 f
                     Pop(optr,e);
% E1 l. t4 ~, x: e) ^# A; X: _                     printf("optr出栈:去掉括号\n");+ r8 C* i# ]" S' s# [
                     c=getchar();6 Z  w/ V2 w; X4 B" H
                     break;& q; `5 ~4 D, ^; \
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
; e; J1 _) Q" m, q                     Pop(optr,opr_t);
8 h! d" F+ ~  ~7 V                     printf("optr出栈:[%c]\n",opr_t.ch);6 ?7 W2 y! Z# L. ?
                     if(Pop(opnd,b)<0)
& T: T* d* t$ T* e3 ?; D                     {' P& s9 q1 e, Z/ P
                         printf("Bad Input!\n");' O. a: P& x" K
                         fflush(stdin);
  G! H) a  G1 v: ?                         return -1;4 K3 ]0 S) o0 R. h* z
                     }
7 U; A- m2 f3 N  F1 h                     printf("opnd出栈:[%f]\n",b.data);' y' [8 {! s$ S8 J# i3 G* H
                     if(Pop(opnd,a)<0)3 f  g1 W* k3 H" B  C
                     {0 @. E8 \' @6 u' `4 A
                         printf("Bad Input!\n");7 Y5 v4 Y, w5 p. q1 S$ R, L
                         fflush(stdin);
! W2 \) s! Q2 E; u# ?- N' q& M                         return -1;4 C6 ^+ x3 C& S! q4 {0 ?/ j
                     }! U0 I3 g7 X! T
                     printf("opnd出栈:[%f]\n",a.data);
$ Q9 n) {- T& U7 X# M% {3 }                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/# {; r' v1 M# r. E, }2 A9 b
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6 K3 |3 w) a! r+ q$ `9 H: M, ~+ Y: g
                     printf("结果入栈:[%f]\n",opn_tmp.data);; ]4 y; y# I* x6 F5 i- K* {) Q. A
                     break;1 K5 K& z7 ~: H* Y! I: e
            }
! s+ C1 i9 Q- x' m! H        }
, I- R0 T, n7 z: P# J' }1 S3 Q        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                9 Z: e$ m2 m6 ?& r) q' Z# k* n
    }
% A2 m/ o0 M- N    GetTop(opnd,opn_tmp);
. z. C; K' q& E    DestroyStack(optr);0 a/ K9 R- b! ~# V$ v
    DestroyStack(opnd);7 ~; ~+ N  G8 @: e
    return opn_tmp.data;6 @4 |* j4 ]2 }5 h7 i# v9 o, B! L( K" X
}
7 _# S, s) u! }+ Z1 \! F6 G: n% ]5 m' m% Q% n! e! S
char *killzero(char *res,float result)
. r# I' I6 R$ o{! x9 R% q# j' h! K
    int i;5 ]( @8 x  w2 E8 z9 @$ J* u
/ f- N0 c) U# ]" p6 X+ M
    sprintf(res,"%f",result);5 b- }, }2 G" M! }/ r
    i=(int)strlen(res)-1;- G  T6 f: i2 \2 t5 x$ r* z
    while(i&&res=='0')' N& Y+ p( E" c7 d3 r  n; u
    {% B6 t& i; x1 {9 }
        res='\0';5 z: c) T) M/ j9 I* I: ?
        i--;! S: e" T2 J+ u& G5 Y/ ^8 B7 w
    }
( C; `9 L5 Q2 W2 Y2 y    if(res=='.'): F! X" t  l3 e3 n4 `' g, _9 Y
        res='\0';
/ `; q! k  c2 r5 P2 J9 w# l    return res;9 ^! v; f9 y$ I% z& ]- _( R  z3 W% o- U
}2 B& t7 ?/ E9 R

. o& ~( V1 t( M5 O; T2 T7 Oint main()% Q2 I- ?5 Z4 p/ ]3 H+ O, I
{, [: I. j7 ~$ I( Y& B" T6 s3 C4 x
    char ch;2 K8 x- ^. A5 A) v# p: w
    char res[64];
3 F6 Y6 V, N" c* ?    float result;
7 t. V& U1 N  L& O6 J    while(1)
0 E6 `) \0 w) X8 ~9 F  N, U    {8 d) z7 Q2 |- D5 M3 C
        result=compute();
& O9 ]: z9 }$ u        printf("\nThe result is:%s\n",killzero(res,result));/ {0 B  I9 s+ T! Q
        printf("Do you want to continue(y/n)?:") ;
$ x/ N0 b  W; i$ \/ L        ch=getch();
. C2 Q2 G: f! I" m7 f        putchar(ch);
( R+ ]: b( ^3 D4 O" J        if(ch=='n'||ch=='N'), }$ Z& p: h! {# b1 a
            break;
7 d0 Z, R# O) M! M8 E- p        else
% C& C/ L% u, h: s: U            system("cls");7 o+ P. N3 u4 p1 f: b
    }
3 |3 C* ?! \" l, Z' s    return 0;
1 X; ], l7 n3 ^}

# p8 l1 a" G' f; ]
, v! r. i0 P# q0 B[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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