返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.' `4 E6 K% _5 D& }  u9 `& y
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=3 c6 o8 l% E4 p! k% ~5 g+ f
/**************表达式计算器************/$ f- E. B0 N. L) S3 G
#include <stdio.h>
; p/ l$ k0 s& S#include <stdlib.h>
4 e5 I* Y4 {+ B. q, O7 v#include <string.h>: U/ N# |2 S  p: N* k
#include <conio.h>
; ]7 Q$ ]' g, l  a#include <malloc.h>1 a7 `1 T3 [  \

6 l! F$ E3 F$ \3 X4 g#define STACK_SIZE 1002 @' w) S# F5 \, ^: q  b/ V4 i. h' {
#define APPEND_SIZE 10
; Y- s. A* N$ [0 Q  r. B$ Y
* I2 u9 b0 P; ?$ _& |! Istruct SNode{
1 `" e  G2 X# t    float data; /*存放操作数或者计算结果*/
( {1 m0 N9 A0 b2 X; h9 _    char ch; /*存放运算符*/& N. u9 S" h3 U
};
8 c9 w) L) ?4 A, Y6 l* `
* T/ b- S" T7 \1 ^( n% H# \struct Stack{( |( v( k- t, T! Z
    SNode *top;9 ?, N( e# F2 R% T
    SNode *base;
3 K5 _- p0 [$ [, c    int size;  U! g8 F0 c% M9 V' L
};
# P% Z% b3 T  o$ r+ ~  c" O. J/ I1 v+ e$ I
/*栈操作函数*/
/ q: L9 k, N5 m  T( x9 Zint InitStack(Stack &S); /*创建栈*/9 N) M- r# j9 K+ u$ H  Y0 o
int DestroyStack(Stack &S); /*销毁栈*/
2 Q9 V$ J" \4 \4 \4 Zint ClearStack(Stack &S); /*清空栈*/; U2 p; j% X/ [: g/ h' C
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/: v0 _# m9 q4 M* H
int Push(Stack &S,SNode e); /*将结点e压入栈*/9 R+ A5 N, m# v
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/6 ~0 }5 e! E) W; s% X7 k

- g9 D0 y2 n7 Q& a& i4 T/*表达式计算器相关函数*/: Y( V8 T) `" s, Q* f8 b$ J* J
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
$ n: Z4 O! K5 u" o+ u$ \int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
4 I& A+ A/ f% I8 ofloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
9 q" K' A5 h! M' @. M* p  Gfloat compute(); /*表达式结算器主函数*/
7 v8 t  N  L9 u" ]char *killzero(float result); /*去掉结果后面的0*/
4 Q/ v7 r& c: g' u8 _6 E+ X4 Q$ D/ p) z. ^8 O$ H& `3 B) I3 ~
int InitStack(Stack &S)0 o4 `9 j- R/ j6 K2 J6 J. w
{
; Z& t" k% R) D* h2 x5 v/ o    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));- V4 @$ r" Z. b5 {9 A/ A! L3 I
    if(S.base==NULL): T4 |% T8 f2 J" g. y; j. v
    {
( V- ~+ s1 Y3 s; k# \- s        printf("动态分配内存失败!");6 j6 a9 c$ v) s1 E- o6 s' x2 ~
        return -1;
7 B" B! Q, Y; S0 x    }' c! J6 K! {4 l: j, K5 h
    S.top=S.base;. ]9 u9 U% e( I- h4 f) }) ^9 g
    S.size=STACK_SIZE;* M" ^5 M7 [9 s) C2 S0 y
    return 0;
& b+ c' `* O& K6 Q4 b( G; K}8 ]; [0 f; N0 i7 ?2 h
' w# d2 g! Z. p, o# r3 i
int DestroyStack(Stack &S)6 c) {4 d% f+ ^0 |) C) F6 Q
{8 y% S7 a2 O1 H0 V, N- c( I
    free(S.base);
' l2 r- p& m( I8 r# Y- i* c) o    return 0;
& v+ b0 K+ Q! p, G* o3 j}
" E: d; T$ ~( l! T5 P/ p/ p+ H  l. X' ~! Q% |$ E) G
int ClearStack(Stack &S)
! h$ U( f. j5 D! D5 l: _" f# B9 o4 L{5 G* i. M' F( I
    S.top=S.base;
: E( i& H9 x4 W, C! f9 k" C    return 0;
* X, n4 ~% \9 k( ?$ [$ }4 L- ]8 M' w}0 d  ~7 D0 O/ e' g# h- X- c8 U. b

/ S  x& E0 m* _int GetTop(Stack S,SNode &e)
6 k% L6 k1 h) L{: w0 k& M: U& L" f# d
    if(S.top==S.base)
; e  m8 u, h, f) d/ e    {5 X  z7 r9 Q3 |$ {* \6 i/ Z2 x
        printf("栈以为空!");8 c' V/ y6 m: d6 z6 y& X4 A
        return -1;
  O" `  b9 `% h    }9 u, x- j" g, u# H8 d% }, ^
    e=*(S.top-1);, p# _$ S, B7 [! ^" m, C
    return 0;4 w+ _; h) q  a/ F+ d
}3 u7 F! @7 d! V, i; q
- g! A) f5 b" M- z& F1 y0 Y% f
int Push(Stack &S,SNode e)
7 D1 `. G) F9 h/ [{
% l  S, s8 D- t    if(S.top-S.base>=S.size)
' h3 w" g% M5 ^    {
6 s, T7 \, B9 p* I" V. N" `6 T        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) f+ ^( P# E8 o; U" p, D        if(S.base==NULL)' G( d* p" h8 \, K
        {9 m! w% L& K4 n. a1 @
            printf("动态分配内存失败!");: h; M' l7 R, K! y; h1 O! d/ e
            return -1;  {. }+ P' T9 V
        }
" i  A4 N4 ~9 k* `( s        S.top=S.base+S.size;) ^- S7 q( [5 Q  x
        S.size+=APPEND_SIZE;6 h: s% Y# S4 M2 `5 u- q; }6 `; K
    }8 v3 A1 C. I, j& N
    *S.top=e;$ |+ d0 x$ l: \& ^# Q
    S.top++;
4 O3 i1 T, I& l$ G3 G; |    return 0;8 O0 h( @6 i# Q0 }2 n7 j
}
4 l5 e% M0 d7 ~( r
3 t  ^* O" S! Y6 q0 U) F) gint Pop(Stack &S,SNode &e)0 v/ M4 M/ Y' d+ `6 q. W
{
- g( J; R$ h! s* J  R) e2 R* Y3 y    if(S.top==S.base)
- T! S  [* q  @: W, a4 x! z    {
9 e7 K7 c9 q9 L* [: h9 x        printf("栈为空!");7 C' R: D! ?& Z7 w" |) p" J
        return -1;
- r! y! A8 u: M% M- |9 o6 z6 v3 ~    }, U( @5 T: ?& f6 a3 k4 C
    e=*(S.top-1);9 Z% I& c2 E# G5 U, }6 K7 r
    S.top--;
7 w, f0 K4 ?% ?- J/ n8 T3 p: q    return 0;
& y1 H: A  P, q: p}; ]* D8 D6 u  _4 y9 N
5 |& W; L" M. j5 p- b$ h
char get_precede(char s,char c)
7 i1 i# g- c8 Q$ b3 O{2 X; x: N/ {; t8 u  \
    switch(s)
' q1 F/ K. E+ ]& k% j    {" [1 X. [% h7 t3 G, S
        case '+':                 
/ h1 r; t+ @1 F        case '-':
; a9 U8 s: R  ]" q* D6 ?             if(c=='+'||c=='-')7 g: m1 k% ]9 x8 c* J: d6 P
                 return '>';
4 P8 A4 X0 k1 b) S* j             else if(c=='*'||c=='/')0 w5 m1 H6 i, I& t4 `5 f8 V' h$ u
                 return '<';
& J; F2 S/ S! Y; B' p8 n, B# {             else if(c=='(')1 j" ]$ o+ W! I" F
                 return '<';
; m4 S8 m" m" x1 w             else if(c==')')
/ n+ D- D$ i$ {# W" \) I! n                 return '>';
- N: z; l8 T7 w, d; |( x# \             else
' D" K' a& S' y6 E) q                 return '>';1 E% ~$ P4 V. q. R* y! v
        case '*':
& U' y' ^3 D. c2 G2 g% {# d        case '/':
2 }0 ~& Y! C5 [. }4 H             if(c=='+'||c=='-')1 f/ i3 U- o6 {# G, ]
                 return '>';6 k. G* r+ ]- D! u$ `0 V
             else if(c=='*'||c=='/')6 u' w. R% g* I4 j1 \
                 return '>';
2 i6 M0 H% b& `             else if(c=='(')0 w8 N  z+ Y; B/ }( l: f( O
                 return '<';
, |& ?8 k0 ~  d% z             else if(c==')'), B- q3 o0 [# u8 I
                 return '>';+ `+ x! {( l3 v6 C7 k
             else
3 p; G4 j! C* F6 |, f8 A8 B                 return '>';
5 V) |  n1 J# W  P3 A3 t' y        case '(':- G+ K, u2 z6 b* ^4 H. O
             if(c=='+'||c=='-')# ]& R5 e6 S: D, B# F
                 return '<';
2 W8 I5 E0 ^" R/ v/ Z6 K             else if(c=='*'||c=='/')$ K& L; O8 F5 i! b$ }
                 return '<';9 S0 V/ l$ j* v. b* M2 j  |4 H
             else if(c=='(')0 `# V. @2 Q8 _* M
                 return '<';
$ A3 {, m& U  R" j             else if(c==')')
! E4 ]. G  y3 l5 i. U. Q7 J4 s/ j                 return '=';/ I2 ?4 U: ^8 ~6 [
             else6 e. j8 [6 d; I" E1 Z) l* C' Y
                 return 'E';
6 N# P; [- b1 K( C$ Z5 A) l        case ')':
, f+ B. l/ m$ @" T3 N             if(c=='+'||c=='-')
# N$ A5 P5 d9 [& l. k  l0 \                 return '>';. }! H' O- F0 P4 R
             else if(c=='*'||c=='/')
  W$ E! @7 z, a* N( }; O( a8 y$ W                 return '>';- w1 q( {3 @, M( O4 J- K# e
             else if(c=='(')
4 z* B) G# ^; W9 Q' O8 X                 return 'E';
+ }. H7 Y8 Y! S+ s+ w& Q             else if(c==')')* C5 c5 A. a! ?+ N$ p: d6 O
                 return '>';
% ?2 R! d7 _. Y1 M8 K             else) k: c2 a. v' n. v7 w
                 return '>';% U3 ]4 C5 j( I- C. N! L3 |4 M
        case '#':
$ K, ^1 s+ L9 }8 ^& g             if(c=='+'||c=='-')
* ~* U4 [$ {# v9 S/ |6 \/ B) k                 return '<';
: g* S9 v, ?5 t, j             else if(c=='*'||c=='/')1 Y  t% B; p/ L, \" i
                 return '<';
) m' p4 l- ?; U: ?5 I/ ?             else if(c=='(')) a' U: |( z& Z6 E
                 return '<';; e$ j& i/ H6 N) g! ]1 h
             else if(c==')')
, K2 e) k5 F. }$ {, t6 e9 F                 return 'E';
# a+ ]) a6 Y: C+ o. Y7 K             else6 {$ Z0 F1 g7 f  s" Q+ A5 V, E' S
                 return '=';
; A) L4 k% I, X& A        default:: z$ Y4 ]$ ]( q4 u# {: b3 u/ V
             break;
- ?0 f# e+ _, @1 _/ C    }
$ G8 c4 B- i: T    return 0;   
" }/ g: ~3 `' y6 ~; ~( v& H}8 O! Z' m' w" M

& ]; X9 G/ N4 l$ W7 q2 [, fint isOpr(char c)0 F, b5 d. f  Z! J: N, e
{
* c+ H- G, U! P    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
' O2 R: [# q* i4 p8 v        return 0;4 F( }) a! Y4 D6 S
    else
; x% o+ r8 i( ?0 \& r( D7 G  A        return 1;" j: \/ E# v% {, b' V
}
6 @4 D& j* ^+ a
; k1 d+ u; K+ ~/ B* E1 ffloat operate(float x, char opr, float y)
4 B1 D! N( ]* V, |- d{
5 y& y' p! \$ K! |0 J% s" a  g+ Y6 j    float result;" E5 q/ b' M9 Q0 S$ z/ k$ P* G8 h
    switch (opr)
& P) N; w$ U4 _% t; O* q    {& ~0 R5 Z3 C6 S8 x6 v- _
        case '+': & `; s5 _- z+ j$ i, `
             result = x + y;' m& [7 |; T, e
             break;
3 Y; _  _- }# c! l) D        case '-':
, r' J9 `& E1 Q             result = x - y;9 l4 Q, F/ O7 D
             break;
# M" E  _6 E) n+ [  H9 e( y( R* K        case '*':
% e+ d+ ~% q# g0 w             result = x * y;
. m9 K5 v7 J; A0 s             break;
: E  y  u  s5 |4 \# o        case '/':
+ K4 z8 K# v2 [7 }6 v             if (y == 0)* N9 J2 s; q7 v3 _# t, I! ]# Z
             {2 h  T; h; D' {6 w! `/ X9 J# s/ w4 U
                printf("Divided by zero!\n");. I; U$ P  q7 j$ I; m3 e8 }
                return 0;; t+ W  x+ f8 b, r4 ?7 i
             }
, N; k" I2 V; t5 b             else$ y2 x5 f1 Y: q7 S- ~6 n
             {, v4 o' f2 l1 A  e: B6 v% R- \: \! {
                 result = x / y;
3 N8 O$ u0 V1 X! a% ]/ n8 t$ h8 S                 break;
# `% ~# `4 \. V, r% |+ A             }
7 O+ N3 M$ `1 t0 y- r! j       default:
+ f% O5 Z' }, W4 @$ X4 L8 n+ j, n             printf("Bad Input.\n"); . }  d, M# [: F. t5 }3 m
             return 0;8 I6 F5 r: Q9 I) f( w
    }
/ S, c6 H  c' s; T    return result;
$ U6 I7 \' ~& i3 L- Q0 |8 ]7 ~}    : b% D: s/ N% v4 t  }' M

' `2 x4 ~) @9 Z& S2 B! t- Xfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
- N! n% E) y$ ~$ e5 L{) g4 S1 J# I3 M+ Y; s* B& }
    Stack optr,opnd;% x5 l  D. u! g) ?$ j6 j; {
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
/ s/ g7 [( @* p5 ~2 \! z1 Y    char c;; h( p7 I% W8 z3 g6 I* G: Q
    char buf[16];
  N: V' K( c& T7 R/ ~2 \2 P0 t    int i=0;' n) o0 u+ T; u9 o8 }$ Z
    2 U' g* ~" k. D' V3 ]% B/ z
    InitStack(optr); /*用于寄存运算符*/6 }+ u& ]* A) a  c- k( ~! W, C# N9 U
    InitStack(opnd); /*用于寄存操作数和计算结果*/! E' k" V; O9 d1 u6 }8 [
    memset(buf,0,sizeof(buf));7 Q. ^# M3 U9 y1 ?5 a7 `/ j
   
# ?4 S' c2 o" T    printf("Enter your expression:");
$ p3 A, P. J) f) ]5 f) Q        4 }7 x5 K6 v+ |: Z7 B3 I
    opr_in.ch='#';( ]! Z9 d/ i8 ]+ L7 F$ X. E
    Push(optr,opr_in); /*'#'入栈*/
( W; N9 ^% s- O) @9 ]    GetTop(optr,opr_top);  V9 q( c6 r+ Q7 B. U. }
    c=getchar();
( L+ L0 t4 Y( u/ {* B1 C. ^    while(c!='='||opr_top.ch!='#')
1 J: @0 h9 c% F& Z    {$ `1 {+ _8 O9 D
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/2 F1 F+ v% u$ c2 c& N0 C: _' K0 ~5 g
        {( L1 K* @0 e* z) T% c, N( ]# ]
            buf=c;
' {/ n% F! H1 |3 C            i++;
1 |8 @1 B: @+ r5 ]- \            c=getchar();
9 @! S, t+ S- b+ N" c        }0 r, j. v+ ?9 {, h
        else /*是运算符*/
) E& ~  r& e/ G        {
+ y6 _4 Y" V( _            buf='\0';
8 u: W3 t7 ?7 e/ G/ ]            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/- S' d) X1 s- }& e3 ^
            {
$ Q+ D/ E6 O( P- R0 o5 }                 opn_in.data=(float)atof(buf);
. b1 k( h2 y0 W; i+ g$ E% z- l                 Push(opnd,opn_in);
4 h$ y* A7 [+ \2 {3 O; s3 q                 printf("opnd入栈:[%f]\n",opn_in.data);8 F: e2 \8 ]4 D: n: a
                 i=0;1 r0 ^' Z# m8 N
                 memset(buf,0,sizeof(buf));
4 ~$ t  ]; c- G) q  o; U/ @            }
; F, _  {9 a2 V2 w; a: Y, f            opr_in.ch=c;
1 ]9 G% Y) X5 r; I: t$ s. Y            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
4 W' Y1 E4 C6 s) X4 K            {
; z9 Y; E$ h. y7 I3 |  d5 P, K                case '<': /*优先级小于栈顶结点,则运算符入栈*/
! H: e/ w, ]" r4 I6 k7 `3 `                     Push(optr,opr_in);# u5 c! @* L# U5 \/ _' p
                     printf("optr入栈:[%c]\n",opr_in.ch);
: h% M0 h% G7 ]% `: e. W2 O, F* `                     c=getchar();" x& C. m2 \( Z0 a9 t
                     break;
8 y& |: D+ L/ ~  z4 T                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/. J! Z* ?, s' ^9 F6 [1 g
                     Pop(optr,e);0 g4 s# q( F9 `4 ]; ?( z1 E
                     printf("optr出栈:去掉括号\n");! M2 X8 R" o4 @4 ~
                     c=getchar();$ ]" h- F' I* q7 A3 W2 d
                     break;4 Z) F4 i- r% k, d) u% C* [
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/2 \* I2 l+ `; ~
                     Pop(optr,opr_t);
! {( V4 }/ l2 t6 a$ X, q/ P                     printf("optr出栈:[%c]\n",opr_t.ch);0 j4 @6 E+ t$ S" b$ N) R
                     if(Pop(opnd,b)<0)
9 S! J. ?" x" T( ~                     {
& V4 Z& n1 ~+ {. v: D1 K                         printf("Bad Input!\n");
( A% m2 E  q9 O% S  ?                         fflush(stdin);7 z7 H' }2 Z+ Z+ A& E
                         return -1;
% ~% B! @& X. U# }; g4 B                     }3 n/ m# X3 E) I  J* ]# K
                     printf("opnd出栈:[%f]\n",b.data);0 ?; @9 `9 l7 g: m# y# ?
                     if(Pop(opnd,a)<0)% d" ]; t, j2 J, c2 d
                     {
) [) ^+ M# o7 }* p+ |0 f3 b                         printf("Bad Input!\n");
7 q3 ^+ @/ D9 Y$ `. ^1 `0 _1 c                         fflush(stdin);. a" b0 N$ h; ]
                         return -1;. ?* U: ?( f- J! r# @3 d
                     }
" N; X2 c0 o1 ~1 _, w9 d& J                     printf("opnd出栈:[%f]\n",a.data);
- ~0 S' d9 z1 Z) x5 x! j% S                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
0 |* `+ ~  [  w, x1 a) Z                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
/ u, t3 q6 m8 U1 q! P+ m+ t( t! U                     printf("结果入栈:[%f]\n",opn_tmp.data);
! f1 c, [3 @" s$ q) U  P                     break;
: m  @8 I7 \, H# M- q1 t, j  [            }! Y5 N/ Z& j5 y$ C8 s& O- d. m
        }
0 q0 d3 w: D/ ^7 R2 |9 j, \        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                  G; d& r' S! y0 _
    }, C1 f) o) @1 F* f4 B
    GetTop(opnd,opn_tmp);! s. C1 [8 f9 A+ l0 t0 g
    DestroyStack(optr);+ i7 t( N, c# o  Y
    DestroyStack(opnd);. u) a6 r' z- ]  W: _. Y. {$ w# J
    return opn_tmp.data;
- W9 f7 B. R; s8 F4 A& U}
. p" e7 ?" G; q! x! P( C+ Q& l  f1 V2 S
char *killzero(char *res,float result)/ o$ q+ y( Z# |! q. i6 Q8 M
{
$ Q7 D' g/ ~- }% v$ _: `. D    int i;( a. m( b6 x1 H/ v, P+ E( K6 [- g8 R
# E2 ^2 p2 }8 H$ Z8 \: N& }
    sprintf(res,"%f",result);
) C- @; s) D. W/ _3 }3 d    i=(int)strlen(res)-1;! J% r" g2 [/ ^- {+ j  A0 K
    while(i&&res=='0')$ |- _, f% {+ |" w9 W# h* V
    {
& b/ g, N5 H3 \0 x8 d        res='\0';
( E8 S$ b" {9 G% D7 E. S  {        i--;& r* P7 V0 m: Z3 l! F7 @4 A
    }* B) J4 x9 f5 Z" S" ~
    if(res=='.')6 s8 q( p& ~+ l# _& r
        res='\0';
& @/ d4 O8 J- ]/ \9 r% G6 D    return res;
! m* u' b5 x0 }* Z6 ]}
! O& y% z/ Y: L. O7 E  [+ F9 `/ ]
- z, b8 ?$ k( [  Y3 Dint main()
" y1 P% q6 E& s% b; Z% x: b8 U9 a{
3 ]2 O0 m) U2 H2 Q! F' j! l8 _    char ch;* X7 f2 X& r  r+ A( ^& A
    char res[64];' h. }0 \. y/ c( ~7 X* ~! |. B
    float result;3 E  q7 T; X1 T! }, S8 @+ `# v
    while(1)
6 r* h  f  y9 N1 m( c9 i    {* s1 l# Y+ v$ j3 l# k+ ?
        result=compute();
7 ]" |* r) m& \9 b1 i" }        printf("\nThe result is:%s\n",killzero(res,result));1 ]9 s$ X7 B( q- w
        printf("Do you want to continue(y/n)?:") ;
, w6 }( G  p0 m1 }: r8 G  U: |        ch=getch();
5 O; a/ R/ l# z: @, ]9 ^! _9 I. C        putchar(ch);1 e' o9 A' W& H
        if(ch=='n'||ch=='N')
9 k9 x7 s: j# |) n9 E$ p4 G            break;5 z  C3 v3 A' P* _* H' [
        else
6 o4 r6 j" c8 d+ `, m            system("cls");
# H" c% o# B  w" f. \5 x/ c    }3 t% \. t9 p7 {& u" O1 j$ s4 ]
    return 0;
0 L* H, I# o* k6 k. u! ^8 f2 p}

' q9 l2 t3 S# O: F
: A4 V( k2 o1 P% c! s[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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