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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.% a' [1 N2 V. w# o+ y8 \
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=4 z: B6 {4 c, h1 j0 A  W# v6 `5 g
/**************表达式计算器************/
0 C3 ^+ h3 V1 M: L9 ?8 _" u#include <stdio.h>
1 q' q% L0 a6 u#include <stdlib.h>* t# M; |: h" B4 T: i% w5 r* U
#include <string.h>0 e$ z; Z& Z( Y! k) ]7 ^
#include <conio.h>
( W. i9 }5 b& |, X9 B* L#include <malloc.h>7 D5 X/ P  e0 n
$ W& u" J# F4 j* G
#define STACK_SIZE 100; A) z2 @9 `% U( _# P" \) u$ t; a
#define APPEND_SIZE 10
( M7 _* X. [  C! d" ]$ p7 ?
; C) P3 D& f9 v, E# F7 _  g8 l- ystruct SNode{
3 q, v: I# W) z. O- A- K3 v- p& Z    float data; /*存放操作数或者计算结果*/
% t4 j& `; e9 u    char ch; /*存放运算符*/$ L* M/ F) |& \# R
};
3 Z+ W6 c3 x# c1 m0 c3 W% R2 m
' f- Z! e; F2 R. a. ^struct Stack{
# m0 T2 q5 A5 M# R    SNode *top;
: m3 ?2 M8 ~; l: G! C    SNode *base;
& P" Y* C. ~4 y! Y* Z) r3 s$ Y    int size;5 `7 [0 N" c; F+ ]& U; m
};
/ e+ x- i& i2 z& {9 `  p
+ }4 [9 z2 ?9 V+ I3 v: A/*栈操作函数*/
: G0 t3 k. ]1 t$ Sint InitStack(Stack &S); /*创建栈*/
0 L% ?7 R$ [: Q/ |9 pint DestroyStack(Stack &S); /*销毁栈*// e3 P. D+ W" f" ^3 I2 ^3 A+ D0 Z
int ClearStack(Stack &S); /*清空栈*/3 f  l8 L0 q+ R
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/6 Y- K2 ~/ H2 [0 K+ d/ C
int Push(Stack &S,SNode e); /*将结点e压入栈*/
6 l' n; u0 i! xint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/) V1 `1 D' q" L# H
5 n5 G" u( `; c  g0 E& m
/*表达式计算器相关函数*/
5 Y% V8 I- K9 \9 g8 q3 hchar get_precede(char s,char c); /*判断运算符s和c的优先级*/& |5 W* f: R  @$ M4 m2 o
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/+ Y$ G7 x* O3 \  O# M# q! x
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/7 l/ l2 n' S4 @& O
float compute(); /*表达式结算器主函数*/& n% e$ t. l2 W# v  \
char *killzero(float result); /*去掉结果后面的0*/ 1 z1 L* D# b/ V$ y2 |* x0 Z6 a

! C% R9 L) }: m4 |& O. Oint InitStack(Stack &S)) U+ w1 w8 i5 d: h
{/ ^! J3 M6 {# y8 Z. K
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));& h) r0 |9 K7 e2 H' A  K+ l' I4 b& K
    if(S.base==NULL)9 m0 Z- b+ L" A
    {9 C. Q+ n; v6 k! A' J- b
        printf("动态分配内存失败!");, m& ^1 N+ c6 G" f9 o, L
        return -1;& l2 i. T, c- e
    }
- F2 V2 Q6 g8 E    S.top=S.base;! U7 |0 H  F4 b$ T5 {( v
    S.size=STACK_SIZE;2 b, E, u: F/ q8 y; W5 m( c$ k
    return 0;
1 }+ m+ X! ]& s}
0 J/ M5 P. b0 J; Y6 c$ `: U
$ k3 p% W- G6 v2 w9 F! _) L3 rint DestroyStack(Stack &S)2 P) P: z0 F0 d4 N
{
, P' d5 H. S5 P    free(S.base);( ]4 \2 e; Y6 b) w' P( p
    return 0;2 A' ]5 w* p  @
}
4 O9 b1 X$ A/ h4 |" z
/ ], K9 o& m# Z3 K5 C$ [1 ]int ClearStack(Stack &S)
8 z) `" W4 B/ M) \. G3 Y{4 d  r" c$ c8 g! T* \
    S.top=S.base;! L" ~7 n, j2 H8 Q0 q7 k, m
    return 0;
/ e  z) O! @9 @! `& }3 p! H, J. G( e}
; R( \) O: U' O5 a9 r. p/ n1 q* U: H; a' Q: h' M- y' j
int GetTop(Stack S,SNode &e)
* R7 W* |6 [7 [/ e{% L( S# \5 B: I( V! h
    if(S.top==S.base)
2 S4 ^) X1 W9 ]7 j9 A0 Q( b    {, c! X$ f0 {& m) {( p
        printf("栈以为空!");
2 ~( D% C; A$ D' S7 q' T9 d/ D        return -1;' J4 P4 d3 ?$ o  q* W
    }: K! p' ?1 n: ?& R# a: Y
    e=*(S.top-1);
! G) p% `/ j) v9 Z, ^$ F% |8 f    return 0;3 |1 X  a) |# C5 W! G/ I
}
) }/ o: J" A( f* ]0 E# v3 h- b0 F, y5 h  y* B1 |2 u5 a
int Push(Stack &S,SNode e)
+ i. n. D: P! c{
" A) @9 E# p9 r; y% s+ x7 c    if(S.top-S.base>=S.size)
$ o( k7 r, o: T  V( n9 t  I    {. m8 f$ Y4 [4 z, U! s. d$ q
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
$ j% l8 S+ a) j- h, i* l  x0 r        if(S.base==NULL)
6 T! Y9 L( I# h5 a5 w. c4 b$ G, o        {3 t, q4 E) ~: l: X
            printf("动态分配内存失败!");0 ]0 m! Q( C" d
            return -1;
$ k- g! U. ?7 L        }
6 D% ^6 u" t: x0 B        S.top=S.base+S.size;
4 J% w8 t$ \: U2 H* r+ v; d0 A        S.size+=APPEND_SIZE;
1 n' S& F. N3 U! m. v) e4 L    }
1 z4 i1 d# p* @' I1 t8 ]    *S.top=e;2 N" r. {$ ^$ T+ @1 }9 t; E
    S.top++;1 t9 W- C0 U( x8 ]7 S! B9 d
    return 0;" D) ~5 q2 t8 r/ q
}
3 l' \1 q; M- a) @) B$ c! ]1 S7 [& X/ f
int Pop(Stack &S,SNode &e)! ]- o$ G1 z+ ]1 K! U. C0 b
{
4 V/ L% k9 e/ Q    if(S.top==S.base)
% N3 ?/ P" g% {" I2 X    {. l1 Q# B! P8 |/ K, f. s
        printf("栈为空!");
9 l! s6 W# u6 g2 L; ^        return -1;" x# V( V/ ^- u1 k9 U
    }
" S$ N0 m5 w8 ~. E    e=*(S.top-1);
# \0 w1 p1 l2 h' m( n    S.top--;
! I5 F4 D  V- {  T2 q6 E/ x) z    return 0;; S' D  c2 R6 N2 {, t+ V2 i" v& c
}
0 C1 k$ c* d4 [& }: f
, F  ?; h5 n1 nchar get_precede(char s,char c)# A' }( y# z7 w1 a
{& d4 \" C& K. [! q; \3 P& g
    switch(s)% S/ L% ]5 B9 R* N' Z8 u  h
    {  j6 v6 W8 q% Q- u! R! b6 }! P
        case '+':                 * j; o& S: G* O
        case '-':* |1 F* N) W# A8 s" N
             if(c=='+'||c=='-'); p7 X6 y! z- `/ [8 E: m& Z. i
                 return '>';
5 C' q* |2 e$ \+ h             else if(c=='*'||c=='/')% P* |2 z1 N+ A! N: o+ l
                 return '<';8 V/ _* [9 k# N$ O+ M6 P) c( G
             else if(c=='(')4 G* t" l0 |$ I9 B; I4 T
                 return '<';, o% Q3 E* I; V: V0 _/ C! [+ ?
             else if(c==')'); _# Z* t2 E4 u& Z2 d. r
                 return '>';
1 Y$ `& Q; c: i* Z9 e             else
9 i* n4 ?! W: H0 t  S3 s  a; a! B                 return '>';
0 w" D. s! a5 E( ~        case '*':6 Q+ U& y! t# C, Y% u2 h
        case '/':$ w+ C7 q* O5 Z+ E
             if(c=='+'||c=='-')! C! I8 j, [" W2 \: h# |* Y
                 return '>';6 W- ]/ n2 k' I0 n: i* k. v- ?. Z
             else if(c=='*'||c=='/')6 o+ m' j  X" {' U8 n9 f
                 return '>';0 z: z  i  [( d0 T% H( S  p
             else if(c=='(')
2 y, ^: U, v; }3 C' N: Z* d                 return '<';6 }, K1 G' f. |9 w. ]# [
             else if(c==')')
' h, A3 t) b' W3 e$ `                 return '>';
! X/ i* m. a' P7 D7 O1 Y3 _6 w9 k/ i             else
. ~0 G- \. d9 u* s  n% u                 return '>';+ ^, G, g/ H& t7 p) r' q- \
        case '(':9 N1 s0 |2 G$ r8 f: X8 o. y1 g. ?
             if(c=='+'||c=='-')0 {/ o1 Y+ ^$ W) a
                 return '<';
% Y+ v2 X2 t1 ^) d( Q  Q. r             else if(c=='*'||c=='/')
( X  \3 Z) K3 p                 return '<';( I' ~6 s; e  z% X; d
             else if(c=='('), L0 @8 N: n/ A7 _( U
                 return '<';
1 W, \7 s. w$ y- b, p             else if(c==')')' `& H0 ~1 {' A
                 return '=';
9 _6 [' @% A) ~  v7 a. O1 P             else% y4 _. f2 K3 V2 S* x* N" W2 J
                 return 'E';% Y0 S% d/ D9 U/ X1 G
        case ')':
) N! q( E" Q2 T+ H  }             if(c=='+'||c=='-')
' K8 m5 M2 E: i: Q- e- {4 Q                 return '>';) A  j- ^) v  Q5 u- [0 ?
             else if(c=='*'||c=='/')
: Z9 B6 R3 D# d: h, [2 j                 return '>';3 J" m" n$ T9 s( ]
             else if(c=='(')
5 v0 O0 [8 j0 ^9 ]$ r1 X0 I% f                 return 'E';. z! A- E) O5 u$ M  @
             else if(c==')')
$ w4 w2 H- j$ T; d8 e1 ^2 i. N                 return '>';, M: |! \6 d3 E6 d$ w) w
             else
9 `6 F* o5 Y. ]4 P! G" _4 q                 return '>';
& U3 T, h$ R: V' h0 n8 E- M        case '#':
6 Z" E. U3 ^9 H9 R8 |4 L             if(c=='+'||c=='-')! o1 }$ R/ p' K, ?- Q
                 return '<';
1 N# u; ]2 i: R. A/ o/ I& L             else if(c=='*'||c=='/')
7 u# U  J1 C6 `8 V' T                 return '<';1 r, i% S" M! @7 s# K" _' ]5 \4 c+ u
             else if(c=='(')% C1 m! U& u6 X8 u9 _
                 return '<';
0 j. M' \7 V! P, H3 D* h; L; _             else if(c==')')$ A# l! [% o  b5 _8 L
                 return 'E';: b' w, G1 U0 `, _& Z: f3 {; z
             else
! q9 \0 u4 M7 t' i& f6 q                 return '=';( O( X* Z% S$ o
        default:1 X  ]% b% S! y6 l: E/ M
             break;
7 j# R3 i6 a- Q3 E% n4 o0 a2 t    }1 y, M+ M. u/ @- R- _
    return 0;    " L8 S: e7 ]1 D# K/ E( B- r# _
}
. W* G% c2 Y! i/ ]+ t) w! v3 w- L# K: }! D9 n3 f2 x
int isOpr(char c)( F, v) Y4 c2 a  J" W8 Y
{  M! P  D$ u$ S7 s0 ]
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')/ h. A) m- g$ c
        return 0;6 S/ T% o( y! c& g2 \0 v3 ?6 j( `: K
    else ; [7 y$ n* c9 U# T% R4 }
        return 1;
- T' n" W) L1 e}
% |+ t& z" D" a- K  }9 b# B0 {* H: w/ F
float operate(float x, char opr, float y)
: {% [, c6 C) P! ?( x{3 u0 V& k& D6 B6 t$ W+ |! A. s& P, `
    float result;
# W( y6 t8 H/ X# U3 v& Y    switch (opr), W3 m9 `7 j( y, f& W2 m
    {$ n- A3 e6 _  U4 y
        case '+': 2 y- X  V2 i9 ]- z1 n3 }- Z) p
             result = x + y;  G; H+ ]8 D% f8 G: N
             break;
( a1 ^! Z( ]* f/ @' u        case '-':
: }1 h" H9 [. o6 w5 `8 a6 H( Y9 z             result = x - y;
: m# @7 P6 p9 K7 d8 m             break;9 L2 z& G& h  C$ B) j/ D
        case '*': ! D5 n  d& ?: m9 J  S% J
             result = x * y;
0 _6 i; I* s! X. H% P             break;2 ?$ S* G; K* F4 i2 T4 k
        case '/':
3 P# @0 F- y8 l, O8 C, l             if (y == 0)/ q) M: P% x6 T6 _
             {! D1 U  H0 ~: B, P3 s  j: @
                printf("Divided by zero!\n");( P2 N3 ?8 B! K4 r( Q, ~: @8 h
                return 0;* |  S/ t! I! i: Q# D) `. N
             }: S- p& ^+ G& ^0 L% R
             else- ]- z3 L( o/ B
             {
9 j9 L9 a' D2 H+ y                 result = x / y;
- R: Y: U# ?$ \  \, e$ K0 B3 G5 l" P5 ^                 break;
& l; x8 S* d+ Q7 A+ b3 i             }, R% D3 x; ]5 h3 ~% I8 t
       default: * C3 ~9 \; O' `0 N* S9 ?
             printf("Bad Input.\n");
/ t0 s9 b2 Z5 A( Y1 K, d/ [4 \             return 0;8 i! |6 X! T& K" M5 e7 m" {( |
    }% @+ k3 |) @6 B( N, R6 |1 S& c* n5 o
    return result;" R8 B  w9 R; G+ C/ q- J2 R
}    9 D+ {2 N0 L& R- M! M6 M
3 U$ k" h$ b" t7 R3 l
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
; @$ n' `) r1 |- _0 v7 V{- |1 M- ]6 h; G
    Stack optr,opnd;
% {! u5 ~; V7 w) X9 t: r5 d( M7 h    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;2 K( {; m& g; Y$ ^
    char c;
8 z/ J+ X) Y7 K' F    char buf[16];6 F6 {9 z3 F( _* Z7 k' M
    int i=0;
2 P. n. P5 G- }    : Q- B1 X2 H3 u" E& H' w; X
    InitStack(optr); /*用于寄存运算符*/, c/ `. R1 U, ^+ a
    InitStack(opnd); /*用于寄存操作数和计算结果*/
' U# H- b) h2 ~) P6 z7 J; e! }# q    memset(buf,0,sizeof(buf));
% z7 g. X2 G* Z0 ^   
% x; i- Q2 M# Y4 h% I    printf("Enter your expression:");2 ^# c% X# D" {! q* X3 ]9 [
        2 V0 i8 O4 b5 Z' X
    opr_in.ch='#';
+ \# t  x/ c! A7 H    Push(optr,opr_in); /*'#'入栈*/" Y+ J+ Z  f! e- W5 o
    GetTop(optr,opr_top);( m/ h( h; y( W# I' e& O
    c=getchar();7 _4 L. M9 [/ k: [" l
    while(c!='='||opr_top.ch!='#')
8 y5 W2 ~6 ?$ O3 P/ w    {
$ U* D# z: [- O        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
- v* ]1 j- T& a: ^- y+ \        {4 t# D* V3 u) b
            buf=c;
% y2 Y. [0 m/ P            i++;& S/ H6 c5 }, I* w3 W
            c=getchar();
& ^# X' H* _7 L+ s$ W        }
. ?) B6 u2 |) l0 g0 S8 T$ X2 u+ p& a        else /*是运算符*/. ~& }) [, [. N- k3 @# j+ Q0 {
        {1 `- |( f0 Y* I/ v5 Q' K4 q
            buf='\0';+ s& K% h1 V7 {7 q
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/) {7 b: p- e7 L& n+ u
            {
+ t' J  P5 s, |" S( W) Y" R                 opn_in.data=(float)atof(buf);# v1 k2 f4 h1 k6 x: Q5 J' u
                 Push(opnd,opn_in);
. W+ K& _. \% T6 }8 U                 printf("opnd入栈:[%f]\n",opn_in.data);
( Z! o& @& l8 c  i                 i=0;
+ B1 ^6 ^4 C! b                 memset(buf,0,sizeof(buf));
: C- ]% l% D' x+ L& U$ f' k5 w1 Q            }2 H$ C3 x/ b; ~$ w/ g
            opr_in.ch=c;0 x3 S7 c1 s( X/ w0 o( U" c- W
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/$ f8 F: P+ c- p5 j
            {
: ^% m7 `8 O# S  A: E. x$ Y6 B                case '<': /*优先级小于栈顶结点,则运算符入栈*/+ |- f6 t0 D' _
                     Push(optr,opr_in);
  ?  C" Y9 V3 u! C" Q/ m; k# r                     printf("optr入栈:[%c]\n",opr_in.ch);
; ^2 q/ b4 v* R3 f/ `% ^                     c=getchar();( o1 B! }5 g) f' ]3 f
                     break;6 [' J. {0 M: H$ V1 I  R; \
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 V) v6 m* B' h3 A% `. E+ ~2 G
                     Pop(optr,e);
& a8 l, B( @* g' h" y) N" c- Q6 @                     printf("optr出栈:去掉括号\n");
$ d- w7 q  o# x7 k                     c=getchar();' W  H7 {% [% y, R* x
                     break;' N7 T: k) k4 Q$ b9 Z. e0 W
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
: Z6 w1 u" `& X) r6 n                     Pop(optr,opr_t);
$ f7 p' Y7 W# X! v4 ~                     printf("optr出栈:[%c]\n",opr_t.ch);
1 K# j/ h  Q! x7 N6 H                     if(Pop(opnd,b)<0)- j* x, Y5 L, M4 ?, `# I
                     {/ [7 c& V" [5 S+ I
                         printf("Bad Input!\n");) V: B. r7 p1 w$ }
                         fflush(stdin);# M! Q7 w. E5 e  U
                         return -1;/ d  B( y2 @' Q7 F( F3 W5 X; r
                     }- S. j0 ~6 z& r
                     printf("opnd出栈:[%f]\n",b.data);
4 ]% N- }3 @+ F, m) f                     if(Pop(opnd,a)<0)" Q; C* _% Y) R- o- E, D
                     {
8 [" l& C  H. i/ B2 f5 Q6 C8 C$ P                         printf("Bad Input!\n");
" e/ c" R* a$ Y; B. C2 K8 P# T; T                         fflush(stdin);
2 s$ `1 H0 K  G% Y0 W                         return -1;8 l# C. d1 d; V
                     }  o" A& @! f8 u: N% n3 v
                     printf("opnd出栈:[%f]\n",a.data);+ C, m2 h0 l- F
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
- V( R, M0 F' X% r6 P. w( f                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/. C  l2 |- S: f/ S2 E/ Z8 c
                     printf("结果入栈:[%f]\n",opn_tmp.data);. I9 B1 |1 t) \  G, K3 J
                     break;
5 L% ?% p! c  e6 m2 g5 r            }/ h" N+ U" ~5 _: k$ w; @/ L
        }
- [4 v9 u+ d# `$ j0 u* j: k' _        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
. |9 G1 n5 @# j% s; M+ V! e    }
1 Z9 m. ?- [, ~4 u) k8 L    GetTop(opnd,opn_tmp);! G/ q8 x& X+ j' d# G, G7 ~
    DestroyStack(optr);4 m8 D$ `! y6 ^. I5 ]+ x4 |1 m3 L) I
    DestroyStack(opnd);  G3 E6 c" ]0 U! {7 }0 G
    return opn_tmp.data;
* Y; |) j# e4 }' t& g}
2 l, L5 _# }  g& P0 C+ j( C7 |  Y' r# O1 M, ^) O8 K
char *killzero(char *res,float result)
" c1 t2 Z* H; g- _5 ^+ `  o{( \3 X) o! t# g4 Q
    int i;
6 M% e" p9 e7 S7 F& _; a: v% }) C: H% H$ W1 X% Y+ J+ P+ j
    sprintf(res,"%f",result);- ^6 ]9 R' S0 _# G1 Z# c9 N
    i=(int)strlen(res)-1;4 C; _% V% U& `
    while(i&&res=='0')9 R+ N( U+ g. c7 ]  g# N
    {
/ g* G% x; r) }# R- y0 O$ f        res='\0';8 Z4 b9 W& \- ^; M6 W0 e
        i--;
" d/ W! V$ x! \, J; T, P: s    }
5 o# j$ L, |1 `    if(res=='.')- }- |( U/ m% {4 G; v2 b5 ^
        res='\0';3 n& h3 x5 |: g6 B. s6 A$ H/ F
    return res;2 ^' X) I/ b6 A* U0 k+ S+ \0 e
}
5 e8 |- n& _7 ?( ?0 d$ P% U
- E8 e! M- p  Q' P1 j  V7 l, H( E2 Pint main()
: ]: O2 K+ Q+ L( {# c2 R{- ^1 F) i; ]& A. i
    char ch;# F7 N' P- `3 [' I" w
    char res[64];7 h9 H; |% E: M. e8 W; N. `
    float result;
% r( u4 O! U& e    while(1)
. Y/ e" C3 E2 M4 V- R. W- n    {
$ u" p, f; Y2 ?, N, f: l7 W        result=compute();) i+ v3 h- L: L* t  x: `2 U. Z
        printf("\nThe result is:%s\n",killzero(res,result));
! X$ m% W  |1 g6 c8 O$ [- O: s        printf("Do you want to continue(y/n)?:") ;/ q- Y7 Y- u* z- Q  T
        ch=getch();
9 H/ k# ?# g3 A9 [$ s: M! K: t        putchar(ch);
* X* }- z! ~- Y5 v6 v        if(ch=='n'||ch=='N')0 L: m0 Y" c% q7 ]1 H/ z
            break;
, Q/ r6 w; p$ ]        else/ t* P! K' r' `
            system("cls");
* Q; [8 `* ^" [3 c    }
0 b  C, ^6 r2 n$ Q    return 0;- f% F9 `7 {" r2 T/ r
}
% Z3 x/ _& G, s- O+ }8 k

! G! x/ z- }6 C( z& Y* M[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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