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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.$ O3 m9 b/ z, E* ~
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=5 l& F, p: |+ g' P4 @, J" U
/**************表达式计算器************/' L& G+ {5 @$ q2 }4 V
#include <stdio.h>6 F) c3 m3 w* m5 D3 ~8 B5 A6 [
#include <stdlib.h>
# ]1 M3 \4 f$ k/ u/ r2 K#include <string.h>
3 Q) N& Y: R  s) R- a+ F#include <conio.h>
5 q4 Q2 w& G* o( ~% a#include <malloc.h>
$ k4 Q# A. z/ f2 o7 d( R9 p2 q5 M
#define STACK_SIZE 100
6 {6 \/ ?* h5 r. `) w6 o$ T7 V#define APPEND_SIZE 106 N7 N! t& i4 q
0 A) v3 e0 e  P3 C: l7 |
struct SNode{+ Z% ~0 X2 ?" j  g
    float data; /*存放操作数或者计算结果*/
- s. V# |- D; D7 X% K! g. m    char ch; /*存放运算符*/
& W, H1 m, y3 ^};! H( N7 X& B# L7 T* J
% [) |9 M% C' m$ K  Q' U8 j4 ]
struct Stack{
# h2 h8 u" z/ E' p2 @    SNode *top;
4 U9 q, Z4 j, N1 p5 s( G, t    SNode *base;
+ T* ^" J% x; `2 b    int size;% \# j0 R; {$ E# ?0 ?" ]* {; c! {9 T
};+ \4 N# k6 }& R" t6 _
' q' L: U$ ?* t  w' I/ |% h* Q+ \( D
/*栈操作函数*/& r3 Z1 }. r1 L4 v* B" `1 |
int InitStack(Stack &S); /*创建栈*/% b1 g& U% x7 T$ m/ [3 Y; @' S& o
int DestroyStack(Stack &S); /*销毁栈*/
% G. N1 k5 R" m' e4 W6 p5 p8 o: |int ClearStack(Stack &S); /*清空栈*/- w2 k% G/ d' H
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/: |( K. h/ }$ r9 U- M3 b) p
int Push(Stack &S,SNode e); /*将结点e压入栈*/" {, ?/ `( e1 x; [' P
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
, y% \8 B8 d2 i1 F/ v5 w+ m# R
) z2 m/ H& `6 o  |, ~/*表达式计算器相关函数*/
. @+ J4 Y1 ^& Uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/6 m$ R$ t$ n* D" D7 ]
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/7 P! E- }6 p+ Q+ ?
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
# M8 @) n, D- B5 M1 K8 b0 hfloat compute(); /*表达式结算器主函数*/  q" ]: [" l& E7 r3 Y
char *killzero(float result); /*去掉结果后面的0*/
% j. z  o7 ?' e& l
2 I. [7 C. y% a; c# P% H( Cint InitStack(Stack &S)
4 ^% [0 N  U4 S% E9 W% j- |{
" a+ C) m. X1 S3 d' i5 S    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));3 Q) P; t2 ]2 @! o/ j6 @
    if(S.base==NULL)
9 e5 w. @" `0 e    {
# W$ ?6 o3 [* P& r        printf("动态分配内存失败!");7 z. }1 l6 ]6 t, ^4 q- K- E
        return -1;
4 |* N: s7 [; H4 ?, H- ?1 a; G    }
4 N8 @0 m. [3 D& m' A    S.top=S.base;3 J4 [: T. K2 t; ?. x- j
    S.size=STACK_SIZE;
3 @0 x/ c, b2 M% h- |: m: L    return 0;
0 [' ]( ]2 E0 h8 v. h}
9 O/ V! w% T' ]! }
9 t! P- m  v* z6 Bint DestroyStack(Stack &S)
- K" R* I  Z" O% s, z+ s; l# e, ]{$ ~' e3 z9 b( c+ X. a0 s  |4 D; t/ g
    free(S.base);$ l$ W1 Q. k, S1 S
    return 0;
& g# [: _, ^3 q0 T/ ~4 B: K}$ \) V4 ?# a6 c$ w. g

1 E# a2 x: y7 H. \0 W- E2 d& `int ClearStack(Stack &S)
4 {. E' O- b- n! [{$ d  _% w( A$ u" i6 w7 R- m
    S.top=S.base;% B" h% k9 r$ z' S9 K# e
    return 0;
. Q7 b6 {+ y; F1 v. B3 }' f}
1 k. u- \5 @# D! G- V2 n4 \) j8 e) d" a, X
int GetTop(Stack S,SNode &e)
2 s& h4 n1 U+ e. C1 a{( r( _. W+ {0 B1 P5 q* e, a
    if(S.top==S.base)1 {& m* k9 s# s. d- p
    {/ z& N/ E1 ?' S3 U( V1 }& j
        printf("栈以为空!");6 x6 P& m" C7 K9 L) l3 O6 z8 e
        return -1;. e0 ]! m. d* ^( Q0 {
    }
( k* K* `9 J+ L! y    e=*(S.top-1);
! V4 {$ y, I: [    return 0;' }$ I" [8 h. Y( W5 O7 o+ Z
}
1 V0 G5 G! U% K
! S- E; p% P' tint Push(Stack &S,SNode e)  r7 [" x- l6 e6 X
{% c2 a+ r# W/ X
    if(S.top-S.base>=S.size)! f4 u! s# D! ^3 E% }, X5 c
    {
! T$ ^  t; ?! b" ?        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
8 l9 e/ L( m$ \  A8 R; }( R) \        if(S.base==NULL)8 j  U) k4 s/ m( J
        {* @1 s0 [; P+ ?# q
            printf("动态分配内存失败!");4 L7 I9 o# D4 T) [2 B' x4 u8 I) d
            return -1;
0 {* q# }5 d9 c7 D        }' L  f' r% ]! `6 W: T, e3 M- T/ u6 @
        S.top=S.base+S.size;1 G: C' F9 O! e7 v5 T8 r
        S.size+=APPEND_SIZE;
( [" K7 |3 x7 ^    }& s- v7 S$ r7 u2 d0 p
    *S.top=e;' M2 E$ `9 S' O6 d5 [) P
    S.top++;
8 z& S3 p* a) c2 n" O$ s    return 0;! h! q+ x0 a. V6 W  _- c
}$ K$ a5 g" L( ~/ o6 U! ?
/ C( A& m2 V% F' X. k/ ]3 V
int Pop(Stack &S,SNode &e)3 f( N7 x  K7 `/ U
{( Z/ ]3 ?, c+ X3 ]: w1 V
    if(S.top==S.base)
# C& ]' n, l( k) `    {4 }. t% N. D# J. q
        printf("栈为空!");. Q: x& N$ C! J9 o3 Z
        return -1;: q/ D% ~5 K+ k3 J6 i9 r" y! l
    }
) X8 w6 U2 s" [  A    e=*(S.top-1);0 f; Q# ^& \) r! N* j
    S.top--;
7 I) ^7 X& [3 C" @4 `! Y    return 0;
# C5 |/ Q, J! u$ \, u}
% X* G  g. I4 X4 O1 g$ Z" i
6 O$ L3 J. C- f/ c* bchar get_precede(char s,char c)9 D0 [' n" X" j. {
{
* g3 u$ X% z; [3 E$ G7 l2 k    switch(s)
% j! Z% ?! _, ?2 P+ A    {% v+ R9 Z% S4 [& b+ t+ c
        case '+':                 6 M1 ^  i* t  ?, ~1 [' y/ C
        case '-':7 j8 G4 ~6 K: V4 N. }/ s2 b
             if(c=='+'||c=='-')
0 e- G; p( H. V2 K1 P, Q5 t7 C                 return '>';
9 Y4 ^9 a9 E4 g  M             else if(c=='*'||c=='/')
; J' H, m: b- {) b3 I, y, a/ `                 return '<';! H0 X0 w9 D7 V  t2 g
             else if(c=='(')5 r5 a0 g5 @8 N1 }8 ~1 [: t
                 return '<';
, q4 b7 l( Q% c2 H5 s0 E  M4 E             else if(c==')')
& s, B" k" ^# O; n9 a- k                 return '>';
6 w: V- H. O7 _& D) Z             else * z% ~( e9 f) t3 ]* t3 D# u
                 return '>';+ _; C/ x, J0 p, l* U4 M
        case '*':/ X/ p' J! Q# Z4 V& R
        case '/':
6 B. X) i% S: j6 W             if(c=='+'||c=='-'); H6 p! [+ K# O/ _; |4 F
                 return '>';" d8 d% l* ^6 r
             else if(c=='*'||c=='/'): `  y* ~* P3 b$ f  r
                 return '>';
% n" w$ Z7 \$ L             else if(c=='(')5 P) I* b. F: e- C9 ?5 R1 J2 C
                 return '<';
2 j1 H9 ^8 m9 h3 R             else if(c==')')* B0 V* h. N0 W4 M6 c% Y
                 return '>';
  x  y3 P# {) C% |, Q1 e             else/ f' @; g# Z0 m
                 return '>';$ T- O" V: y' j7 s
        case '(':
# u& H  E6 Q8 O6 J/ V             if(c=='+'||c=='-')
# {3 i0 S, D  g5 \5 x                 return '<';
7 o) t1 O) e. o  i! e             else if(c=='*'||c=='/')
" q% n& v0 W7 G0 `4 V$ r                 return '<';
! c1 t1 M5 l0 }- g4 ]             else if(c=='(')) L4 [1 p8 i0 X  \
                 return '<';
$ T! e) Y% P5 R9 C3 i  Q             else if(c==')')
) k2 Z$ j! \4 q" l! `                 return '=';
9 W0 A& `, R( Y" ~; r# S) b             else* o% S: ?4 S2 H
                 return 'E';
1 j, @3 N! b- Z' `% y9 F) z+ q/ p        case ')':. S. }; k( d! a
             if(c=='+'||c=='-')
  Z9 b& k! w+ w8 O                 return '>';" l8 Z/ p" p# W5 b
             else if(c=='*'||c=='/')& q5 \- n% `* E
                 return '>';
4 r9 g7 j8 x: ^             else if(c=='(')* _3 V. W" [2 `
                 return 'E';
5 k7 N8 ?: l6 R             else if(c==')')
+ _: x0 ]$ Y- ~1 |. N                 return '>';
- m( ]0 u8 x, U: o! M' B! u             else6 Q  n5 @" f9 J3 M+ D6 K& E1 G
                 return '>';2 e! q9 Z# p$ ~& L; v
        case '#':
; Z* ~5 ?& R$ H  h% _; o2 K             if(c=='+'||c=='-')
& O: K! n& K. K/ {  v  X. y                 return '<';5 z: ~) w0 P+ w% a" j* Z$ d
             else if(c=='*'||c=='/')
/ j/ F, o0 J, G; I1 q                 return '<';
+ |( t6 g8 z. Y             else if(c=='(')
9 z; Z9 s+ f* [+ L; {) Q4 v/ S                 return '<';: H$ h: v$ y3 p+ ]* Z
             else if(c==')')
7 \- C- i" w# _9 c4 y. S                 return 'E';
( Q0 G0 ]% w# n) I, b             else7 Y. k- _9 [3 J$ Z
                 return '=';9 Z/ N3 G0 g- N" e# ?
        default:" j9 B7 m, [! P8 b( ]
             break;
* Y  M  N- z9 s+ Q/ b0 J0 \    }6 m5 x$ R" v" D& [* Q5 b8 p
    return 0;    + B2 P5 D6 \8 Y! s# R% C5 K
}1 @3 a+ z! p8 a8 x. W
+ E( H  i. k+ j- F, l% ~% ~
int isOpr(char c)
% O# e  t5 D- X; K) {5 B& s{2 T% e  E9 k) w3 z( P
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')4 u5 p7 J) o8 @. ~6 o9 ]
        return 0;
2 v/ w3 o$ @. D  C6 _6 R5 a  O! D# \    else
$ U3 N! d) Y' `1 }+ m0 ]/ E        return 1;
- n) E) @& p2 T! k}  U) j7 ?- N% }3 p; [  n

5 N) h: h. K  D3 q) a) Afloat operate(float x, char opr, float y)
6 y+ c4 w& C5 T3 e4 I9 y- @{4 S( e0 M; r: K0 j
    float result;1 s8 b! ]( D  T/ j8 t! I0 j
    switch (opr)
7 `3 n: |3 D. m: G2 r    {3 W6 s6 b: |' ], f# w) j" q
        case '+': 1 D! R) V; ^& x6 g+ I7 @, E
             result = x + y;
% [, z. c( k( M9 r             break;
  q. G8 R/ N$ L/ T8 I        case '-': 3 C9 E6 h% ~* E( |/ L2 Z
             result = x - y;' W( B, C5 K, N
             break;+ {3 [8 E8 l( f) ?& c2 Z8 X
        case '*': 7 j- z7 l( B' l, W$ ~8 ?* ?
             result = x * y;
/ {1 n; ?# |/ j0 l2 k4 `, n             break;3 v1 z" E9 v+ o* `3 ^$ \
        case '/': ' R% R# r3 {; }5 o2 S) v8 x8 s
             if (y == 0)0 w9 w4 i& l* M2 ^3 v$ `
             {1 n7 o7 v9 f6 {5 ]& H/ ?
                printf("Divided by zero!\n");
" o/ R! K* @: w6 \( T7 X. S  n                return 0;: P, O$ D: @/ y7 I
             }" o4 V. x/ I' b, F1 I0 Q' }
             else
! M* M: A1 k4 k! V             {& K  A. x, ], M- _  {
                 result = x / y;; w. `  s, _. j; b6 |) N7 P/ ~& F
                 break;: A+ r9 I6 }' c. L: g/ |
             }# |5 {4 i2 x$ q% _" T4 e
       default:
+ e7 @* J1 h5 U7 Y% K9 N( Z             printf("Bad Input.\n"); + H1 ?& C/ P6 Y% O( I2 i
             return 0;
5 w, |! \2 [1 e1 E+ M    }9 i  v- B; c! x5 z
    return result;0 g/ d1 i; p8 z# b8 y% i+ G, A/ S
}    ' q& a  _% w# n8 @. u" P" _4 Y

7 V7 H7 B/ ?/ d% ^; efloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
/ e) }! Y3 u/ Q) @. r. o{0 T5 [' ]0 W: E& @2 V6 ]) I# O) K" P
    Stack optr,opnd;
0 K; H8 t: k+ J  \9 V2 [    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;+ z3 o: U5 J) ]8 [1 l0 J3 [6 h
    char c;, T; n  j4 Y% t# f+ j
    char buf[16];
8 h, v0 X3 C8 Q    int i=0;
# L+ X0 H; H9 l7 U9 \   
+ k' U* H- `" p5 k1 [1 n    InitStack(optr); /*用于寄存运算符*/
! Y+ s% C& G+ k! Q% C6 X% V5 ]9 q2 H    InitStack(opnd); /*用于寄存操作数和计算结果*/
0 B& q; e1 K& C$ c) y8 n    memset(buf,0,sizeof(buf));  C9 g/ {% W. v: @7 U8 g
   
4 g# h* ?6 U# K8 D( [' H1 r    printf("Enter your expression:");* [& b$ u& _1 t& }& p& t
        
9 W3 p) a7 e; {  K4 }6 l0 r    opr_in.ch='#';, E/ l% l+ T) D' u
    Push(optr,opr_in); /*'#'入栈*/
. p- k7 b/ Y+ M4 T+ K    GetTop(optr,opr_top);0 W5 Y/ \/ r4 @" E, V" ]
    c=getchar();
; x% k* D* ?4 o3 y- g3 d    while(c!='='||opr_top.ch!='#')& `& N/ b4 l. F; _1 u9 E: B
    {
6 q% z8 t3 H- h        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*// ]) ]* I" B/ ]" a& n5 I
        {) }8 L# K; }$ X
            buf=c;# J" S- G1 c  d, X# P
            i++;
$ s3 t# G2 k  X! m4 t            c=getchar();+ ?% E% h6 T# X2 k
        }
- l5 ?( N7 O( P3 `0 q+ {" o# S        else /*是运算符*/& H% q7 q$ Z2 t* q. M! n) {
        {( p8 q* ?" |- |' V7 `0 z! I4 A& {, D
            buf='\0';
7 Z7 y2 G0 m8 H6 @, @# L            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 J& q: y4 ?  @+ r5 F$ [4 K0 k
            {
: m& V  \3 v# x                 opn_in.data=(float)atof(buf);
  v" j* o/ e$ R5 u. l' H! s4 u                 Push(opnd,opn_in);
/ H! B; I) ]& a2 L* w" l% n' S                 printf("opnd入栈:[%f]\n",opn_in.data);
; F, `' u- O0 p3 Q7 ~3 j% Q1 Z: N                 i=0;: V  G% G% m; @( A6 A- |- t. D
                 memset(buf,0,sizeof(buf));, ?0 l2 h  [6 X2 N" o0 _
            }
" v5 ]* U  b1 P, f9 C3 v/ @  }            opr_in.ch=c;1 H8 c* U4 }: J7 V- P' E
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
) U9 ^' [( n& A. n$ K# ?" }            {
- W- A- Y3 X- D/ A! p9 P% X                case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ Z$ a; u# S2 L7 n& u                     Push(optr,opr_in);
; a4 A* R$ y. f# P" g5 N: D                     printf("optr入栈:[%c]\n",opr_in.ch);
/ o; X7 B+ [5 p2 m                     c=getchar();
" \6 B2 _* R" X, @' |2 d+ n                     break;' b! O$ ^8 v: I9 W* \- Z2 W9 ^+ G* q
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
8 A4 j" n) q8 D1 y8 v5 F9 B                     Pop(optr,e);  k5 q4 E: A5 w$ t  _) k  B
                     printf("optr出栈:去掉括号\n");" D1 h2 l1 U% A. j3 C# a' Q
                     c=getchar();
" w5 p3 {* S- y* ?                     break;
& I) _' e6 s3 u1 e  f                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
5 @% T! `2 Y1 }# O1 `                     Pop(optr,opr_t);
9 A# w9 S# _) W3 g+ |- m3 y" I4 k                     printf("optr出栈:[%c]\n",opr_t.ch);+ e9 p# R. O6 Y6 _- @; S& R
                     if(Pop(opnd,b)<0)& F  F0 Z: E$ }; i% M$ v$ Z
                     {
. g$ [* [' Z( C! o  O0 w                         printf("Bad Input!\n");( T+ F! a+ I+ ]; {& X* ^, S
                         fflush(stdin);
" _$ P7 c: ]% u5 k, U3 B                         return -1;, d  L! s5 Y+ E
                     }8 ?' C. I/ I) Z' s1 H6 q: J; ~/ l8 f
                     printf("opnd出栈:[%f]\n",b.data);
  M# r5 [/ F$ o                     if(Pop(opnd,a)<0)6 X" w" V( z" l( A  b, u# M2 ~# o
                     {
8 M0 }  x5 K1 x* `/ e. _, V                         printf("Bad Input!\n");; I- p4 h7 Y& P; ^0 O2 q4 `, i
                         fflush(stdin);
0 u7 H* u, Z# \% w3 a; ~9 n2 c                         return -1;
0 p. p2 |' [5 V# E) u2 ]                     }
) o/ s8 M/ R' _" |                     printf("opnd出栈:[%f]\n",a.data);( W$ P, ]% l! Y: v3 g9 \. z
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9 ?1 B# ?0 K+ v- U                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
  U2 a; g, r3 g# U/ I( S                     printf("结果入栈:[%f]\n",opn_tmp.data);; v+ s$ X" x, c
                     break;
$ c( m/ Y- L- K5 V0 P' i) X            }. c: [1 d9 T' @9 W& O
        }
1 T7 y0 M9 L: {9 E; g6 V4 f        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                3 K$ N; A8 A+ Y) M6 S+ B& H
    }0 l. T1 s  y& v! ^% F! v1 {) ?+ ^
    GetTop(opnd,opn_tmp);
# ?6 b) p$ o6 |) g  f    DestroyStack(optr);
: M) _2 o& l7 r8 J7 \$ S/ E( `    DestroyStack(opnd);
* [. N( Z4 i4 `. u4 y    return opn_tmp.data;
# l; M4 W5 ]4 d6 P) D  N}
. v6 H$ t' d% d* p$ D# ?# f
/ c5 H/ M  G" P7 d; mchar *killzero(char *res,float result)
% v9 }' ~8 Z8 O" |1 }1 v  _6 O/ W{
! ?1 X# \1 M* i7 V    int i;
+ y  m1 P( `5 H5 o$ _& o0 J/ ?
5 `& W2 n+ V" B! N+ P) P  F    sprintf(res,"%f",result);# O/ D5 k' }) Z' e. ~  V; I. H5 Y
    i=(int)strlen(res)-1;
" u8 G0 ~+ `" R( p- p* ~0 _    while(i&&res=='0')3 T2 R+ A3 A4 v$ O5 [9 l4 b
    {
6 Y4 J& F+ h6 Z* E0 A* v        res='\0';" E- B+ ~1 @6 d
        i--;$ t+ j7 M- y2 H! `9 ^4 R
    }% O1 M, L2 |1 {1 b
    if(res=='.')
2 A8 D& a/ S. S! m7 ^        res='\0';8 f) K9 F2 ^5 Z5 E5 q9 c) e
    return res;
7 `3 [" |; H% d  A4 Y' n- F}" V+ h% h1 ?7 p. s

9 s- t' E/ V1 m3 T6 A- e5 ^& J% I, }int main()
" ~+ I) \) m5 {& X{
- t* V, I+ W! U: r8 h5 l    char ch;7 ~" C% E0 v4 T5 c3 H( C" j2 ]
    char res[64];9 c4 z% C7 g1 r% ^' u2 {
    float result;
) p5 Z  ~: o4 p* |, _3 i* \5 E+ S' h    while(1)/ R. W7 u( w  [% f; V  K
    {5 o" D, }  K: X, S2 t+ L
        result=compute();
0 L8 C" L  P$ e        printf("\nThe result is:%s\n",killzero(res,result));
9 @0 A1 r" ?7 T1 n" }& q7 E+ {        printf("Do you want to continue(y/n)?:") ;0 R4 G3 ~! k/ t2 i0 R
        ch=getch();# @: g2 Q2 u% c. V. C
        putchar(ch);
. S" K# e8 }. R7 s- d        if(ch=='n'||ch=='N')- l4 s/ L8 k6 j) T/ G: X" \5 ]  ^
            break;* J- [" {- ]" N
        else# N9 _% X7 |" E0 L" J! E. V9 c
            system("cls");
$ L: `% ]# Q1 [% O+ }) V0 A$ `2 \    }8 J4 h4 E" Z" M. m, V( G
    return 0;: C# D) w7 G8 O" {+ Y/ K
}

. f3 I* D; `2 D+ h& `5 g, g
9 o5 q# K$ U7 y, h2 T[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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