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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6 N* Y0 ^& Z7 ?0 F) X
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=# a) ~, o, y& @6 m: f( [
/**************表达式计算器************// d+ m9 X! n* r9 X# x( V9 Z. r5 \
#include <stdio.h>
9 U" ^2 K5 ~, i2 {& c7 d: h* f#include <stdlib.h>
: ~& ~8 r3 s7 J5 I! a$ D" _#include <string.h>. Y$ ?! w- n& l7 U* ?
#include <conio.h>1 B2 P7 C+ Q/ O  y/ ?' ?, t
#include <malloc.h>4 p( X" }1 d' x9 x
$ G- L0 g9 D6 P6 E
#define STACK_SIZE 100
; \: P( Y( g3 h#define APPEND_SIZE 10
3 u6 q- p# h2 j  G4 i7 T0 k
8 F" @4 K; j, k1 Fstruct SNode{
* A+ s( }7 B& U# P    float data; /*存放操作数或者计算结果*/
: x8 l, x* f- `* O2 w    char ch; /*存放运算符*/( `$ D2 @8 {8 `; e( ^+ \/ ~
};8 I1 ^4 I& X' g+ z* w; d

& h* Y7 l8 f" cstruct Stack{- Z; o+ \7 p; k" G
    SNode *top;0 d. e. ]# r5 q/ W
    SNode *base;
' }/ V' d$ s/ {) W* j    int size;
1 ]; B& m, |3 r5 h};
. x( p8 ^( m7 Q8 `0 o9 j% l; {! {! J# K0 [
/*栈操作函数*/
. Y4 c! J% Q  @/ V6 a* j: V) c. ]/ Iint InitStack(Stack &S); /*创建栈*/
# J2 ~+ D8 \$ F# f, m- u! bint DestroyStack(Stack &S); /*销毁栈*/
+ d) k/ @- q# B: z' `, S- Rint ClearStack(Stack &S); /*清空栈*/
8 [) t0 `0 C6 B3 j6 ?6 f8 q8 eint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
2 S8 K7 D" [, X, B* K' r& o0 Yint Push(Stack &S,SNode e); /*将结点e压入栈*/" Z2 Y% H% U. p& T. M% r# H7 v
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/6 H9 d9 }- ~! F8 `+ H  d

+ l2 U7 Q8 F0 d- j/*表达式计算器相关函数*/) F7 f5 l3 J: h2 ?& Q. ?+ l# e& M
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
- ?! `. X, O' Y6 X( T) @- Gint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
* s3 P2 D( k3 T% l3 i9 r% x% `# a/ Ifloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
/ [% S" J' ^3 u% Mfloat compute(); /*表达式结算器主函数*/) n& k% s7 u, I$ o' d
char *killzero(float result); /*去掉结果后面的0*/
8 t: K* C7 I6 C; ~8 p+ c6 C3 y( J% ~+ l' c
int InitStack(Stack &S)
# v4 }. Y+ w* c3 E{' \6 Q7 W# d0 q. y- h
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));7 R2 l- u  u0 w
    if(S.base==NULL): T( J( g' r5 i: k# L$ g
    {
1 z- m, A- A: s5 w4 E        printf("动态分配内存失败!");
" B3 U" t  C$ J$ g- A8 ~; t+ K% m        return -1;  h8 ?# A& \5 D
    }
4 M# x9 V" P9 q1 {8 I0 }9 s0 Q    S.top=S.base;
& ?* `% P" P# J3 G( M    S.size=STACK_SIZE;+ s8 H  |7 s8 V, N0 F
    return 0;1 Z7 X' e* q: s9 b
}3 b* R" l2 j0 D$ U
2 a# a' ^7 ~. l: Q
int DestroyStack(Stack &S). x" E1 V- g7 {) i% h
{* B4 H$ k1 s0 {* [
    free(S.base);% E) z' E- }2 G1 H1 E
    return 0;
, W6 a; {' n7 d) a. B$ U' T+ B}
- W* q$ n! T8 ~  t3 F- w6 `5 y2 n  y  A. [( C7 N& E1 _
int ClearStack(Stack &S)
1 D, H& U: ?( u2 ^' ^3 z9 X{
* p" R% X9 C" N6 h$ i3 Q' K; w    S.top=S.base;
- `* U7 l; ^6 _2 H" F# D  O+ ~* E    return 0;
' C& A9 ?! J2 S4 o' b4 `}
* g6 o$ K9 j% m: t6 }. _9 g& B4 W6 a$ h+ m
int GetTop(Stack S,SNode &e)" u+ ~* h8 P4 c9 m: o$ F) v) U
{$ S4 Z# F. O; e
    if(S.top==S.base)
, J7 u# H& s; p  M    {+ H: p. M/ G. c, t, r
        printf("栈以为空!");$ |0 |3 P( q; U6 W
        return -1;9 q) V, L8 A: f: I7 k
    }+ k0 E6 G6 D7 w: C) h& D3 v" l% ~; e
    e=*(S.top-1);8 B2 e5 @# i5 M8 D4 y
    return 0;
+ A4 d2 T8 {' x2 P. k3 u  z7 U) m. J}& J/ w9 c  F3 j6 }

- X9 A: X: y  ^, D: Qint Push(Stack &S,SNode e)
$ v' J2 r# W, |9 k& y{
' d# Y4 k! h8 r2 m    if(S.top-S.base>=S.size)
( E/ y) C# Q* @1 X' w+ n    {. f; z- n+ L- M$ s1 \4 x; m4 R
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
5 @) X) @6 e) K- E) B# q# \2 ^        if(S.base==NULL)
! H2 E( B( U5 ^+ B; i9 ^1 J" Z        {% A6 A% v- L$ Y4 K9 n
            printf("动态分配内存失败!");
6 x. u2 R7 }+ J9 L            return -1;& u: D6 d3 J( d: D% i. f) o
        }
  L$ h" N* C2 ~3 f' G2 F; f' N        S.top=S.base+S.size;
- \; a) x4 h& l4 ]7 S3 e        S.size+=APPEND_SIZE;
" M1 ]) D9 i6 S) t) U9 d0 t& ]    }
6 A3 W, ]3 d* ]3 k2 N0 u    *S.top=e;
( ^. E5 T& B  R* ^7 j: e8 D* L    S.top++;: `, f. q' ^( v) s- O4 Q
    return 0;
) p1 e9 s  N% e; j  L}
+ V" }7 p. B2 l7 i! I1 J1 ~1 S( U5 ?$ ]3 X
int Pop(Stack &S,SNode &e)
% V+ a$ Y! t5 R6 v$ Q1 r{
& D  d8 ]9 e' v" {  ?    if(S.top==S.base)
$ J# G$ o$ p5 z# Z8 f- y7 K+ m& t# C    {! Y* G; n6 e+ v, \$ O
        printf("栈为空!");
1 @0 t+ N5 @" O5 }) [        return -1;
2 w' {+ q; f# D' x# H. }3 C    }; O& j# _8 \( K
    e=*(S.top-1);9 m$ {' i; w" X5 O% Q  l5 e8 N
    S.top--;
6 T; {# Y1 Z" `    return 0;
; K5 @; H1 W+ G0 h! h; e$ c}
& j* _0 N7 b8 T& M+ z4 I: [1 i- `8 X4 w- p! z2 J0 Q- c
char get_precede(char s,char c)
% b+ i3 I& f4 k$ m1 u- a" k1 a{
& x: m' b$ M- U& K5 ]2 e    switch(s)
0 ]; L! ]+ ~& E6 D8 s    {
2 S6 Y) `( Z9 t% X2 K" c        case '+':                 
' }, C+ p$ N. i- x: Z        case '-':
$ t# m6 B& K( Q) |: w+ @0 }# t             if(c=='+'||c=='-')
. v. c, n9 n: K                 return '>';  J/ J8 s. }$ {' ?! z& ?
             else if(c=='*'||c=='/')8 M: a+ B  e+ E! @
                 return '<';
8 n" ?: P5 Z: Q' [             else if(c=='(')5 A0 ]/ [6 J- x* K
                 return '<';; Q5 o: O: t- s+ Y! [
             else if(c==')')
" a: o! k! d/ \. E" Y5 `) T                 return '>';
6 |) S. v7 c4 c             else , G" R+ C0 L1 ^
                 return '>';
) [- K/ }7 c( K, V# g        case '*':1 `6 a# ^; f8 p* ]- Y" @
        case '/':% ^+ p6 s7 ?* b8 D7 Y5 K
             if(c=='+'||c=='-')
5 b, g! A4 G. D0 G1 I. e5 n                 return '>';0 [' N! D6 |, n+ p5 V
             else if(c=='*'||c=='/')
* H% e4 W5 G% F0 ~( J' c9 A                 return '>';6 h  g) ]. ~% k, Q
             else if(c=='(')
8 S( l4 s1 L3 f1 ~9 W6 b2 a2 D* P4 V                 return '<';
9 d/ K4 B5 P% q             else if(c==')')
5 ^- i5 ]$ F. ]* `, S& `2 }                 return '>';% J, C* X5 _$ r" D5 t# m
             else
9 i+ u  }8 h7 P7 V                 return '>';
) C+ l( O. v3 {        case '(':
6 R& L" K8 S- c/ S0 C( _             if(c=='+'||c=='-')
) i4 C( u! h2 d5 P/ _- s                 return '<';/ H* V; s5 E6 M+ j
             else if(c=='*'||c=='/')
7 N) Y; ?, c9 u3 x( s: U                 return '<';( |9 X+ K1 t# j4 v& c
             else if(c=='('), c' x1 ?- ?" K; ^/ Q" r. j4 K
                 return '<';! B1 J! v1 x8 i3 z/ g
             else if(c==')')" m2 s: @0 e' D) u4 ?2 X
                 return '=';! @/ x! W& L& s3 m1 e# ]9 a
             else
9 O6 ]* K& P+ ]% |2 I; d; C                 return 'E';
' M8 t1 S, l: s8 q2 ^8 x        case ')':
6 _$ }% R$ Q$ W* [: V             if(c=='+'||c=='-')
% @2 D0 k9 X# B/ h, _/ N                 return '>';7 j; M2 ^9 @1 ?7 K- R# T  n
             else if(c=='*'||c=='/')
4 ~' {7 D0 K1 S, Y# V% H                 return '>';9 ?7 [) z- w. r7 Y" S# s* B
             else if(c=='(')& D, u+ B& V0 U& v: |6 l
                 return 'E';
" c4 {7 e) z- _4 ^             else if(c==')')
/ c% D3 [. P, @" C+ t$ G                 return '>';
( R5 E7 r/ j5 X6 W$ p             else5 h0 z2 [) C, E3 V: }' I: B
                 return '>';, Q& H8 y  G1 ?
        case '#':, ], _  D, v9 i+ h
             if(c=='+'||c=='-'), t, J6 H* p* M, D
                 return '<';
3 q7 a9 N( f3 y1 Z; w' s* S7 G3 e5 b             else if(c=='*'||c=='/'). X$ @( ^9 T9 ~
                 return '<';  o, o8 ~7 M- T, n
             else if(c=='(')
- l9 i  G: \" I" L                 return '<';4 y: V6 e4 C$ y. i
             else if(c==')')$ Y! ~4 a, j* \. i2 \4 ^8 J
                 return 'E';
! A  c! u* S: [. V: c& L$ L             else! k" _3 L8 {2 D2 ~; p3 W
                 return '=';
' Y, c, G) k4 M6 [        default:4 V5 v: s: b9 ^
             break;
; A4 e' T% d2 ]' [    }
1 N1 U6 S6 N$ H0 Z/ D* a2 n$ |1 O    return 0;   
) C+ g4 w; h4 b) ^}8 @) ^% u7 o' z5 Y# h
. Q" ~* n5 \# S( A) S: T
int isOpr(char c)
, Q" y0 _$ T# v" U& }{
* K+ D6 I' ^4 }7 f3 p/ g- v" n    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
. w# o3 W/ |5 F+ F# t# R        return 0;
& b& w; q- u8 k8 z    else 6 L( Q5 m# S) o7 v3 ]
        return 1;; J  p9 V& }2 ?$ l/ }. R
}  M! F# T3 N# X( g

2 I' T) o" i( V3 O$ Pfloat operate(float x, char opr, float y)- _) o2 r& W' W% w
{+ ]6 M0 h$ N: J2 j0 Y4 c
    float result;9 w+ [7 I0 X) Y( _7 U+ s1 F
    switch (opr)$ \" c; M" X# L3 l& h
    {
7 Q4 \1 c7 l' }2 g8 S: n  F        case '+': 9 U. C# U/ X( k0 h8 Z/ @
             result = x + y;' k" y/ g% d; O' P* S8 K* e
             break;8 F1 S, c( a: ~. e8 n3 g; S+ l/ n
        case '-':
/ }$ Q* b- O# D             result = x - y;6 j; }% b; ^: ~& o
             break;
; I1 t, B5 G9 A" e! T& v; Y        case '*':
% r$ X: m2 N$ Q             result = x * y;4 T- a3 |9 E+ T3 N  c/ z
             break;
3 F2 s8 E  g8 G6 E, O" R" o% x        case '/':
+ m9 W" g) o8 ^9 M7 C             if (y == 0), x/ W: @) p  j
             {  C4 p4 {" \& j2 D' D# ]  z1 U" Z
                printf("Divided by zero!\n");- R& [: h$ I$ w
                return 0;
3 p8 B% |3 j( _. h" {             }
5 O+ s" r( u9 {1 E' o* T% Y  }             else
1 @* F# f5 D+ S6 ^9 f             {
7 b) k5 A/ W( w3 l0 S  B% ~# {                 result = x / y;- T- v( {  r; I/ f" ^5 q
                 break;7 i7 E9 P4 U$ E- F+ z: P/ D* d
             }
( }4 G" s7 ?. o$ ?. O$ F! N       default: , a  R0 U( J: Y! S5 m( z4 V
             printf("Bad Input.\n");
" V  r* @* D& z3 i             return 0;
, ^+ J7 ^4 F6 k9 n    }) G( ]3 j4 n4 Y
    return result;1 r) I5 h0 @8 B1 z
}   
+ V1 H$ w. J" m9 h
# g5 p) V" s6 `) g' P8 T0 ]float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 y* b4 s5 E9 G6 g/ R{
5 Y# i* r& \6 a9 y, {  `    Stack optr,opnd;
/ I1 e# b; c4 W    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;( u! c: y) R  ]9 j1 m
    char c;: h- f; j- D! H" Z( o, T
    char buf[16];
- G; Y; s9 }" Y. }. Q# l    int i=0;( Z! C' N: p, D! U% Y; E* ~& O- \' b
    ( A# a& l/ c# @
    InitStack(optr); /*用于寄存运算符*/
% b5 L0 c$ C# D4 `: A7 a, ^    InitStack(opnd); /*用于寄存操作数和计算结果*/
; F2 a* I$ ^1 |! ]7 w    memset(buf,0,sizeof(buf));
; ]% Y8 [! D0 E. o% n7 O" G    7 |% L! R! y+ u$ e: k
    printf("Enter your expression:");
  R/ m) X6 C* C# k        " P4 m8 v' Z7 E) @* }
    opr_in.ch='#';4 e5 D( K; _3 N
    Push(optr,opr_in); /*'#'入栈*/6 Q7 n1 C" F( l. I) r  P/ f( @: y' Z
    GetTop(optr,opr_top);; T1 f$ n# `) g% t
    c=getchar();8 D9 r* k7 L/ p+ p4 t+ \
    while(c!='='||opr_top.ch!='#')
# |- G( o4 k& i; l( U' c9 k" y; O" X    {4 ?) k! h; \( a4 H( {; h# z
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/, m; U, B* B% ]. r
        {( g% F7 F$ ?' f: [" b
            buf=c;$ h7 |7 [# ^- A4 D
            i++;
. F8 h& D8 i5 m8 X) Y            c=getchar();
7 o9 _3 ?) e8 v        }
7 ]" M0 `( G1 Q9 u: o        else /*是运算符*/
3 d8 s+ e0 u5 V2 Z% u        {4 P8 R8 X0 a5 ?
            buf='\0';
( P  Q- d: f' x; u( H" z9 [% ]            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
. L1 D; H& e3 ?! {, j) e; {, @( t            {
8 s0 d2 o) T6 ^4 {# y- g5 w                 opn_in.data=(float)atof(buf);
& S) d; F4 w" t5 H+ O5 N; e! g1 C                 Push(opnd,opn_in);& B5 r4 z1 b5 Q+ k; q7 A
                 printf("opnd入栈:[%f]\n",opn_in.data);
2 \" r% ^. V% b3 f; i$ ?                 i=0;
% W: m; A* _) c$ _4 O  u                 memset(buf,0,sizeof(buf));
% t9 U. s+ R% [            }
* p& t2 t9 q  a, a- l            opr_in.ch=c;
  r3 i) W$ K' x            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
  m, w) R9 L: R5 q            {
7 X) R, D7 ?# o# a5 z& q                case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ }" u; c- z' L9 e" Q                     Push(optr,opr_in);
: _( O6 E! D0 }) h                     printf("optr入栈:[%c]\n",opr_in.ch);
& j: O8 S* \, _9 j                     c=getchar();
& o8 l! S; Y; Y6 X; K                     break;* B# y) f4 p9 H( o4 ]9 k+ i
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 G. k& p" J, z! Z) F5 X0 q
                     Pop(optr,e);
6 W$ ~3 r% m: _3 ~8 z. i8 v                     printf("optr出栈:去掉括号\n");' H3 a$ Y2 K5 e3 C
                     c=getchar();) e  o5 [5 ^* L' ~7 v
                     break;2 D7 g9 F# o5 y. l* C' u5 F9 ~
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*// c  v; S6 S/ Q) @3 p
                     Pop(optr,opr_t);- ]) t+ W# w$ E/ V) a
                     printf("optr出栈:[%c]\n",opr_t.ch);
7 C* u/ z8 C( u8 h9 b7 T( B                     if(Pop(opnd,b)<0)
% M3 w" z( g- B' [                     {
5 f+ Q  u, w0 ?2 o) V                         printf("Bad Input!\n");
: q# u5 _3 B) F8 c/ S3 L                         fflush(stdin);
1 f  V; I1 Y8 Y; R1 L5 t- @% j                         return -1;
0 i2 ]" B( a3 I8 j. ^2 I( j9 E8 g6 p                     }; k8 O1 i  e% B. C
                     printf("opnd出栈:[%f]\n",b.data);
0 @4 N3 ?3 _8 y3 C; j2 R                     if(Pop(opnd,a)<0)1 J  l. e! c6 R6 M) `0 t
                     {
: y2 h/ y5 O# r) ]* o. U! d9 E& G                         printf("Bad Input!\n");  F  |" m9 {8 P0 B( i% j
                         fflush(stdin);, Y' {" J! l5 R3 g! ?$ F
                         return -1;
( @' X. I+ z6 a# T; ?* S7 z, M                     }
7 @7 m) v0 q$ I% e                     printf("opnd出栈:[%f]\n",a.data);
) C: _! Z$ m0 g7 K/ A- x                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/# v6 K* T2 g" Y
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/5 V3 V( Z& B9 F
                     printf("结果入栈:[%f]\n",opn_tmp.data);9 {3 l/ p' u! Z  J3 c& K! o, \
                     break;) m& u; c# u3 u1 o. Y7 v
            }
( n/ ~- t- s, X2 R, u        }
* t. t+ h- x# q/ P' ~( n. o$ l: w        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
) q/ w, N) J3 D7 J4 S) M$ B    }9 c( i2 e; G$ v
    GetTop(opnd,opn_tmp);
% R  n% G/ S6 m6 H4 m* w" G    DestroyStack(optr);0 U: }$ j, ^7 v5 R: N% u, w6 c
    DestroyStack(opnd);
2 [$ E: }# g( ?- ]% N; d    return opn_tmp.data;
: U. i3 h, c# d& M0 {$ e}! }' m% v' G' S; q) D' X
8 _& n8 Z* g. J, b
char *killzero(char *res,float result)" x) K# \6 v4 a3 I  d6 m
{
5 V( w3 n" e+ v' G) t8 y    int i;
; u- Z9 r7 q/ U2 y
( E9 b( o2 o! E6 J    sprintf(res,"%f",result);
2 p, d2 b  g, S# J5 _    i=(int)strlen(res)-1;
4 I0 o  w4 d+ ~    while(i&&res=='0')+ Q$ ?! ~* A! r1 p$ c+ u2 H
    {" r% D) Y# h# f3 Y$ V# {
        res='\0';2 N% H, M; [% p/ n- e% J- ]
        i--;5 Q- f8 Z( T' F, k6 f
    }2 V* d9 A6 p% \4 t
    if(res=='.')
; r  Q: \  f: G2 L- A  {        res='\0';
  K- L3 K3 b4 v/ Q    return res;6 K. O% [, F, B1 W) O. {  F
}
, ^9 c1 U& i' [* Y: Q2 U0 T6 h* @4 S8 l5 ]5 G  X! M
int main()# {9 N4 K% H5 e* F4 W* p4 ]  S
{3 A/ j5 Q' O4 G5 `$ f
    char ch;
& i/ c3 W8 n- ?9 T9 y3 y+ O8 p    char res[64];
& g7 g2 Z3 `9 x1 B    float result;
& @4 x4 G3 k: {, D  i. W# @2 Z: r1 B8 x    while(1)
8 D- I/ `) g; d) B    {0 h+ J' d( _  C/ ?& o" h, @- @
        result=compute();
. c. G. _  p% {: g3 a        printf("\nThe result is:%s\n",killzero(res,result));
# f9 p: h: F/ y        printf("Do you want to continue(y/n)?:") ;/ e2 v- p4 P+ b1 i/ E" G
        ch=getch();0 {# @1 t+ r) k0 V
        putchar(ch);) l9 L8 |- U/ F( x7 Q
        if(ch=='n'||ch=='N')# X" ^& z% W  I2 y2 A5 I7 T
            break;
6 U6 I4 a! i) U        else8 U3 D$ C1 x% a3 x* z* y1 `0 t) x3 S# ?
            system("cls");  G2 y4 z5 F  U$ R
    }
4 J( K# ]3 @: g! w" U, k: O    return 0;- z1 y( S* t: r' E( M
}

' W; |" |1 H: K
3 j$ A4 v* z" e8 O2 g[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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