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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.# i7 B7 h$ {' `' E
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=0 K3 g" [4 J6 J; V7 W0 Y5 q0 J
/**************表达式计算器************/
0 Z' P! x+ S8 Z  f#include <stdio.h>
% y3 w$ `8 @  m1 z1 [! f# A#include <stdlib.h>- C3 z2 p! j. F, M
#include <string.h>
2 r, z* D' n* M, d4 ?4 b7 m#include <conio.h>
6 f% a' F3 v  }) D. [6 ^$ A#include <malloc.h>1 T0 t( \' K. C5 M6 K# r

4 q9 }6 d: F  Y  z/ H' p$ n#define STACK_SIZE 1000 b0 ]1 k' `+ c3 U% c
#define APPEND_SIZE 10# p  t9 t$ ^# N6 V/ H' \% ~: Z3 j

' _, s+ Z$ ~* E1 U9 z( [struct SNode{
2 ]* }0 I2 K" W5 {8 p4 F2 O    float data; /*存放操作数或者计算结果*/
5 V7 ]: g! T! N3 a% x' Y0 O    char ch; /*存放运算符*/- U: g5 g; Z& C: O( i: k
};
) z7 N, O+ e, w2 q
' t' s, C0 V; [; O$ @3 xstruct Stack{
* q$ {( H4 ?! ~( D    SNode *top;4 c# E7 l3 K0 |/ K6 G. O
    SNode *base;
1 z8 e  |1 h! ^. i    int size;9 U8 Y9 B7 {. t$ T8 A# t! ]5 H
};, g! ~  n) O( ]0 c. P

- Z- f1 }+ p$ |+ k  v  z/*栈操作函数*/3 k% B- m9 |/ s' {
int InitStack(Stack &S); /*创建栈*/
% [8 Z: `7 n4 K& F5 Oint DestroyStack(Stack &S); /*销毁栈*/4 {& a! J. s+ ]8 h0 L+ B9 O2 x
int ClearStack(Stack &S); /*清空栈*/
* K# w' \  a0 r. ]- C6 jint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
: o5 @: D5 a( e) Gint Push(Stack &S,SNode e); /*将结点e压入栈*/
9 b& l7 h  `. C- ?0 H! l$ E# w8 Uint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
! ], O& i  L/ A; I2 m+ ~( n5 e
- D6 O9 x0 ^. c$ o/*表达式计算器相关函数*/! L' L4 K* k$ y7 u' @7 E9 s
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
1 U9 E4 s: H6 @0 E# _! N0 Gint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
, H5 N* F3 p$ e2 Y) ~0 i* M4 H9 Mfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
) H9 l, ^- o( [4 g; P' Kfloat compute(); /*表达式结算器主函数*/
6 x8 X- g/ r$ Cchar *killzero(float result); /*去掉结果后面的0*/ 6 n, G9 k$ [0 p+ r

4 \# x4 t. j& ?% {9 T/ W/ xint InitStack(Stack &S)0 i, q3 B5 R3 H! p; j  z. s
{" g* a! Y8 q* A3 L. j! z* r
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));, @6 H/ M% X) l. N# w" G# [
    if(S.base==NULL), i4 n8 M* t& t
    {/ h& {' T; P- L
        printf("动态分配内存失败!");' g% N- F) u0 M* q- g8 V# b0 B
        return -1;5 {8 m4 }- |% o9 O; S2 I
    }
6 t: U8 S  R7 E" a. J0 h    S.top=S.base;
$ S9 s" r; m2 ^& h8 ]9 r; u$ X    S.size=STACK_SIZE;
4 @( P, f9 r: g$ A+ Z    return 0;8 v" G' h$ B1 R) j( \
}. V6 R  g, v1 @9 p2 O% x

! x. j, T) z! g. fint DestroyStack(Stack &S)
, f; Y; o0 A  i3 M{
% ~$ l$ J9 K* H' G7 i3 g' d    free(S.base);/ J  c) O6 l- N
    return 0;0 c1 O; a: a# d; l9 D6 u7 @: I) m
}  h. F: K4 ?# _: m! d$ J

7 a: U. p1 d2 V! g# G. nint ClearStack(Stack &S)
! E0 y& ^7 C3 A{  a, S; P) C  [# Z, y
    S.top=S.base;8 e* e( C8 T8 F' |, M$ I1 H
    return 0;
4 W& Q& q- F; g! Z2 h  {: {1 `}$ Z2 u8 x% ]  M% Z+ `/ v
& @) o4 b$ c4 s
int GetTop(Stack S,SNode &e)
7 ]0 g4 q1 G, \3 m; a{
; M' `2 t2 f, D9 P/ ~1 W    if(S.top==S.base)! X. L- m; |, S3 l
    {
( r' I. q* r$ ?: O% f        printf("栈以为空!");
# P. A9 F& D$ n. }  M! D+ d4 T        return -1;
- ^. e: A' K1 E- i3 m    }( E& m% R. Y6 |# o/ i" S
    e=*(S.top-1);
6 D6 k5 g' ~$ Y: P. ]    return 0;
' N: t& i# T/ q) ]5 n7 I/ Q}
7 q; j: V5 a8 o5 |8 D% q7 r9 Q& p% v0 h; ^, q. w
int Push(Stack &S,SNode e)
% P& [+ d3 d5 K* G" S9 r4 h) M{8 {- a) C+ [5 ~+ |
    if(S.top-S.base>=S.size)
) S8 F" g& l" L    {! j9 N- G0 u: M0 `# `5 ], P
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
  w% v* W6 s# E& v* d0 b        if(S.base==NULL)+ ]. y; u( u# G" B4 `
        {
# l' `  N3 \% s# Y7 N            printf("动态分配内存失败!");' i2 `( C. O6 N: ~' M
            return -1;7 E$ a( R7 G4 |4 }% L/ u0 g
        }
. ~9 `4 Z9 [6 ?7 w! {" |) `        S.top=S.base+S.size;; v" t! ?# i6 S' e* D( O
        S.size+=APPEND_SIZE;) J4 p5 q( Y4 M
    }& O, m& L) P, e! Q" M  V" J0 S4 q2 }
    *S.top=e;/ {  x' h4 T% M0 x/ L
    S.top++;; J0 g$ W. Z" E4 Z! V! C
    return 0;
. I  P; q! w/ B8 C4 d! c2 d- B}
6 a3 T- c; s" N6 l0 G
' ^* G% {. u7 X8 F( I# y6 V) c; uint Pop(Stack &S,SNode &e)
: M( J0 f$ Y9 ?/ s) ]{" v; {- K; p( Q2 T/ O4 |
    if(S.top==S.base)
6 h0 U% |3 k4 d8 R- i8 n$ f# Z    {
' a; Q: {. ^! u        printf("栈为空!");# r( a2 a* ~& ]+ \
        return -1;  r0 c2 \7 K* ?7 @1 q
    }; K1 W3 D: A& v; X7 y' D7 U% J( i
    e=*(S.top-1);
; m; \3 s, s, @8 s# |( ~    S.top--;
" P  M# b2 s& N! {- |    return 0;) {0 ]! n/ u1 t2 N
}
' T% y" e3 o) I; w
: B8 ^% L, \- nchar get_precede(char s,char c)
  _7 I8 N: P* k{
7 _$ x9 ]5 S+ c1 g5 O+ |    switch(s)
: z1 I5 p- F% H1 J9 e& _3 y) `1 `    {
" X9 d- j0 f- n% [( k! |2 ]( U        case '+':                 
2 r& B+ w- L( c. J5 A& f- |        case '-':" W1 U  W6 X  M! S+ P
             if(c=='+'||c=='-')  l/ B# ?# K( r% a2 i
                 return '>';
! O! I( ~  T) j7 T+ a6 C# i8 H             else if(c=='*'||c=='/')/ a1 }" R0 ?3 \' Z
                 return '<';3 b/ ?6 p" }1 g3 F
             else if(c=='(')
5 I% x; y  a2 K3 y' L                 return '<';
* C7 [8 k. O( A4 m0 ?" D4 K             else if(c==')')5 u" t: R7 j! q# D# v8 \1 S" |
                 return '>';6 X4 U3 O9 C9 B4 a2 i
             else 8 t' C  i/ f2 v( |4 R7 U- H
                 return '>';
: S; Y  w  j  n: G# c        case '*':3 y0 p$ T/ h$ U+ Y1 l
        case '/':. f2 I, s, M- D3 Y
             if(c=='+'||c=='-')( w9 ~5 ]& L: ]1 U6 _
                 return '>';6 |  G5 E/ s3 ^" F" h4 n2 q4 Q5 W
             else if(c=='*'||c=='/')
- Y" B- E. T- f, ~9 d                 return '>';
! T" ~- R  x5 b2 r; K) C             else if(c=='(')7 v0 @  x5 O; w# B" ?9 ^3 C' ^
                 return '<';
; M% {, R) s  P5 ^' j3 @             else if(c==')')% J- h- I" r- n4 |" Q
                 return '>';8 D+ i: ?8 L6 L* d2 Y4 v9 w9 @
             else; Z6 S- ^6 C+ C. H; |# |: m
                 return '>';+ ]: a9 |9 @  t( i) X; Y  A1 M
        case '(':6 h4 v, [9 S9 s/ ]* d
             if(c=='+'||c=='-')
( q$ s5 t: \: {, R) x7 ~                 return '<';
1 S. e! k. }' J5 i8 N" W! B* n             else if(c=='*'||c=='/')( l0 e! Q9 r5 y  _
                 return '<';- e5 t4 v9 @, e. A4 l; v/ V3 ~0 y
             else if(c=='(')
3 `- G, [, {! E  _: Y$ A                 return '<';1 ]$ A9 ]7 Z: `
             else if(c==')')- @. X: H: w+ K  w
                 return '=';
8 a5 @6 ]" o& b" N, W# b             else; A" `2 n# D, @8 R) U. @5 m) b
                 return 'E';2 D* K8 T0 z8 s* w& G( Q0 c# T
        case ')':
. l& E" Y" X& p4 Y/ a" R7 |% n             if(c=='+'||c=='-')5 [. h7 s0 H* ~; H, A6 V
                 return '>';' ^$ J' Y, u0 i* N
             else if(c=='*'||c=='/')9 q' e1 f" e4 V' v% H
                 return '>';& c. q( G/ U5 |: G
             else if(c=='(')
8 K- L! a9 X0 \+ D( T" X2 L( @  k                 return 'E';
7 I& k, g; m- w: z% F7 n             else if(c==')'). d7 i) B! E5 P5 h4 e( g$ W
                 return '>';
  b# Q* V8 j' o2 f; Q) C1 l) V8 \             else- h  V) S: @0 o, V% i+ }/ f' i5 O
                 return '>';
* g& C' X: C; u4 \! v' K        case '#':
! `8 o" I/ G5 e5 U( ~             if(c=='+'||c=='-')
. b7 c; ?" a0 z$ `+ U( C+ L# t                 return '<';
. C& p' S: O% G! T6 Y+ O# E. i             else if(c=='*'||c=='/')" t3 \; v) Z+ n7 [0 A
                 return '<';
  X$ ]4 z3 C/ b; l, j/ }3 y             else if(c=='(')1 B( F) a/ \- ?4 I
                 return '<';
  p7 L  s0 [* S: a& O             else if(c==')')
% s) T  p: T% g6 z' w                 return 'E';
2 h$ g5 L0 X& G4 q5 g! c             else
! T8 |( G, ^$ \: k# {                 return '=';
5 b- e) N) S5 ]% L0 O        default:
+ q( c) E; E/ u/ Z# Z1 M             break;
1 K, M9 Q, z' Z    }5 v5 u0 S# S: J3 {" f  x
    return 0;   
7 }. \( _  V0 i6 o, |  ?0 ^}. D7 d0 Y! |& V

" `" G8 m1 N2 X$ {6 Nint isOpr(char c)+ q$ i1 I! W7 s( |3 u
{
$ f6 [2 F8 d0 s( K; {/ E) S  R8 u    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
5 M: H* {3 E6 J1 o" J        return 0;7 V4 r3 e) V) f- M0 ^# P( x
    else
# P# d! u  w1 j# V/ U; v! B; ^        return 1;
3 r  E6 U/ L7 j" i+ a}2 r3 \  e: y' a/ o( m) u

3 O$ L8 g. u% v- M7 X  X* G" ?) jfloat operate(float x, char opr, float y)
( F" }/ a9 ]! v6 S4 s{
: q) `3 O" c# `; j    float result;6 n* w7 S7 m9 m5 K; b% h1 ^" }
    switch (opr)9 E: T. Y5 J' l+ v3 x
    {
: }# ?& R: q5 \9 V; R; o        case '+':
! u3 W' P. U6 ^. L5 r  ]             result = x + y;: y% l/ _; a9 U1 [1 D* \- O7 K
             break;
: a  j9 @1 J0 n( q$ b& k+ l2 @3 E1 ^/ f        case '-':
3 e" t6 M) v& s6 `1 e: Q9 i             result = x - y;, x  Z  R' z2 I( K, O6 N1 v
             break;
/ [5 @4 d1 ^* Y# @6 K        case '*':
' G- f7 D/ }4 P+ L& j# L             result = x * y;
7 B' D+ ?/ E% s; Q& _! V$ R             break;& |8 J( N" E" P9 |
        case '/':
7 I3 ~; l' [* ?" t/ J+ |" a2 {             if (y == 0)
* r4 f: l4 `+ |9 A             {
  P* N( [3 l- O. A3 l                printf("Divided by zero!\n");
5 g% c! Y# B1 N; T/ l5 m7 G                return 0;, B6 l1 h0 a) E9 U
             }
! P+ i# Q2 w. A             else# [& {$ E7 k/ a. I1 j0 t
             {! y2 c8 Q; B7 [/ g' o
                 result = x / y;
1 ^. F' a$ U4 K. i( m8 {                 break;% t- W8 t- I, T% }: \. Z  t4 x
             }$ Q/ m$ z& G- ?& {6 b3 ]/ K
       default:
" y6 x/ W$ m6 f, r: l7 S             printf("Bad Input.\n"); 3 c- g2 l& \( I( o# A& W6 h
             return 0;
9 _  c& _  R; R2 w6 |  [5 X! y    }
+ O+ I3 b; d3 l    return result;2 v. E2 w; o: T! S# d1 L7 w
}    8 |# D5 ], Q( r1 Y# ^; n
8 e# F: h9 v) o/ N6 T
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/, x5 d% z! W$ o: ]
{
  U# p0 q# L) G7 e    Stack optr,opnd;
/ @; w% S! z% s. G" B$ Q4 h    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;- T. p" _6 J" t  ^* h( \- e
    char c;( p+ ^) d8 a. f
    char buf[16];
3 \. Q. F+ N; s- K$ V$ J    int i=0;
9 V# I" ~* U" [. O! T7 d5 v   
7 ?. N" I" T$ H( {, l    InitStack(optr); /*用于寄存运算符*/1 B, _" o  z! F
    InitStack(opnd); /*用于寄存操作数和计算结果*/9 \( _0 w6 c( b7 O+ K) Y
    memset(buf,0,sizeof(buf));
/ Y, B8 @9 ~5 E% _: K0 I    1 `; @# d1 V2 g$ \
    printf("Enter your expression:");+ p0 n# y" W6 i* N. T; Z' A
        
8 D  |8 V7 B: v! k8 J    opr_in.ch='#';
% c  v, l! q0 y! ]. o    Push(optr,opr_in); /*'#'入栈*/
( e. Q, @7 v7 v, k+ O    GetTop(optr,opr_top);0 P, l  M/ l. g; g) H
    c=getchar();
) O& {3 D7 {! B. f    while(c!='='||opr_top.ch!='#')
2 ^2 x1 f1 m0 t, n. q/ H7 P0 j9 A    {
& X. G, O+ M/ c* f2 j        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ I* x" m- \0 I; S' c$ ]        {
) }+ s* P. y6 t, A+ T            buf=c;
2 l" c) @2 D7 f; {" R5 d            i++;
8 }4 g+ `) X% i3 v: o            c=getchar();
& K4 l: t' C0 D) e( j        }  j. H; t+ a3 P& c
        else /*是运算符*/
+ B9 x" \7 e# X        {
8 i2 Y' u5 ?% U3 f$ \- U3 D& I            buf='\0';! q9 U1 M+ t" u1 n5 J% _1 P' F7 K0 ^
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8 d: _% `) z5 I5 R            {0 C" D9 t; A+ o7 O. ~6 g( P& M# x+ z3 t
                 opn_in.data=(float)atof(buf);7 S4 j/ Z& X8 v* |; P% X& {
                 Push(opnd,opn_in);
! v. h' C* {! m# N                 printf("opnd入栈:[%f]\n",opn_in.data);  G5 J# K! `+ t% R4 y  t1 Z* Z0 P
                 i=0;
4 q9 J; {" }/ Y3 [                 memset(buf,0,sizeof(buf));
3 O* Y/ V. t9 p$ w2 J/ o            }6 h. b2 M) t0 K* J6 O
            opr_in.ch=c;- X9 _0 A, _6 y( X8 E+ I/ s7 Z/ h$ d
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*// N: ]" p' h& o8 T: l+ }# f
            {( F5 x( l2 Y( X3 @
                case '<': /*优先级小于栈顶结点,则运算符入栈*/* f% k( |: q+ s/ Q/ `! U
                     Push(optr,opr_in);
: B' C4 _7 D5 }# I                     printf("optr入栈:[%c]\n",opr_in.ch);4 U# _# r' k3 }0 _3 u
                     c=getchar();
$ l+ a6 P* n8 }) A* T- C; }0 y                     break;
& p& ]4 v) l. x# c7 v                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
4 O5 t; w8 a  z5 Z1 l+ Y" {: U7 {                     Pop(optr,e);2 _8 I2 C6 T% [7 p6 h( t" E
                     printf("optr出栈:去掉括号\n");$ n& X$ {* T1 D/ \
                     c=getchar();
# l9 ~+ z& X- o( v8 r/ b                     break;$ O) O7 x/ p/ X* N( J
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
3 H4 G# s7 [1 i9 y6 |  l                     Pop(optr,opr_t);
/ T) K4 O; |9 j5 i3 ~9 M                     printf("optr出栈:[%c]\n",opr_t.ch);
1 ]- E$ S! R2 D: U3 s' d& M                     if(Pop(opnd,b)<0)
6 J& v) r) e( M' r                     {, F! h  S1 V; Y$ ?/ f
                         printf("Bad Input!\n");. R% U  q5 @# z0 S8 n% E
                         fflush(stdin);
# R+ c. l6 k$ ?# O2 o8 l/ v9 L2 h                         return -1;
6 F. Q5 |- s) _+ C& f& I  z                     }
" H% ^! P# ?' u  v8 C8 _* e                     printf("opnd出栈:[%f]\n",b.data);
5 l8 s; N) v% L- A7 ?& t/ R. a& e                     if(Pop(opnd,a)<0)
/ \' Q* h' a. o9 A3 h                     {
1 e% J8 p! X# e- I) h                         printf("Bad Input!\n");
; R& R; i7 p3 _& M) ^                         fflush(stdin);
( M, M0 w& K* Y0 ^7 }                         return -1;
* A9 `: s) O: e9 p) K5 M                     }
8 j5 c- i3 ~) w) B3 e8 I                     printf("opnd出栈:[%f]\n",a.data);9 n4 L% C8 m" c2 b
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/& f7 ]$ ~& A7 D' [* |9 v$ R# z
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
- [6 J5 j# B' X# ^9 H3 k                     printf("结果入栈:[%f]\n",opn_tmp.data);3 _- S7 P. E1 c8 _8 ]3 s( N7 Z
                     break;
  Q; O% d6 x7 h0 C            }% W/ q8 G, C9 J8 a
        }
) @- \4 |3 @+ c, Y        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
, L+ C9 O: R# N: Z; q7 C    }% y3 i3 ~. F* n' o
    GetTop(opnd,opn_tmp);
# k: a1 T$ d( z+ X) U    DestroyStack(optr);
# y0 o' _- m, P7 o    DestroyStack(opnd);
8 }; j! e2 L, e8 Q5 i4 A    return opn_tmp.data;, u- x6 l# G. K3 I
}2 u- b8 h% q0 v2 U

0 D+ j( E( C+ T0 ^  U5 ichar *killzero(char *res,float result)" j+ ?+ r7 q' t) h- q+ F6 B
{+ U& D2 |* l  F
    int i;& g6 k- N+ {( W) R: x8 X+ }
/ a/ f- E% i) k
    sprintf(res,"%f",result);+ l' a: J( ^! k% a, J" Y7 B
    i=(int)strlen(res)-1;& k7 x. ?& W0 _+ o; @8 w2 E; }" t
    while(i&&res=='0')
; |9 E5 y0 T+ R7 |& H2 q    {
6 ^7 K$ a; t1 T9 U        res='\0';4 g( L( h3 i+ J- U7 ]1 h0 o9 t
        i--;4 |' D+ |# j5 J. k8 M
    }
3 z" x) q  B- Q7 s# N9 {' d( E2 f    if(res=='.')
+ @, f) C3 h$ D! W: C( F# z        res='\0';0 b; u2 A& r" n1 K4 D5 D8 s4 c4 o
    return res;
3 _* O, s% p+ u4 F}% R; b) L5 g" X3 q! [& {
; g2 w2 x; P; F5 K+ s+ V6 f
int main()
" E. j6 r4 U7 _{8 X2 a/ Q3 K6 e0 w* v( a! B
    char ch;
* }5 Y# F+ K, r    char res[64];  f& f- ^6 e+ w: w! W# x% ?) e
    float result;9 ]3 P) A; g" [2 S, v- [# G. b: d# x
    while(1)- o  \' O$ d& i2 n6 U" @
    {
# Z) v8 d6 D7 R% p        result=compute();  b6 Y( G8 z8 ~/ I  |
        printf("\nThe result is:%s\n",killzero(res,result));
; a/ h# ^0 M2 V' Q6 [# j        printf("Do you want to continue(y/n)?:") ;, P# X  o) j. S5 d( _+ s9 Y- w: Q
        ch=getch();$ `3 y& g9 V6 E: r' Q
        putchar(ch);
+ [: S+ l" U; P: p6 }. l        if(ch=='n'||ch=='N')2 }& g% f: U4 M* \% i
            break;) B! q/ y! I" \: n1 O7 k
        else
: t- Z: X1 x8 Z! i0 y5 G            system("cls");8 g! n1 k( f5 f8 d
    }8 \; |) q: Z0 F) L, ~1 ^
    return 0;/ Y3 Z! e/ t7 `+ `8 P* n4 O6 K
}

6 ?$ y% n9 {+ H' X# c! U# M/ |+ j1 _' l& e+ v
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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