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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.2 F+ c. e( M4 |1 h# J7 v+ y
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
3 f% ]% K9 Z# ]4 Y! l& s) B- m/**************表达式计算器************/
, `6 E, M  q( q: r& ^9 \#include <stdio.h>0 {% V  X; D3 Q1 n/ O
#include <stdlib.h>; |8 E) `) t8 W  ?
#include <string.h>" P/ R* N- \5 q
#include <conio.h>7 D- x# T7 j6 A" ?  n% `$ r5 N
#include <malloc.h>% p# O5 A. k9 P3 |+ ?

0 G' Z+ v. D" J% L) ?#define STACK_SIZE 100/ [8 d. Y* D5 D1 o
#define APPEND_SIZE 10
$ g! o& U) d7 p
( t0 O5 ?/ y$ ?& k1 Wstruct SNode{
, g1 g1 s8 O: r" `3 Z    float data; /*存放操作数或者计算结果*/5 Y/ j$ a7 b, z# v
    char ch; /*存放运算符*/# G! \8 h8 C9 j/ g
};
  K4 E; @. f  n2 x8 v! V; A
6 m( E5 V) V1 t& d* ^struct Stack{7 B- O5 o; `2 }9 ^) l6 ]8 A0 B% t
    SNode *top;3 A' `6 \1 o" p: P! h+ t$ e
    SNode *base;, F& u  ?, c, U, V) f# q! I
    int size;  C0 K( v# n$ t5 y: o
};
* k8 X7 q. i! s' c) }% B  K. {# u* G. q5 s% k- g$ _' a
/*栈操作函数*/
. c& k4 n) c/ J, X" k7 c. B9 s( uint InitStack(Stack &S); /*创建栈*/
1 ^- s4 m# @, L) d- K7 vint DestroyStack(Stack &S); /*销毁栈*/
' u1 p1 S1 J0 F. X% Rint ClearStack(Stack &S); /*清空栈*/
& ]# x$ @! R' h" C: x6 uint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/, R2 V$ `$ p" H
int Push(Stack &S,SNode e); /*将结点e压入栈*/- {$ R1 r8 S0 j9 W" j$ F4 L  v
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
) l+ {: ^1 }" s/ N
9 C  V# ?# t& }' V) e0 ?$ @/*表达式计算器相关函数*/1 m  a; Z2 {5 y" |( b
char get_precede(char s,char c); /*判断运算符s和c的优先级*/' L& S% y: s! i3 f  E/ Y/ @; d
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/, Q, g$ p: f; d* u6 u
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/. P) N. x& H8 U
float compute(); /*表达式结算器主函数*/
' T) t/ u7 d( C  Xchar *killzero(float result); /*去掉结果后面的0*/
4 ]5 Z& N/ G8 {( [8 [+ E! P
7 p, G* H  f0 l1 K6 Y. Gint InitStack(Stack &S)
7 g" J& P# r3 ?/ c/ c8 |3 _{7 U/ C7 E  h1 a" g: r& b" x
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));) x3 q4 f- h# f$ y. i- a) U7 b/ o% p
    if(S.base==NULL)* u! w4 J0 |0 R0 g9 C
    {
8 T9 C; T5 y7 l9 r. E- B' D# b        printf("动态分配内存失败!");
$ f, I! i" k# e' H: w        return -1;
" b. o  k3 L" S* G0 A, w; b    }
6 f( g' M' k. l* {: v$ E    S.top=S.base;
) `5 T0 v2 q# f6 A, H    S.size=STACK_SIZE;7 a& K" ^  b' i
    return 0;
+ S- `) R2 Z; d+ s}8 F; O7 m/ b1 x6 ^3 ?1 R+ v

7 j8 \/ U3 w, }4 i/ s; Eint DestroyStack(Stack &S)* H* [/ k1 a: W9 l6 x
{
/ f% X. }$ h3 Y$ }    free(S.base);( s) v* v- x/ i( Y6 [) V
    return 0;: @  X* E. i' v- H
}
! p* ^9 }3 w( a' _7 b' p
7 R5 h( y4 c( lint ClearStack(Stack &S)
5 ]& G$ Y4 e- ]8 E. l{
6 V) S& t% s0 G# ]4 C+ [3 W/ A/ L  O, E    S.top=S.base;! w7 @9 b# M+ i$ L0 w* l
    return 0;
1 M1 b, ?0 j4 B7 R( w2 W}+ t' r; q& y/ ~, p1 \* c: t

% j; h5 G$ m. M# xint GetTop(Stack S,SNode &e)
) Y8 ]: @; ~5 [4 N* t+ u. E{" [% n. `7 D) p5 c+ o
    if(S.top==S.base)6 T2 F9 _. E$ \* z
    {' s0 D/ P, l8 T' b3 x- \! |
        printf("栈以为空!");
4 A3 @8 k* g% P) V  t9 g        return -1;& s3 v* ^! n, }+ B/ ]& Y
    }
4 L* [( Q0 F2 p" ?: T3 h    e=*(S.top-1);$ o2 b- c2 O+ T6 v4 R4 a
    return 0;" ^( D7 i: A- U
}/ l% g# U! ?" W/ }

3 b1 X# z% N1 Q& _9 w& O0 Rint Push(Stack &S,SNode e)' O9 Q3 S& t3 {  Z4 ]0 g
{2 v$ k0 i5 n5 p
    if(S.top-S.base>=S.size)1 V% \4 \9 t8 [
    {# j& Z( x+ y# A# b0 ~
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));8 ^& g! Y# m3 A- B4 v9 j5 A$ i" d- [3 G
        if(S.base==NULL)! T# L5 N$ b# k9 U
        {
* D! E) }- V" u; R            printf("动态分配内存失败!");* I3 c: `3 \3 {0 X
            return -1;
6 W: A* t& d& J4 I. ~9 e$ L5 {        }
$ k( c  |3 k  x" W( X        S.top=S.base+S.size;  l  E" q5 a+ k
        S.size+=APPEND_SIZE;6 e1 |. D; E6 f8 I" T6 W
    }
) S, a$ Y+ ?' t    *S.top=e;0 G) P3 a8 u/ x2 d2 |3 E0 J
    S.top++;9 ]7 ^4 L# W0 ]: ?5 G3 H
    return 0;( L, a" K  E/ n+ H0 @3 N
}
0 b; c9 O* Q/ F6 \* V6 p$ L4 Y3 J" E3 S2 D; |4 A9 w' _
int Pop(Stack &S,SNode &e)
- ]% c, u) |/ x% N# ?" |{
( g7 z2 f2 G4 T; l9 p8 x; g    if(S.top==S.base)! Z; ?) E  h4 v
    {
' c7 f- E, g7 d: s2 |) l        printf("栈为空!");6 ?' k( Z. i0 |8 g3 o
        return -1;
0 A4 q' m' Y9 h" |. e    }
, S0 |) S9 ~6 b$ @+ t4 p6 L    e=*(S.top-1);) M8 m6 I1 P# [
    S.top--;. B- P2 a+ \( i9 q+ {. @' u; n6 ]3 V
    return 0;
/ i& r8 b" f$ e% ?}, ~4 n% d+ x, n+ G( v: V

( r- L: `7 X! G% E& F, [char get_precede(char s,char c)
1 R  S/ K8 Q! R1 s" P+ u{
% e. ^. `) {; c0 z    switch(s)
' o# ^6 M% m+ }    {
# j# d* f' T  j3 r' d5 C        case '+':                 
7 S1 c+ y; E) m4 V1 H. W# R; G        case '-':5 o- P( y: h8 \' |- T2 H
             if(c=='+'||c=='-')
; a$ D0 K3 m# T& b/ k# m                 return '>';
! O8 R3 P& X2 Y% `$ ]2 Q             else if(c=='*'||c=='/')
; M0 I1 S4 k/ P, N                 return '<';
: ?" x- G) e4 u& b             else if(c=='(')6 w- x* X- {6 Z( U" H+ X: O6 s: q' V8 e
                 return '<';
! {% Y3 m* _# A/ O             else if(c==')')
2 ]3 ^/ X6 C: z" |. U- _; }                 return '>';
) Q  U4 F0 a9 P( C& ^             else   h) b! h- ~6 u8 ]7 B( D( H8 p6 F
                 return '>';
( z! `/ s; d- g        case '*':2 w" i) ^$ A, P# ~& M. _
        case '/':
% Y9 C, Z% m3 H. T             if(c=='+'||c=='-')
) {) T. m4 j* m) c( |6 V# Q+ d3 X                 return '>';- B  `1 c; w% y% B/ O: C" j# M# |1 G$ X
             else if(c=='*'||c=='/')6 {& q6 Q8 }8 K7 j- S+ D2 U, Y7 u
                 return '>';
- j1 K! J! u/ N( Z" q' g9 U             else if(c=='(')) q0 M. v, K5 N) r5 y- F. c
                 return '<';
$ b; S% O3 [& D: |6 Y             else if(c==')')
' C8 w: D* m/ T4 G7 Q7 n1 |                 return '>';
  z2 M0 T2 ]. u( Y" t. z' W- h             else
6 ~& }( A; l! s4 d$ i% N; Q" A                 return '>';
4 I2 P5 C2 e4 V" w1 y: o& h        case '(':
2 l/ r6 Y2 E' S! H+ a             if(c=='+'||c=='-')3 b; y9 [0 M0 |
                 return '<';
# D* l  a, k  P2 t             else if(c=='*'||c=='/')
) w' O4 x* I5 A  A/ k/ o" T( c3 _9 y                 return '<';
* B2 I2 ?3 P0 f2 B; S) T' b             else if(c=='(')
  c6 o1 p" R2 Q0 P/ x8 V! x6 i                 return '<';
* a  k! }, ]3 ?' _8 t% R  E7 d             else if(c==')')9 v! Q1 Z- M7 O, s" Y+ u. L+ ]
                 return '=';1 F0 _; w& W/ {9 d8 H
             else
: F% k) ?# G/ Z2 U+ N( m0 n                 return 'E';
' _0 ~. f1 l+ t( I        case ')':
  O" ~& `  k1 ~5 R             if(c=='+'||c=='-')
1 j- r* x! z' u9 P8 v                 return '>';. ~5 P! p. k$ {( p5 z
             else if(c=='*'||c=='/')
7 S; ^" w: G5 l  T9 @" {                 return '>';
! h0 }5 Z$ d1 j. k4 s! z             else if(c=='(')' Y0 ^; B: _9 H; M  U
                 return 'E';& m& [3 b, b3 _0 a$ f5 M
             else if(c==')'), {- J1 @9 i* S
                 return '>';
0 p1 h' p5 A- R& ]             else9 }( w* J; W5 ^0 i( \
                 return '>';
  e3 Z( j  y) o. Z7 X& f        case '#':/ F1 j' {! F: s' Z( r
             if(c=='+'||c=='-')9 f% F" `" }9 I5 q
                 return '<';% y4 Z2 g2 G: d& r% W9 W7 Z
             else if(c=='*'||c=='/')* C6 j- t5 ~+ N7 Q6 D& e/ S
                 return '<';5 X& D# }# ]& `
             else if(c=='(')
3 u* S3 X1 B! e% N4 {                 return '<';- d3 s7 w* p9 a8 H' T: g# b
             else if(c==')')" @- H& l7 ~& B6 f
                 return 'E';
: Y* s; R* H8 C5 ~  T( D9 z             else
& r9 ]2 `4 p3 {# {                 return '=';
4 b" N* }- J* N( }+ ]% n; S( L        default:
) |0 h) Y3 K) L3 R0 G             break;" f! V) U! I* K+ V7 g2 w6 I
    }4 u: r% c8 H- n- Q; L: g
    return 0;   
/ r0 K* ^+ U% @+ ~& J' ?}) n8 D1 W4 \- n6 ^3 ^
5 n* z' ]4 l9 s6 x
int isOpr(char c)
/ E0 N" w3 l: z{7 h3 |0 S5 Y8 z) D. x4 Y- y3 e6 K5 }
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
' E& }4 h- f8 d$ K: R- u  |% A        return 0;* p4 F/ F- `5 f5 `  J2 U
    else - J8 e0 r  Z: ?) I* B! I3 ^
        return 1;2 C5 g6 a9 A, g; b
}3 q5 A. l2 C' i$ s

- x5 y9 F: S& V- K" wfloat operate(float x, char opr, float y)
: h, S  T7 Z# \! c- {% j{
/ P- k, C8 }, }, u- y* d6 p- e9 u. j2 j    float result;
% Q) V* C% _& D6 I    switch (opr)
5 M' ?# y1 T* \  a6 ~9 z; m6 W    {. L# j* A# n, K( `& H
        case '+':
- d, t  d+ X+ t; D; Y  z             result = x + y;" c) H3 `7 R- I4 x% i) s. g
             break;
; N' e6 `4 Q$ w: J' O        case '-':
$ q: z' x, Y+ O( A3 I9 o+ K+ W             result = x - y;- Z: y' J* q3 o
             break;( Q, ]7 e. N$ j( b+ R% [
        case '*': 1 q1 w( t  u( ~) ?+ g3 w/ D' I
             result = x * y;
0 }# {. H' |6 j             break;0 _9 o# B% \- M
        case '/':
% \) |1 f* P- R0 N% c: q: W. X1 i3 t             if (y == 0)
2 T( A( K& Q, l' k# g             {
5 ^6 v/ ~! w0 N9 J& ~' ]7 r# D                printf("Divided by zero!\n");
; W9 C2 A, H4 D. m                return 0;
$ E5 A+ C( T5 M             }: Z1 N5 ^+ |8 Q) o/ S" w% |  s' {9 R
             else
# N  I7 H% o3 w) j  Q             {
( i  x2 G, Y/ f                 result = x / y;6 ?2 v" g( V  f/ V+ P
                 break;3 \- E8 Y' r, N% j1 x
             }, |; H$ o: j! F8 o0 T
       default: / i  d; V' o2 s% `: ^  A3 h
             printf("Bad Input.\n"); " X( `% p8 T$ N. \, |
             return 0;
8 t) k# ]: R: G$ L+ ^( g    }
3 W. `0 h- u/ j) P0 ]) E    return result;
/ c% F6 J& @( p$ I}   
8 w' U; A; p6 m* d3 L- M+ p9 v5 t% s% h
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/5 w* G9 i) u+ c+ k; {9 d9 v! G' l
{
# Y& `5 b0 p: G3 d    Stack optr,opnd;0 P  m3 C4 s( J2 N4 H8 ~
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
9 ]' z5 t' v; D    char c;5 \3 _0 W7 J& d3 v! m& H
    char buf[16];$ [2 I$ b4 ]' |6 H! ?
    int i=0;: D% |1 n% Q) r
   
7 D2 j9 O$ c6 e! f. Y    InitStack(optr); /*用于寄存运算符*/
7 L, k) l! U. B* ~    InitStack(opnd); /*用于寄存操作数和计算结果*/
% N4 q& p! J: [- C9 {. W/ c    memset(buf,0,sizeof(buf));0 L. E8 W& l4 ?: ^! S* @
   
: L* H6 @+ K; [& ?, R' J    printf("Enter your expression:");
3 c$ N4 k2 d5 d: u" }: q" G" i) U        
; s- n3 a9 K/ w    opr_in.ch='#';! U- k+ K, ^4 G/ l$ B5 j; [
    Push(optr,opr_in); /*'#'入栈*/
7 Z) W- `* f" q' N3 ~3 R    GetTop(optr,opr_top);3 z( F6 D, l( r* |" G6 m
    c=getchar();
) j0 e3 Y# s3 d! j) S    while(c!='='||opr_top.ch!='#')
$ _; k/ T8 x. ~: X7 m' _    {0 a. m" ~+ y1 ?- K
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
  I  k2 ]! b. o% o( M0 R        {
7 T5 w9 L+ E6 a# x            buf=c;# m8 G7 S& b: o- F  w
            i++;2 M, y: \# w8 j
            c=getchar();3 a6 A% ~" [% }; j; y1 x
        }
4 s( Y+ h: L! e- ~/ g" i        else /*是运算符*/
& c! g) _4 w- z        {& p! W5 Q: X. ~
            buf='\0';
8 {0 ^3 \8 m3 o            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
; O% Z1 I' j3 j# ?  u" `( F8 e/ D            {
- V7 O6 v5 f: |                 opn_in.data=(float)atof(buf);
9 G4 M* N6 {. v5 \/ ~3 d                 Push(opnd,opn_in);
8 e9 E0 D' I* ~                 printf("opnd入栈:[%f]\n",opn_in.data);
0 \9 v" `& O5 ?' _/ J3 J                 i=0;
* S" q3 g" _" u6 X  c8 n3 _                 memset(buf,0,sizeof(buf));8 a4 c& b7 e9 V! J& {" c3 x
            }+ d$ M, b+ G' q0 V: Q, Z
            opr_in.ch=c;. L) q  w. C( }. }% u
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
: a0 Z. b' g! z  m" `            {
( J  G* m! _- C3 {6 o                case '<': /*优先级小于栈顶结点,则运算符入栈*// m8 |; F3 `/ Y/ A
                     Push(optr,opr_in);- r4 o: \* s- z6 R* q4 e/ x
                     printf("optr入栈:[%c]\n",opr_in.ch);4 J2 k$ s4 W: }- Y: R
                     c=getchar();
9 G2 D# `, W- e& V2 u5 @3 C9 y                     break;, W! c' d( ]  `( u" \; r" o  j% B3 s1 @% J  |
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
3 m% w; t8 o6 I6 }3 S+ O                     Pop(optr,e);
4 Q7 y5 n9 {' g. \/ Q9 s) `. b                     printf("optr出栈:去掉括号\n");4 t4 v1 Y# }3 I; ^) a1 U
                     c=getchar();2 n5 h4 }6 O$ \" N6 E1 ?
                     break;
7 a* g9 K# ~& ]1 x7 d: P5 @                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
! B, v, @' x1 z7 \2 C& c                     Pop(optr,opr_t);2 b6 t! u$ i' ]8 x+ o1 M
                     printf("optr出栈:[%c]\n",opr_t.ch);
# L+ x% X7 I9 {4 U, ~- N; B                     if(Pop(opnd,b)<0)
9 y1 Q4 q3 N; w: z                     {2 D4 e( Y7 u* A" n* f7 B
                         printf("Bad Input!\n");
; q3 f/ ?4 ]" {, P( e# M                         fflush(stdin);' |) q+ _: M' H) {$ p
                         return -1;( x8 ?! O0 E/ D9 S
                     }
+ c  E; {! P8 T( z                     printf("opnd出栈:[%f]\n",b.data);2 w1 K  v& t  i; Z
                     if(Pop(opnd,a)<0)- q. n! L& L, A5 o9 k- W
                     {
* w# T( Z% Z$ V                         printf("Bad Input!\n");
8 C! ?: V2 T/ m- G- g: J9 n                         fflush(stdin);  M8 ^+ D. z: g; d3 Y, r6 v* T7 X
                         return -1;, a( J: F6 r' k; R5 r
                     }
: v# x& X% h3 n8 m# S8 F2 z                     printf("opnd出栈:[%f]\n",a.data);
( b9 B* j4 }! E0 M                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
; Y; \$ D5 q$ a7 g+ a& S                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/  f% b) D; _# k! v0 S& \4 ?
                     printf("结果入栈:[%f]\n",opn_tmp.data);
0 v( q2 O2 j* D' t" j                     break;1 b8 Q: s9 @/ x0 [0 ~
            }0 c6 ?! L" x& j) W, E3 G: \8 s/ ?
        }& b2 {7 \% c& K  A7 W1 C+ C( `
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
3 Z) d! g" K; d- |    }1 }+ _( M* G; C& W$ z
    GetTop(opnd,opn_tmp);
0 z1 a* T; [5 [9 n6 Z+ \    DestroyStack(optr);9 @. n( g5 m9 P4 j2 s) g# l6 I
    DestroyStack(opnd);7 Z# E/ I7 I" B+ I$ V  k
    return opn_tmp.data;6 [* f, C# p7 M- C
}
1 q! q5 @& N! x: z9 a1 _; s! w; z1 g- A! y$ }) ]8 ?3 ^
char *killzero(char *res,float result)! F' [1 u6 c# ]  g- p& |' C
{
6 e- B" U7 f3 a# o. c    int i;
4 f" L, D( ]/ u, d% r8 R6 D/ P
% ]2 ^$ m& b1 ]$ U$ h! P+ N    sprintf(res,"%f",result);
- o0 n6 D& v, T+ L7 g+ S  [/ j    i=(int)strlen(res)-1;& [9 I- Z' d1 n4 B" q& g, q
    while(i&&res=='0')6 e9 _: ^- C: ]5 h8 F
    {
! S, l% Q, k, z( V        res='\0';
& n; i7 Q  S# |+ ~0 X  I8 t        i--;
5 l  b/ ~& J' c/ ?2 D$ k    }" A6 t9 F5 |' `) w
    if(res=='.')- ?6 \2 ]2 G5 |9 P& S5 @3 f+ c& L
        res='\0';
# a7 X, l8 K0 \. i/ f. Q    return res;
/ w/ x' G( v+ `% `}7 }9 {. B8 s$ p4 F# w& r% \
$ @1 @( {) J9 X/ b" W9 Y
int main()1 T( @* _; O" I& l
{% v6 x; c3 U2 D( }& Q5 w. R$ @
    char ch;
! W9 _; g) V+ v    char res[64];) }+ W) V4 x  T7 \" e
    float result;9 c  t5 w9 R$ P$ m  f' |" [8 A, v
    while(1)) c& B' O4 p) F8 o" K! J
    {
6 s4 F" m2 }0 k        result=compute();0 P8 b. W9 a, l7 i5 b5 t/ f
        printf("\nThe result is:%s\n",killzero(res,result));
' k: }. c  f- N% W: r        printf("Do you want to continue(y/n)?:") ;: j: R, a; B" M) l& E3 i2 J: S5 U
        ch=getch();
( x  T2 M- j6 r( u" P6 }+ V        putchar(ch);3 c) L# C6 t8 L$ e1 b$ N
        if(ch=='n'||ch=='N')
' f& Z* O7 t3 Z9 p4 [            break;
! ?1 E8 g6 R1 \/ H3 o# U) N% B$ S        else
- {$ U4 O; C- R: j$ r. `2 D+ K            system("cls");
# c" D: ?7 p6 x6 S8 T1 B" J    }
* E+ V& p: E- R6 e" j    return 0;5 l2 ~/ H2 c, ?  @, B7 _
}
- a2 u6 ~2 u! C

; Q/ J8 D! {) U: e4 y  \: l[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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