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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的., x4 t0 O' {/ |1 K
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=( T1 }3 G+ g- ?* H0 T; C
/**************表达式计算器************/
/ V; v9 P4 d9 J) l#include <stdio.h>
7 g( k8 t, u5 x6 d#include <stdlib.h>
$ k) V$ T; r$ \* S5 }6 Z* Y#include <string.h>- M- U- d; o- b' n
#include <conio.h>4 K( M# ^* j& Y$ Y% x8 \0 R( a* W
#include <malloc.h>: B( r' \# B$ E- ^6 Z: Q7 M

4 `5 |- t% E1 D9 {9 N) @3 C5 ~- s#define STACK_SIZE 100
& {* i$ M+ N8 Z# M3 B/ g+ w3 C#define APPEND_SIZE 10
1 |/ Y1 m  u& W( O4 X
  A- f" C' Q  z* q2 n( Fstruct SNode{
& o; p# z  s; _# @0 N    float data; /*存放操作数或者计算结果*/
) \/ r8 ?8 [2 r4 g# ]. G    char ch; /*存放运算符*/
2 k  v4 m, L# c8 V8 Y9 }2 `};
) Y+ @7 P! d% V
, j5 ~6 S7 T2 L9 b. S/ N0 ]  a+ Ystruct Stack{: Z$ ?$ W4 F( ?+ M3 c
    SNode *top;
5 p! z# a$ ]. V3 T% x    SNode *base;
  z: U$ g9 z$ r3 T/ S    int size;
4 T# i% e" T: ?9 ~! U7 M8 W8 b};
/ N" t: l+ ^: b/ ~5 k
4 M+ s+ m- t8 h- H0 u3 Q; A" F0 P/*栈操作函数*/
$ l$ Y& Q8 b$ k2 K( `1 g3 \% _8 X5 Uint InitStack(Stack &S); /*创建栈*/
" u: S* y' C5 D/ L" Y$ y% ~3 B" Fint DestroyStack(Stack &S); /*销毁栈*/3 M: L' R- [; N8 e
int ClearStack(Stack &S); /*清空栈*/
8 }9 A1 S4 `4 Tint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/% {# K$ ?) L2 v3 w/ Z/ r
int Push(Stack &S,SNode e); /*将结点e压入栈*/
6 {2 ~7 F# ]" K1 }1 s$ I% hint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/  a& B5 z9 m, F. a$ }( P7 ]9 K
$ ]: g7 L% M' y- e6 `, |
/*表达式计算器相关函数*/
' U8 I3 Y  t9 J$ R$ ?char get_precede(char s,char c); /*判断运算符s和c的优先级*/
# C  y' [2 F( g5 h# [' Y5 E/ qint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/% T$ V! g- f+ o' B5 X$ Q
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
" o9 ^/ s0 H2 N( Ofloat compute(); /*表达式结算器主函数*/
3 K8 }* |% ^! W8 }) pchar *killzero(float result); /*去掉结果后面的0*/ 8 j* S3 g% R6 t6 ?9 a: {8 {9 k4 E3 ~
( }4 @# I8 Q; V" ?, I; ^
int InitStack(Stack &S)
# r2 x% I  L! C" \! R{
+ G  a# i) c4 M0 n    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));8 ]4 H' ~0 ]+ X# n7 u9 S! \% j+ a
    if(S.base==NULL)! ?+ O" _$ C: Q0 ]$ i2 \6 s" T+ u
    {; w% [# h9 Q! |* r- S
        printf("动态分配内存失败!");
5 M- O% C' t1 a3 [+ Q2 u        return -1;# h1 A5 Y2 z9 X% ]
    }  Y1 K$ P7 W$ t% E
    S.top=S.base;
: o1 I6 I" k3 |* v$ Z% K5 s: t    S.size=STACK_SIZE;
* w  R$ J2 u! }/ y  A2 ], R$ F3 P    return 0;. y" e9 T! {' f' f
}
+ R# v4 s) G- ]5 y- \& L* d/ r$ a9 V3 k
int DestroyStack(Stack &S)
1 Q) L; }* v, E3 L0 f{
% n* @* s3 N. d+ _7 q    free(S.base);8 P" H0 R" \; A9 e! X, H
    return 0;  d( E$ @- z* ]/ i$ B  Z
}
( x) m& ^4 j* i7 S+ F& u3 e3 A$ t* H% E5 v6 f- ?9 y
int ClearStack(Stack &S)
1 S) c* L% A4 G{
+ z) e! O( h2 ]9 a6 E! J6 I- M    S.top=S.base;( ^0 r* s3 [! s
    return 0;
1 V; `4 v* e6 F( t}# g+ T) A: k7 o  ^* j& f: j( |

; }! [! `/ r% B  Qint GetTop(Stack S,SNode &e)3 N" }: Z8 ?% Q+ c/ V# v6 l
{7 ^/ [# I" B. m: J
    if(S.top==S.base)
+ H' f$ K: Y& S! \    {
8 J. j; j( ^1 S/ Y3 p, D        printf("栈以为空!");) c/ @' g5 x2 `* N* |8 ~
        return -1;
6 B  Q3 Z, \+ [& d, z& L    }  l6 P, e/ |% k
    e=*(S.top-1);
5 |& M, h2 O; Q4 h: z9 a    return 0;
- \9 `1 [8 [- V7 V6 \/ j3 b9 b}: C% _$ @- U7 @& s: E, J, Y7 C, X
+ N6 ~; ^1 _7 P9 b7 k
int Push(Stack &S,SNode e)
( z% E+ c0 M, w. z{
% w8 K! P, ~5 \; H. r    if(S.top-S.base>=S.size)% P- X; P0 N# J2 o' t  ?% H' s
    {
: h) h2 [* H' m* s7 v/ @& c9 y        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
+ K$ c4 _; W8 a# a        if(S.base==NULL)0 T: U* D1 @0 T% d5 y
        {  D$ I' Z- H4 q
            printf("动态分配内存失败!");7 H" K; B' I6 N3 y
            return -1;
2 |* {$ ]  z7 M1 A1 I3 E, J4 V        }
9 r% T- H! I  f" |        S.top=S.base+S.size;5 |& M5 G8 {2 w5 u8 L
        S.size+=APPEND_SIZE;2 k$ e8 n1 Z/ B4 y- s9 B) M
    }
/ q2 i& e8 l6 I* B* M$ s    *S.top=e;
3 {$ Z8 U$ m; b9 E3 B, s4 {    S.top++;
( i$ b9 |: N2 \. p0 F& e    return 0;0 m' E3 T9 |- W) s
}  ]$ W0 B# T( \& S! s

) h1 l6 P2 V' Fint Pop(Stack &S,SNode &e)
. h" h- ~0 Y' v. x{
/ M; a# m; D" g7 Y% w+ [    if(S.top==S.base)! i; F) C) w5 }: E& f- q3 I- q
    {# J( Y4 P! @2 k4 g9 ~; ~
        printf("栈为空!");
: |& [  S: \! U4 C# {2 F2 P        return -1;
, I' }; F) K5 U- c8 f2 w/ s    }" |( `+ F( g$ F; P
    e=*(S.top-1);5 |% e* x# ~9 D. J
    S.top--;
3 S% O3 n  b; ?5 Q: v* m4 N    return 0;
4 w' k4 ^2 y! E5 n  U/ h* o. {1 _}" P6 z9 t, j  L- I9 D' \, C

1 H8 j$ @* T0 w1 _$ [char get_precede(char s,char c)
" h! Y% ?0 r- }# {{
0 {" s2 D+ s  }; n1 _    switch(s)
1 _+ F3 y: h- x) ^% y  @5 `    {( ?  N' I0 P0 Q; i# V( g' E
        case '+':                 
' @! l+ V8 g  A/ }: X- A8 w        case '-':! G' w! M- E* j
             if(c=='+'||c=='-')( w; \5 a8 W' b; W* J6 }9 k. c! k
                 return '>';% c" ]- a7 @) X4 W4 E
             else if(c=='*'||c=='/')$ w" A) G  |5 H
                 return '<';
8 n4 X0 @( c+ T: ]+ w             else if(c=='(')
1 {6 P; q. H1 G1 |( p6 h                 return '<';
6 D5 A/ N. y) c5 w             else if(c==')')
& l5 k4 d( _* I* u                 return '>';
. k# U5 [' `$ F0 S; D% W+ ?3 L             else 1 `: j9 O7 n- ]4 g3 p- [/ h- p
                 return '>';/ W  r3 M- L2 F! z+ C- S
        case '*':
8 Y  u, N0 w. X        case '/':) o8 ^) D* c: f5 }3 [! U+ [4 D. [) y
             if(c=='+'||c=='-')
3 [+ w, F6 C7 _5 I- t& ^0 S                 return '>';, e2 d. y. }( j1 x1 J" X# l
             else if(c=='*'||c=='/')$ N0 N, H9 e$ w/ ?9 m6 h
                 return '>';
5 t, E9 @; m5 ~0 R) _             else if(c=='(')  c" L, Y) g- n# E! g8 ]9 A, d
                 return '<';/ q) M7 U1 i6 A4 K/ H
             else if(c==')')
5 V) H0 C3 F; w* A                 return '>';
. \$ t9 Q$ T( ?             else2 b$ C. T2 s% r6 K$ d
                 return '>';
; F; [4 L0 k; y( Z        case '(':+ @* L) c6 r# ?: f# i! ]. ~8 z4 M
             if(c=='+'||c=='-')
% B2 m1 T% o# G  @- Q$ U                 return '<';
0 v6 U  S+ ]0 U; D, d$ b# v9 H% i; N5 G             else if(c=='*'||c=='/')
0 I' U. I) d7 F. ?                 return '<';' V0 Y) ~' |' B& m
             else if(c=='(')7 O" G% l. A# [* N! \* P6 E
                 return '<';
7 q9 e# V8 j; T. |2 X9 u             else if(c==')')
  i; _% U% Z' u                 return '=';
+ Q8 O; {7 d( P9 V             else
2 N! e7 [" X7 T& {2 \2 `                 return 'E';. h* t# y, ^) I0 z$ Z0 C
        case ')':" I- B9 U2 B8 v  o
             if(c=='+'||c=='-')
4 k1 v" ]1 E* H- G                 return '>';7 x) W: b% [% f0 ~; H
             else if(c=='*'||c=='/')7 s& v9 Y: [  H" M* ]; E7 q
                 return '>';$ D( j5 m+ `7 I+ x
             else if(c=='(')8 E% x3 K, t; [3 b7 T$ b" r3 G/ S
                 return 'E';
" c8 w# ]! F8 p7 n2 l7 `% n/ E             else if(c==')')
, ^; R$ V+ h* G( v                 return '>';! s% H/ U  z8 e) G2 }) t
             else: D6 p& m* @, o) m5 @
                 return '>';4 l( B- z: k% T/ N7 P: \
        case '#':
/ w+ K: J' ?$ N) p; E1 Y3 j             if(c=='+'||c=='-')3 A  K* p% M; m% v+ ]9 I
                 return '<';+ Y0 A- U3 `- Q$ F9 V2 D
             else if(c=='*'||c=='/')# o2 W) Q  I, E! d+ t! J
                 return '<';
- H4 B1 W) M( c; y% ~             else if(c=='('), R6 B+ s% n1 f' F- J; P
                 return '<';9 d* a, @& `4 g" z  D: n
             else if(c==')')
5 l! d" Z/ q) |5 ~$ I+ @                 return 'E';" {* k% Q- e7 t/ t1 z
             else- t& U) b  d, @/ r6 _% y) u
                 return '=';2 A7 S% Z+ j) w+ l$ F; z6 e
        default:
! c; o. s, ?6 ^2 M/ l' Y             break;
2 n6 I8 g, l( @; X2 F    }( L5 {9 c' W! ?$ g& u, Z7 H
    return 0;   
9 O- ]" l5 N$ H; e}
5 h% u! |( G) K: S+ F* h. ~3 R5 k9 [  W/ h! h$ D3 M. F
int isOpr(char c)( Y7 }3 E7 }8 x0 B% D+ k1 [3 t
{
" d, L7 ]5 N# K( P    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
+ o5 J6 n1 J; ]        return 0;9 G0 r# v6 Z2 c4 O: Z
    else & H% G: p3 P& \" u1 _
        return 1;$ _2 X7 c9 s6 [7 C
}
$ o( |- w2 C, y6 p1 l' V( a6 Q& N) w2 F0 r. j, }( n$ f0 }4 ?" V
float operate(float x, char opr, float y)
5 C6 E0 m* U0 S9 `. q( i{6 ]. @7 |( C# l0 u7 C
    float result;
8 \' ]+ Y6 d( |. A    switch (opr)/ y8 y5 {# s% `1 E
    {# f# d1 Q4 a; _8 `
        case '+': % U7 J- G$ `- {' {2 I! @2 D
             result = x + y;) r  _) [7 V6 Y& e+ X
             break;
. ]" H# d" {9 ~- c        case '-': 4 N6 e' ?4 |6 y# W0 U" V4 n3 A; A
             result = x - y;; ~0 C# T) ]$ r9 d% y7 Q( R
             break;% z( t) y& k5 R% O* g, g
        case '*':
7 _3 a6 ]9 R- \# o/ Q0 i             result = x * y;
$ Y  _* {9 k0 i9 N/ s! u             break;/ Y/ N! o4 u$ F5 H5 e2 B
        case '/':
, f; F. r  _1 ?             if (y == 0)0 `6 m8 z' k; I' i9 {
             {1 |5 \1 j  a# }: e/ X7 J
                printf("Divided by zero!\n");4 O6 x* A# y) E& v
                return 0;
. }7 f5 m1 ^& j7 _             }
* g, t0 ?" S! V2 o6 m$ _! m             else. `, v) |( h+ S: E! X+ ]+ t
             {3 B& I) }: p4 ~" H  i" F4 j, y
                 result = x / y;
" i. Z4 C' p$ c                 break;
% }$ {1 L* o* y. i$ p4 `             }! `& R: q( E1 l' f
       default: & c4 [) Q; `2 y- r" ~% j
             printf("Bad Input.\n");
  Q4 C: c* H6 @& \7 u             return 0;- m2 n/ D; l, _1 L% n
    }. b- u/ J( z9 T$ D
    return result;
! P% w7 {' s% b5 \' D}    2 d* v2 U: l% `0 O" t

# |: k. I9 A# n3 `- E; Q% o$ `( wfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 n5 b; ?0 P- S8 l( L) Z" j, n{
7 J: Z' Y; v; {7 j- N    Stack optr,opnd;( b& ^* {( a) Q1 W" Z. n9 v& B
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
% @- E& z3 ^3 T, |2 s    char c;+ g# c4 @- w, p5 @* w5 R
    char buf[16];
/ c' _- `' a# _: {5 _    int i=0;
" b, [- f/ m) l; f: v   
; ~. `% u- p* F/ B    InitStack(optr); /*用于寄存运算符*/8 o6 o; @7 {2 W" ]9 ?. o
    InitStack(opnd); /*用于寄存操作数和计算结果*/
% {9 z* ]& U  t# _5 S0 B& T    memset(buf,0,sizeof(buf));
) m( Z9 Y8 g0 L$ M% b, K    - G4 o( E# h9 v7 k; }0 |: g
    printf("Enter your expression:");* @; L. t) I' B$ D
        2 y, `8 \6 O' ]& r! l8 R
    opr_in.ch='#';
" b4 K& I: J+ V    Push(optr,opr_in); /*'#'入栈*/
1 j6 Z3 v) W4 d' [0 I: [7 n9 t    GetTop(optr,opr_top);7 O! {  U4 s( i2 V6 `4 }6 E% K, j
    c=getchar();1 J/ d* Z/ P* P2 ^3 @8 y# Q- `. X
    while(c!='='||opr_top.ch!='#')! {( Q; e0 _9 R2 a6 k3 Y4 t! Q! q
    {
$ j8 Y& W$ {. g+ W. B        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' u% q9 x+ y: m6 F9 N0 B/ L        {
9 _( `3 Z3 U' F2 U8 u            buf=c;
) G) y( @2 ^3 ^9 Y            i++;
% n9 V( |& ^4 ~3 U4 }9 W. E: w" r            c=getchar();
- d' j) a% w4 k6 E* t8 K. x        }
( L+ ~; b1 `; Q+ Z1 x% k& ?5 X        else /*是运算符*/
( Q+ T9 f6 m- ?6 K7 m        {
4 o: Q+ }; f6 v, ]# Q3 R1 v: ~1 B            buf='\0';* b: J/ W' c3 W/ a/ [8 }* `
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 Q  D  S) [' a% G
            {
6 H  [) h! R: ~/ O2 A- Y' [* I( j                 opn_in.data=(float)atof(buf);
' S# P; o4 s, M' q                 Push(opnd,opn_in);
& `% g+ V" F4 C9 ?                 printf("opnd入栈:[%f]\n",opn_in.data);: i( ?( ~4 x8 u2 K; Z) o8 Q4 Q$ }* Z
                 i=0;4 }3 Z$ W$ r. f5 R1 S2 g
                 memset(buf,0,sizeof(buf));
4 g. [+ c! F8 J0 x7 Z- r            }
1 A3 T& @) E& |, |( T3 a            opr_in.ch=c;
1 d: L2 h; E8 C  i) x* l0 i; _            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
; V1 O7 X- m9 b+ f4 ~+ i7 G1 C4 M            {4 g& B% W$ B  f& w9 P( {) Y# j
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
# j) s1 l7 j8 k9 T% i5 ]                     Push(optr,opr_in);  C, H0 W  B/ e& b
                     printf("optr入栈:[%c]\n",opr_in.ch);% w8 V/ H+ c1 ]) W  q) M
                     c=getchar();* C% ?  t9 r0 V# ~+ Z
                     break;4 Q2 B+ A; G. k+ P$ y5 I
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/7 \: t+ I' |$ z0 O% k8 u* ~
                     Pop(optr,e);
1 `7 |; h" R- i1 K                     printf("optr出栈:去掉括号\n");! D+ U. u* O4 M0 E7 x& M
                     c=getchar();
  |% t4 z+ s4 Q) B6 N8 @* p5 Q* S                     break;
* t" W% Y7 |6 H( t- c5 l                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
; H# H1 |, i$ ~- B                     Pop(optr,opr_t);
" l- N9 g9 J. M7 V                     printf("optr出栈:[%c]\n",opr_t.ch);
) A0 j& O1 r, H                     if(Pop(opnd,b)<0)& P! v/ v8 `& p' ^2 \" j$ q; r$ @
                     {
9 c8 }" z, _) n( X& N7 c4 b7 l                         printf("Bad Input!\n");
! K' G3 D' q: @. a                         fflush(stdin);
% s' Y' Z* j" B4 e                         return -1;
5 s# b  X4 |% A& x" _                     }$ C: P0 [5 e) Z5 o# J* i: W
                     printf("opnd出栈:[%f]\n",b.data);
+ o* o$ |3 `/ g2 J( M* f                     if(Pop(opnd,a)<0)
8 n4 N% X) O* g" m                     {
7 r7 `( ^1 ~; F) C1 }4 B                         printf("Bad Input!\n");
$ _3 d" ?  q7 x7 j; ]                         fflush(stdin);
; ?0 i0 _) [( d1 c9 r  M                         return -1;
0 [' H5 d/ u: A1 s                     }
! e% z  F) ~" B" l  Z8 X' d                     printf("opnd出栈:[%f]\n",a.data);( K/ a* L! d, e0 }
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 @5 D2 Q1 E3 V' z                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/  T- W! Z* W' j& P  p5 c
                     printf("结果入栈:[%f]\n",opn_tmp.data);
$ d( \7 |) J8 d2 l                     break;3 b' O, a' \% l9 a' G
            }4 ?8 d# Y1 z( i% b+ C
        }; |% ]1 n% p' I' q/ X2 B( M
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ' W0 y  e2 F; S  F* j/ i8 {
    }
1 v0 R0 h4 j* f7 f; h% b% N/ ]    GetTop(opnd,opn_tmp);! T: z  O  _9 }! L
    DestroyStack(optr);9 P0 z; y. `2 f. Z% ~
    DestroyStack(opnd);+ a* Y5 m- G$ J1 o) x- z+ l* F
    return opn_tmp.data;2 J' F3 U( x6 }3 o$ {4 P# A
}
' l" |7 I1 o4 |0 s; ^3 r' b' n5 m) E# Z# a& E5 {# F. d
char *killzero(char *res,float result); T' Y7 _/ p3 e' d3 ?# T9 j
{
/ J9 N) V" y8 ^  \7 k5 x0 d; ~* r    int i;
. A* x- q( U/ x" A
% i$ t( q+ m: H7 g! Q# E5 Z2 ^    sprintf(res,"%f",result);
5 d# E  q# X6 D7 q    i=(int)strlen(res)-1;
: l& L2 G( Z9 v# w5 u    while(i&&res=='0')
7 C, r0 l* t2 k9 o/ Y    {9 D% V) z3 P4 k- K/ J  R* x
        res='\0';
  s9 F# C" o; F; x        i--;
' J2 h, S# ^; {# }6 r: Q    }
6 H: C1 i1 X! o1 R    if(res=='.')
2 i# g8 \5 K% p* ?. `        res='\0';
- s2 G4 L1 e, G    return res;& ?+ i0 X2 c. N  T& n- j, g) I8 p
}9 x, |8 g# @- O: t) E2 }6 y

6 B) ?' G! m& i* D" Zint main()
( i' p7 h2 j- \* o; {' @- e# l{
& G; h2 a& f& e. x/ ]8 p  \1 }    char ch;' w0 p6 j: W/ Z2 n9 D4 f
    char res[64];) g+ T7 Z8 u* s1 O* a3 i
    float result;
/ `- a2 m# O; `    while(1)7 p. E3 |" y& j0 x8 e; r9 N
    {  H/ Q% ?( {, z$ j7 e
        result=compute();
2 e# F0 P* w" d3 U( i        printf("\nThe result is:%s\n",killzero(res,result));9 E1 w. S& y  n. p& t! ~
        printf("Do you want to continue(y/n)?:") ;
) d7 j$ |7 u4 F/ ]        ch=getch();$ c+ _- A8 r# D; ^4 _9 q. }- b
        putchar(ch);5 h1 e; I' @1 \
        if(ch=='n'||ch=='N')
9 k6 o+ l4 z& o! v* ^$ O( N            break;; a: U+ T( [8 p& H
        else
  s- n$ z, Z( `3 [" {            system("cls");
) u/ |+ j) l/ e% U/ n. r    }
0 d/ k  ]( ~4 ]8 @, p; v  B& E    return 0;
. l1 @8 q2 a, T& F}
4 o6 \1 r2 G& g8 b+ }# W# o
* ?/ T2 E3 B7 h/ Z  X( _
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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