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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
' L. w6 J2 k* k6 }* I3 ]程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
8 t& _; t( V' T& R/**************表达式计算器************/2 ]1 E; G/ b. n( V& O: t3 A
#include <stdio.h>5 ]4 W. |4 w/ O& W
#include <stdlib.h>; x. }8 W; C$ @3 u, b# Q& ?, `) V
#include <string.h>0 h+ c* j( Y/ a+ E! d
#include <conio.h>
8 z  S* O4 p" U& r; P1 o- F' p4 k#include <malloc.h>; I0 V+ ~" ~, Q/ w' N/ {6 ^2 W

( [, J( M7 g7 H) @( W* b) _# {#define STACK_SIZE 100
- ~% L$ Q# I. G$ K# `#define APPEND_SIZE 10& s# b) L' X1 N
  Y/ z0 T/ p& G- u7 U" h
struct SNode{
2 u2 X# s8 r5 @9 d" ~* }' C: |  `9 ^    float data; /*存放操作数或者计算结果*/
& v. f. ~( U% ^9 z- z9 ~; O    char ch; /*存放运算符*/
4 o: O7 }2 y  @};7 U% j& c& U& @% p

2 B, Y, s9 P/ }. Lstruct Stack{8 k& ?5 X3 _/ }& B' S. }  l( P
    SNode *top;, ?2 `5 v  Z. O' U- \$ ?9 q: C
    SNode *base;
; H5 H0 C, n6 r; r2 b    int size;, X; y$ W: j* J
};7 w/ J8 G% s8 s( @2 R

% {9 w- S8 @$ B1 s; a2 [* C/*栈操作函数*/4 m9 D9 Z+ b! c9 A5 s: [
int InitStack(Stack &S); /*创建栈*/
' L+ @  [! r( z$ p+ r* G; |1 pint DestroyStack(Stack &S); /*销毁栈*/  s! Y( q* r; p
int ClearStack(Stack &S); /*清空栈*/. g- U' g1 h5 `9 \" J/ I, }
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
2 _6 P. r, a: c% k. Y4 yint Push(Stack &S,SNode e); /*将结点e压入栈*/
4 P# a# s8 f7 c: B+ n. _( ^int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/4 s, |+ L, L  B# j, O
0 s0 `8 A- O; L8 U
/*表达式计算器相关函数*/
1 W7 w8 E# V  n) U+ xchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ J4 w6 ]- H# G& ^; @int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
) j  D3 c5 b$ q& hfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
+ A# ~7 C; q: F; i& `6 L2 bfloat compute(); /*表达式结算器主函数*/& ^; b1 t) y7 P/ O! z% P
char *killzero(float result); /*去掉结果后面的0*/ 4 @8 s. h+ T$ k6 M  n" u

6 n1 H7 C# P3 Xint InitStack(Stack &S)
2 b/ f, j8 {9 q; Y{0 ?+ p+ z: v: f, A. b
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));) G1 M, R7 n% J
    if(S.base==NULL)7 {" I0 s3 r; E' B$ H0 L" {6 ]
    {  R; M# k4 N6 i; X" w
        printf("动态分配内存失败!");
6 I! \3 D1 ~$ D" w        return -1;' ^$ l7 Z4 ~! e
    }; U- ^9 K6 r+ V+ u
    S.top=S.base;& f8 M8 x) r: V+ \3 R% L
    S.size=STACK_SIZE;8 t5 \8 G4 L4 }/ R
    return 0;3 u9 c8 M' b/ H# Z$ _* P. p
}) x  x! l5 P' t! O) R+ z) x
7 D3 F! m9 o1 m6 K, v: M
int DestroyStack(Stack &S)0 D$ g( x3 }$ W+ f+ C" O7 o
{
: O0 e, S3 d3 T% b    free(S.base);
$ G4 n! O9 h. Q( ?0 h- i, \    return 0;- T) X* j+ P0 \2 N4 A; X
}3 m/ `6 j$ X7 Z  m# F" n2 _! o9 q
5 d! I3 E& k8 b  T( N
int ClearStack(Stack &S)$ S; A: O' K1 \- ]; s. }5 h7 m
{) x! S( `/ n9 p4 M
    S.top=S.base;/ K5 @8 e, a6 a8 T
    return 0;; b$ E9 W  b1 m
}
+ S5 B* i, A8 S8 k6 g' t& s
, O$ y6 \$ t( }. m0 Iint GetTop(Stack S,SNode &e)# U) g$ u' P' J
{
+ r- i( e# r4 M, H( K# v    if(S.top==S.base)% v6 M* e5 L& _% n7 e5 K- _/ {# a) p
    {
3 I" }! [9 `/ T1 c# f* ]7 s0 a        printf("栈以为空!");; [- a/ P9 ]$ ~0 X: ]( K2 {
        return -1;
" d0 d6 E0 ^" O* F7 ?  k. n9 |    }% R% E% o6 Z7 \0 m' Q$ r
    e=*(S.top-1);- |3 z2 ~/ U( y. c0 F
    return 0;
$ Q0 z/ K( d5 H: i$ E! Y}, e4 F( g+ g5 f
, N& i4 O% _3 _: l  ~, i2 B) [1 b
int Push(Stack &S,SNode e)( ~8 k% M$ }7 n9 l! \
{8 ?  m! t) r; N3 k4 U
    if(S.top-S.base>=S.size)
6 {+ J% U4 w8 w    {# J. q! I3 N1 [7 a$ B
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) N1 O4 }5 E" o, x+ K% t3 q# o        if(S.base==NULL). Y2 w. y* Q5 M
        {
* E( d, E# B) J$ F9 N. A  M            printf("动态分配内存失败!");  @/ U( b* h3 w0 C6 l& V4 t# ?
            return -1;5 W6 b  ^2 j9 k0 T# r& Y
        }. `0 H- q4 y( D  R
        S.top=S.base+S.size;
+ U9 x1 N( d3 r0 L1 `- C" _        S.size+=APPEND_SIZE;
" h- n8 W* Y1 R; `6 {, m1 e+ W" ^    }
* V  m- J9 n; [2 \/ ~& Q    *S.top=e;
# ?) l: i1 o& ?6 b- {, }    S.top++;
! Q6 `9 B2 G/ Q    return 0;
7 p! S8 F5 f! S; p; u# W3 ^}' w  [0 l8 ^1 b) [
7 Q. |8 H  v$ Z
int Pop(Stack &S,SNode &e)3 ]+ A# S, Z) e* ^1 E% _
{$ }# `7 x! E7 C. A
    if(S.top==S.base)
( [% V8 g- V+ F: I: G! v% j4 d    {
" E% h! O& a. T6 h0 t* A        printf("栈为空!");( f! G+ N' T* S3 S$ I/ A/ a- h
        return -1;( `, B8 f/ q# A6 v1 X( C
    }) s  p- [, `/ B% a
    e=*(S.top-1);' U' S; z4 q! ?% j" V
    S.top--;8 H3 `! V1 M2 a: O' f9 o
    return 0;' j$ X. U) a3 ?: N) n; S) Q
}
6 D& w  H+ Q2 r2 h  W
. K# ~  l8 u8 n* A# Q: Bchar get_precede(char s,char c)) M. i' Z- c- L, B5 C1 O
{
: Y4 G, m9 \7 x1 M) D% p3 Y+ i3 R% n    switch(s)) w3 ?: c; \1 f& T" ~
    {) p; O2 C2 y4 U0 f- S7 d* ^
        case '+':                 ! E) d: U" @* ~4 Z% T
        case '-':) q+ l; J3 E7 z& T: o4 i9 j$ A
             if(c=='+'||c=='-')
0 W' L1 I* a; t( B/ z( \                 return '>';8 I* M$ I% W4 e! B8 k3 r; k5 @
             else if(c=='*'||c=='/')$ d8 \! }; a3 E
                 return '<';, P+ Q- N% J& V- J1 ^) K3 J
             else if(c=='(')
! C% o0 o6 K* r2 O* q1 T" ?                 return '<';
7 N" h  J; H4 G+ \             else if(c==')')# {: `+ X& ?; W3 s: X
                 return '>';
9 T, C: x0 r/ a8 E- H" A             else , {% i8 {( I: D) y% R6 T+ n
                 return '>';
. x  y- C' M1 J        case '*':$ d) K6 V, E: Z
        case '/':- J6 w$ D& }! j* v/ p$ U& U4 `/ V( E
             if(c=='+'||c=='-')5 `2 [1 @! k: S+ R! l
                 return '>';
. f8 c' ~7 y' e4 I6 d             else if(c=='*'||c=='/')2 _8 h5 ~2 X( n- H+ g8 p! y3 J5 A
                 return '>';
0 k( A; X5 W6 z! J             else if(c=='(')
! a2 w2 p. y! l                 return '<';
0 N& c1 K& F! E             else if(c==')')6 W8 z- C+ W$ o6 q2 w! _+ X
                 return '>';
3 e' O  ]) M0 Z3 N: j4 Q             else
% \. e7 {0 S" C$ I& _9 J0 ^  b                 return '>';
. o7 U4 X& H, r% b. u4 f% F        case '(':
0 U! B; I3 g+ ]" I' k) @$ l             if(c=='+'||c=='-')
* [' Z  o: k% H% m4 q6 Y  k                 return '<';8 _: z; L# i6 Q! U3 Y5 u4 `! b
             else if(c=='*'||c=='/'); y9 Z/ a1 A+ C4 a1 j2 o
                 return '<';
2 B, L& o7 T5 V) x3 ~5 ?! s             else if(c=='(')
' A! O- w" O1 ]( X2 Q( d                 return '<';: ^6 k# o* r5 A. ~$ S
             else if(c==')')
+ Y* h% J; `! D" \. ~' h5 b                 return '=';# _& t* }5 W9 s( y! m5 [
             else: c8 c% L/ p) u$ e4 O
                 return 'E';
  x+ {$ n0 S7 M1 j+ D        case ')':
9 E. h) B. K+ P' n             if(c=='+'||c=='-')
, ~1 o: E0 z3 Z% A, k; J, `                 return '>';2 r& N# @7 J+ y- H. w0 c
             else if(c=='*'||c=='/')8 c2 E/ c7 W/ q5 y' z
                 return '>';1 X1 }" A: r6 g5 O. B
             else if(c=='(')
4 s! w& B9 D/ c* U/ V                 return 'E';  [( d( M- u4 o" _* J& D# C" K
             else if(c==')'); _% ]# S) M; F& c2 a2 z! r) ^
                 return '>';
1 a7 m! K1 i, [# s  Q8 I             else
4 W* }4 V% m  O: z" ^0 r7 |& J% R                 return '>';
0 F! k8 U4 d/ @3 o; {9 b( I" y        case '#':
0 h; a) g3 j+ F' J$ j8 R$ V/ F) F             if(c=='+'||c=='-')
8 L! m! D2 c! M$ C: b6 z                 return '<';3 D" E& ]5 _" a* L3 T' w. S
             else if(c=='*'||c=='/')
) W5 ], C; }% g4 ~$ y& B                 return '<';
& p4 E) e6 V1 ]$ o$ B( \0 u* ]             else if(c=='(')
% \9 H5 P! p4 s' d9 ~                 return '<';
1 i, f# R! w, y1 z/ Y$ ?; `             else if(c==')')' d0 H/ k" R+ v6 e& W' I3 s( y0 n3 W
                 return 'E';0 l8 C% a) E: f/ [6 E1 T
             else
- u/ U" l8 `: `+ Z! i1 M; l: P                 return '=';
+ ]  }# ~* I' @        default:
3 r6 u) e: q3 j$ M% K6 \             break;
3 L( H: v+ l) @% ?    }
% C/ B: m% L) H8 o. B% T3 H8 V    return 0;   
9 T$ e# H: c& y1 b# ~}
& X8 g8 Y3 p+ l5 E$ u/ R2 {
1 x% J6 r* h# o" nint isOpr(char c)
, C3 c; A1 l: A5 l$ \  Q{
2 ^2 S  m+ ~6 _: C    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')* u9 m1 n; m, P$ ?( A
        return 0;6 Q6 M1 h. I5 ^3 [3 L5 ?2 Y* j
    else # D/ V/ G/ U* {  j
        return 1;
* q7 B' B, Y( t" x; A4 u8 T}5 v, C6 {+ F3 M
1 \+ v2 Q0 _, _0 _/ b
float operate(float x, char opr, float y)
* F  U7 ]. `( Z' T{0 t! @  c% y1 k' A6 [6 P* L3 o/ H
    float result;
9 e6 y3 x) m" J! H0 T, ^    switch (opr)) \% p5 u( D. D
    {
  E5 n9 v7 K- r8 A7 p: W        case '+': ( J% U0 {6 b+ O6 v# w# k
             result = x + y;% h' N/ D" C8 w) t. \
             break;% t, b# X% [  f1 A5 w6 b
        case '-':
6 `5 H3 _6 [; Q) W             result = x - y;
/ Z6 w5 _9 y7 n& b, _  V$ d             break;9 O! C2 j: W! d! O
        case '*': 0 ?$ K5 j; s) t! Q# p% q
             result = x * y;8 ^( g1 f3 n9 t3 @9 h0 b
             break;
* ~7 k* g, P5 m4 r5 k        case '/':
; w$ ]- D- }7 j" R, X- A) v1 l1 h. \. U             if (y == 0)8 j) d" S( n. [$ d. \5 G2 _5 s$ I
             {0 w3 T6 k; g6 M/ P& P
                printf("Divided by zero!\n");* E3 g6 K- }6 \
                return 0;
8 }/ Z4 S$ m$ y& _% t5 w             }
6 L' h- \) o  t# m             else
0 N$ R* y* D2 o1 h, V             {- Z. _, L6 z$ |5 ^6 [
                 result = x / y;; N) E8 n7 k2 m! J! D' E" M
                 break;
2 C; y1 H5 _  q: N9 T- B             }
9 Q  Y3 ^9 Q! p       default: + W) H- E( }4 y% M8 z1 Q
             printf("Bad Input.\n");
- ]6 Q3 f6 i4 K- m7 [3 l             return 0;" K# K3 `7 Z5 K. K5 p
    }- a; ~; j+ l1 i8 s% E3 I
    return result;/ ~0 Y' c  Y$ d
}    % `- @' m. E1 ]! L- t$ F
4 n' y' P0 D$ @! z
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/4 _% C2 p* X( q* K) K/ j
{; K" \% A) Q2 Q7 w+ v' X: a6 L
    Stack optr,opnd;
! P9 E7 Q" S, a8 C1 P    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;- N: k  l6 A; T3 }( B6 q
    char c;5 P* W9 D" p1 g  ~: M
    char buf[16];. M3 Q' y2 j6 k* L7 @
    int i=0;% J9 @4 @7 |* v* }* W1 p4 ^' Y
   
$ m3 ~) m/ E4 j2 `1 k: C    InitStack(optr); /*用于寄存运算符*// M" J4 k$ O' r' H1 V: B$ U+ `: \& c) a
    InitStack(opnd); /*用于寄存操作数和计算结果*/
& X, t/ C2 K: i3 m- a/ v& H    memset(buf,0,sizeof(buf));/ M7 B$ n* m; s, j) V: {
   
; P: }% A' E; w3 V    printf("Enter your expression:");
/ ]' s) E) Z9 v        
) |* N  `2 S6 X$ c    opr_in.ch='#';
+ @+ @$ |# D5 |8 {    Push(optr,opr_in); /*'#'入栈*/. k) C/ j9 x) H& {8 H
    GetTop(optr,opr_top);
' k! g1 f. _9 I* |    c=getchar();$ N3 ], T0 W7 S$ C/ U/ P( b
    while(c!='='||opr_top.ch!='#')
0 R# f, w9 j4 B    {
* B8 K6 H3 B+ @/ j2 N        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ k* W) @0 o4 f  @1 u% K        {
; b, V0 J3 u9 ~5 [            buf=c;
" ]" c) s+ x( |/ M# x, z            i++;
4 P0 L6 E! l4 ?. @3 f# I5 e" G            c=getchar();
+ X$ t) d$ `. }9 t        }
* E9 _# Y+ S. X+ o" p        else /*是运算符*/
: o# P* ^: g, H' x7 Q. M        {
' e  q& s- U, Y6 a, Z9 Q# P, h) {8 v            buf='\0';
, O- O9 z0 N) R" J' D5 ~0 B' n            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
+ m6 J( n% \; u            {  _; u" k4 a9 F  g' F) }6 {
                 opn_in.data=(float)atof(buf);" r7 e0 l: Q% w0 F) n$ A- w9 h
                 Push(opnd,opn_in);6 w# e( b' @/ C
                 printf("opnd入栈:[%f]\n",opn_in.data);5 x2 R- ?- C. S  A, _" B
                 i=0;
% [; v; @) _, {2 a( }/ P  [) ]                 memset(buf,0,sizeof(buf));8 a: J* H- n- A% C
            }
& t% s3 F8 e, w            opr_in.ch=c;& n: j* V" T) c3 W7 K- P2 z" W
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/* h: a& t0 |$ I& u
            {
8 P0 K  ^/ i& `                case '<': /*优先级小于栈顶结点,则运算符入栈*/& q9 c1 M* }/ y2 p: C1 J
                     Push(optr,opr_in);
0 {) T% k* E; [2 `6 w+ Y                     printf("optr入栈:[%c]\n",opr_in.ch);
8 `! w+ u1 s( W2 N) \5 Y                     c=getchar();
9 R' q6 W% ^  U. D4 {9 f$ m9 s0 }3 p                     break;
% _, t5 r6 q" H4 P) X( J                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
/ F0 B5 e( [% D% T- d                     Pop(optr,e);( w+ `1 x. r& D" G8 d
                     printf("optr出栈:去掉括号\n");
$ p! J! R$ o/ H- u2 T& S& m3 @                     c=getchar();
+ w$ W; s% a- T) Z( D                     break;
) e$ i% l$ T6 o% R. `3 H5 x% {                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/  o( O  n+ U( E$ C/ C# o2 Z
                     Pop(optr,opr_t);" I/ i) `7 q$ T) t" Y
                     printf("optr出栈:[%c]\n",opr_t.ch);. z+ F! m9 O8 H; M7 P/ N' V
                     if(Pop(opnd,b)<0)
8 @5 n' b2 M; C- h+ h/ ]                     {
: j+ P& F, a' Q( j' r                         printf("Bad Input!\n");
& j  h8 Z  E" z4 c. H                         fflush(stdin);' F2 J: n( g0 E/ y: `0 b; D
                         return -1;; `" k6 N: |! c: f
                     }: r4 f0 B$ w- M8 @
                     printf("opnd出栈:[%f]\n",b.data);* [) j% d! N, z% X6 |. T2 w
                     if(Pop(opnd,a)<0)
+ h  C) |  d& u- m/ o: l                     {
* N0 M/ O" B% ?+ v! D2 y: I                         printf("Bad Input!\n");
, |3 r6 E  k5 S9 V3 p# D. T) f0 J                         fflush(stdin);# u+ @8 u4 {* f( Q8 d0 i
                         return -1;3 l' ~! z" P: M. k: }% E3 v
                     }) E- [( G8 L8 ?7 Y
                     printf("opnd出栈:[%f]\n",a.data);! |1 a  g, J1 K& Q" R
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
- h2 v5 o. J# m+ W) e6 X9 O1 r                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/( Z5 B. a8 G+ S" d" S+ M9 i
                     printf("结果入栈:[%f]\n",opn_tmp.data);
! l2 u5 l" C# G2 {3 h$ F- P- b                     break;( e2 X2 O  l4 v( k' K2 v; z" ~
            }
' E" h3 O: `' {1 U        }
6 ^) l. ~4 e, B* O$ d        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
2 C% \6 [2 w3 T& g    }
; F6 z: e  S. i0 K/ \9 m% n    GetTop(opnd,opn_tmp);
5 C3 [2 K' L) Z$ U    DestroyStack(optr);  r* A/ x9 p5 z: R7 F' B
    DestroyStack(opnd);5 k: {) l2 e# Q: U- U
    return opn_tmp.data;
/ `% S9 T" H- B, s& }% i( t8 q7 T}3 z2 \0 s5 k. K; Y  z7 z2 h+ g2 q

+ N% F! w6 @  |: t# s9 ^$ @char *killzero(char *res,float result)
( C, R( w5 ~+ p& {6 M{' v3 J0 K5 N, p6 z! T
    int i;. [# l+ p9 e+ _8 f8 P/ M

3 l6 v6 V7 z6 R$ t    sprintf(res,"%f",result);
+ P) t2 H8 p3 ?/ P' v* z$ K* T/ ]; A    i=(int)strlen(res)-1;% b7 b6 D5 R' j6 v* `
    while(i&&res=='0')) B6 D1 J+ B' \+ U$ p
    {( T) i8 u+ \' O( M
        res='\0';
# b9 J, f/ H* x. ?& J        i--;" @. ^9 y! k( S5 k5 n! p. P5 v
    }
) n3 Y0 w" [# @8 |( H2 q2 _' ?% h' c    if(res=='.')
; h2 Y- p+ J7 d- C6 E! Y' q7 j        res='\0';+ c  j7 I) j8 d: Q* h, W
    return res;4 o) T! u! {. r. x. C1 }$ h' c  H
}
4 k$ d# |: U4 k& q
0 ^5 F4 D0 ?* Y& n" h4 bint main(), U$ j: L: X% K$ p4 n9 U! c: o
{. I# X: `* z3 R7 `( l3 Y9 w4 k3 b
    char ch;0 L) m# o1 G  }1 S/ h  _# K
    char res[64];
8 ]- @! X* h0 ]9 o5 a, q' |0 E    float result;
0 o! Q- r# C+ @2 \+ G8 B0 W    while(1)
7 S( d6 @( X- [* N$ p    {" ^5 p, {" A6 ~; G# G
        result=compute();; o; s4 l4 O% I' |  i
        printf("\nThe result is:%s\n",killzero(res,result));
0 T2 S+ ]0 l' W: m' Q- u- {4 J' `. J        printf("Do you want to continue(y/n)?:") ;; {& h/ d$ @! V' h7 N. p% _( K% o& g
        ch=getch();2 j# T4 S: G5 x" h( N1 l& P
        putchar(ch);/ D$ h$ x3 a9 }
        if(ch=='n'||ch=='N')  c5 I) f& ]* H- C/ r
            break;5 |1 W( ?) I2 W& g" c4 i* D: ~
        else$ k" F6 G& T) l0 I+ \) @4 R  g3 z6 Y1 w
            system("cls");" _! f2 t6 F2 V* L) U. V: @; P
    }. g- i7 I7 V" G4 n
    return 0;
* \* c. m9 V) z" l) [}

1 _) L6 R; v' {6 `' K! G; H3 |7 d& r, x) T
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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