返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
# K# u( F3 _& Y程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=; c; K+ O# Y9 y3 K  s! [! ~' g& R& {
/**************表达式计算器************/9 `  _# g$ W) ]5 u. X6 \/ T& g6 S
#include <stdio.h>
9 w) C2 Z$ S# [1 z! ~- v#include <stdlib.h>
( B# d9 G  d1 p: O#include <string.h>
' u3 W, e2 a+ P2 E0 x0 c. E- ?#include <conio.h>
* ~; h. }7 F. b#include <malloc.h>
8 o. h1 t6 V" e# r5 @* U/ C% Y/ q" j6 Y8 c! S6 Y! y5 r8 P5 s* B) k4 I
#define STACK_SIZE 100
! |8 F, V) _. U& u9 H3 I2 N1 G#define APPEND_SIZE 10/ U4 l6 U! O3 k$ F- |: _% x

5 q+ a; o/ ]' a' g, N. r6 fstruct SNode{
+ n  b& V" L* y8 ?. a) {    float data; /*存放操作数或者计算结果*/
/ i) g  w3 h' h. s, y) C    char ch; /*存放运算符*/; }9 {; ~4 [7 C: A' J
};0 m- q) O! S; _1 U
% T0 s0 H' T/ D
struct Stack{
/ x" T, c& s* t4 H9 Q    SNode *top;7 k0 S+ n4 `- i: k
    SNode *base;
; V# ~8 d1 t7 W+ \! Z    int size;7 V0 ]( A% @. X; J6 Z$ H
};! u# Y$ _( r1 A7 c9 V* K

- K4 O* S- ~' U; I2 f2 j/*栈操作函数*/
3 @, R+ I* b( k7 V" r  |int InitStack(Stack &S); /*创建栈*/# N) m( B6 E  d$ X- E" B0 J
int DestroyStack(Stack &S); /*销毁栈*/
3 k& y* c) c1 fint ClearStack(Stack &S); /*清空栈*/* k# _  C# E9 u* y
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
8 @4 P/ |: l3 y+ b" |int Push(Stack &S,SNode e); /*将结点e压入栈*/. `0 E# J8 U4 I8 g6 \
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2 |3 ]+ n+ S" ^+ n. n& e( t0 d0 ^" p1 f; A; H- N  @
/*表达式计算器相关函数*/: d, n9 j* W( i' x/ n- }2 e9 B+ O
char get_precede(char s,char c); /*判断运算符s和c的优先级*/  J$ [* n7 I( n( d7 [3 b. a
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*// F$ v/ I5 V3 v( A/ D6 e
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/: a- @* R3 j* b1 m% z5 @
float compute(); /*表达式结算器主函数*/3 M) a, W2 `; s: \3 y
char *killzero(float result); /*去掉结果后面的0*/ & z& a! ~6 \# \) h

8 k& b8 D- @1 T5 T% W+ kint InitStack(Stack &S)
' G: p6 h3 Q" n3 M) P8 M3 b{
* v5 A" R/ `% w1 H    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));4 V6 P5 i% c8 \3 P% g
    if(S.base==NULL)% M; r+ X# L* I- Q: R7 z
    {8 Y0 z# R- X! V
        printf("动态分配内存失败!");) O0 u" T& l9 p, X% T
        return -1;9 `; y; b' H$ H( w6 i% C% ?+ F- U# }: H
    }: V$ c$ v$ j3 w  M' f# r) k' ^3 P
    S.top=S.base;" A$ V1 Q2 A1 o' o& b3 {, d' U
    S.size=STACK_SIZE;
" L" c# o( \! O9 h, z. Z* f7 {1 g8 a    return 0;. `  ~/ P+ t' z3 q% Y
}
& m7 e" z4 D" L0 U) l/ x7 s! e* q( h; m
( ^$ S0 _+ i3 \6 yint DestroyStack(Stack &S)! j, m6 ~7 V) ?# P# q$ P
{. |3 M- [" t8 g4 O$ ]
    free(S.base);8 x% o( [. g1 m6 \# Q
    return 0;
8 _1 D, h5 A! K; ^2 R& U0 f}4 N' r* b3 t5 C- i) y7 c
2 d8 V, \) p7 g) R, L4 |- J
int ClearStack(Stack &S)
  _. B& c1 ~% n9 G0 x{) Y: O( Z) @- ]5 I
    S.top=S.base;0 a( I- G) w* t- P& P' t9 G
    return 0;5 f0 p9 K6 L( a0 t3 ]) \
}( j- k+ k% }. W+ n4 _
* p. V! w1 }8 o1 U7 n
int GetTop(Stack S,SNode &e)
) _& N$ U# R+ S0 S{
6 X. y- X" M* t7 b    if(S.top==S.base)( }0 n" T1 r8 p
    {* i, |' M. m3 n8 n( z
        printf("栈以为空!");
$ u  ?2 b' Y: }' H8 N# B: n        return -1;% z7 j; r% c4 X1 b4 N# a5 R; b/ [
    }
+ x1 \% O6 o7 ?    e=*(S.top-1);
1 w: `: @5 F+ H$ e4 f    return 0;6 X: j( j; W4 {% O
}7 u2 L6 i- {; }
; b5 _5 F  f' v) Z3 t. E
int Push(Stack &S,SNode e)7 F" c6 K2 T  Q; n
{0 v& t. A) K5 c" g2 V. ^
    if(S.top-S.base>=S.size)! ~" ^) X6 J" G2 S; h
    {! I" |( y" @$ X9 P
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) v7 g: \% @  H1 L( D; r5 }4 ^( {        if(S.base==NULL): F, l3 ]8 s) u1 c' b
        {
% M2 }8 c) T& F) x* J' v/ T$ m            printf("动态分配内存失败!");
" u7 }% w: m: q$ O* s            return -1;
0 O: V( p+ V/ s3 f2 t. w        }
* e$ m& K. v2 t% [9 @        S.top=S.base+S.size;
- f- f8 [" }6 B; i7 h0 Y0 t( L- c! p        S.size+=APPEND_SIZE;  d$ M; x: r) q  t/ X
    }
* r8 n8 }* _5 E* u    *S.top=e;* I8 @# r' M* J  Q; f. X+ P
    S.top++;
& \' Z- M, M6 E, @4 g, s3 q9 A+ F    return 0;! p$ m/ W' W+ ~1 s5 ?6 q0 P# g* A6 U/ \
}
% r5 ~% y; a3 _+ q% `" ~' ?% T* ?: ]( t, g' k4 Z
int Pop(Stack &S,SNode &e)  }5 B1 }9 N, c* V, X; k- I: r9 U; d
{2 y5 M) D% ~4 v  s* E. W
    if(S.top==S.base)# X' {, z- m) b1 T
    {
2 B- x, t! D# t        printf("栈为空!");! V$ `& n- V$ j/ `
        return -1;- l% L% l- o7 L8 |$ X
    }
2 T& {) R( h9 u8 J) ~    e=*(S.top-1);0 m; h  z! z  ^$ O# C5 O
    S.top--;3 A! B2 [& t; l1 `
    return 0;: \1 ^( n* k* ]# s+ s
}
2 O- v1 O& ~2 o% P; `1 D
9 H, A  ^) S" R. N' ochar get_precede(char s,char c); Y3 {& ]: E7 O$ M: O0 L
{4 b" ~/ j" I% \" b/ }6 b; ?% P. F
    switch(s)0 c, J6 @+ y  I; x0 T; C( q
    {
. Z" X1 G8 W& H! L" |1 p, T, v        case '+':                 2 S1 X+ ?7 O" u1 D7 `0 Q7 n
        case '-':
$ V) g) p' L1 ], d( }             if(c=='+'||c=='-')9 D6 s  G, x! ]9 Z( ]( m
                 return '>';
1 t. p/ e. f7 H; U             else if(c=='*'||c=='/')
" y3 M/ ^3 w$ T2 q, p                 return '<';, b9 V0 ]) m5 X
             else if(c=='(')# t9 I! O# |$ t) G( ?
                 return '<';
/ m* a% j+ p, q  f" L3 p0 A, D             else if(c==')')
% j5 x8 P# _, G1 y0 {# S( I3 J                 return '>';$ n% M. W, s% L7 j& K$ }9 D
             else
2 a) D9 \! H, M9 }  P5 W' F& L                 return '>';
9 W  Q/ h5 u8 J  ]7 l        case '*':
% _3 \9 r  W8 B$ e; c9 Y        case '/':
4 S8 t  |: ~1 n             if(c=='+'||c=='-')  f3 Q4 R( ~0 q) W& X8 I& O: I+ l
                 return '>';
$ y$ v/ k) ^$ O) J9 h             else if(c=='*'||c=='/')2 c, P5 W2 b! ?
                 return '>';% E7 _4 X: J1 d2 u
             else if(c=='(')) h; l5 Q. X3 \; P" Y
                 return '<';
. @  d. a) G6 q             else if(c==')')
$ c$ R4 o% n1 o$ H0 b! ]3 u+ Q                 return '>';
8 [4 v$ Z" e- }& t6 ^             else
( t6 P3 F2 G3 O6 @0 A& ~% N                 return '>';
& l) d% R$ s0 w        case '(':# T5 X- ~% m5 \: {4 b* x4 U
             if(c=='+'||c=='-')
( E" n$ i; q7 {3 W8 o% ~                 return '<';
* ?5 p: i/ Z6 X' M' ?* ?- k             else if(c=='*'||c=='/')
* T" k; F. @0 a  J' w4 Y. D                 return '<';
" t- ~+ N& Y1 Z5 H             else if(c=='(')
9 w. B# s) ?5 c. a# S9 K9 p, q3 a2 z                 return '<';% r/ v. ^7 D: J( m* Q, a3 @
             else if(c==')')- [& {; m; I# o4 r+ k
                 return '=';
& {" N4 h- r, e+ U4 T1 Z             else$ d% Q" C2 L  j! ]; Y* m3 w8 l
                 return 'E';4 Y' }2 c  l6 k. u
        case ')':
1 `1 @6 c: ^) f% a* Q' R8 M' H9 @             if(c=='+'||c=='-')
! B- O8 J* b' N- v                 return '>';+ s2 H1 W) Z  _0 P, E
             else if(c=='*'||c=='/')
& V! L( v5 @! U3 Z% I/ _2 Y                 return '>';% `( T; h- Z6 l1 _1 c* }5 U
             else if(c=='(')
6 ~9 t. h  }* T                 return 'E';& p; @: k9 {3 S2 W1 r% X: A
             else if(c==')')
- @7 i! y+ \; ]+ T/ M* J! k/ O                 return '>';
; u2 z% p8 X" x& A6 N$ x& a             else
9 f& }) W! h9 C. n9 F1 o9 p# _5 S                 return '>';
: }- s' q0 @8 N7 ~. L! _        case '#':: t. N" ?: v" l8 t, S
             if(c=='+'||c=='-')) @5 q! S( j) F4 b# U8 h
                 return '<';
( J& H; U; S* `             else if(c=='*'||c=='/')
* y, c" V- L& h0 c, l- ~                 return '<';
  e& Y6 M2 r2 n- l             else if(c=='('); V$ \! Z/ e( X% J
                 return '<';+ j5 E1 h+ b# M/ E
             else if(c==')')+ ~/ g. H) a; F$ g/ \' r
                 return 'E';
+ A2 D% U2 d: B3 E             else
4 i2 D; q  n; Q! e6 @1 A; H                 return '=';
8 ?, [- A/ U7 K4 t4 @% G$ O: a        default:
( \& F. `5 Z  b6 R7 z             break;3 D; k. i/ U; C9 L' v7 w" N. P
    }
" J) O; l# }. z; T& K    return 0;   
2 U8 z, o) C! d7 A}1 q9 R0 b- F: B' A% T: {! h! W8 t# n" W

  G' r% e; @1 a! r' wint isOpr(char c)
1 ?$ O. P" ]6 |{! y! F" t& o' `( @- ~4 a
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 G: M" E% m; S  j$ i& H" |0 `
        return 0;
2 }, b4 d3 J0 s1 _    else / m% ^! R  p! C+ K* N5 M
        return 1;$ y! G& P1 ~$ i. d4 O/ r
}
( q* N& V4 H# P, b2 l& [. A0 K# |  `! P4 E
float operate(float x, char opr, float y)9 m( R) t' n" b3 [+ G) d
{$ p5 i2 c2 h6 X6 m& V/ g4 u$ W5 V
    float result;% W4 j; k- o, D, s4 I7 j4 j
    switch (opr)
+ z+ P* L9 ?) K* w4 k. }' F    {5 ]! [7 _2 x; c+ j/ G, m
        case '+': 7 X- W, f7 c: z0 C# G; n0 K$ n
             result = x + y;
% l1 {1 e1 S& s+ V; B             break;) X3 \6 N4 L8 n1 v# P
        case '-':
+ n9 M$ q: C$ [- M& _1 h* E; `             result = x - y;
# U& E' c0 E5 H2 x1 K             break;
# W$ }% A/ E# g6 d        case '*': " t& o. {. s9 Y/ R8 h
             result = x * y;7 S- f& J3 h5 E! M
             break;
- A4 t$ z5 l0 C8 y( j7 ^& i        case '/': ( o; q6 o7 m& Q2 J$ Z
             if (y == 0)
2 f/ Q; s) T7 i/ h) ]- U8 }             {: O1 z5 _4 s: _0 w' ~
                printf("Divided by zero!\n");7 M% |+ u; L0 y7 T( V
                return 0;: x, Z/ d8 e3 L4 E4 D
             }0 R- M" K: i! Y7 V! O7 ]  h6 ~
             else/ b0 C. N3 D) u% N' l+ a4 [
             {
! p  _0 c& a. x8 d                 result = x / y;
$ @/ L3 ^& N0 D* S& E                 break;5 v. H" O; I; t' Z5 I* R
             }7 k% K. G& q& Y" k4 ^! U+ p
       default: 9 I. _: d) l9 W# O
             printf("Bad Input.\n");   w* \3 ]' x, k- j" K" c, }! ?5 Y
             return 0;
) e) t. k. H% X6 [! O* m  Y    }
7 E1 B6 b: O: H7 J; r% M    return result;: Y7 @! x0 j& W, z+ H
}   
1 t, Z# n5 p/ Y2 `, M
- G9 @- F* d$ a: U/ Rfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
* d0 y' `6 Q( \( e7 p8 u! i{
" E0 j4 ~2 {; J( }" `9 P    Stack optr,opnd;5 I; @0 @2 G, z' b- I
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;5 z" r8 B6 A( q7 S& i7 J& p1 o
    char c;
4 R! Z" b1 p& B4 q" O- ]    char buf[16];
8 H/ W3 K: q( ]8 p5 Y4 A, n, B# H/ r    int i=0;
0 P* M, ^: M- D  [4 Y; d6 j   
' X9 L3 i; H) p9 q) {5 s% c/ d    InitStack(optr); /*用于寄存运算符*/1 W  l/ z8 u* k7 y
    InitStack(opnd); /*用于寄存操作数和计算结果*/: |+ l* _# o1 x; E/ Q) v
    memset(buf,0,sizeof(buf));0 X( D. M. M, D  J8 [) ]6 M* h
    # d4 u4 V# Y* x7 z% C
    printf("Enter your expression:");
9 G( K. K# T. M6 l3 l' E, V5 X+ R$ h        ' M8 h. `0 @- i
    opr_in.ch='#';* V. U" i1 @: F* i
    Push(optr,opr_in); /*'#'入栈*/. u0 }  a! p3 N: \
    GetTop(optr,opr_top);
- I. H! L2 J; e" @3 S0 B* v    c=getchar();/ a  |/ e  q) Y, [# i8 ~
    while(c!='='||opr_top.ch!='#')
: n& g1 c& ]9 n! J0 e    {, S% w8 `0 {) T- L
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/5 B3 n" ^2 ]' x; `( m
        {$ v) h, M  Q. ?$ P& B# D9 F: q
            buf=c;
2 r; I! ?  `- P7 G2 k            i++;
+ O0 A, j9 X( m' b6 }; Z, u  M  {/ Y            c=getchar();
5 m6 i  \: u+ {2 ^- T        }
* M. ~0 _2 r- @# Z        else /*是运算符*/  ~" ?8 a8 _4 X9 H" @8 L8 o
        {
2 o; L. O$ a, l4 c$ M7 v- T            buf='\0';
, X8 X- a+ `+ ~* P2 l$ V# r            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+ m" c. y# U4 G& `
            {
  o7 x: Z4 a; r" I, Q7 f                 opn_in.data=(float)atof(buf);
! t) e- s3 c* {, _                 Push(opnd,opn_in);. L+ U3 A+ v# v0 G: l
                 printf("opnd入栈:[%f]\n",opn_in.data);+ e; G4 Y( k9 q6 k% |0 x
                 i=0;- R+ n  u6 ^: d
                 memset(buf,0,sizeof(buf));+ d: U% K4 @3 U* k: |- o
            }
+ O) O/ y: R5 v* N            opr_in.ch=c;
+ a3 {( Q! U( v! O, P            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1 o$ D+ c  s. m4 f- R3 b8 t            {
' a$ K- ?8 R  x# N: X                case '<': /*优先级小于栈顶结点,则运算符入栈*/- |6 U* g/ h9 r
                     Push(optr,opr_in);! y7 ~! N& v9 Y: i7 @* T$ m+ m
                     printf("optr入栈:[%c]\n",opr_in.ch);- _4 s% }- W; c: K9 B
                     c=getchar();& _- G* j- p( e) H- R! y2 K
                     break;
% t/ ^5 L0 k' Z" g4 ?2 X) s8 o8 _                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/: O) J4 u* k9 y
                     Pop(optr,e);
# d/ C; l1 h7 k/ k9 w% W& S                     printf("optr出栈:去掉括号\n");
" B( _0 x& T& N2 O  q: C$ O0 j                     c=getchar();( n, H+ n# [7 p& d* r  Y3 z3 ^; n1 J
                     break;3 [* ^0 W9 d6 P6 _- [2 i
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
9 s! O" ~( j: g0 g                     Pop(optr,opr_t);
* }+ v: V! t, J4 Y) L& n                     printf("optr出栈:[%c]\n",opr_t.ch);
0 G' x9 P$ r* ~! z                     if(Pop(opnd,b)<0)
/ }0 L, D# E- `" R7 R                     {6 n  s0 w& W7 b: q* E
                         printf("Bad Input!\n");& G' ~' w) i# b7 t5 w  [
                         fflush(stdin);% u; n+ z1 e4 y- w
                         return -1;
9 u2 T, F. y. d! u1 W                     }/ F! Y% ?# s% h7 A7 R& [% E
                     printf("opnd出栈:[%f]\n",b.data);
1 [; C) N6 e! |                     if(Pop(opnd,a)<0)2 l6 _: t; |9 D) u! q5 Y/ D
                     {
+ W+ ^8 j# C; c                         printf("Bad Input!\n");
" u, f9 }4 U( X                         fflush(stdin);2 c$ q$ G  F. S: d' Y
                         return -1;
: I' ]$ B; J/ P( j( C- V& A- J                     }
" k) d( @& Y" e                     printf("opnd出栈:[%f]\n",a.data);* v, V, P# C  R' a# s% `
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
4 I' \5 r6 y& }' a: C) r; H) b                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/: X0 R, Q- u  c8 Y- F" ?$ ?
                     printf("结果入栈:[%f]\n",opn_tmp.data);
: T9 `* C5 F' p, ~                     break;
0 i0 c( o8 D% M8 A# V            }
1 e: l% e2 a( g/ b0 i        }
  C2 O" e- M5 R6 N1 e# |! d" [; @        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ! b2 I2 \9 I/ g* i9 f7 c
    }/ I: ]% r- r- x
    GetTop(opnd,opn_tmp);3 u% _" @  S2 `
    DestroyStack(optr);
; a1 {3 [$ n  l$ H/ f; |    DestroyStack(opnd);# c5 |$ \. N/ S, c& I  h) ~
    return opn_tmp.data;
* c' t* h( A# d5 l5 U}. A8 r0 `: f$ D4 E

& [4 ^! ^& V3 A/ d; Achar *killzero(char *res,float result)
7 _5 N/ r9 }7 Q+ {% d1 Y. w& H4 I* l{
1 x% c! c2 \; m3 c3 f5 g    int i;4 V3 {& M, H- q+ \, l& U
' y* ~9 r, B1 S) R! |) q; ?
    sprintf(res,"%f",result);
$ C  l. k: C9 i( N% n    i=(int)strlen(res)-1;
5 ?' Y" q' A  @5 _( i# W: |& i    while(i&&res=='0')7 L& B5 Z) C& k
    {! ?( r" Y2 Q: V- H! x% R+ U7 i
        res='\0';
3 c9 ?; q5 O9 [* j' C        i--;
! A  O. Y0 T+ s0 u- z    }
1 H/ }. b/ \) u: y$ h% @/ X! ?    if(res=='.')# U+ Y  _4 O9 b3 G4 X) s
        res='\0';  }4 \& O" v3 y5 j# l4 H2 [9 ]
    return res;
. A, a: Q+ c/ _7 ?. T}
/ I. n" b2 [0 L' `/ L2 @- _- H
int main()
: ?$ v, s- Q" l: b3 F{4 @, G( a# |  m; g* a5 |
    char ch;6 u# Q8 x# v! ]( D5 x
    char res[64];  H0 v6 S% Y7 p8 Y+ K
    float result;/ B' N0 k$ `+ g0 O6 m/ y
    while(1)
: Y1 v; X- E" k. i' g    {
" l. ~. B; b% c2 R' @# ]        result=compute();
. m7 X  \# C. }/ V: ]        printf("\nThe result is:%s\n",killzero(res,result));0 z+ @4 q8 h7 p& H# B
        printf("Do you want to continue(y/n)?:") ;
5 c+ O& \0 i# A- d1 v/ @/ u1 Z. d        ch=getch();2 Y0 g* d3 v: T9 c, ]
        putchar(ch);
. Q: d2 u- ]* Z" n+ b* }        if(ch=='n'||ch=='N')3 T4 {( G/ X+ h( B6 b7 L5 c
            break;" |  i9 ?' ~/ A6 q8 s1 i( s
        else
) c* M( p, ]' W- m- r! N, c            system("cls");
7 k' q3 l0 J+ n; T( \1 m- D8 f    }
6 u$ i) H, U+ B) t% ^: [    return 0;
3 u# X* W$ F) r}
% m! l; f. {  w$ b. c0 Z8 x
5 S! ?2 C/ s! S  R& a- W$ |
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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