返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
" F0 P% y0 |7 h% G( w程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
- O' |( }) q  z4 Z0 J! @7 u2 f6 u/**************表达式计算器************/
. g8 H7 W8 r1 p5 @! L8 @: q#include <stdio.h>$ g0 l8 }5 |) G1 m  ]( R8 p
#include <stdlib.h>
; W/ G1 E! j7 y! t3 o7 i2 j#include <string.h>
, y2 v0 P2 ^% J/ H  a$ s7 r#include <conio.h>- Y, ?7 W* a1 K- A+ ^, F
#include <malloc.h>0 _/ O7 U" h4 k, h( M; V

' S  M7 k4 u2 A, A#define STACK_SIZE 100( s6 o2 N- O9 Q. f  r- t, q
#define APPEND_SIZE 10
5 K1 o- Q+ C* W( U2 Y$ t6 `" x/ y- j$ U
struct SNode{
, F" g( W+ [/ Y- {* U    float data; /*存放操作数或者计算结果*/% f. m7 }( _  B4 B" E
    char ch; /*存放运算符*/
( S6 c, t1 Y; x7 u% {};( k% o; v+ Y5 v- [

* t  Q, [- u! ?6 s% |' Ystruct Stack{4 j. d6 g) w4 ]0 s
    SNode *top;
1 N% {% J& o- x1 j4 m    SNode *base;
6 g) ?: {. w4 S    int size;: H/ Q- `1 A9 F8 ?) C7 R% m, `
};$ i" a. j, \2 K# [3 U5 Q

7 P$ G. p+ V3 Q3 k. x) {, r9 U/*栈操作函数*/7 L* F9 A. F) r+ G: u9 Y
int InitStack(Stack &S); /*创建栈*/
: V* z3 g! I1 d" v. H+ dint DestroyStack(Stack &S); /*销毁栈*/
* F9 a5 c6 X8 v% A& }1 Gint ClearStack(Stack &S); /*清空栈*/
& Q# h5 A8 i  Mint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
3 q9 L; i6 D. Xint Push(Stack &S,SNode e); /*将结点e压入栈*/" C- d# k% Z* C
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/* G" z0 c7 o0 V, f1 e" @8 G

% ?5 _) `8 G! `8 G/ H/*表达式计算器相关函数*/
; O7 n: x# H0 ?7 O: xchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
7 s/ w, V9 s1 Xint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/$ w1 T6 J0 T8 s: J7 o
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
  k: j/ }9 X: j. bfloat compute(); /*表达式结算器主函数*/
" J7 y0 P. v5 |4 U- qchar *killzero(float result); /*去掉结果后面的0*/ 8 d2 b! k. m1 c, T( E7 l$ m
3 g2 P% i" d0 r& o5 I0 p
int InitStack(Stack &S)2 C9 D, A4 a, H8 @6 H  }1 l
{
3 F$ i. B, H, i% a1 V- T' L. J    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
- }4 w& e; f) B) |2 E$ L! n    if(S.base==NULL)
& s9 C0 _7 @$ M9 y4 z    {7 b; g% P' i4 R/ N2 o2 Q) l. ^. L
        printf("动态分配内存失败!");0 Z; z# `- v; f4 l1 u. L
        return -1;
3 n7 ?6 i6 O( Q5 `3 q& [+ C    }
/ m& O2 p; i1 G( M; e    S.top=S.base;
$ j6 V  s& ?( y: N; g% b, {    S.size=STACK_SIZE;
/ O/ x/ |, O, Q1 ~8 C% V. E    return 0;8 X8 i& a5 }* V, l  t
}
4 p2 F! L$ x0 G; p0 L( ~+ O' Y( P! f  w  Y1 B5 m( l5 d
int DestroyStack(Stack &S)5 X+ S' D) x% a7 {& L2 f! C
{
, c2 e: {* G+ _; U& |$ h' Z4 ?6 H+ B    free(S.base);
, o% I! V. Y/ U    return 0;4 u& u- X5 r) ^' T9 r
}
: T! ~" F: g; {2 X. O0 h" x/ E/ e: v
int ClearStack(Stack &S)' c+ N1 G1 Q, q, T) C# E0 N5 z
{* a0 f! Y: ~( ?" ]' O# i
    S.top=S.base;4 h' ^9 u  I3 _1 E. R1 L
    return 0;- y( w" H& R/ E: Q" x3 s
}* f# r5 Y7 X0 ?! d8 E( H

) g- h! a1 X: h3 Y# H& S5 }int GetTop(Stack S,SNode &e); v. l: r- B! q6 y
{/ P; k; R& r* S! V! T# H
    if(S.top==S.base)
6 U' f6 S+ T. V/ U    {  Y) ?+ O, p( X  R
        printf("栈以为空!");
% c4 B! B  `3 y5 N" x- J& t        return -1;/ f" p; B: z$ U0 x1 I% u- n
    }6 q* X. w3 T( j$ N0 l
    e=*(S.top-1);, Y$ U" z1 B8 ?) G5 N6 b
    return 0;
/ I" o1 @, H9 E0 U1 U}
* Q" w! W  C4 T  s8 \5 z9 l1 |3 A# @2 s( o# W. ?( T
int Push(Stack &S,SNode e); w7 @( O1 @! t8 p( u
{
3 J0 V+ _. p2 {2 @    if(S.top-S.base>=S.size)1 ]% L6 c; e. A; y; x  s! o
    {. g: L2 ~) j  _" R
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));( U: w6 b5 {; x* O9 W6 X
        if(S.base==NULL)9 ^( K" l: A' p- B0 p
        {
* I  ?( C  g/ [% m# p& Q            printf("动态分配内存失败!");
) f- [# Z: }7 t5 Y5 {! J            return -1;
7 [+ x4 y" ~- h        }
) C2 D! M* y! M; I& y        S.top=S.base+S.size;5 ]5 y# q; m. V1 y# P# i
        S.size+=APPEND_SIZE;& L( d- e' D' F9 F% {8 y4 I& P
    }$ s3 n: m% D1 m7 I! `$ m0 c8 ^) r
    *S.top=e;
& [9 ?( F! V+ d. Q% B' [3 Q0 H    S.top++;$ W+ n/ r) o$ N7 N0 Z
    return 0;
' R! n3 s) g4 M. ^7 a2 E}
& E" Y# X0 S( m9 G- w- h8 K  U- d
4 s6 F3 T6 G6 pint Pop(Stack &S,SNode &e)4 ~- X8 K; L: m8 n, ^9 _2 ^5 p
{
# I1 z0 @+ L1 W9 B    if(S.top==S.base)
$ _/ s( m3 l( E$ [2 E1 W    {
# e. S6 Z; v, G! ?        printf("栈为空!");) q+ @, I: n( E. r* v: ^
        return -1;
5 P4 o0 {; T$ J& F! n    }5 t! D  l' o5 T& {; c
    e=*(S.top-1);
7 `6 \/ c1 }% z& T: Z0 i$ |4 o    S.top--;
6 `! d% b; [/ a    return 0;
, W: }. S2 c6 |8 e+ ?}& N5 }. |: S* w

. |) a3 e- y! N- wchar get_precede(char s,char c)5 R$ f2 r7 R4 p
{
  B4 P- j+ H% n+ @$ x    switch(s)& Q# V6 b0 N+ o2 }! @: Z$ s" x
    {* ~) Y' C$ I; S2 s' p" T
        case '+':                 
# k* e+ ]9 i; e) G- Y        case '-':
) u, \* V: g( r- J3 w6 r             if(c=='+'||c=='-')
( h8 y! ]7 s# R" r                 return '>';
  K" ?4 Z3 c, S  V             else if(c=='*'||c=='/')& Y% O& o7 \, S
                 return '<';. R/ q# J6 w* Z6 i3 K
             else if(c=='(')
& o6 J7 u9 M1 O8 o; x* c8 ^: Q                 return '<';) r0 m/ n2 s5 X2 t) {, p( n* K
             else if(c==')')# Q4 H, E( r" _  F
                 return '>';* T5 M# i( Y1 d( h& E0 @
             else
; w$ d6 j0 t; d5 [                 return '>';
# d3 ~. a' w5 A  N: K, z$ k2 K1 a        case '*':$ K9 @7 M# t: M! a# h6 `% J! m
        case '/':9 ]" ?' O* v# f3 D. w/ L: i
             if(c=='+'||c=='-')
% d/ _7 g! C. g' G  e# d                 return '>';
1 y: r% ]' E/ Z8 A             else if(c=='*'||c=='/')
' ]9 q' m2 s1 ]                 return '>';$ g; h4 l* L4 f. z2 T8 Q+ B, w
             else if(c=='(')6 F7 T+ o* B  ~* x
                 return '<';
; `& f* d. E; a7 F3 x9 }- a' R             else if(c==')')
# a9 ^+ G' ~3 |' A2 E9 h                 return '>';1 i$ L& W: g1 c, A6 j
             else: b9 M, n% V/ |
                 return '>';
2 a9 ]( p* N3 c+ M! g& Z        case '(':
  A4 N- [3 E& U1 ~) {/ I6 Y             if(c=='+'||c=='-'). K# z/ C4 h- i3 J8 l" S% v
                 return '<';
% q- N! I3 G1 o- _  X. i5 v! Z             else if(c=='*'||c=='/')
6 \+ F8 C3 O5 e                 return '<';% F- q( R/ A0 ~% R) l9 r
             else if(c=='(')3 [( S1 [0 `, X" `9 t  b: o
                 return '<';! _* F7 s7 P% a% F1 l- N
             else if(c==')')5 U- o, D0 I8 u4 x: W0 X+ F
                 return '=';
# @$ \6 h: _4 @+ X' l8 q             else* t% w6 @0 ~" r6 @
                 return 'E';- M1 M+ U  F: I
        case ')':0 [8 f. i9 P$ h5 ]- `. H
             if(c=='+'||c=='-')( H& N9 X- a* Y
                 return '>';# f! B& O* y# o& v: M' r! N
             else if(c=='*'||c=='/')
1 A7 r0 \7 i. M1 K% ?$ \  r                 return '>';$ r: s/ p1 p: l4 ]3 V9 X
             else if(c=='(')
4 K! }( n* s; U4 ^# k4 a" g                 return 'E';" v5 [" s- s3 @4 k+ |
             else if(c==')'); K) B. u" o1 q* H! d2 [2 J
                 return '>';
/ @1 {; i- s1 m, u* _* J+ k6 ?             else4 E: ^+ S9 X& |2 c1 x( K' X+ B
                 return '>';$ t& P& g' {0 {3 G& e
        case '#':: W& ^- G* E# t( x
             if(c=='+'||c=='-')
' A% e3 D: k6 ?; ]                 return '<';2 O8 T& A4 b- c% ]4 b$ j4 {
             else if(c=='*'||c=='/')
, D6 I# T) l% g                 return '<';4 u4 e8 h% w+ Y) G) j
             else if(c=='(')
; L% C7 I7 u5 B7 L& p0 I                 return '<';0 t0 O; Z) f4 B4 D2 L
             else if(c==')')
2 l+ J/ Q0 d5 |9 K0 _                 return 'E';
' Q9 _6 y' x0 n/ s- K             else) O, W3 W8 R5 @; i$ C9 D9 T
                 return '=';  ^  N& q+ |+ U
        default:0 \3 t5 m1 U# H
             break;
% k0 q7 C- ^- k    }
* y* i8 Z& k! S& w    return 0;   
" O* x: y6 ^7 C. Q. Y}
6 p- s) p# b$ U+ h& z& d9 C2 n! E3 q( `
int isOpr(char c)* I9 m+ ]( ]. d3 q! Z
{
" O  K) Q' m* g7 B! V+ W    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 e  m5 ~" V. _9 o' m
        return 0;! i, j. x. I1 v7 X
    else
" Z2 A4 y/ D! t3 G3 z, G4 T& G        return 1;1 n. m4 N6 d. y8 Y7 j* s  s* u
}0 A: g* s% w& _- K# @$ j

7 F" ^/ W- B8 [5 ^. e; afloat operate(float x, char opr, float y)+ k* @$ k: M! \1 B! z
{/ @5 b* T# c2 _- l9 d
    float result;
' a; u7 o$ e1 T% z6 d    switch (opr)3 n. f: b/ o6 R; K
    {5 U, ?1 {0 A9 ~( X( W
        case '+': 5 G" }$ g8 K; c/ C' w9 p
             result = x + y;
6 i1 M6 L* t0 O7 B+ |% V4 H             break;
4 M; C; \6 d" E, _2 k9 T6 l% r        case '-': $ C. u  E" n2 E9 T- z
             result = x - y;
' Z: v1 i: B8 m7 d             break;  Q3 w2 L! ~% F: T
        case '*': 2 ]$ ]; }* @) K- g; V: I  N9 \- @
             result = x * y;; B) F! s$ t7 P* W- e: {1 i2 ~
             break;
' A5 ]( J" @& a- r# d8 x  K: w/ I        case '/': # a4 R( ], @* J7 k4 j2 u9 a
             if (y == 0)( Z7 }% B0 e4 _/ ?6 l- K9 ?5 e
             {
' Z5 u7 s  y: M0 J* M                printf("Divided by zero!\n");
3 n- R- b6 _/ |+ L6 v: P                return 0;5 N4 p( k, ~  u* G' n' M5 o4 u
             }3 x) X; h1 T+ ^$ R! z5 Y  X
             else
2 U) `* g" A/ U' m0 [- I1 X5 U             {
* [4 Q2 Q+ U) J" V                 result = x / y;
* X# ]  S+ Q5 q2 c; |5 B: w  F                 break;/ W5 x" t# L2 G
             }7 ~8 l: Z6 x$ l, V
       default: ) ~" I* S8 e( m0 b" @; W# x
             printf("Bad Input.\n");
4 y: a: U  \* t- Z6 l             return 0;% x7 G* _" Q. p6 K$ v/ y
    }6 x" M1 c* Y: u+ \( ^
    return result;
1 u  E5 I9 P* v6 N( t}    & l4 V" S5 J! ^' c; a
' N- f: g: g1 C! e" [. L  S# m: {0 [
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
) w" `/ W/ [- v6 y+ g{# N& U( \) r. |: u
    Stack optr,opnd;: q" H4 C2 N4 U
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;& \. b$ V1 W' u/ c0 J# N3 ~
    char c;8 U- u3 w8 h+ }9 l" F
    char buf[16];; n1 M( i" r% q8 @; I; C0 I. R9 h3 ^
    int i=0;0 L& Y+ O2 N$ b6 u: h# P
    2 N2 G) k  K# n( g
    InitStack(optr); /*用于寄存运算符*/
4 w. H( K2 G  n9 Y. c/ w/ M; `0 ~    InitStack(opnd); /*用于寄存操作数和计算结果*/
. U) t, I: P- X) u1 L+ \; }/ y    memset(buf,0,sizeof(buf));
& Q* s8 E/ B) A8 Z   
+ B- {! A% ~. Z    printf("Enter your expression:");
. T$ _: H/ G( \$ G        - B# }; f8 ^: ~  t) [  g) z- K
    opr_in.ch='#';
# f+ m6 p: \/ G2 B& W# Q. T    Push(optr,opr_in); /*'#'入栈*/
& |/ C1 ^7 C: i& c( h    GetTop(optr,opr_top);
8 D# x* j8 o: L& m4 J, N3 r    c=getchar();
  B8 H, R) Q1 u- Z    while(c!='='||opr_top.ch!='#')1 ]+ u! P+ o5 z
    {
; O6 A. E" }% y+ o  L/ [3 H3 F8 k        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
6 \- {8 `5 j! B6 N" J$ _& L        {+ ]3 b& J( D  i7 o
            buf=c;1 U( Z# z- U" S3 T9 i
            i++;9 c, s# b& |8 \7 q
            c=getchar();; i0 B9 X1 X+ B5 M' l
        }
! V: Y" c$ e  V% O        else /*是运算符*/0 V6 R! @/ M: i
        {. Q  k. F& f, `7 s
            buf='\0';+ e# M7 m& t8 @% N1 N+ @
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/5 l* s: A6 S6 |/ Y3 i
            {3 J. ]) ]8 T9 ]* O
                 opn_in.data=(float)atof(buf);
$ ^5 L2 ?; W/ n                 Push(opnd,opn_in);) u! @1 f9 ?  D9 d) V
                 printf("opnd入栈:[%f]\n",opn_in.data);/ a3 w4 S/ [" X" }+ w% R
                 i=0;, Y/ P; M* x/ z; |& Q6 B$ `
                 memset(buf,0,sizeof(buf));
3 K) c/ s* ^8 f. l' ]            }
. w& H% p3 o$ d            opr_in.ch=c;, g! {) E# Z8 Q; ?" N( m' V7 s
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
2 h- \  N9 \3 S2 E! z2 A            {! I- x4 O' j' Y6 C2 i5 a! X: u
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
# }+ u( Q/ |% x4 f4 O                     Push(optr,opr_in);* ?1 ?8 s5 l: I; O# y: u
                     printf("optr入栈:[%c]\n",opr_in.ch);
- o. E6 f% i7 ?9 q) X                     c=getchar();
% u" H8 k, q& Q  h2 Y                     break;; Z* Y; r. E4 p7 ?4 }) H9 m5 U
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/: `$ i6 u. \: Y: G1 }/ H
                     Pop(optr,e);# Z) p5 v4 W4 x3 z+ h/ b" G
                     printf("optr出栈:去掉括号\n");# a+ Z- H$ v1 c7 d) Q9 B8 g9 x
                     c=getchar();
/ i* |% }- q1 p* {6 i3 ?                     break;) o  v/ \4 k+ l" j4 ]; Z
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
+ l% r: k$ H9 T% U9 _                     Pop(optr,opr_t);4 S  W( I2 e1 p
                     printf("optr出栈:[%c]\n",opr_t.ch);# S% K! V; s5 a: l/ A
                     if(Pop(opnd,b)<0)
: Y) X5 H3 H3 W; V0 q  M! O: j                     {
2 h, M& b) n( f# j8 Z2 j& Y                         printf("Bad Input!\n");
! h6 N) r, J, Y# K3 j8 G3 `! C+ u6 k                         fflush(stdin);
9 p$ D3 ^* E* ]# B. q1 L                         return -1;
, o7 M/ j& Q! P& v$ m- W                     }
8 u- E& X4 q2 W# R* x                     printf("opnd出栈:[%f]\n",b.data);
6 b) C! P2 n5 _0 X7 Y1 N  }; V                     if(Pop(opnd,a)<0)' I# G$ B9 b$ f! h' M: i6 D8 ?! }1 p2 H
                     {
" e7 Y* }( h* e1 f                         printf("Bad Input!\n");
' u1 V/ I1 K- g  ?$ V# Z1 \% W                         fflush(stdin);+ a2 o  e6 q) O: j4 T% @, g9 v
                         return -1;
- L" q( g. u& a8 T, ^4 N                     }
6 Q4 F- _( l. z! E) ~+ f3 k" x- y3 e                     printf("opnd出栈:[%f]\n",a.data);" E* ]! [1 T* {7 q) {7 U
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*// b) u9 ?( G" N2 K7 x! t0 M5 p8 Y
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/% L6 y2 u7 U" Y7 ~. D. C
                     printf("结果入栈:[%f]\n",opn_tmp.data);* g! Y1 k$ {4 F& U( w/ _; e
                     break;
" o$ y6 c  E: ]3 s3 Z" F6 k4 ?            }
1 ~5 c3 d- ~! C' Z: @        }
; Q" t6 g2 M" X- `) n        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ' U9 Q1 f% t5 C
    }. m  m4 b3 i+ \* F" g' a. I
    GetTop(opnd,opn_tmp);
& `+ x4 O3 M8 d5 s: q: I    DestroyStack(optr);6 J9 ^% C# @0 ^( J+ r) }
    DestroyStack(opnd);2 F2 q3 v3 P# X" N) f
    return opn_tmp.data;
$ d6 W! x" n2 ]& Z9 a3 \}
% ]6 O# [9 Y( h' m; {, q  H% h( H! s
char *killzero(char *res,float result)8 |8 U5 {* S. W) j9 u% _, h' s& t
{  O4 i. J5 ^5 W; A
    int i;
3 r0 q, r0 I7 M  D8 O) o; u5 y& o* x+ i* Y0 s, E* k6 B
    sprintf(res,"%f",result);  m3 u! s3 [. A3 f( U7 y8 u) u9 w
    i=(int)strlen(res)-1;$ L. ?( q, F& j. O( @8 B$ k
    while(i&&res=='0')0 ~+ @7 e6 K! ]- k- V
    {
5 j% F) T4 c0 p( {! Q        res='\0';
) m! o/ {3 p  Y( Q& Y        i--;6 i3 S! s5 z% s9 K* x
    }
/ ?5 O$ S; m- F  U    if(res=='.')
. b) W# ?# D  \9 j- P* O- {        res='\0';
1 y! L8 i+ q) O, }; C! o% j( `5 s    return res;
4 A* q9 i: b& }) r}
& \9 q0 c' X8 P7 H  Y" ^4 Z* ~0 w: g4 w% c4 g. f7 D; n
int main()
/ S) n. y/ R0 x+ E{
! e/ m, S/ R' v3 {2 n  U    char ch;4 k) Y/ K' V$ D3 u9 {0 g
    char res[64];, l& w6 ^* e0 I# S) o
    float result;% o3 r6 ^( y4 P
    while(1)' J  ?: w) x( S8 U& m, I
    {
4 u) Y) T* @$ W! j3 J" ^        result=compute();
) Y. O6 U* s9 J8 L' _; J! M        printf("\nThe result is:%s\n",killzero(res,result));
. X& S4 b, @* L: _* N' \1 @        printf("Do you want to continue(y/n)?:") ;
" m5 }  M; F% h, b: G% c5 U+ j" G        ch=getch();+ ^, j* e- N0 T8 ~: x( f) S' i+ c6 h6 \
        putchar(ch);
' r: F6 @+ [* s( b/ c        if(ch=='n'||ch=='N')
' u" D  c: k  E$ i# Y            break;
: \) x' n) C4 K: U        else
4 g6 `5 ]) M; H% _% Y; Y8 @! @5 A            system("cls");6 W" S" e9 E6 l( a2 ?! }7 Y
    }
$ a+ f. q7 V7 ^, n# Z, ~8 S7 D3 u2 x5 n: i    return 0;% t+ J* i: Y* Y. S( _# W$ F
}
- \8 g" J6 x- }. g+ I+ k# O

/ k; K3 {2 x7 i2 k[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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