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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
$ x1 @6 E' p; F$ H2 k8 {* Y- n8 K程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=9 Z0 R" m' m* g& ^
/**************表达式计算器************/4 ?3 q0 C7 I9 v, \% D
#include <stdio.h>1 z( h# n6 e& |
#include <stdlib.h>
  P1 t. T* Y( a9 y7 {- r, e2 K: w#include <string.h>
+ z$ t! F9 _- J6 e7 l" i5 d4 z, x#include <conio.h>
+ Z8 Z0 S$ v4 W( z1 @/ H1 O4 q#include <malloc.h>! v8 l6 b- |1 M
  @/ f) E7 Y  Z! H+ K
#define STACK_SIZE 100
( Q1 i/ f3 ]+ Q; V$ k$ s! w3 t#define APPEND_SIZE 10" X) u0 X& J& t! O. |2 v

+ D5 ~7 i" U+ Lstruct SNode{. H" u& f/ W6 Y. j
    float data; /*存放操作数或者计算结果*/6 z! C3 r4 N& ^4 q% d' L+ s# x5 t
    char ch; /*存放运算符*/
$ @8 `# ?$ ~7 ?, `2 s) z};
  d. I+ N: n3 {
$ Y& V- x; j* ^6 o8 H  dstruct Stack{" Z" y; E# d- d+ x: W# u* p
    SNode *top;; t$ H$ K1 c6 {+ X, b6 i
    SNode *base;
0 y; E! V1 l. s, `& c* {    int size;; ~$ |9 l) j1 X3 H) Q
};5 e8 N8 Z" Y' s0 ?8 H; J
1 _4 i* f+ S& a: I  ?4 `1 x% Q! K; [
/*栈操作函数*/
6 ~5 r- c1 e! Tint InitStack(Stack &S); /*创建栈*/
2 ]" f: h. D2 g( ?5 b) tint DestroyStack(Stack &S); /*销毁栈*/
9 m7 P  }5 J* x" H+ u5 j0 Yint ClearStack(Stack &S); /*清空栈*/
' B: p2 }$ h$ |3 W. Rint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
3 I7 m( i' v' B1 L. ^5 zint Push(Stack &S,SNode e); /*将结点e压入栈*/
/ \1 |3 K2 H) z- [int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/; }0 H6 ~% U) y' K

. b6 E% ?: Z" C# S$ S0 x6 h/*表达式计算器相关函数*// T: `, F3 E! l: \2 {
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
8 l& B2 r0 @0 i) Y+ }int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
, @& T0 A. Y- t+ |float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
+ c# T" f( Q) J* s0 O, g$ t- d9 Ofloat compute(); /*表达式结算器主函数*/: b/ h( X% r: ^/ q" o
char *killzero(float result); /*去掉结果后面的0*/ 7 R" x5 s& [8 K( L% q# `

9 c; E( K$ U$ p4 F9 @0 Lint InitStack(Stack &S)
8 [: ]2 x: ~; ^% A6 q{
2 v/ F& V1 A3 m3 b! e    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));( b0 ]" A2 I" |5 K. W0 a
    if(S.base==NULL)
2 I) j/ Y* w0 |3 e' |1 A4 W    {
2 X3 k- c* ?2 s; S# j8 b7 {        printf("动态分配内存失败!");2 D8 ^$ V- G. H) Z
        return -1;; L: L  A1 f3 O
    }' G; P0 h+ ?( A9 P; a. ~7 x/ D( q' C
    S.top=S.base;
1 V" J6 i" \$ B- p    S.size=STACK_SIZE;
! s' f, d. a- L' T' L  {6 v8 N- W5 [0 `    return 0;
  o1 D# S6 Z. D% D}
; I8 n1 d1 ~# h
) ^. [* l6 [- u! c( @$ Mint DestroyStack(Stack &S)" f/ W2 l5 q7 f
{9 N5 s/ D$ A1 k6 `9 x3 Y$ F
    free(S.base);8 O7 I3 r" Y7 k2 K3 V: Z
    return 0;
  h6 M: m  }; t}" k/ Q/ z7 S8 J" v1 x) Y  \

$ k3 G: L; d3 P. q9 z5 I. @2 \int ClearStack(Stack &S)9 N; {9 ~* j, W$ o) k2 Y2 I
{, T8 q, |5 Y; r7 |) ^
    S.top=S.base;( ]/ k% A; V/ g$ u7 L, R5 c
    return 0;
) d3 ]# G# m# k}
. a# Y/ t! i' W
4 W' U& h" a- s5 i6 [1 G" K+ ^  a& bint GetTop(Stack S,SNode &e)0 `1 [7 u7 a2 ?& ^
{
( A$ v* V) @8 m& u. i    if(S.top==S.base)
: ]# d* f- X3 E5 S. Y- \) l    {5 f( k/ |5 E. j7 R" U
        printf("栈以为空!");5 V' a' u+ @! l2 x1 \% ^% L
        return -1;
5 R2 D- g& @6 k2 v$ u% _( o  A1 N$ w# v    }
* Q0 y7 q1 T* n6 G" I    e=*(S.top-1);
; L: f9 D+ A4 }# {4 N    return 0;8 z  q8 u1 \/ m" i
}- B- K7 y9 \- C" I: [  a7 B/ [
! @" b  R( _* V% D
int Push(Stack &S,SNode e)
5 j' L3 o# D# u, D{
2 @" o; ?7 W' t! m    if(S.top-S.base>=S.size)
, |0 d1 f8 A9 n& k  K    {, z) z7 z3 Z( W- K$ h$ P# L
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));1 Z* h3 _8 V, k' K$ k2 g  J
        if(S.base==NULL)1 [  Y9 K+ ~( A
        {
2 s: S" Q& w) A$ `( h5 i            printf("动态分配内存失败!");7 F) o6 R; Q" o  ^. _0 v9 s
            return -1;
3 Q2 L$ t: Q9 a        }
! |8 ]) _$ m4 A  p; J5 {' m/ Y% t        S.top=S.base+S.size;8 K$ i6 l3 R0 W- X5 ?
        S.size+=APPEND_SIZE;0 r1 N) p: V/ i6 E; p3 w6 `
    }
! G% b5 _! x" D! V    *S.top=e;! ^$ ]9 J9 ^5 _' c
    S.top++;
2 a3 y5 |! l& E5 u- V    return 0;  U3 U( S9 x% P+ b
}
$ d! @5 J+ E; e" t+ W/ C4 s; f; d# o& _3 Y+ \6 z& E
int Pop(Stack &S,SNode &e)4 G9 Z- }: w, K1 z
{( ]$ H6 d( o, W# {& P# T
    if(S.top==S.base)
2 w  q" X4 T: @* U: h  L! D% M* S    {
1 v1 `/ j% g1 U& |  g  U        printf("栈为空!");" w( `- @0 l: @5 ~. e, n! S
        return -1;$ V: D+ W7 k: j) W9 O" ^. _( `
    }% E# e( N7 B& g3 @
    e=*(S.top-1);' J8 R- i" L" i& M0 Y
    S.top--;
" D* g+ V- P9 V+ C4 Q& ?5 G/ u    return 0;
" a% r# N$ P' e5 O/ p; P3 e( A}. H% g2 ^8 }& {9 s

* \2 k  J1 E5 X4 @4 {. e7 I- Achar get_precede(char s,char c)
; k% U$ f! h6 `7 l$ a0 v! q  ~8 b{
6 `0 f2 d3 W" [    switch(s)0 B& s- ?9 ~% @) N
    {
9 r& r# `, \# l4 W9 w2 Z7 x        case '+':                 " Y3 T- b, y; k. B1 N7 v; @& j
        case '-':1 S  {' `" u4 h3 Z8 E, j2 F
             if(c=='+'||c=='-')7 D+ \: a$ n3 I( `+ S8 \
                 return '>';
; }8 L; _6 b6 F' d             else if(c=='*'||c=='/')
: h* ~1 \6 K* s. y( [                 return '<';
' K! u5 d8 v, t8 L0 o' \0 z             else if(c=='(')
2 z! q/ D: H3 @: K$ }( D. L                 return '<';
5 t! D, \5 M5 O. M% f* _8 W             else if(c==')')" J3 A5 w: ?( h9 G' t3 ^4 H
                 return '>';% v5 V, C9 a# p6 N" h
             else
. @" }5 T4 A. h3 R* Q* H                 return '>';
# G9 T0 |7 {. e8 z% a        case '*':
+ ?/ |) Q- u1 S        case '/':
# b" T/ G1 l; C. G2 g9 X/ S             if(c=='+'||c=='-')
/ w, n. C! M, a% W                 return '>';" d/ @& Q( ]1 I& L# C( R/ H
             else if(c=='*'||c=='/')+ G0 I; h8 m$ V* a. ^/ ]# X
                 return '>';
. S5 O) g( L, `5 v             else if(c=='(')
$ A+ ?  m) F6 d1 U1 \' ~* l' {                 return '<';* S2 R3 G5 f9 `5 y2 _- w- a$ |
             else if(c==')')
+ v( U. o, i5 `" U                 return '>';
6 h; ]! c' g1 ~* f8 z             else
2 u9 d8 N1 E, b' s                 return '>';
) ]2 b! `, F2 M3 a1 V; I        case '(':
+ H' t9 K) n2 _5 ]             if(c=='+'||c=='-')) {+ Y& E! x" }
                 return '<';
' T2 A3 R/ e/ S5 @+ U% }             else if(c=='*'||c=='/')
% S! b1 B5 ~% Q8 \' [                 return '<';
4 N3 {' H4 ^8 X5 F& A             else if(c=='(')
' M0 V& z& S. {7 e3 y" E# k                 return '<';- Y( z& U$ w& |; f
             else if(c==')'). B3 [- I+ Q9 g  Y3 G, a- p8 r
                 return '=';) `  \$ j3 G. p
             else
; Y0 L/ W4 V  Q: q$ w7 C2 C: e8 B1 o                 return 'E';
0 u8 r" _+ o) G; z4 X/ A& N        case ')':
7 G! g) |" x0 n* l             if(c=='+'||c=='-')) o/ Y  ?& ^( _$ L
                 return '>';
% }5 V) n- _4 ^! Y& O$ e* R             else if(c=='*'||c=='/')4 l  M% e" ^% E" f1 N' a# T
                 return '>';
6 m; o0 j5 s- b6 ~- @             else if(c=='(')7 i. i. e) M1 @+ i
                 return 'E';. U2 S: h$ v& \2 @5 i$ v
             else if(c==')')& o" G9 p! g  e  B# c/ ~
                 return '>';
! Y$ x6 u) }! A0 m; O( l$ g             else
; e9 w- R5 C) |7 d                 return '>';
2 C3 m! h4 }" P- P8 j        case '#':
) l# l1 H3 F4 o7 I             if(c=='+'||c=='-')
( C& z' w: z9 v% x6 i* h; ]6 R                 return '<';
. U8 `2 ?$ `  @- J# @             else if(c=='*'||c=='/')
/ e( r) `* C) z                 return '<';* Y) ?9 B, M( b) T
             else if(c=='(')1 e& j+ d, q% ~  L4 m" _* P
                 return '<';
6 L) u6 E: L" @3 C. x5 e             else if(c==')')# y" A$ n( r  i2 J/ _
                 return 'E';' v+ U7 i& q4 i% S. N& L: ?: g
             else  G7 F( e0 g" o4 R) c' p
                 return '=';
4 Z5 @( u; Q  |. ^* d+ L7 L        default:
5 z# B0 @6 X1 w4 j, z% v- {; X, l             break;
& r% A! t. a( L$ T    }1 g! l4 U( P( h. M* [5 V; V4 O
    return 0;   
7 S1 \0 ^: B, Q7 C0 {( q" W7 P! J. ^}. a5 Q1 n0 D' T6 [" |

# v4 v! q1 {: g6 K7 m9 b) Aint isOpr(char c)
+ s% v1 q. M. H( W; C+ |9 A{' A1 y5 o* q- [1 n5 C6 u
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='), G% w: G8 P, n" m- D  o' P3 n, Q
        return 0;
5 u2 V$ {/ H- h) c. p/ H% H$ f" P    else
4 `2 G) `% Q$ p' j1 r) ]( L, ]        return 1;
$ @* h9 \8 E. _( X6 R6 Y, \}
4 W& X5 K; i/ |. i, H6 u1 r! ~* N9 W+ e5 L; j
float operate(float x, char opr, float y)/ K2 S6 G/ ~) ^) [$ [3 G
{. x% ^: X, L9 Z& I
    float result;3 l8 Z6 s4 b8 E7 {
    switch (opr)
3 g% a3 [# i: U& q$ g    {
5 \, r/ n6 B8 ]( |+ U8 U        case '+':
2 l9 U# o' h/ Q' g             result = x + y;' B4 t# f/ j! Z5 ^
             break;/ t9 q; B7 ]9 Y
        case '-':
; z) Q! C) p" r+ \; ]7 O' _% C             result = x - y;
1 U! U' G2 r1 ?0 g, e             break;
& Y, w/ Q) P8 q5 j! i        case '*': 7 F; q. ?1 g8 y) x, M
             result = x * y;
1 K* Q# W' L5 i             break;
. z4 M$ \. {7 `        case '/':
+ C; h; r; e& b- M, \             if (y == 0)0 H+ n8 x, ^1 C9 S- @$ h8 W0 Z
             {6 m3 H% I* S% e
                printf("Divided by zero!\n");8 {- k+ H# H# V0 V8 x- R$ ^( B# a  s, b
                return 0;
3 V! b2 J9 Z2 v0 m  e             }7 K( L! z1 s8 L6 }4 u( c5 p! T
             else
. ?7 s+ S$ _) T+ U; y, ]             {. y7 p0 D& A$ @( t- @7 _$ M; i% r8 s
                 result = x / y;/ F) c6 [- z0 D9 z' e, l
                 break;
& A+ R- M$ ~% F2 U. O             }
$ x7 o8 q1 Z# |7 r8 ^9 i6 C4 Q       default:
$ h, [2 K3 B: _+ \! T9 a             printf("Bad Input.\n"); 3 I9 H- A2 z5 x, i- X/ P
             return 0;1 n0 M8 K; C- ?' u8 Y) T) j9 }2 k
    }
5 C. N5 u* A5 N( l/ Q7 p    return result;5 o. F2 E* j; ~
}   
6 ^$ ?+ t( L& I0 _/ H+ J1 `% I. N# K
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/4 B) Z( F; R; U
{
7 z( {3 k) {' \( R3 {1 T    Stack optr,opnd;, {, N( U- l2 U# X9 e
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
. n0 m% t" ~  L: q# V/ D, g; L2 T    char c;
% H2 t+ ^$ `0 E) A5 {; w4 F) l) k    char buf[16];/ }" C1 p9 c9 J/ i8 [; d* p
    int i=0;
- [$ L& O8 ]  X9 F   
1 i. d+ D7 w0 @" {    InitStack(optr); /*用于寄存运算符*/% V, A/ l) d2 H8 Z( i
    InitStack(opnd); /*用于寄存操作数和计算结果*/
) k% ]7 C3 @8 @    memset(buf,0,sizeof(buf));$ X1 g# O& r( W. Y4 ~
    / X+ d5 Z9 E( S0 I# o
    printf("Enter your expression:");
# z& \5 w$ Y& }+ }        
9 f7 P0 b( S7 `* ?; }    opr_in.ch='#';4 Z6 I' p# a4 ]& M/ {9 h8 C
    Push(optr,opr_in); /*'#'入栈*/8 |( T0 ]  d1 V; a$ m/ E
    GetTop(optr,opr_top);
% l1 ^& j; H; o    c=getchar();2 o9 s& H; I: ~3 M1 J# D, A5 H; |
    while(c!='='||opr_top.ch!='#')( ], }+ p9 L- \* @8 S4 s* n5 g
    {
# A$ E0 _( s, J: R- \1 {+ W        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/% l6 J; W& e' d( S) b. p
        {
$ G" f; o5 i1 s* b/ G9 x7 B            buf=c;
. ?# o( C2 k4 H6 n7 N! |            i++;& X8 E4 X' b/ D- F0 x9 s) q: h
            c=getchar();
3 C: U/ r  [& U# X        }+ O3 N0 s) n# ~; g1 |" ]
        else /*是运算符*/
9 N8 ?) g8 \4 q( X        {! L7 ~' p" w5 l5 `! l
            buf='\0';' ]; |8 {/ `+ o0 r
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
. C& Q* ^' }; k5 @            {
- u; y, |) E! p- c4 k0 a                 opn_in.data=(float)atof(buf);0 `" h* {3 E+ M& H6 u, o3 r+ h8 B. B
                 Push(opnd,opn_in);
) b1 [  x9 c# [# t                 printf("opnd入栈:[%f]\n",opn_in.data);0 ~& G( T3 ?. p9 p2 m; ^2 d1 e7 g
                 i=0;# R; D' G; c6 n: Q8 q9 u
                 memset(buf,0,sizeof(buf));
  `& N/ v: Z' C8 v) {) A            }
/ e+ `4 ~8 }3 r! }5 \1 m" a6 v  w* f            opr_in.ch=c;
  `1 N. Q* W4 S: g8 h            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
/ J3 F/ t/ Z0 |$ N$ e* Y            {% ?0 n6 H6 B& D' c$ {' y
                case '<': /*优先级小于栈顶结点,则运算符入栈*/, M) B& _- T, ^; C2 ^& B; J
                     Push(optr,opr_in);
1 B6 \+ R9 L# W3 X                     printf("optr入栈:[%c]\n",opr_in.ch);1 x2 T9 M; G- X; D1 z6 T( O
                     c=getchar();6 W) k9 M$ R0 z
                     break;
0 z$ S0 P  d! G' F; ]                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/" r' u& A/ s. k* A
                     Pop(optr,e);
4 W0 g# I3 M  s$ a                     printf("optr出栈:去掉括号\n");$ u; k' ]& c6 W1 a- m( ]
                     c=getchar();- Q4 C$ V7 H) B. s, A
                     break;9 @% P, ?! i' _' S5 j* K, c. G
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/! R& C/ t! l9 p
                     Pop(optr,opr_t);; _- A. r- }1 f+ L1 f
                     printf("optr出栈:[%c]\n",opr_t.ch);
* V8 k) `. \- b& _( ~% C                     if(Pop(opnd,b)<0)8 G1 h$ C& P" t& x+ @0 R: d
                     {' \" `* t3 S2 s+ [3 v! ~' I
                         printf("Bad Input!\n");, K, j" f' D) G) h* n
                         fflush(stdin);
: g3 d* s, r. V! Z9 Z$ \8 X                         return -1;3 _3 R- |4 `6 k( ]* y3 S
                     }- i- @3 Z8 _6 }  L  Z
                     printf("opnd出栈:[%f]\n",b.data);
" c/ i% ~$ X7 j7 h. D                     if(Pop(opnd,a)<0)
7 L9 G8 l% B+ R                     {
1 ?% M) _% U1 q+ ?# [                         printf("Bad Input!\n");) i5 T) d6 d' l, C, ~& J
                         fflush(stdin);
/ q2 w# Z% c: X: v( R                         return -1;) @3 b; k5 Q7 l: x5 v+ R
                     }
" Z; M/ f$ E; e3 z                     printf("opnd出栈:[%f]\n",a.data);
+ X' Y. E+ V3 c! Q7 O) H! `% Q$ @                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
  M+ ^( }5 p: l& n; G+ N! S                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6 s6 o" G. y; |; t5 g
                     printf("结果入栈:[%f]\n",opn_tmp.data);
6 C! E" l, c7 B* K* [; ~/ e1 N( R4 D                     break;( f( y; T1 Q( ~" W- F& C$ \
            }7 |, h7 w3 D2 S" ^3 e$ t( O9 l5 @
        }& P6 T4 O' p5 D7 d" ^) [1 c
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
# g3 B7 o6 Q- h1 z. j0 J# |) E    }3 i* M8 @' }3 ~/ @7 p
    GetTop(opnd,opn_tmp);) X- E$ l8 e1 C4 q8 d
    DestroyStack(optr);5 T' k' w" |8 O0 \1 {; E
    DestroyStack(opnd);
; i  L: m5 Y+ [  P9 |* G8 q% a; [    return opn_tmp.data;: h4 \- n2 n) ~3 r; ^& q0 q
}
  k9 W& w* x  H1 w, h! v: n, A
1 Y/ U- G- U) H- S* T' S% G" ~char *killzero(char *res,float result)' l( k8 o  I7 m
{
& \; t  B! b8 b3 {    int i;) x6 Q' G  Z  b% z

- n8 q1 z6 c$ I  m4 z    sprintf(res,"%f",result);
1 |6 }7 ?0 f( ]. R8 L. i6 ?$ `# _7 O    i=(int)strlen(res)-1;
7 s3 l/ B8 \# G- p4 d9 F% _  D, t! P    while(i&&res=='0')
5 G1 {6 R$ N/ U    {
5 T2 q0 Q$ [) n6 t6 m/ I" J        res='\0';: |6 Y; R* V' {( P8 }
        i--;; b# l( H% d8 V9 T; [/ n+ K
    }
) v1 k. R1 @* p$ U    if(res=='.')
, P& R* w; g8 P1 e! ^% Z( _        res='\0';5 ^/ J- Y: H8 e- c) P6 p
    return res;
$ |% y: f5 E3 D& N* k! U, ?. G% ?}- G& Y6 Z+ r  t  a

& B3 \1 z, N- [7 g  r- T" Aint main()( v% o$ T% ]# `7 o. T5 `" N
{
* r% K7 @) ?7 Y: Z! A/ w) e2 a    char ch;: e* ~3 v: n' N" u
    char res[64];9 c1 J& m0 @" R8 l* D7 p, X
    float result;7 {$ H% H  ~9 Q" h  ~
    while(1)
5 C5 f# _) @% a9 B- g    {, E0 y+ R) M  L; g
        result=compute();# t* w; a- f, t0 p* t( d  I  ?
        printf("\nThe result is:%s\n",killzero(res,result));
) Y! _: J+ n1 F1 _% P        printf("Do you want to continue(y/n)?:") ;
1 V9 I8 I' I; |. p& {0 Q2 j) m( R, y        ch=getch();1 Q0 d/ Q, D" m5 j" z3 m) F* `
        putchar(ch);8 t+ Q! G# s) g7 m5 V7 H
        if(ch=='n'||ch=='N'): S0 w% Y2 K# j9 x
            break;
6 l6 n) j4 D+ m        else1 K- u0 A# G) I8 J: S0 _" `, U
            system("cls");) W1 J/ [* M% {( e
    }' ^6 t% G; ~2 Z' }
    return 0;' a3 a3 f4 Y  S8 D+ ]1 y" h6 j
}

' X$ S1 [5 o3 |" ]% `; Q$ F
* \/ }0 Q1 O4 H% s8 V- B, j7 v[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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