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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.: F3 Q4 _0 m& Y% S% f% U' X
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=# |% `6 |3 ]( t( E# h4 ]1 ]) `# z
/**************表达式计算器************/0 r, b: f% s3 G) E
#include <stdio.h>
3 `% f  G% M! I# z#include <stdlib.h>
9 r4 Q5 S/ f( w3 p8 C$ N1 b#include <string.h>
# `2 X' d+ a" L( b#include <conio.h>  V. P5 M% W% [( {
#include <malloc.h>& |4 M# @& F; |! x. m1 u

7 c' p' F7 V3 F' B, T#define STACK_SIZE 100( O8 s$ O( B5 \3 z! G" B' q
#define APPEND_SIZE 10( e8 F$ V8 D% [/ I5 i# z

6 W( b% E9 a0 S) d8 `struct SNode{
( q7 R9 B% w" h8 k6 ~; @    float data; /*存放操作数或者计算结果*/  F7 l' T4 E9 f$ Q4 y
    char ch; /*存放运算符*/
. ?% `4 i1 L. w9 u' U# G};
0 ~( z2 l# m* r3 e1 U. p0 u+ K" ~9 F6 t9 D. a" f1 k: \! m
struct Stack{
1 G: D, N) j+ ^$ K    SNode *top;9 y) [$ Z' x: N, r+ p6 [5 r5 ]
    SNode *base;
0 s! C1 u" I" |4 v! t    int size;
" W+ `' f8 n& q: ]- S};8 }8 y1 H5 |% ?% @9 |
# M. R, b/ A. c+ J: J0 b5 g5 Y" Y4 r
/*栈操作函数*/
6 i( F; e6 N/ i- Z. P6 v+ N+ iint InitStack(Stack &S); /*创建栈*/$ ^; \# g& a) V( f3 ^
int DestroyStack(Stack &S); /*销毁栈*/
2 v  t( |* X+ b- ^; W3 ^% R! C# iint ClearStack(Stack &S); /*清空栈*/- _  ^" t$ g; v7 t  H
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/' D4 A) w+ s6 ?* Y; b! X" L
int Push(Stack &S,SNode e); /*将结点e压入栈*/
- l" O! I  Q. O7 t( ?  ^int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/" r; H6 R# P& B9 S9 O$ Q
- H/ E3 o. _: V
/*表达式计算器相关函数*/
& G2 n& M8 _5 b% [9 }: L2 q3 T7 Tchar get_precede(char s,char c); /*判断运算符s和c的优先级*/( h+ d1 e5 j$ g+ E0 @5 X' _  p
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/. t+ ^; u' C( L9 e( U
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
- Z: F) t" i/ I2 S, p7 K. Jfloat compute(); /*表达式结算器主函数*/
. l# A2 v2 B# A8 [* [  ^char *killzero(float result); /*去掉结果后面的0*/ 5 i# }  p# B2 ^8 ]' R" j
! e4 L$ L+ f1 C/ D+ \
int InitStack(Stack &S)" a1 z4 S- x, o: r( @. d0 H
{  Q8 `2 r6 Z* ?
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));. H2 X0 f! ?! G, R* b
    if(S.base==NULL)
2 v  L9 R4 L1 @    {& l  A3 d0 ~8 i9 r' y4 n8 j' ]
        printf("动态分配内存失败!");
' A$ c! B. e" T+ ?8 g$ @4 |4 S9 ?        return -1;1 n% G3 |$ D5 Z  v$ w3 X
    }
" x6 p/ H% B3 Y& X    S.top=S.base;
1 q; [) Z$ b3 D, s$ ?    S.size=STACK_SIZE;; x) j7 _' z, `& P' l3 X
    return 0;! ~( D+ n) S& I/ a
}
+ b: G) V1 G  E) ^% d4 ~
/ ?( N8 l. J5 G: Xint DestroyStack(Stack &S)
; t! B7 i7 {) Q- L. ^; B9 S{+ g1 Q. x$ \$ A$ m
    free(S.base);3 E' c! M- j& G
    return 0;
- e% k9 u4 U$ }' Z}
6 q5 z" [% s* S+ M5 A
; P1 H7 G, a2 f: l! {9 M) gint ClearStack(Stack &S)
; v0 u; d1 B* E. q{
, y2 [2 t" |. r' B" H    S.top=S.base;
3 m0 m, W0 @, ~6 R; ^' a    return 0;
# V% Q- o2 @8 Q" W& `}: E! d. O1 _& L( k1 n8 T
: v  T( `( Z. W/ l3 a- _  c
int GetTop(Stack S,SNode &e), C) }% _3 q$ B) W! H
{
9 W  |$ |# e0 ?1 O/ w    if(S.top==S.base)% B+ k2 N; J+ O' N7 Q9 T) K" {" Z
    {( v5 o# [8 h$ A1 O/ c# T( @! G, H8 E
        printf("栈以为空!");
! b$ I3 W9 I% S7 q5 K        return -1;
2 Y: L: r! X' Y3 f/ S    }
" }4 q/ h1 Q" G. s+ q    e=*(S.top-1);1 [* H' W8 I  Z) h9 S# l6 K
    return 0;: Q' P  H! x( q; s2 U  b
}
2 X) |5 c- t, i7 H: O6 s
) U6 a& y! V& N4 t$ p: yint Push(Stack &S,SNode e)
9 C$ o# u5 y' U7 o1 O0 t{
1 G$ B+ u/ z8 d4 |0 \    if(S.top-S.base>=S.size)* n8 i- p% J. b$ i! ?6 w
    {
. p/ K- r2 X* ~1 W; i        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
& l$ q9 _4 G) K, Z5 b# u5 @; \$ v        if(S.base==NULL)
5 G7 `$ T6 d* j3 e        {( ^2 a) `4 w$ U& N  F
            printf("动态分配内存失败!");
' A5 ~& V( j2 L* C( c0 I# k            return -1;- b; E2 s6 K: O! y
        }
7 h! [* U# g9 G# G        S.top=S.base+S.size;$ A' @8 T1 c( J
        S.size+=APPEND_SIZE;) p! o# f; p6 a
    }
* u! F1 c9 u" s# j7 _    *S.top=e;  B, _3 _0 M$ l
    S.top++;$ C& q) P4 J( [  r
    return 0;
5 K$ l# `# |3 B; Q% S" Y}. C2 [( E9 @; a- H1 c
9 Z% A7 E8 y# l9 i& `3 H2 }! G
int Pop(Stack &S,SNode &e)( D. b- e6 T. B0 D$ r* {
{( V5 ]6 C/ x6 B1 T
    if(S.top==S.base)3 L, T3 D! P2 y) [: }
    {( W  |3 S6 ~! X; V* E! V( H
        printf("栈为空!");
2 D* j( @$ `* w! T: S        return -1;% {- i) p0 d0 J0 f  K
    }% D/ p! `4 w( k/ Y( |9 ]
    e=*(S.top-1);% K$ M1 |8 S3 _
    S.top--;! X1 Q% g! A6 S1 H8 L
    return 0;
- ~# \; P6 x. p% w9 U}
* U* R- [3 F! t: v9 t
1 Z9 |- }" m0 X& D; }: {& Gchar get_precede(char s,char c)4 [- q9 {4 q  D* ^
{
8 q: Z1 S; E5 Y8 V! o! b. s    switch(s). A: y% ?, j. t% Q
    {
+ N1 d0 z. w1 X( k        case '+':                 
0 B) Y' X- o4 I9 P& E, j8 d        case '-':
( h: P$ u3 r* h6 |$ r, q, Q             if(c=='+'||c=='-')
) a0 n( L. ]8 M6 F                 return '>';6 s6 M4 j; t% l# s& p0 ~! O' S4 t
             else if(c=='*'||c=='/')
: x; t  H. W' h( y& v/ d4 z; z                 return '<';0 x# S$ m2 `6 l$ F5 B- u
             else if(c=='(')' {) `0 f- O' `3 Q- K, P* l; Q: C
                 return '<';/ D/ N% j4 K0 k5 h8 h
             else if(c==')')0 p' ^' V# U8 D2 z9 ~  a4 U
                 return '>';. h1 a" W9 C# `. X3 n
             else ; x# `( b( @0 i* p
                 return '>';  ^. }& V) x! |& L- u: a
        case '*':8 p% _3 u3 o7 ]' k+ N0 n6 {
        case '/':- B/ D2 q$ d4 o0 B  w' ?( H
             if(c=='+'||c=='-')0 D8 e, K0 Z' N& L
                 return '>';" \. t! E$ {7 `
             else if(c=='*'||c=='/')
/ N; b2 i- y. ?: s# H                 return '>';4 n/ m4 H7 k2 A! S! Z: f7 g
             else if(c=='('), h7 w0 j1 W! }% P( p
                 return '<';+ R( X$ q( ~& V, c7 q( ?; z
             else if(c==')')! t' \& d3 [, m& P9 u
                 return '>';
) A3 e* c6 S6 S2 f5 a             else
+ ~0 z% a. E& b+ E                 return '>';
3 x2 a" d% R1 M  L9 K        case '(':
8 Z# L' E3 T, w/ a" [             if(c=='+'||c=='-'): U! T0 |) u2 p, r# X+ G7 ~1 w
                 return '<';
9 A3 u. v/ N% \+ ?& k5 P7 |4 B             else if(c=='*'||c=='/')' t; e$ j8 B" \! t
                 return '<';+ C" b' ^: S1 a4 p1 L, y  d* F4 T* K
             else if(c=='(')
. a6 Q- y- O6 ]# a                 return '<';, f8 ?! X/ v" q) K3 L' h
             else if(c==')')
- A# ^0 h: b3 s  |( Y; r                 return '=';  B( S) g) t% B
             else" i( r& B# {2 O! c% G
                 return 'E';
& Z( g7 p8 Q) ~% \4 W. g        case ')':
1 j1 U2 H+ T. C$ A             if(c=='+'||c=='-')& c' j% F7 D. ?  G* N& b' R# @( i
                 return '>';
+ H1 V: Z9 o8 m) X5 Q6 D             else if(c=='*'||c=='/')  V/ x0 B2 Y9 R/ C) {( L' S
                 return '>';3 i* z8 H/ o) [  ?, e5 i* [# e4 e
             else if(c=='(')
$ |2 ?4 Z0 S- ]: a' W                 return 'E';
5 ?) N8 u- h3 P; `% }& [$ M* j             else if(c==')')* i  A3 R( y% d
                 return '>';
5 u6 g/ R6 y. A- A0 `: E+ l6 m2 Z6 k             else
# V( M. K* f/ U% s. k& ^                 return '>';* W5 b" F; ]4 J6 }5 P1 }7 o
        case '#':
( U& F0 N; W" r             if(c=='+'||c=='-')$ u: L4 k3 m1 j; Y9 F! v
                 return '<';, W& U0 e3 j+ c3 z3 x
             else if(c=='*'||c=='/')9 U; R" `! E( l% H; [
                 return '<';
2 ~# O7 w2 V' k4 t/ k( ?             else if(c=='(')4 ?! p4 g" [# @- o% ?: C! ^
                 return '<';0 M  m: N: o4 l. l. D
             else if(c==')')
, R5 Q; A+ P$ N3 }4 q9 V                 return 'E';; h- b- g9 z5 {
             else
! C7 e  E9 H0 a& U0 j( q6 U' d                 return '=';
  O* V# K; `& B. M# E% v        default:
/ q+ p1 Z( c3 m& U. h4 ]0 [7 `- h             break;( D8 |/ D$ r0 o6 d* y; {5 p: @. Q3 W2 S
    }
: Z5 K3 Y& G4 A& p% x* g    return 0;   
; _+ ]0 {2 O0 H1 X6 b. p}) H+ N# h* I' s

% d. C7 c; F9 t$ vint isOpr(char c)
  g  d7 g4 P, C' j% k5 A{2 b+ S" I( q, f
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')1 r3 m& _7 e: l( k- c7 V% D4 @
        return 0;
1 X' W, y6 [/ F( f5 j2 Z' h    else   u) N# X) R. g* @
        return 1;  q8 [7 \2 h. G' y/ e( g/ `+ U4 l
}
* x5 p  @! ?/ H& i  f5 x3 L$ X. m' {2 H* ^# ~0 [5 G" R
float operate(float x, char opr, float y); O/ W# g* @3 p- R
{
$ Y4 }3 N. j3 ]7 C) E% D    float result;! w' k2 s$ `( G4 ]
    switch (opr)
) T; w5 t4 j+ q  Q    {
2 j( Q5 l4 ]. s( _( ?$ ?% ^        case '+': 1 \- L) s( \. x# v* e
             result = x + y;9 t1 {( z3 ]( M
             break;
3 u& \1 E8 ^; ~2 r# W        case '-': 7 t- a/ t1 n4 C3 j4 t1 m% [4 Q' t+ K
             result = x - y;$ o3 h( {: I5 ]2 f9 l
             break;
" m2 p" |/ c' m; x        case '*':
  O0 Z0 @" y( r/ M" z  J             result = x * y;
1 _+ J8 G( Z3 I9 H$ N( ?             break;- {; m- _; D3 T$ j
        case '/': ! E4 |1 h5 g. i, P7 W
             if (y == 0)
: p- r- Y2 l9 w. m: N/ b& F5 J             {
! G0 Q5 ^" Z+ s: |- L7 j                printf("Divided by zero!\n");
# _3 B1 q) s. ~1 e! E: J                return 0;
) C6 N/ M1 r' o5 W( ~             }. \6 [( v: ~4 D& g9 C
             else2 |0 ^% S' X3 ~% g
             {
9 y  ?8 V  U8 F1 r9 W                 result = x / y;1 p0 H: \. I% o
                 break;
' J8 P$ V& U4 A# A% ?             }- F/ L8 l, |1 G/ e4 O
       default:
# j+ ]5 `5 A4 k, L0 X/ E. l             printf("Bad Input.\n"); ) G- J- D: n8 F& i8 M' ?8 ~1 j4 N
             return 0;
- ^- u: n( V- s    }
! F7 g- V4 ^0 V* Q; Y    return result;9 H. W. r* Y  K' [- Q
}    9 `0 s% i  _- _& O7 \" {( ]
$ h/ |$ q3 [  i7 ?1 E( I
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
6 M+ ]4 C8 c3 K8 g{
6 j! z5 @. m. T0 T& }! M  m    Stack optr,opnd;
7 O" M" ]: o; A( L! b    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
* V9 c* z6 W- [% S# p    char c;
9 r" ?/ Q6 G3 Z( x+ e  J9 c( X    char buf[16];
- `: Y$ U5 s" O8 a2 X6 y    int i=0;
. g$ D! c, \" U1 a  K* n# w   
: ^" Z1 w2 w. e) b- c% S    InitStack(optr); /*用于寄存运算符*/
: f, N% p2 i( b    InitStack(opnd); /*用于寄存操作数和计算结果*/" x# }1 C  X  N' |* }  G% W
    memset(buf,0,sizeof(buf));8 b9 l' e, ?/ l" S; Z/ i
   
; P8 p% s. K& _  ?: w9 @    printf("Enter your expression:");' t4 h! q( B% X5 H+ M, j/ _/ r
        
9 i8 J( W, Q4 D- P6 |    opr_in.ch='#';+ }' ?, ?2 R* _( J; O8 C6 g9 T
    Push(optr,opr_in); /*'#'入栈*/5 c% F0 T1 K( @  @# e/ f
    GetTop(optr,opr_top);* d/ l' r1 C; u& [
    c=getchar();
8 |9 }( h5 z0 ^# Q    while(c!='='||opr_top.ch!='#')
% ]" c5 L2 J( U# E. L: O# B# u( p    {
9 v, l* j3 x' c5 u0 n        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/8 \' c5 B* S. {7 N4 ]1 m
        {# \$ F( {) ?+ r( A2 @4 N( Y& _* r
            buf=c;! o) Z" N( A$ g% |! o. |9 |0 w$ F
            i++;
; b7 X) ~. [% z6 W( b6 e- {            c=getchar();
/ `. C4 T+ x* i        }
' o) d: \. Q# T3 |+ W! i        else /*是运算符*/
# r8 z$ p' l8 a" _- c        {* W& x/ t0 u# p8 H
            buf='\0';3 M5 `" r# \, ~4 t% e& ^
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
( H1 H7 M3 X4 o/ ~6 o            {. s+ i- z3 k" N5 q" q4 o
                 opn_in.data=(float)atof(buf);0 A6 {/ I8 E) ?$ J/ F& w' K
                 Push(opnd,opn_in);& u# ?  c- g& |1 z
                 printf("opnd入栈:[%f]\n",opn_in.data);
" w1 x/ q; F' {$ ~3 y                 i=0;' K9 q' i* E* B! x$ v
                 memset(buf,0,sizeof(buf));
% B6 a4 p0 A3 M, `) L2 g0 G( }( x( r            }4 |6 k. I  ^$ f( h: ~
            opr_in.ch=c;
, |) J8 o4 L$ `8 b6 D# P" L& ^8 G            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
" s/ _' b* ]/ i% `7 S            {
& \; a" @: P% f8 q4 P                case '<': /*优先级小于栈顶结点,则运算符入栈*/
! b9 W7 v9 ]0 z: I8 s6 a9 C% h# d                     Push(optr,opr_in);: O* C7 k2 [- ~/ a; T3 Y
                     printf("optr入栈:[%c]\n",opr_in.ch);( c6 Y* m8 r6 R/ @- Z: D$ H8 e$ ]
                     c=getchar();5 D. c* j. ]& C" ^) h' ^, V: |9 y) n
                     break;
. c, ~3 |' P1 O2 x                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/5 ~" ~; O" k$ ?( k
                     Pop(optr,e);) H! _! q7 x) B* U6 ]
                     printf("optr出栈:去掉括号\n");
2 v2 Y  G7 e* W                     c=getchar();) Q7 K, Q' b7 g, g7 t
                     break;
! T) D6 Y3 N2 l& f* n: ?$ I                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5 s. |/ Z4 C- C
                     Pop(optr,opr_t);
+ F# R4 p+ X! F5 p, @6 Q# j                     printf("optr出栈:[%c]\n",opr_t.ch);! v6 P( n) |% o5 U6 W2 R: ]0 ^! B
                     if(Pop(opnd,b)<0)& R( p1 d$ D$ S2 o" Z) \
                     {: \- j* I; N' D7 _# y" B* M- n* w  }" T
                         printf("Bad Input!\n");
" b7 z+ [0 O5 F                         fflush(stdin);1 d2 j' S/ K9 X6 {+ C& C
                         return -1;6 D' M0 r  ?: Y. {* L
                     }
2 k0 z# h4 G: H2 L# n2 A+ A# J: `' }                     printf("opnd出栈:[%f]\n",b.data);$ @9 ]% G5 o! ]
                     if(Pop(opnd,a)<0)7 y8 c( |  I6 F+ z  {* L8 U
                     {
. y# G+ k$ x& u; q9 q7 I# v% Z1 P                         printf("Bad Input!\n");- m9 J& H5 S, |" F+ c4 q
                         fflush(stdin);. t( Y$ k- c( S. I. U' Y" r  u2 C
                         return -1;) T9 u7 T2 y6 f2 Y
                     }
+ H+ \$ h' o: N; r8 ?" _                     printf("opnd出栈:[%f]\n",a.data);
0 T6 S8 ^, @( P7 h! q' _' m9 k6 E) r                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
; r( W8 c* F. O' o                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6 q% m; t. R% |+ p1 L: Y. ^& @
                     printf("结果入栈:[%f]\n",opn_tmp.data);8 y3 m* h8 n$ a
                     break;# F! I: Z' e& B8 c  S
            }
3 {+ D* q5 G9 s* O0 k4 w: F, C: o        }* U2 K$ N0 L  |
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
4 Q5 q4 {, ~3 M  a4 d# v  u    }, L; T9 N1 a3 ^& ]9 X1 t
    GetTop(opnd,opn_tmp);3 r# o% |2 |/ e2 U9 P- y' I  d
    DestroyStack(optr);6 q$ v6 Q/ h8 _1 k
    DestroyStack(opnd);
) @$ h6 g2 J; w* |+ P    return opn_tmp.data;: l1 y4 L2 v& p) Z. n0 I
}
* z2 h- P7 J6 K3 P5 M0 D  F: {) ^9 {
char *killzero(char *res,float result)( }& k/ X9 J0 x; N1 |
{4 u1 A7 j4 ]! c  j& {
    int i;9 D' c4 d$ a; R& y

/ o( N2 }" }+ r& A* E% h    sprintf(res,"%f",result);
/ o# G7 `! p5 X( A5 W+ H8 y' V    i=(int)strlen(res)-1;* E' i' }# C/ K# A$ i5 S
    while(i&&res=='0')
( z; s  }6 ^- D2 b) p* @% T    {: p2 H6 V# ^) z6 `; N" B2 X" C  K
        res='\0';
# |# a4 _9 {: e2 m+ Y0 n        i--;$ ]" g- Y$ D- X" z& d
    }; ]6 w4 [& e8 o1 I8 I
    if(res=='.')5 S  b* X* W1 B, @3 R
        res='\0';
9 K; W- }3 y$ m+ b% l7 [/ j    return res;& \4 ^8 p2 b3 a5 |$ I$ b
}4 o2 p0 \7 k! `; K) y

& b9 ~: Q5 z$ ^+ n5 d' jint main()) u+ G/ l  _- V6 g! Z. D6 G, {. n
{
5 t$ \1 M( I0 {0 D& l6 n* L    char ch;
; b7 e5 w5 i" E* ~: }  e    char res[64];
; L3 Y$ h! \* H& H  b8 Y    float result;- C" L. f" B' q% \9 X
    while(1)$ b# M! q- r% y3 o) r
    {0 b/ Z7 g2 D8 [3 ?8 R! Y
        result=compute();
& ~! F1 G$ }$ j1 z1 s6 ~        printf("\nThe result is:%s\n",killzero(res,result));' I8 {" W; k5 d+ n; I
        printf("Do you want to continue(y/n)?:") ;8 ]( F, ?( y7 G, j9 j% P8 S5 J' J
        ch=getch();& R2 P; ?1 B9 |! u! m0 [4 ]1 A
        putchar(ch);; s# O% P: U, E4 M* C( z8 d4 T
        if(ch=='n'||ch=='N')
# J7 r3 r8 U) A  N4 Y            break;
& n/ O  e  R% _) q1 f        else
) p9 d4 j% J4 |/ o" z3 d) i            system("cls");# D/ v8 Q: Q* L1 _
    }$ B5 M& \% E) _5 s( H9 R
    return 0;
  ~, V, a5 S9 {, |3 ^. O}
  I3 `- x( D* U
% _2 X4 U7 s/ ~
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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