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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.5 C$ z8 z* T3 a% o
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
& y3 @( l8 T4 I4 q/**************表达式计算器************/5 z+ s% ~6 V) [2 b; s6 o" M
#include <stdio.h>
9 g* b3 t3 E3 }- D9 K#include <stdlib.h>! K; j/ t3 f7 Y. ^4 T- t
#include <string.h>; T/ j& I& w3 {2 e3 I
#include <conio.h>/ q" c0 W: S7 z' Y
#include <malloc.h>2 `4 ^& x* J! c3 w

/ _) a0 W+ [) Q/ S#define STACK_SIZE 1005 @& I7 u5 d8 P2 }
#define APPEND_SIZE 10  t. P  s# f4 H4 z

! a& y$ G# U* H( F, n; i5 k& \6 fstruct SNode{
6 }- u* F! Z+ u2 T) Z0 N    float data; /*存放操作数或者计算结果*/% `$ v1 K1 b; @1 X1 g4 Q
    char ch; /*存放运算符*/  e6 n6 Z1 J; D! q' p
};/ v9 H, l& Q8 a. O3 _

2 G- t' Q- b- e1 c3 zstruct Stack{6 F" {5 \/ Z4 Z6 u9 k' L
    SNode *top;; F/ W. h6 M% m3 B0 o
    SNode *base;
7 |+ |, N/ Z4 x- ~* L4 n    int size;
1 E, Z! ?% v* W};
! F0 c3 ^2 {; u: x, i9 I( U" H7 d, e3 {! h
/*栈操作函数*/
# }8 p: }  y- H$ \int InitStack(Stack &S); /*创建栈*/
7 u1 p$ I7 r' k9 D; @# [int DestroyStack(Stack &S); /*销毁栈*/
% u( P$ |, {4 ?# ~5 G# hint ClearStack(Stack &S); /*清空栈*/
+ C  o3 l) z( O! S# g9 D& Wint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
! C. q7 x) J! ]* v  z' M5 o6 I. g; Xint Push(Stack &S,SNode e); /*将结点e压入栈*/
8 i( t1 x3 W8 A8 {. Uint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ U6 C3 i: l3 e* L
4 o  n0 y# N# a+ v4 Y; K/*表达式计算器相关函数*/
' R: w  F( \' {. ^( R0 X! Y/ ?2 Rchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
9 @  t0 I, o! Z4 B- Zint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/$ I( Q" N* `& L" D  L) X! n5 R
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$ \( F- \$ f( U5 n! @/ a
float compute(); /*表达式结算器主函数*/3 b& U! {3 u1 E1 `9 K
char *killzero(float result); /*去掉结果后面的0*/ , P& q# l- v( v! o7 R& m
$ G8 s7 }' x/ D/ B% w
int InitStack(Stack &S)
! D" U$ S" i( Q- ~{$ c$ U( l! ^& f. x2 J5 E) P' R
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
/ Q. Q; \' R1 Q    if(S.base==NULL)- I, i; t' l( K& U' E8 ^) m! _
    {3 x/ T* j4 d; Y1 H
        printf("动态分配内存失败!");
: r0 e5 H* Q/ d  {  \& v8 X. `$ d        return -1;
+ o$ H  y! q# _* x$ J  U    }, T) t  }+ h0 x+ Z# h. i+ e. [
    S.top=S.base;
5 C6 ^( ]. m& j# [, a) n6 k* z    S.size=STACK_SIZE;6 {* {; U1 f( @. e
    return 0;
$ z" i1 `6 v/ Y2 ?$ n2 {9 c}4 ^* Z& H8 t: T& A; _

( S6 F7 k1 U" k5 W  h) sint DestroyStack(Stack &S)+ ~$ w: }& s8 d, v* `
{" K: \9 a6 \3 S7 y. |" {
    free(S.base);3 [' e% ?& G! ^2 x5 {0 @+ V
    return 0;
; d! q' ]" ^" g) H}/ r6 R! Y+ Q' X

9 W# M5 r' W# i$ Pint ClearStack(Stack &S)
3 O1 |  O; U+ M& w* ?6 |% R. y- N{# u% v5 M$ Q, t- d# T* v, K+ a/ C3 e
    S.top=S.base;
; ^: y. E& F) j& g% i    return 0;4 t% C+ n) _1 j+ s9 U% E
}. @% s: X, a& N0 `. j
& x5 q$ c6 D& y3 ]9 M3 O
int GetTop(Stack S,SNode &e)7 C( ^7 i( h! E( x, ~/ i4 l
{! u  ?& M; M  u  B
    if(S.top==S.base)9 p, l% W1 {) z% w
    {, C% k, P3 [6 Z/ r) g& ~8 Q
        printf("栈以为空!");
/ E7 n+ Q  J2 z& N5 B5 n7 v0 F        return -1;
* x% w9 t8 K1 S* O4 n    }
% C4 A; h, {* h) {! b5 I    e=*(S.top-1);
+ s* d6 J( M  W4 y5 X    return 0;& e5 {; m5 V+ |/ Z
}
3 A, v2 S) s, u' _. |6 x) E, N, C+ P3 G8 Z" R/ K
int Push(Stack &S,SNode e)
/ f$ p% B5 P" G+ J( G: c) ^{$ U4 ]6 A- ]3 {  q: k3 k
    if(S.top-S.base>=S.size)
* b. N2 I0 w! [    {3 m, C( B+ g) s: G. q
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
4 @( {+ }! g2 `5 u        if(S.base==NULL)0 S7 q" A4 X) h. w8 {( `
        {% Y; l4 |0 p! i4 Z3 s5 D
            printf("动态分配内存失败!");
7 w7 X) ?' u  ?' U, x  {) \            return -1;- j' ~. j* G, m- w) e3 ?
        }( d- n# V; Q: L* w* ^
        S.top=S.base+S.size;
; U; [* R1 ~5 w) Y        S.size+=APPEND_SIZE;
! M3 f8 \% s  y4 `" n8 F) l0 X6 s) E0 S    }
3 U6 S9 f, J0 H    *S.top=e;+ _2 c- [1 _4 o9 z5 l' m9 I
    S.top++;
3 k% E; X. r7 @% I' b4 z, ^    return 0;
$ r1 N$ n: @+ b! O* _4 a6 [& s}
! u0 I+ L4 F3 e! ~4 S5 z4 v+ P/ Z5 h$ k/ p$ J
int Pop(Stack &S,SNode &e)/ a2 b, ~) M4 @; R0 |* r' M
{) s8 u& D& L4 z, ?- Q/ p* `
    if(S.top==S.base)
% z, L; Q  L2 s0 A  m# y    {
$ V- H( E  [. i- c1 o2 J        printf("栈为空!");
+ G6 N9 L# q/ j% c) Y        return -1;! |: {4 f  {+ Z5 [2 p" [2 Q+ b2 J
    }- i. U, A2 w% t2 z8 T& f4 ^# Z, e
    e=*(S.top-1);9 m, v7 ]) {4 r# W9 Y( e, q
    S.top--;
0 @  j5 L* S. [+ C) Z0 l/ F! L    return 0;
. X8 ?0 c1 M# `* l0 G; A) L}- U, ~, z; N& C4 W9 o8 q
, Q+ N. D4 [1 L6 ]% }6 M, E: M, r
char get_precede(char s,char c); F6 Y5 t5 W. O. a% a
{
/ q9 ]$ w( s9 j/ K2 a" C- k$ }+ [    switch(s)
# @1 F" ?, ^- s8 ~, z" ~    {
. Y+ m8 x5 W, m6 U- U) V+ K: }5 H        case '+':                 / e9 x7 G7 A: B& R
        case '-':& b# l4 L1 U6 P  O6 Q
             if(c=='+'||c=='-')2 N% O0 G: n" f  n
                 return '>';
" W+ m. b* R7 J: A             else if(c=='*'||c=='/'). ~) t, u* L( p5 Q7 H" G( \
                 return '<';
: U" y2 P, i3 O( `) F( f. W             else if(c=='(')
5 M% a6 j8 b; D                 return '<';7 _0 M& H7 i, ]9 W9 c
             else if(c==')')9 u  D2 \/ m+ A6 s& B
                 return '>';8 d$ \: J* i+ Q: ]
             else . `2 g  a% g$ B3 V8 w
                 return '>';* M4 }5 O1 i2 o8 m1 Z5 [
        case '*':
  Z- Q3 V! P* q. |        case '/':
# o$ a$ u  j* M2 `) t             if(c=='+'||c=='-')1 E$ B$ x' L1 j: i
                 return '>';
; B  L* o) @& K. ~6 N- z6 i9 a8 T( X( s             else if(c=='*'||c=='/')
; p3 ?6 N: U9 q) r) I% F                 return '>';
3 R0 U! ?: O! s/ y             else if(c=='(')
9 q" p4 i) A0 ^9 e- W; z7 \, @                 return '<';
# f7 D) N, y+ ?& G             else if(c==')')
& {/ |% w. T# R9 M0 R8 ^4 F                 return '>';* l5 f5 p- A4 }) `" q: T
             else0 g( \% G& q# j2 B
                 return '>';
2 S/ i8 O  |# P. |- F( k        case '(':2 k# z, G& q9 g1 n* E
             if(c=='+'||c=='-')
5 g/ x+ _. M! g2 F                 return '<';
2 `  }+ v, c' N. b  q6 I% O  {             else if(c=='*'||c=='/')
2 d5 ^8 W; |$ R8 f; m7 o( p                 return '<';9 e  M) y4 @7 g, L/ |7 w$ @
             else if(c=='(')
) {9 [/ m+ r! @# A) {+ Y. }                 return '<';0 {" D4 U& |( Q" Q
             else if(c==')')2 ~3 V; |$ e5 v
                 return '=';, r; t9 A3 M; N% o) V# g
             else
; Q7 W* D8 \' q- z6 @8 }# Y                 return 'E';
% o. [& p/ M  p9 L$ V7 ]        case ')':
0 N3 \: d8 [5 @             if(c=='+'||c=='-'): v4 r' d- M' F& C
                 return '>';
7 V4 Z4 x  N; z  L% d             else if(c=='*'||c=='/')
7 r7 X% B* r9 c' x$ w" g                 return '>';
3 `6 I& T: S4 P* E1 u6 X! P             else if(c=='(')
4 a5 |/ E+ }! {, D                 return 'E';1 P5 u* R' C+ `. a, Y0 D
             else if(c==')')
' `! w# f3 p+ b( J3 q. T                 return '>';
5 A0 ]% \# o3 ~; m0 Z) w) T7 N; B6 [             else
# I/ W* Z: _  {* D  |                 return '>';) o1 ]5 E) I, A8 y+ ]; z1 o
        case '#':. l! d7 D( t( Z2 v( i
             if(c=='+'||c=='-')7 o* E' \- t6 X
                 return '<';+ s! v2 R: z6 K; Z- H
             else if(c=='*'||c=='/')
3 a; d3 [: U8 T2 P                 return '<';) m+ K# Y+ `7 ^( B/ i
             else if(c=='(')! |7 B; C8 C$ O, _: a1 N. n
                 return '<';9 V& o& J& X0 W9 N1 k, _
             else if(c==')')
3 f% e0 a6 G6 e0 d% }3 F                 return 'E';4 v% O/ X- X7 p) U
             else
3 O- A0 n0 C2 H8 D* C3 C5 S                 return '=';
1 x7 x/ c" D; Z        default:  M5 }9 O, E2 Y0 e- d# A) k" E4 V6 P; _
             break;7 B) {. e2 a% F9 x$ m
    }6 O( r, ~* j) M; _! h
    return 0;    . R; _: [3 ?; L% D
}! b8 l2 c0 i! C! H7 e  ]
6 M$ z4 `; h7 z! y. y  N& v: ^" M( Z
int isOpr(char c)
9 [1 \0 [3 c2 }" I9 n6 K$ d+ l{8 z5 h# N. ?+ N  B4 s  J- e. c' [
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
0 Z5 p1 J3 {  U1 ^6 y: e% E: I        return 0;
) o7 g; H0 p) V  ?- d6 e    else * N. [8 h% v% ^, w" V2 E) X
        return 1;
& H9 e! w* g1 Z( g* k}1 D# N  r' c2 X) w) X2 G& ]- `

! U7 Q5 a; s; Z! G. ]8 x3 n# Ufloat operate(float x, char opr, float y)
' c; [7 a# M# D$ t. i' u- x1 A& k" d{4 X( W6 f0 n0 t" c" k: e: S8 t
    float result;( |- k' m- \  l$ y7 @' o
    switch (opr)/ H% V6 n4 e7 v, J* g# q0 d
    {" g- B( o& H6 U7 f- d
        case '+': ! |& [  _! o, ?: d0 ]
             result = x + y;
& H9 k- e: G2 X2 X2 I1 C( Y             break;
: G9 [. W& ~1 e7 q1 g        case '-':
2 _9 A" S) e. P! ^) A0 f2 E             result = x - y;
, t$ r2 @1 H1 M# L             break;. G0 ?1 K, b0 ~
        case '*':
" `$ k9 {( T% S6 S) h. [# O' k+ B             result = x * y;
% y% {& t3 Q; z  Z5 c" @$ ^! u* A             break;
6 M$ [) E4 w7 v6 w        case '/': $ `' J4 P" R3 U# X0 B
             if (y == 0)9 H2 j5 C) g9 V2 K+ z
             {
, Y9 Y0 K' i, w' T# c                printf("Divided by zero!\n");
) ], r  I+ c/ S2 o, C7 }- C% e                return 0;9 C" w' w1 S2 Q( g8 K
             }& f) U# p4 x+ i/ U' b% S6 h
             else
9 j% R+ ~  f- H* I; E2 ]             {0 S7 V# Z: S  f' x
                 result = x / y;
" X# Z: u/ r2 V4 k3 _" K* U                 break;
+ W/ W& G% O& k6 R             }: R; `6 K: `8 Y9 b7 t
       default: ; m# A) H, _/ D8 q! t9 ]
             printf("Bad Input.\n");
6 U  p) |  U4 ]             return 0;% Z) S! p3 G+ a
    }: k7 u$ y) d" l! o8 `1 `4 N
    return result;! U4 c& \: x8 n; p+ b
}   
( L4 a. z- _# A- |4 z* r0 _
9 @4 D8 V, Y/ T& f- Zfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8 w. G7 m8 i* i+ M  c/ b7 ^3 {{
5 M0 H4 O6 D/ w7 Y, g6 {/ O    Stack optr,opnd;
2 ?. d  D) x5 n" ^* e    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
% A8 u  k7 J# W  F, \% N8 _+ {    char c;
- k/ k/ C% Y* N9 \% q) C    char buf[16];
, r' }" M) `: M8 A$ ]2 E    int i=0;
  z" d; w6 ^2 |! Y    3 [5 B8 o% _' @5 P; |! w
    InitStack(optr); /*用于寄存运算符*/) R. ]0 P, }) q
    InitStack(opnd); /*用于寄存操作数和计算结果*/* g. x6 @8 t, l8 Y7 y$ g2 W7 S
    memset(buf,0,sizeof(buf));
9 Y. l0 K0 \9 @. `   
5 q. e: o1 T) J# K    printf("Enter your expression:");' V) J/ ^, L7 S' T0 d2 E
        3 E  H- |5 _% D" s
    opr_in.ch='#';4 x  w7 B* A1 |0 d5 _  C
    Push(optr,opr_in); /*'#'入栈*/7 C. ]" v+ u7 E# N: Q
    GetTop(optr,opr_top);
0 A9 j& W9 x- p; `- W0 i/ L! z8 ]    c=getchar();
$ H8 o3 r) Q8 n9 q& G7 s    while(c!='='||opr_top.ch!='#')
, i4 h& U1 ]: i) k+ C: `    {) f1 z; d( Y7 c* z4 w
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
: m4 e) G1 _1 b6 `# r        {% `0 K- k) x: i3 v& z" T2 g) a
            buf=c;
4 b7 G% V0 J7 ~5 `3 q% j0 |            i++;1 U, E, Z3 e  N# X# O9 y/ l" Q) g' u
            c=getchar();7 s8 n9 {7 C( y1 g( f  P
        }; v$ Z- [# ^- q3 c* V% _
        else /*是运算符*/
2 j( @. L5 |+ C$ h# a; d+ s( w' v( M        {
0 u* ]8 k4 k* m: F9 v+ K            buf='\0';* M% G. i( Y6 z5 G0 O6 g
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
5 H6 K% Z2 _6 W            {$ n' D7 x3 L3 i8 S* s! M9 e
                 opn_in.data=(float)atof(buf);; H  s6 i: [3 v/ \4 B0 u/ o0 s
                 Push(opnd,opn_in);
6 M+ o: Z. Z6 E1 Y+ w  s7 [                 printf("opnd入栈:[%f]\n",opn_in.data);
4 {0 O6 _. U( R0 N4 n. E4 F                 i=0;
4 k  q5 P. @6 j) o1 m& C0 u/ f8 Z                 memset(buf,0,sizeof(buf));; H/ d4 g5 l7 c
            }9 _1 E: P: E9 M
            opr_in.ch=c;
; f7 B3 M& Y1 S% `            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
  ^7 {4 A, {8 z( I            {5 V2 z- x8 i3 K- Y! c) A
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
; X% L3 E+ j/ \# t6 z* Y# ]- D2 P  Z                     Push(optr,opr_in);
% i; r; h+ `, D8 T; w% p" w5 e                     printf("optr入栈:[%c]\n",opr_in.ch);
9 C: i, m. p5 ]3 i5 v! Y; t                     c=getchar();
1 L- K3 ]- G! c$ L                     break;% q8 A: t5 {; X+ B6 f
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/( S2 @# |5 C: M! k, k9 l
                     Pop(optr,e);
& b( ?1 `& b# @                     printf("optr出栈:去掉括号\n");% z- V1 |4 |' l/ h- X6 h
                     c=getchar();
" R3 m0 U9 X7 D9 A# {/ L1 d                     break;9 Y" a  h! U4 u8 K
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/" T3 x$ j/ H. Q- m
                     Pop(optr,opr_t);+ M; g* H& Q7 r' X& ?" v
                     printf("optr出栈:[%c]\n",opr_t.ch);) h, b' ~' b* S: i8 a* L
                     if(Pop(opnd,b)<0)" \7 k. K3 @' k" D9 _
                     {
4 H( w5 Y4 I# P, g0 E, e                         printf("Bad Input!\n");3 N. I1 A# w) g* m1 m; A9 `& j' q
                         fflush(stdin);
7 V* J! |( h" y# x3 j                         return -1;
9 z8 ~4 F  g" C3 x1 Z                     }5 X9 H8 R# A  i9 @
                     printf("opnd出栈:[%f]\n",b.data);
+ b! N/ v8 V  K8 G                     if(Pop(opnd,a)<0)
; `- {8 }- C( r4 G& `                     {
/ c$ ^+ E" c' o9 u! G! R+ }& x. D                         printf("Bad Input!\n");* j+ r$ J0 ]% U' D. _
                         fflush(stdin);0 M" G% P7 p# T* U# M
                         return -1;, ^- w, m4 j' v  b* U5 q' d
                     }0 t, D! H" ]( T; l# f
                     printf("opnd出栈:[%f]\n",a.data);
" I% |& S& q) H3 W. v) C                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9 E6 ~4 B0 T5 Y& s: `                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
6 W9 o) R& c  x7 t2 H) N                     printf("结果入栈:[%f]\n",opn_tmp.data);# p, l% v3 S8 F& m7 f
                     break;0 Q2 O6 p& }) x  ?1 f
            }
+ }& F8 P& m3 w# M        }
( [' Z6 h( q- n        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
  @1 b8 t$ ]4 K* ]. ?$ l    }+ h1 M' I" `2 V7 u# l3 v0 P
    GetTop(opnd,opn_tmp);
: r: U4 x& w& u0 o# b/ Q8 Q    DestroyStack(optr);
/ _1 y) N8 Y; m- u  a  T    DestroyStack(opnd);( M( D8 R: \" m; _
    return opn_tmp.data;9 a, S6 V% H: x% J
}. W' S: X! Q  o% U7 P: E2 J/ j; o$ B
1 r7 w$ M* V3 ^+ D
char *killzero(char *res,float result)$ w' D- f3 W, p- `6 P+ V9 g0 @0 P
{
; Y* j- J% k3 L0 d    int i;" V% @2 t1 I# Y0 _7 n; q1 y
! F. s. J% c* D
    sprintf(res,"%f",result);
5 m9 l9 R6 d/ U+ r5 R" Y  g) o    i=(int)strlen(res)-1;0 }8 Z# p4 L; j+ _, m, r( x
    while(i&&res=='0'). |- v4 S2 `+ b- a+ \4 o
    {1 d! K" ?9 W; G5 @; M
        res='\0';
* N- B; i4 Y& ~6 F        i--;& C0 O# y/ P- z
    }+ G) K3 f4 h( a0 B2 D' I
    if(res=='.'). I4 }4 x' g+ o; b& |5 M+ s8 p9 z
        res='\0';
1 M+ |2 i$ p0 S" P; P$ Y  U  _) h. {    return res;
, j; L5 z: o! f) ?}
# U1 [, D2 O- U, f
7 ~4 P! ~( G3 G; G4 fint main()
% V! Z$ H0 Z  w5 ?( W: f{
2 a3 F' E5 Z. n+ V    char ch;
: {# x6 e) g3 \' ]" ?    char res[64];/ \# |* l& d4 e4 c- H& r4 O; Q5 l8 ^
    float result;
4 `' [4 `5 l2 U7 D$ l: e    while(1)
: H- h5 G: m7 Z, Y    {
  L  B# v# v, H        result=compute();
0 L7 g% f# B$ c# g8 ?/ T        printf("\nThe result is:%s\n",killzero(res,result));; H, q( `. u, o) b3 _
        printf("Do you want to continue(y/n)?:") ;
3 F. u! E/ K6 K: {8 a- x        ch=getch();! f4 w5 K3 c" _
        putchar(ch);
5 v2 \' X: @" o3 [        if(ch=='n'||ch=='N')7 {# g3 E: p: R1 ~+ ~0 s6 h
            break;
; ?0 p. U( J, M0 E4 y  G        else
+ H/ k' q8 W( {+ q            system("cls");
& g# g4 v! b8 G4 C1 o    }
" k6 `6 q6 q5 s, T    return 0;) h! m# X$ q% Y. e4 R+ U
}
. q; ?4 x9 b) U# `0 P$ s1 B; `4 |
0 @' N2 V/ a. |  d- I6 X
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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