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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
7 h8 x& T" H! B& p  e程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=) m$ `& I( P2 @* o; k
/**************表达式计算器************/
. h1 J7 v& k2 s+ [#include <stdio.h>
. F4 ?3 q$ n# C1 a6 @2 E( `#include <stdlib.h>$ m9 p- E( f0 k. _# u
#include <string.h>
: j; k& v3 M8 k1 j! w, x6 R! L9 N#include <conio.h>
4 I. I# m. Q! R( l$ b& T#include <malloc.h>
; b& z& t5 z- q" c
# C: I( K- D4 u+ U! z$ X$ g' E/ N#define STACK_SIZE 100
, \. ]: k. O9 f#define APPEND_SIZE 10/ d# z8 W3 `) f+ o6 D2 T  r
7 I0 R  F5 k5 S1 j
struct SNode{
5 Y9 H8 U- t3 E2 m    float data; /*存放操作数或者计算结果*/
  i: Q8 d0 E, s$ H3 h1 }6 S    char ch; /*存放运算符*/8 q1 n$ d7 b) C8 @) _
};* z- T% K2 ^3 T: b1 z# S4 |

6 u2 w% j# C# e& x' H$ d$ mstruct Stack{
% A' ]8 X# a3 K    SNode *top;5 ]7 E: Z, P7 L% L4 q' n/ ?+ L2 H; c
    SNode *base;% t! e0 _2 t# w" o1 U
    int size;
( N: ~& Z( B5 d% N! S, y6 E};
5 G) P$ Z* I; Q0 H% }0 u( Y! {3 c2 |- F5 j* E( A# o
/*栈操作函数*// J  R% V$ \/ f# j$ r/ \5 G
int InitStack(Stack &S); /*创建栈*/
$ L' M7 L4 J: K! c8 I; w* J) ~int DestroyStack(Stack &S); /*销毁栈*/
  d$ l) R! g$ ^$ F* Vint ClearStack(Stack &S); /*清空栈*/! D0 k# C. q- x, ^
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
& z  o6 ]$ p- L, ?int Push(Stack &S,SNode e); /*将结点e压入栈*/
7 u% X* K+ S0 x4 J$ ]int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/: C0 O; [* M) _$ b  U( v! G2 W
8 v4 t, y2 ]; J/ p$ G: m
/*表达式计算器相关函数*/1 s& D0 F0 j& ^8 K" A5 w$ o
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
9 V8 W& K. \4 z& Oint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
, Q/ J, ~' c- T3 X. x+ O5 cfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
: c8 I2 t, V+ H) p8 e4 Xfloat compute(); /*表达式结算器主函数*/
' U+ A1 R' A- |& ~7 y+ s$ Fchar *killzero(float result); /*去掉结果后面的0*/ # y; k) ?9 M8 f; s) ^6 w1 E; s" }# O

4 s0 I! r! U- ~" |. kint InitStack(Stack &S)
: `; P6 K* N9 E% B{
* \8 P5 }& q) U6 L0 f    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
1 k$ g% J. Z- c5 v' F2 [    if(S.base==NULL)0 S8 F/ L% d4 d' C4 g( w
    {: X6 b" {( W  k( a2 o3 U  T0 w% ]7 \
        printf("动态分配内存失败!");
$ a2 V0 a4 H! q9 V6 Z; V        return -1;
7 ~& B% f& o- k) _$ G9 i, q" K  z' O$ h    }
2 M  P$ @3 R5 O- o8 C7 _/ i    S.top=S.base;# a- `5 P2 f7 B
    S.size=STACK_SIZE;
/ X# r6 W  ~" C; V4 y    return 0;* t' A0 g0 ^0 `) n" w/ m/ ?7 P
}
5 d; G* m/ y4 D! W& e, w
6 e6 Y' n7 O, D$ R+ v5 aint DestroyStack(Stack &S)& e+ `. k5 G0 X
{5 }$ l+ d8 J  ]; g6 O2 |0 z
    free(S.base);- |" m4 V; X: Q/ ^/ _
    return 0;
5 l" ]* F, m$ |3 Y- e}4 s0 \; @" e+ d2 |, E  n9 Y0 ?

  }7 u0 z( F/ {# [- E( o! B* {int ClearStack(Stack &S)
# C5 [; S  b  g" Q1 j8 t{% V$ w% k! ~" X: \; Y4 z# C9 \. K
    S.top=S.base;8 M! v3 ^/ V+ c/ j9 e  _
    return 0;( w0 V- Q- \$ {1 c, b
}/ }4 z, ~! }/ n  s& z8 f
7 S4 M1 C1 B) K/ G
int GetTop(Stack S,SNode &e)
# [$ F( G0 i8 X3 X{8 S7 b5 m3 M5 t9 l- a% w; B: X
    if(S.top==S.base)5 b, L2 L9 x: w  F/ R* u
    {* i( ^* g, Y9 V
        printf("栈以为空!");0 M" T) e# d( w/ t- K, @/ Y4 N2 e3 X$ n
        return -1;
$ `* S8 \, V3 D9 ~- g) n    }
- C; l+ E5 J5 \  C    e=*(S.top-1);
& _- G+ |+ B, X- W; w3 u( k    return 0;
" S' Z2 D1 j3 P}
# Q: ?* m) p+ m' U
3 y$ W# H! s- C5 Pint Push(Stack &S,SNode e)8 }. v4 K- f, b$ o" C2 Z4 }
{' p0 i8 o: S; D; s% Y7 l6 w1 Z
    if(S.top-S.base>=S.size)( s! g7 c  T1 `7 N' Y! h7 S. Y5 ^
    {  G; W  O; U4 C
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));: P2 |5 t+ l+ x7 G, @
        if(S.base==NULL)$ h! w, i: i  E* U: u4 v' ?) L
        {
" O$ e, M  q. z5 f  ]6 J0 a' B            printf("动态分配内存失败!");
' Q7 v% g! W" @            return -1;2 h% ~+ F3 l9 Q- @
        }+ l# r7 `* M' o0 U! i  D
        S.top=S.base+S.size;5 b( P- U" i# Y. t
        S.size+=APPEND_SIZE;
  ~7 F5 b: \+ Q" D6 `8 l5 Q- r    }$ w+ Z6 X4 l# R/ L
    *S.top=e;
: u  ?, ~9 P" f1 J1 ^) C  O    S.top++;' R8 @% o4 K7 x$ h( }  d1 }
    return 0;
4 K3 b' ?0 _1 j& v, J}9 k+ ^4 p/ K, d. k/ c- i  J4 v3 W9 E! H
$ E5 p7 z/ Y& p
int Pop(Stack &S,SNode &e); ~& g8 L. Y" G! n! ]9 {
{
) J( {5 J% W8 w+ a; x' ?    if(S.top==S.base)
- z( n' p( L! w2 }    {
4 `! z" u! D$ s% o7 G        printf("栈为空!");2 s+ D6 `) }2 ^% Q) t$ F# J
        return -1;' m6 p0 R: A* _, M& v& x
    }; a% Y# x+ O) A* T2 V0 U
    e=*(S.top-1);
: ~9 \; f0 ^; ]* v& `2 I    S.top--;+ e7 X* o% u0 S% c9 ^+ |4 J% b7 U
    return 0;
9 N: c' z$ {! h3 I/ g) ~+ L}
- e8 @/ l% T- l, K- H2 s! q' P& L. u
char get_precede(char s,char c)- k; H/ H) o" W: G0 \2 g; Q
{
3 X% n, J  b3 q3 e0 O    switch(s)5 Q% [% X: S7 B
    {
9 V* w1 B5 ?7 ^7 m/ z8 a; Y        case '+':                 # |5 W4 p$ X2 _1 A* K# K
        case '-':
, F7 s) G7 V" O/ i1 H3 b8 Y             if(c=='+'||c=='-')
+ l  y6 G" q) b* A1 q  R5 y                 return '>';
$ q  G5 h! d, d7 i. ^             else if(c=='*'||c=='/')
& p8 X) b  c0 t7 X  X                 return '<';
8 l+ s. s* e, t+ x; k% J4 j             else if(c=='(')
7 {$ N7 k7 l: N$ h+ e8 l, m                 return '<';
% T$ g: \+ z  _$ s; B  J# F  v             else if(c==')')) y: x6 G. M) R+ [' ^0 ~6 j
                 return '>';
# N6 c! ^) t  I  N9 K% [             else ( }4 F+ S& _: c" b* Y- e9 w8 w
                 return '>';
; I# [7 y7 T! R        case '*':
7 {  L/ C$ I, [) q6 J        case '/':
/ k$ @3 _0 h. ^3 `6 b0 T/ w; Q             if(c=='+'||c=='-')/ [8 t& }3 S9 a1 _5 d1 [" y* ]8 g
                 return '>';( U; X& P' e8 b0 f
             else if(c=='*'||c=='/')( h2 ~3 ]$ i" N2 @# w3 c
                 return '>';
( W. z% x# L$ l0 M& n3 v             else if(c=='(')( Q1 {! Q' o. y7 K
                 return '<';* S: @) f: o( V! g; F
             else if(c==')')$ N7 T9 R8 N/ F2 d: A
                 return '>';$ m: x3 n7 A; s3 k
             else. Z* I$ V$ A* {2 P( [" z( k8 l
                 return '>';# P- k4 V' z1 Q$ @) g8 }
        case '(':
" c* M/ t6 l+ P$ O# y! f, N0 N" Y/ u             if(c=='+'||c=='-')
" L4 E; P( J8 ^3 w9 R' l                 return '<';6 Y1 T8 r% z, M, P( N
             else if(c=='*'||c=='/')
$ O1 G5 l' C/ G! E                 return '<';, w5 }2 G& r" j
             else if(c=='(')  M  _+ w2 w2 F2 x; g4 y
                 return '<';) ?# i# |( ]* i2 V) u, \
             else if(c==')')
. |% z' [7 A: x1 ~& d& @' V                 return '=';
( E9 G# n; k$ \3 l# U2 t8 G7 A             else1 a& [$ C3 H& B2 q8 R& J
                 return 'E';# S! d; S: ?1 j
        case ')':5 X2 Q$ V2 w- T* ^; \
             if(c=='+'||c=='-')9 K" A9 s: p2 l* C+ p# f
                 return '>';
5 l$ B: A- U/ w! e5 D: x3 c             else if(c=='*'||c=='/')
) ?  }: }* o8 r& H' H                 return '>';
% Z4 o# A* \2 j4 b" b9 B, x" e             else if(c=='(')
0 v5 M6 d6 i, p: e+ e6 t" K                 return 'E';
+ o% D4 s4 u. }7 y+ v1 _             else if(c==')')- B+ s* H7 ~- B! z& D
                 return '>';
/ d' X& {6 K2 r7 r2 l             else
. Y: D8 H8 P8 r                 return '>';* O. O1 X; r- ]
        case '#':. D! h6 Z3 x! e& i( o
             if(c=='+'||c=='-')
' t! ~# ?1 y/ N                 return '<';
6 v$ [5 B8 ^$ E6 h; L$ q             else if(c=='*'||c=='/')
0 e/ X1 R6 X$ ]. g                 return '<';: z2 g  a/ s  m. q
             else if(c=='(')/ |' z3 m8 e7 Q2 U2 \# v# \
                 return '<';2 X4 `. |9 l7 S+ z- u& s
             else if(c==')')
, j* C* x/ l1 N6 `4 I4 `4 g* R                 return 'E';
- l1 Z# ?9 J9 q" J1 f             else
* O, [4 n3 }+ X; K2 U( \/ `                 return '=';
: Q; J! W/ [8 I% `" I        default:, R( H* X: }4 S2 Q" @+ J" i
             break;
% m, z7 C3 R; C    }
* r) E& d7 s6 J# O& B) @    return 0;   
4 ?' v8 U* g- D7 L}
" U$ O/ g3 a7 Z3 m$ u. o/ _5 Q: T$ S* }7 p' V: M% F+ i5 I
int isOpr(char c)# Z( o: r; {+ |& g
{& G6 i1 ~- c2 N7 i
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
+ ~0 v& G4 w$ y) A/ C. b" x% I        return 0;# x. r9 O, d6 ]6 H
    else
! v( ]0 O- B9 d" M2 D9 t        return 1;
& x$ P- l- V" ?! [, S" N}
, `$ z' i4 K: W$ c& [( p6 s$ W( B) U5 F0 |- x* c. B
float operate(float x, char opr, float y)5 d  s0 P" k# t7 H
{
2 f3 H6 b' S% Q9 n: t8 I+ d+ m    float result;
/ t" [  f" [' {+ g$ M" @$ j    switch (opr)$ j; d# P' Z$ h
    {
6 V: t& z. {3 g7 M( s        case '+': 6 E+ {! j# [" e0 H' M8 W6 y) g
             result = x + y;
. o% z$ y% ?, ?3 v; i+ D             break;( z0 |5 [3 B+ {* ?- s
        case '-':
3 P% Q4 n/ O9 o; N' ~7 X& p             result = x - y;: o- n2 O4 N. a
             break;
  h* }# i5 v6 ]7 J6 Q        case '*':
3 }2 S3 m6 v4 I( j% P' _) M) I) t             result = x * y;. c1 S0 I7 s7 T7 E+ C* f7 V4 v7 F; O
             break;& X; j6 ~  n9 V7 @/ e
        case '/':
0 y1 z: r: K, ?) g, m, }             if (y == 0)
( |9 ~! V4 W% M" K$ s% q0 ?3 h             {
' O6 Q1 ^5 W8 z; C0 M                printf("Divided by zero!\n");/ ]/ L, t! V3 u9 _
                return 0;
/ C& c+ y2 k5 _             }
6 C2 J1 B9 H7 Q) ~' o# U             else+ ~/ _: i6 a: G
             {
! U7 V+ n8 }% \1 h& ^                 result = x / y;9 X7 A# ~8 f) [1 L* l
                 break;
0 M1 I, i# ~( r5 y" c$ x             }
0 G; d1 x5 M5 q; P  ?       default: ) O  k& ]& e. V" y  @8 G
             printf("Bad Input.\n");
) y3 Y: {0 B' P             return 0;
6 ^6 V! Z5 }" O# w" ~+ T3 @% Q    }
: e5 U3 m7 _* a( s9 p    return result;
" j9 z* F  Z' ]5 `}    : ~/ G* @) i6 M

0 g6 X! j/ h8 v& tfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/' N) U- C/ P8 I- d
{% f' \" c# e$ z$ b' ]
    Stack optr,opnd;- S/ k& I  j- H- _: F
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;: z& V3 R% q* U$ y8 L3 H7 ?
    char c;
8 x" p3 }' K$ P3 A7 m/ v7 A    char buf[16];  o% I. _4 {+ E/ u& A1 L
    int i=0;
, d  V6 H# t; E# C1 r6 J3 P* w    ' ?3 V" O. F( _
    InitStack(optr); /*用于寄存运算符*/$ [9 D+ y: Q- y2 @6 H0 M9 D1 g" j. p
    InitStack(opnd); /*用于寄存操作数和计算结果*/
6 t, F4 W9 \2 m- o    memset(buf,0,sizeof(buf));* L6 I8 ^1 p; s$ l) c( B3 o" L0 v# l% R6 ^
    " l6 @# ^; n* v* T5 v9 ?  S; q
    printf("Enter your expression:");
7 o( M4 N$ ?/ n        9 P# i& B* a1 b% T+ Z- v' J
    opr_in.ch='#';/ D6 \7 t* ]% f7 p0 E2 F( X% e
    Push(optr,opr_in); /*'#'入栈*/6 g; A2 S* z$ U( c- f1 A
    GetTop(optr,opr_top);# ^. ~" r7 @2 j2 d- p* }
    c=getchar();6 `! Y1 o& V) Z2 U2 }8 R
    while(c!='='||opr_top.ch!='#')* N0 R. ^7 E" H1 I* F
    {* M# X! f4 I+ C  ]$ Z
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/* E6 ~5 N. A, i: `
        {: [, C! m1 M- ^. Q! i! o' @
            buf=c;
4 M, Y( d4 m8 Y; {$ |( u            i++;" P- F$ j# d5 P& m' f: u7 e# `
            c=getchar();5 {; o  l8 B; i
        }' t+ @( n5 N, n) P/ S2 V2 c: c- f
        else /*是运算符*// h- O. z& M* ?
        {
0 ^6 g) w: S! r5 B9 N( ^0 N' V            buf='\0';
: e  p5 T# T$ e2 q7 G            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
" `3 v! N4 T5 C3 A1 e2 K0 ^            {
1 V5 |7 b5 P4 G' o3 z* I& q, ?                 opn_in.data=(float)atof(buf);
7 }) T; Z. ^* K                 Push(opnd,opn_in);
$ O# k, u. z& F5 Z& k                 printf("opnd入栈:[%f]\n",opn_in.data);
. d5 z6 l6 r% q9 \2 U3 d1 O% C                 i=0;/ u8 ~/ p  k" I& D0 W* ~( P
                 memset(buf,0,sizeof(buf));& Y/ F6 V5 V/ U* u7 P" J& J' U5 W7 Z
            }* A8 \6 {& ^$ }1 G* G6 `
            opr_in.ch=c;* E$ V( s# G3 M0 L3 S
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
  k0 U' R% w5 o6 B1 ~, i            {
- X$ b1 [) B2 O                case '<': /*优先级小于栈顶结点,则运算符入栈*/) c9 p  d. W$ t, _4 [
                     Push(optr,opr_in);; }5 P. o  X- f2 {6 @. N
                     printf("optr入栈:[%c]\n",opr_in.ch);
6 d1 @- r" u$ `- B6 q6 e) u                     c=getchar();
4 v+ T3 B. W9 m: E                     break;
1 \+ L' C( ^; Q$ S2 @                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
2 Z, R. N$ q9 \* ~% y3 I% M4 y                     Pop(optr,e);
$ A3 e" B% `$ U. V# s  I                     printf("optr出栈:去掉括号\n");# B7 t# d6 V% W" ^
                     c=getchar();+ T2 h' S& I0 Q- k, W6 u9 ?
                     break;
/ C2 E2 b: Q3 s1 I                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
) c& H/ r) ~# r3 z7 }                     Pop(optr,opr_t);
8 \: p0 B3 T7 ]                     printf("optr出栈:[%c]\n",opr_t.ch);0 Q+ P2 Q. Z! I; B' A' j" ^' O7 u
                     if(Pop(opnd,b)<0)
: Z( b' W- ~. Y6 F                     {
6 ]* X+ B8 P: f- u2 @% x                         printf("Bad Input!\n");
- S" M$ f( K3 T0 k2 ~! L                         fflush(stdin);$ f$ W' h; j% x( o: ~
                         return -1;6 N/ b1 g! a1 w, G+ u
                     }
/ l7 W' Z# J: Z/ e! h$ C! C                     printf("opnd出栈:[%f]\n",b.data);
5 y. a6 k8 a. P! G- b                     if(Pop(opnd,a)<0)
' F8 Y" u6 U- `+ k: f5 h                     {/ e1 z3 o( @4 J! k; F' u
                         printf("Bad Input!\n");1 i8 ~& X; S5 ~% {1 X& f1 @8 x
                         fflush(stdin);: D, W- `2 s% X' r/ ?
                         return -1;0 }6 W$ Y- D/ f& X* _& T7 ?
                     }; I4 |% q& W4 M4 `5 n( A
                     printf("opnd出栈:[%f]\n",a.data);
2 ~% ~2 o7 t* U2 P. ]# K                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
- C' j4 M- ?" {# S. S                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/; B- R" t) S6 }$ `0 o- }
                     printf("结果入栈:[%f]\n",opn_tmp.data);
# l8 _& Y7 W. E  B- Q- |                     break;- a' q) }7 o) O! @3 p+ e; e
            }- ^+ i$ s1 |9 v0 z
        }
7 ~! J' n( w  p8 {0 H& _        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                , r/ |; E- U% `! p
    }5 F7 \/ T$ z3 P3 C7 f6 h# [
    GetTop(opnd,opn_tmp);
& `# d/ Z  ^# j; t    DestroyStack(optr);
, i: A8 C9 k+ g+ T& ~    DestroyStack(opnd);
, p! e% I6 P% m/ Z8 ?    return opn_tmp.data;
, P6 K% ~' L) d7 O* W- @}
, d3 s, X* b) {4 Y0 Y4 ]0 R8 |
% y# g* M# G0 g1 Nchar *killzero(char *res,float result)  m+ g- v. x" w: j2 H! |3 k% W
{
8 a" ?5 J1 z0 [    int i;# i% N& Q5 Z& g! P9 d# M
2 F8 w9 \0 w# V8 C* D, i! `- i2 G7 k
    sprintf(res,"%f",result);3 K, K0 _' R# @6 Q/ z
    i=(int)strlen(res)-1;, e& W8 @3 {& |  w% q& t
    while(i&&res=='0')2 f$ J! ?& l2 L- Y* s2 m# w- l
    {3 Z. R  D+ }4 y6 c9 Q
        res='\0';- o8 d- e% ~8 [/ k' P* [( g
        i--;$ c+ M4 x! F$ R. t7 w/ r+ M* H
    }
1 n) Z; E& s7 x    if(res=='.')- c# n) ], G: s# Q, S7 S$ _
        res='\0';2 @: _% \1 M: W% V
    return res;; E0 h/ }! }) d1 @4 Y: v
}
% k# L: r- A4 a4 s7 M% |
, D1 t- g3 |& P' s, xint main()
! d- w: r  p" ?! n2 H' b' |! g{
% c. w: G, l/ \7 z    char ch;
1 n4 H1 g5 L- D5 {5 Q1 R3 e    char res[64];) j; s' O' S: N- ~8 X
    float result;
: f6 @- w. K  w, ?    while(1)
' D: T3 f1 V+ D5 i2 p7 Q5 |8 ^    {
6 s9 M, L0 w! y! Y- h; n        result=compute();1 k) e. h0 Z& @) K9 g
        printf("\nThe result is:%s\n",killzero(res,result));
! B9 f  L# }# A' U2 A        printf("Do you want to continue(y/n)?:") ;3 q; o4 b4 m- R
        ch=getch();3 p8 T; `8 D1 \6 h. a& O$ c
        putchar(ch);
* {9 q% }8 P; D! G6 I% S6 _. \        if(ch=='n'||ch=='N')
5 r' ?& c9 T( \+ A; M* A            break;# E( L9 `" [/ d1 u8 Y
        else
5 X* r$ d$ X& d! w+ Z0 p$ X            system("cls");
3 h" ^3 D5 |( S    }$ q8 q) O4 c) _, ]
    return 0;
1 z" q6 [' w& @}
/ ~6 z, U" G% L0 u2 \# ~0 k1 l
* y( c( O- Q  }7 b# I9 \. ~. L
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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