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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
9 A6 D! M5 J4 o& D: b, c* U程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
1 K2 C8 i" O8 \$ n% c/**************表达式计算器************/1 h7 G6 S6 b7 C% G8 u8 E
#include <stdio.h>
" m. L8 L- I& i#include <stdlib.h>3 i8 J* f: C' D% _1 I. W* d. i
#include <string.h>' O" D& c( G9 f! ?2 F' w. b. q; U
#include <conio.h>& _0 {, N; I3 X% R! `9 n
#include <malloc.h>
) {8 i, _( Y7 [6 ^' f0 d" J
6 y3 n6 @# K/ X* ^6 N#define STACK_SIZE 100- X& d( h# P4 I; A" F9 [
#define APPEND_SIZE 10& M" m& X6 Y" @2 B& k& E
4 E, v0 Z4 h6 X# n4 n1 q+ S
struct SNode{; I& ]3 @( R! \9 x0 b  L
    float data; /*存放操作数或者计算结果*/
! Y: |# {5 B. N0 F4 ?    char ch; /*存放运算符*/
- @9 v* |0 k# n6 y) g, S; S};
( J0 ?0 U0 C) f. P( M. N7 y/ Z3 R: v+ l+ k6 j
struct Stack{5 j6 f% q1 P, y- x
    SNode *top;
1 l- g& s0 c  E. Q- I4 z    SNode *base;
8 V$ g9 l+ [7 c  p* @    int size;
- ^" Y# v4 P8 E, e$ f" C* g7 Y7 i, |5 G};  s: ]2 d8 p; V( b" i) j8 B
  Z" t  v$ T9 N3 l! X/ Q' m
/*栈操作函数*/% L$ L& C7 P$ f6 ~1 b
int InitStack(Stack &S); /*创建栈*/
, d! O7 _! I- e3 u% P' G7 dint DestroyStack(Stack &S); /*销毁栈*/
) ?& ^5 Y0 X; N7 R* _int ClearStack(Stack &S); /*清空栈*/
1 ]* M0 r3 ?/ A7 a  L5 yint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/% e* F5 v; X' x# k
int Push(Stack &S,SNode e); /*将结点e压入栈*/% e. h) [9 w2 z; [' E
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/& N, _2 O3 c& R: X

4 m# t, E8 J$ r6 T; {* Y/*表达式计算器相关函数*/
9 ], E1 l! }3 Q4 |7 |1 w5 @char get_precede(char s,char c); /*判断运算符s和c的优先级*/
) \, w% [' R3 N& z6 d% g+ Xint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
. e( C2 r0 D8 ~2 G5 s9 ?1 hfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/3 C9 y+ j: [% z# l6 f
float compute(); /*表达式结算器主函数*/
7 e+ @, R1 G- ?4 w6 W" F) o' achar *killzero(float result); /*去掉结果后面的0*/   P% \( ]/ Y" n: h/ x
; H: [' L' V: K7 G- M0 U' o4 ~$ f
int InitStack(Stack &S)
# Q4 k& l/ [8 K; E% {{
. R' f0 K3 R4 Z8 \  G7 b    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));0 q' U! V; o& K5 L# [
    if(S.base==NULL)
& {! [2 L* [" _. ]    {# C' [# {9 Q* F( ?! v& Q
        printf("动态分配内存失败!");
- a# ?0 w  {8 |$ Q6 j* @        return -1;. p8 u1 m3 q% I1 d
    }  `  g0 j# ]2 G' E# ]
    S.top=S.base;
0 b0 s  R6 `) C    S.size=STACK_SIZE;8 z9 {( g; f) z2 I; ~
    return 0;* X1 y/ E, Z3 P* K7 Q9 ^7 b
}- V2 @4 v, F" q0 D) o

& w" C  ]0 k: M7 Lint DestroyStack(Stack &S)
7 r3 V, ~+ V1 d1 l. p7 |{* ~: G7 ?6 ?: f1 Y
    free(S.base);
7 s$ X( n1 m3 m2 o/ x7 R2 }# R4 N    return 0;, ^* k; y/ d4 r! E
}" ~; }4 w4 X2 }6 X5 U

& u8 w. o8 N- a$ ?. G) s+ Vint ClearStack(Stack &S)+ w4 ~+ |% P* ~4 h$ Y  V
{
% N3 U, k$ ?3 Z8 }  l/ x    S.top=S.base;
" P- `+ a. @. m! V2 g3 U6 J    return 0;; ^; b8 m% ~! s8 D9 }$ C1 T
}
3 t: o5 m3 \4 N  Y" B# @/ P, [, y0 U) m
int GetTop(Stack S,SNode &e)
6 i$ T6 J8 ]. e' o2 j{7 S& A' G; W0 S: Z% V" `4 h
    if(S.top==S.base)
) `8 h) R, [( q" m3 h6 F" n4 D/ Q    {
1 }% D$ u( ~% D+ m! @        printf("栈以为空!");% S+ ^7 }$ t/ Q) S/ D6 y
        return -1;
& i  O8 F& Z" f: l    }
6 b1 |, f8 ?' f8 W' k9 K' A    e=*(S.top-1);6 S/ X' t& z% ]6 z
    return 0;' O6 d" |6 C* W
}
0 u4 i$ {6 s% u# X- e9 }; P+ l6 g- A4 h+ {6 X/ I( ?/ I' V4 `
int Push(Stack &S,SNode e)9 y: Q$ v# n# d! Y$ q
{" {' F# Q3 m8 M* O9 H
    if(S.top-S.base>=S.size), O( P4 \% y" K9 P
    {
  w6 @/ T7 j0 q( K' A        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));; o  S/ F/ u0 H* {8 w  J# {; \! L
        if(S.base==NULL)
8 m& Z. F  T' e0 M9 H4 s4 Y        {9 y+ r, g% B  W
            printf("动态分配内存失败!");
- O; P! d- H3 P  ?! y% i4 V/ @            return -1;. D. W; b% Z5 Z' x4 i3 ~
        }
  i7 ]6 T1 S! O  n7 S        S.top=S.base+S.size;
% o4 [! a" J- t' k$ L7 z0 O( T, G- B        S.size+=APPEND_SIZE;
  {! L# ~9 e+ [3 s, L: t    }, A1 E- c# t: U8 `
    *S.top=e;" f' F6 r! R* J( e: \/ z
    S.top++;
, Q% X' f4 ~; {" D0 d    return 0;+ g/ s- l) s* O! l- I
}
. T  v0 t, ]2 e) d
* x  Y+ S5 C2 Y# x9 wint Pop(Stack &S,SNode &e)
" M' h/ M' b& g7 j  U5 s) b' E- c! |{
! e8 G2 G1 E. B3 J    if(S.top==S.base)' h; M7 F6 D" d3 G0 ]+ W4 Z
    {
. E! C: S4 I' D' M: d        printf("栈为空!");% F5 |% V: h: F. K
        return -1;. k$ G5 N$ X9 d& ?5 Z
    }
% h# |4 Z0 G+ m* h. x! W    e=*(S.top-1);
* H2 Q7 t/ |7 T9 ], `- t    S.top--;
/ y7 r3 P; G, C    return 0;% l3 \3 ~1 b6 `% L. ~
}
4 A6 x* O- B# s( Z* D5 x7 A. g9 S$ U; B- ^0 O
char get_precede(char s,char c)8 ?/ Q! V7 \. D5 I) w
{
1 q' w7 ?1 l+ S$ ^    switch(s)# g' p. j( F0 D' {1 [; p( F  r
    {: p0 X: l# w! }
        case '+':                   |. S& h3 R' U" Q. v  X* {" m* O
        case '-':2 C0 C* M( _" q; d. }
             if(c=='+'||c=='-')) q4 ]8 a: K0 \2 f) X* A
                 return '>';! q( V2 T4 m& Y. U3 |1 ~
             else if(c=='*'||c=='/')
+ `' T# p  n9 C# E! K2 {" {: w                 return '<';! H# ?) j& H7 E% S$ y
             else if(c=='(')
& W) c( y$ X; n8 W: M3 y                 return '<';4 b) }4 r0 Y, P; g
             else if(c==')')6 h: M; `8 l. y2 `$ B. [
                 return '>';
" ?  {0 K# r3 m, V6 a- F             else
4 p7 y( g) ~, V" Q7 h5 U# L5 S                 return '>';
- h% p/ h3 R! P  ~        case '*':
2 _; s% v2 K6 w% I7 r        case '/':' @/ @# Y8 Z% U* [
             if(c=='+'||c=='-')* z% \9 `. l7 Q. ^
                 return '>';: T' |7 T. S, L# w
             else if(c=='*'||c=='/')% G. C  S- f. J. d
                 return '>';2 ?5 O: M% ~) ^9 w5 j7 n3 E
             else if(c=='(')) ], N7 X* C2 @# \7 C3 e0 {
                 return '<';  z8 @$ x( ~+ L/ r/ p
             else if(c==')')$ r0 |  [# K7 p# A/ a" O, q9 c
                 return '>';8 q& x) A0 u/ f' r: h! ^" W: E
             else
3 {( r$ j+ f/ F3 q! E; j. `                 return '>';$ g& s! E; L. @: v: f5 l' X- ]# O
        case '(':+ C5 Q# g* h  J8 T2 ~
             if(c=='+'||c=='-')/ O" t! S& O" a
                 return '<';
6 Y* y9 @9 a  R8 e; r2 m4 E% n             else if(c=='*'||c=='/')
8 H% R& S4 S' j1 d: c4 f                 return '<';6 n9 a9 ?6 z9 m1 \' I' P; @  Q5 p
             else if(c=='(')
, B: L4 {' j$ ^* j                 return '<';
& d0 a9 F# x) G/ V3 D: a" v             else if(c==')')7 c4 [0 S4 B( D0 p
                 return '=';- a3 r& u2 u9 S8 c* t2 G/ M
             else1 k" |9 K( d+ n" N, g+ j( G
                 return 'E';  {/ X+ m/ O7 Y7 \5 n  R
        case ')':/ D9 P  F6 p6 j5 W! S; P2 E
             if(c=='+'||c=='-')
1 _  Z) P  z5 ]& ]% o! \0 `                 return '>';
& F/ ^5 F4 Q( l0 S* P$ {' E             else if(c=='*'||c=='/')
  ]0 R7 f& o- z1 p5 ~                 return '>';
: b( }3 C8 t: f0 V% g             else if(c=='(')
# P5 @0 J1 q6 p$ [                 return 'E';; l5 r+ u) H  E/ P8 P# k4 B
             else if(c==')')
6 l1 H) _( T9 J                 return '>';" ~4 _& Y2 E% E% S8 d! j
             else( R6 D7 d4 I" T: {0 w0 W( A
                 return '>';
5 v3 @( K0 t+ n3 r0 l5 F. _6 a        case '#':
, Q- T( z( p% g: l             if(c=='+'||c=='-')
* m+ j1 n& A9 Q$ g6 a( M" S0 \                 return '<';1 B& R  v; E" J
             else if(c=='*'||c=='/')
) p  y% [  R7 H9 ]6 S4 p                 return '<';' b) `& l  Z1 n; D1 u
             else if(c=='(')' G7 F0 S( B: B8 U+ W% Y0 a2 B
                 return '<';
& a2 O' m+ ?4 t! B             else if(c==')')2 r1 r2 k: J. f- B% }
                 return 'E';
, L+ s' a& F1 V4 j% t             else
3 p9 `5 p; y, p  e$ f, V# c                 return '=';
# X. p) f2 B6 a        default:' I, A) T4 }8 ]% h- B4 {/ o; r- S0 L
             break;
, Z* `+ x& [# H8 ~& d4 [+ J    }
6 R, t4 U8 ^- ^5 Y( s4 ]) Z    return 0;    7 Q. P. V; X/ w) k9 s2 ^
}
6 D3 ]' G. j* Q( f- o0 B) D5 b+ g( [; P2 j
int isOpr(char c)
/ c8 b6 j1 D, M1 R1 A8 e' V6 W! P{
2 c3 P) a3 j* j& k/ m, I0 k0 x    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')9 z; D, d/ ^& y1 F6 I
        return 0;
+ d1 Y: V6 ]2 C6 M    else
  ~0 N4 D8 z# p; ~$ _3 w/ V; y4 f  A        return 1;
2 T) A9 x. ~* m, y- m9 A) A/ I}3 g7 Z/ H' F* u
9 a( N1 P) ?+ ~! Q
float operate(float x, char opr, float y)
/ x" K* [7 \! c: g5 ?1 Z. Z' Q8 V3 P{" b, D" g4 P, E  h
    float result;
6 v. x4 P: @3 S/ F3 P    switch (opr)2 V. [. n: J9 W+ r
    {- i. e+ M$ X  d! j* E( `2 U
        case '+':
* I$ U7 y& w" h             result = x + y;- H8 i2 G! N7 R4 O3 Z" t
             break;9 p7 O( K* R0 A" l  E$ X- K0 F
        case '-':
) c& \; R. j4 [             result = x - y;2 m6 z) ^7 i5 T5 |
             break;# E9 N  u! x! T" I: d. X5 U
        case '*': 5 b$ }: w* T+ @8 L. o0 ~* `
             result = x * y;
: [' p( _. f: E$ y             break;" C$ K* I; \3 E) \
        case '/':
# l0 f. q( g: Y+ k1 x2 |             if (y == 0)
+ @: i& p/ u/ Z( o$ B! G4 |5 i# N             {
; O7 x# P7 E+ [) u; D. o- E                printf("Divided by zero!\n");+ ^( z& B; q% l9 S1 e
                return 0;
# ?" J9 u& }1 e6 C8 @* C  K             }$ R, x, @9 g. K$ w( [( S
             else
, h3 z2 A. |2 W1 A/ I: q) _             {+ \0 k5 p; U! f5 }
                 result = x / y;
8 S! o) E+ A: _8 W# g                 break;
3 {- [8 o. I; {; a4 _2 S             }
7 U# T7 t: A) |       default:
8 \  o' t9 V" e2 j) O             printf("Bad Input.\n");
) F: L$ P/ B- w: F; `2 r             return 0;# Q0 W% ~- a" K6 b
    }
( C1 W: ?# b. L+ |  h( A) C; @    return result;; g5 P6 r1 H9 O9 E) Y# o1 ^2 |
}    + s* v) G& ?% H8 P9 n- H
% k2 M8 C  V1 V4 V
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
; K7 l/ V, S7 n{
, [9 \% N1 u( \    Stack optr,opnd;/ M$ r0 [' B/ l! ~
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
. Y: k; R( A; V! m( C    char c;# _6 `+ X% M: _& h+ u
    char buf[16];
$ K' S4 i+ ^+ Y# Z, O5 a7 s" z6 B    int i=0;! N1 C) z( C: O2 v5 ^4 f" t
   
2 s+ B* o1 K+ A! ^, c1 f    InitStack(optr); /*用于寄存运算符*/
) a' S8 p( V  d5 F8 b    InitStack(opnd); /*用于寄存操作数和计算结果*/
# M5 r* h  V4 k, B    memset(buf,0,sizeof(buf));
0 _: P! A2 A: A: D: y; e   
" m, T; M: d8 O  `7 M    printf("Enter your expression:");
! H' t" u1 f+ h$ d: ^        
- r( }" G1 W: I1 i) F2 e& E4 e  Z# b    opr_in.ch='#';
" M* A. v: g+ E9 P% w/ M    Push(optr,opr_in); /*'#'入栈*/
+ ]) H: f* @2 s. I! p5 `    GetTop(optr,opr_top);
* p6 Y8 E* k6 q    c=getchar();
  z1 L, y4 }) K2 V    while(c!='='||opr_top.ch!='#')
: j5 H* u5 _' v4 j    {
- n. }; f9 R$ _) @2 g" S# d3 m        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/+ k6 o4 \) g% k2 x4 I
        {, \" A+ M+ {2 p* u2 |
            buf=c;- }. J6 B, t* M$ O, J0 w0 E. V
            i++;
1 s) d# i0 E8 ^& k% t9 d) p# A' l$ l            c=getchar();
8 l- V# \, `8 X* A, b/ n        }: b  p6 c* X- Y3 q* [+ N
        else /*是运算符*/
& X; N; P- G. o5 v" \& G        {
. n+ C5 M& G* H8 u, Q" S            buf='\0';
$ Z+ }( x# M" v+ F6 q            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
7 ~# N" ^/ \6 q6 }            {# r- j! {$ T4 x# g* m. d& \2 M' y
                 opn_in.data=(float)atof(buf);  j  l2 E6 |/ ~1 h) K7 _+ J0 V
                 Push(opnd,opn_in);& I. U8 i2 j6 m* b4 z
                 printf("opnd入栈:[%f]\n",opn_in.data);( ?3 ^" Z2 }3 X8 T7 W
                 i=0;1 ?% K* x" v; {/ x0 I5 G: X' v
                 memset(buf,0,sizeof(buf));' E; X  G3 t' q7 W2 o  B
            }
  o+ |/ a. e4 }! ^            opr_in.ch=c;. J8 r7 T" |2 @1 q" @
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
# ?' t* _3 v7 H& M# I            {
( m& M! O$ X5 }4 D. R+ d' D( t6 V                case '<': /*优先级小于栈顶结点,则运算符入栈*/
4 x3 d1 G1 i# [  e, [                     Push(optr,opr_in);
& |$ M' i  ]! y1 g9 Q                     printf("optr入栈:[%c]\n",opr_in.ch);
, f  r$ l) N2 q                     c=getchar();3 j' A$ x# n' q2 k8 f
                     break;
3 z& l3 c* \5 C                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/5 n. N7 S$ q: |& v# ]* D
                     Pop(optr,e);1 c0 P! G3 R  D% e+ `
                     printf("optr出栈:去掉括号\n");: D7 A5 u& c( X8 l
                     c=getchar();
; q4 D: L. Y. E: Q; d                     break;
& s& g3 b# ]2 r$ A: O, G                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
3 g, |! K5 J& ^+ N0 s) _* A1 b8 K7 t                     Pop(optr,opr_t);
! u" B( Z) A$ k2 c                     printf("optr出栈:[%c]\n",opr_t.ch);/ Z- O, N3 |: M
                     if(Pop(opnd,b)<0)
  Q8 v. u4 _- s, i# a! \                     {
% I" L* _! i* e0 }/ v3 z                         printf("Bad Input!\n");
- H0 a  `: c9 ^6 Y                         fflush(stdin);0 a1 N( V( y8 a
                         return -1;
- C4 ^- k% }% G; l8 y* [) C% I                     }4 P# r# O' b# t' @) h3 g5 p- J
                     printf("opnd出栈:[%f]\n",b.data);
) Q. N, l8 @! g5 h% ]                     if(Pop(opnd,a)<0)
1 w2 b. m2 O1 z& j                     {& r; X! q- C- a2 G- Q
                         printf("Bad Input!\n");" R0 P- K7 w/ z
                         fflush(stdin);2 Q8 s# n3 u, F
                         return -1;4 ~% w" P: l% v5 B( E; D$ _9 T
                     }0 |# [0 u" V4 f2 }' J4 \
                     printf("opnd出栈:[%f]\n",a.data);
! A3 g7 a) q6 g3 @% @& k$ w& W                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
8 x, O  [+ Y3 @+ S  }9 h                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( {0 ?" [2 G& \. B( _3 }: X                     printf("结果入栈:[%f]\n",opn_tmp.data);
1 V  q: Z) [* P1 e) p" O                     break;. ~* x' V2 v. s! p3 O% [
            }# M; d/ G, c! j; G; X( K
        }" P" j+ r% e. [" U
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
& U$ ]+ O% w4 J5 E    }( O: n9 X$ f, n) X" ~
    GetTop(opnd,opn_tmp);: }4 ]! F+ y7 t5 i0 e6 M
    DestroyStack(optr);( T" |7 S7 }; O) I
    DestroyStack(opnd);2 K/ @) Z" i% L) z" O! X( L3 z
    return opn_tmp.data;
5 T2 Y0 G* s  ?. L- y; y+ w}# h! q& N5 v  i, E& `4 l

5 H5 o# p6 ~" z' k- p6 uchar *killzero(char *res,float result)
1 C, U( i# [* M* f+ l! O9 Y{# ~& a3 c  n: o  }6 J2 Q
    int i;, j/ }$ N' A7 J) ]# l. @

- P- B: T+ B" S    sprintf(res,"%f",result);
, @9 L$ o) w& h. V" s1 S7 T    i=(int)strlen(res)-1;9 M' z; _: A3 I# `4 L
    while(i&&res=='0')
4 T, |& u! n! m1 W9 Z, }  u    {
% W; }5 {2 D9 [+ D& c+ M        res='\0';
# H4 i( Q$ \( M1 u0 @        i--;
) h1 i3 d8 s- y% ^    }
8 \* Z% s$ x& Q) ?/ `( R) C9 P    if(res=='.')
% ~* n+ Z: H6 p! v& p; Q        res='\0';& {* E$ K, V/ Z
    return res;
. t2 ?& [+ g7 i$ c" ?4 a/ M}
" Z: t7 f7 H- W8 q5 ~/ [9 f* }; k$ d( B! k% W. r4 x
int main()$ ^# y2 O$ K7 q7 O7 E/ A
{: I" H2 l0 W" k3 D
    char ch;
- `0 {$ n% {- }# ^    char res[64];) k% g. m8 c& O! Q4 E% z
    float result;
+ ]0 S! F2 N& h- h! W* `    while(1)
1 e7 m0 Y! c! U$ o    {6 s2 w9 j; B) C4 P; W) p
        result=compute();
  s7 |" ?# m1 I9 i' _. M) t4 @& m        printf("\nThe result is:%s\n",killzero(res,result));
8 j6 ?" P+ E6 M9 Z- ]( w$ U0 k. h        printf("Do you want to continue(y/n)?:") ;
6 y" l( h7 M; y6 Q7 M; V        ch=getch();' f& F1 x" W2 w4 h/ @
        putchar(ch);
9 m9 t( O9 Z: ^* s' f        if(ch=='n'||ch=='N'); T3 d" ?4 R! z2 h: l$ J
            break;. [, n$ E; J% B5 f
        else6 X4 q( I: Z- u
            system("cls");' z5 ]8 b6 S2 X$ c. \: V
    }
/ p0 w2 F: l( M    return 0;
( t  P8 O8 d; B4 U5 b  [. w}
% Q: @5 b! {2 \# p
1 |$ `, t+ V9 h1 s
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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