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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
! B; u% e$ f  L4 a程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=3 s0 B  I7 ~0 e" O4 }
/**************表达式计算器************/
; l0 U# S$ W) `8 J#include <stdio.h>7 H2 v! i2 w' \9 }, v+ E
#include <stdlib.h>, S& c# ~# e& n' I) T
#include <string.h>1 N2 X# L$ r$ c! `
#include <conio.h>  ?0 W7 l& F& z  q) `
#include <malloc.h>
, u4 U2 m" g" S1 I$ P5 J0 E2 x% t/ Q% h
#define STACK_SIZE 100
* _/ O5 [+ U! R+ P: u: Y' \#define APPEND_SIZE 10
! Y. `7 u+ T% D3 |; A( M# {+ ~4 e: l% D. s$ V7 f
struct SNode{
% ]: l% X- o) i) ^    float data; /*存放操作数或者计算结果*/
+ O5 w& U1 _( E& W5 n, w9 ^* H    char ch; /*存放运算符*/
  e9 ]" W( z7 W) R' ~};
) c; o* a- @. a; _5 q" d8 z( @: R; d' I
struct Stack{
- R4 j) k4 R5 E  J9 `1 X$ `    SNode *top;
% {3 J' h# y# Q4 X1 Q9 M6 [$ |! s    SNode *base;8 F( i; G& E1 n. S: K0 X
    int size;
/ g2 V; I( g( A4 w};
& x) V  h2 W! L
) \' z% A* E% e. P2 S; O3 g/*栈操作函数*/- s# [6 z3 j) l! R
int InitStack(Stack &S); /*创建栈*/6 c: h! Z+ N' k  n- o( ]9 x
int DestroyStack(Stack &S); /*销毁栈*/
1 ?$ Q: O. P, O1 e1 Y1 eint ClearStack(Stack &S); /*清空栈*/4 U% _1 J! a) t
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/% N3 m1 M6 _. T5 V+ l
int Push(Stack &S,SNode e); /*将结点e压入栈*/
( z, u8 ?) e3 ]' u  E) X2 sint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
; T+ }! H6 a/ e; Y' D! J
  F. E& R$ R5 h( q2 C4 h5 k5 v/*表达式计算器相关函数*/
; f5 F( `8 n. ~4 Pchar get_precede(char s,char c); /*判断运算符s和c的优先级*/, e) l$ i% T1 `8 e, ?
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/0 p8 `5 u  s. q3 K4 m8 R, P
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/# |$ l& O2 \+ m+ Q* U! i
float compute(); /*表达式结算器主函数*/
+ ~8 y+ F% P" a& m, y0 h& pchar *killzero(float result); /*去掉结果后面的0*/
6 p9 C! D0 O9 g5 d7 ]
7 q1 s4 j2 z/ e0 gint InitStack(Stack &S)8 P$ Z$ m, I% I' _  l9 f2 q
{2 p- E) _9 n3 r+ j7 @5 O( ~$ k
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
7 N: P, j+ {$ j" p) W    if(S.base==NULL)
) f9 ^$ H8 C$ i5 ~- w- P    {: `/ ~, ^3 p  M3 K$ S: ^
        printf("动态分配内存失败!");
- v0 f& J2 D) G( l) g        return -1;, ~: G6 o3 d% X
    }& Z* y% S: O& E
    S.top=S.base;$ b3 E' l$ u4 N1 r, r
    S.size=STACK_SIZE;
' _! \( R0 x5 S: \3 z' G3 m    return 0;
+ ]' n0 E1 Y: K) ~}
8 V5 g5 s* ~" _7 @/ N& J: X+ t) W+ o: p5 Y6 y
int DestroyStack(Stack &S)9 r; w1 O7 @3 \- _2 N7 w0 b: Q/ V
{! o! j+ F- S* b9 B8 D' L
    free(S.base);! j9 J# q( p( n
    return 0;+ W' V/ Z- a4 Q) e
}
2 {" ^' v8 n% R) C3 G2 ^& x- u2 f( p1 G' _
int ClearStack(Stack &S)
, c, P1 k7 w; _% U% {{
/ X! i0 O; v$ \    S.top=S.base;& I* a% t' d( z' H& ]+ c
    return 0;& C3 Z: Q8 }( d+ @9 E! Z) V$ c
}& F8 l% }% T+ l" o2 N- G& x
- K/ ^2 _- w) p. m
int GetTop(Stack S,SNode &e)- ]1 o9 k( `4 J( Z$ i! Y3 J' s+ z
{
% ~8 K, c3 M9 k: m6 q3 H6 Z    if(S.top==S.base)' o' {, Q# c) m
    {
+ ]" E4 b- }* ^+ C0 }: e        printf("栈以为空!");3 H0 u# u( ^, S
        return -1;- }9 G# Y; V( W0 s7 P8 h
    }
# T+ |: \% F1 V2 E* c) t% E" a    e=*(S.top-1);2 @6 E: p8 u4 x
    return 0;
) |, N4 v5 I+ D& B& \/ E0 w* V}; |/ ?3 z1 `. `& F1 Z" m

# u# r4 |/ N. [% y1 ~1 `7 q% z2 Nint Push(Stack &S,SNode e)
6 m9 y" L1 r+ j$ j{
: e! i; X) C* h& @5 o    if(S.top-S.base>=S.size)9 S# F, H+ h- S/ A0 @% I+ H
    {. ^: \7 [! O$ n  x8 a) Q
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ P* c$ k& e/ o4 \3 y9 J
        if(S.base==NULL)7 X- s5 N# p% O( r/ ?4 ^
        {3 u1 y3 b. i) @( w% N9 M
            printf("动态分配内存失败!");
1 N, h% t( h( I6 I            return -1;, R& S# o, f. C& k" y: f7 O9 i  v
        }, @3 ?" o' c/ }+ i7 J
        S.top=S.base+S.size;
% g. d  d# h2 e- C- K( h        S.size+=APPEND_SIZE;. h- u1 t5 U$ u, U+ b7 n
    }) T8 _( A1 Z. ?+ w
    *S.top=e;
+ x' V. J: X0 X& ^    S.top++;& I- M5 }) B* k. y" N2 U  v
    return 0;
' i& n1 U. v) `0 |2 n}
* E% s4 Z/ q  N, ~$ H7 H
/ `9 R3 J, _* S3 p; d8 A4 Y  lint Pop(Stack &S,SNode &e)
, D2 |% X% ]' T: y4 \{* y* t' M  C1 j7 e3 g) B# Q$ B+ ^& p
    if(S.top==S.base)! @1 B, a% p. G  Y' A  j
    {/ R& n  j  C+ {' {+ S! O1 L1 Q) p
        printf("栈为空!");% W: A8 L+ s& N3 {9 T, P' L
        return -1;
7 {9 k! y1 b' h" t2 \    }) q' e7 c/ t+ r+ I/ p
    e=*(S.top-1);
8 g! |' j% Y6 W# h+ j    S.top--;* R# s" J, l" b/ I' e' `5 l/ S: K
    return 0;
4 L4 x& k$ u8 ?+ C6 b}
% l9 o  J+ h" C3 C) \3 z
0 ~5 V# Q/ K3 e# p6 [char get_precede(char s,char c)
" Q. x9 [& s2 y# Q: e( K{7 r: @* o! N+ O8 l: M3 Y( t; H) }2 F
    switch(s)4 D. ^7 S& q& L2 B* N' j
    {
) k/ k" O" T3 d, F        case '+':                 , I- H5 q3 l. Z- v
        case '-':
% o, c% m' h$ P* X0 ?1 M5 ]             if(c=='+'||c=='-')
( p. ]9 k& D! w. Y; c' c3 B5 a                 return '>';
! [- ]1 }7 J6 h. N$ e3 J             else if(c=='*'||c=='/')! r# |  o. i1 k% Q# d: }+ m# ?
                 return '<';- b  j9 h% F9 I6 C" x! |
             else if(c=='(')
; i  Y5 q; x% k+ N                 return '<';
6 A5 w. k) N, q; U4 |! |             else if(c==')')% y' i+ Q, E- m: H/ W6 V4 N
                 return '>';
- W3 }( w+ {$ K. R3 k% |$ O& v' `             else % S, b8 t6 I3 p0 _+ w% M# h7 P
                 return '>';
8 ]2 w' i& |- J: X4 k6 X5 K/ z8 C        case '*':
' T0 |" D9 L, a$ T& d4 Q2 v, r        case '/':
  {4 m$ P# p6 e  x; _6 Z3 F             if(c=='+'||c=='-')
4 D7 G+ g$ i( o2 B                 return '>';
; t+ i4 D' l0 ]& [7 F             else if(c=='*'||c=='/')
- `" Q% ^' Q2 Z/ p% P$ O                 return '>';
/ [/ N' {- S. N( a  e9 F4 [+ U7 E             else if(c=='(')
) o6 t1 g! J0 i: I( r% M# z3 O                 return '<';
- b- I3 y5 U$ s! _             else if(c==')')7 k+ y3 f- L0 ]# g& I( N! C
                 return '>';6 l1 o- [0 }) l
             else) k. F' t5 c/ Y
                 return '>';
# t0 }7 }. F9 a$ \        case '(':
* G6 D3 ^. V, p) K# a. a             if(c=='+'||c=='-')
# m; R7 @  [* ?3 V9 ^                 return '<';
( [; X  e+ w! Y9 M. m$ C. Y7 x             else if(c=='*'||c=='/')9 u! c1 s& W6 F' @$ I0 ?2 B9 P
                 return '<';
' y# c' _/ i1 l" a3 N             else if(c=='(')
- i. Y" M2 p8 W" u' H                 return '<';
* ~4 T8 f5 e" x$ ]% D" o             else if(c==')')
% _6 s! z( \* Q( A                 return '=';
8 X5 A3 I3 s1 b  E0 Z7 \) z             else! I2 ]7 c( [/ }
                 return 'E';1 S. k; n! Z: u! Y7 z/ _$ a5 g- c8 {3 b
        case ')':
! p/ ?% F6 A7 r2 q" a             if(c=='+'||c=='-')
4 Q# x" i) }( ?. Q: f  h                 return '>';
6 X, Y6 k1 {; x* q- N# H             else if(c=='*'||c=='/')
6 \. b( N1 m& K0 ?3 O6 V                 return '>';0 A' j0 S6 c' x$ P
             else if(c=='(')
4 [0 |) l- f' s% {: |; K                 return 'E';9 B8 a! m& r2 |8 w6 @
             else if(c==')')6 U5 q! z+ |0 w* M1 n
                 return '>';
6 ]7 G6 d, u; M0 j' c$ o             else
* ]4 s  w' X% O                 return '>';
* [% o& e9 c* A" U" U3 o$ o3 ~        case '#':
# ^  m" u& @3 i* M, `% k' X: r             if(c=='+'||c=='-')
5 Y7 t  V, E: N                 return '<';
  V5 q, H0 ~7 c! \3 e             else if(c=='*'||c=='/')
/ n/ l% A1 X/ a. i2 D' |2 W) K                 return '<';4 Q' L4 [9 }, M& Y3 S
             else if(c=='(')1 [* X* C; b" z2 y6 W1 |  M+ X3 }- n$ M
                 return '<';) u$ L' A) d, h
             else if(c==')')+ Y: F$ S0 `; m0 D
                 return 'E';
8 j) l7 o. v( r& U- f             else4 P; i9 |9 `" k1 Z% x$ r; S
                 return '=';/ Y" o# ]- O) m. W7 m& |+ ?
        default:
" `; t. w/ ~6 m- a& i3 p# s             break;
. t$ ]; T# {3 H2 q0 C4 J, K    }- W0 }. e: o8 d+ X7 x1 l. }1 P4 E
    return 0;   
! r# d6 ^( s8 {& h8 y( B5 h7 K  \}/ p$ q  N: T$ K6 I  {
0 q# Y. N& @. ]
int isOpr(char c)
0 {# w4 @% n5 `4 u& G% G{
: |. _# M9 m" o( v    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
. s  _5 W0 @' K, [        return 0;
: |4 ?& }  Q) {5 ?2 }$ v5 w    else
& g# L2 _% c! q        return 1;
) [3 V( B" d9 i  a4 P}5 x: u- C$ }8 w# P% j# F2 _
7 T5 ^5 V* e3 j; A5 g
float operate(float x, char opr, float y)6 ~5 t8 v& Q, e: C
{" g; ^( V6 _1 U  V, I2 Z
    float result;
: P3 d; S# p( k0 o, {( `1 f    switch (opr)
# e* f, ^7 }5 x: t+ n    {/ `- u  b6 b% V% b! @) v5 U& r
        case '+': 3 }9 Q; p7 P* ~6 P1 r/ l. O  f; C; R
             result = x + y;  e5 r, N, _6 N, @- `( [' D4 F3 V
             break;* [) x: E. q% a2 u0 g0 V- ]' x
        case '-': / ^* B2 C# q/ H* r0 }4 B
             result = x - y;
. q- [7 J6 Q. h             break;/ j' a7 I  X$ I1 G; H6 ^3 {: h* S! t
        case '*': . P0 v3 h* N% F6 O' f- \4 t
             result = x * y;9 N" P) N; T; C& D: l0 _6 Y
             break;
: j/ b9 b$ n: n) n2 n) X. a5 t8 i0 y1 {( E        case '/':
/ B& F/ C' Z: c- G$ i             if (y == 0): N  M4 O: g, U3 ~% t
             {
4 r/ @& ^- V; e, t3 t# e                printf("Divided by zero!\n");
% }0 {! _% h2 C) ~4 G5 b( m                return 0;/ u! ?) v& P8 S8 X* j$ X% Q
             }* u8 f* z; [  l$ k6 B6 i
             else
$ n1 t8 \% c" e% y! V- G             {
5 T. j) m8 m6 i  [( m                 result = x / y;
9 i% f& Y8 M6 B% s: f                 break;* ^& x6 T" J/ r; @8 Z8 B8 {
             }, n: I  m3 j1 C% R$ r; V
       default:
1 {$ z8 C/ H; a; i             printf("Bad Input.\n"); & w* o, x2 w! g2 `
             return 0;
9 a# @3 m- K2 \" M! r# {6 j    }/ A1 Q4 e% H6 ]: D
    return result;
# P2 d' d" O: W}    3 Z3 f% P; z% U% c8 T
' P  v9 i& F5 Q. e4 g; j8 t9 z
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 {! K4 C& H& A  F& r{
& G  o) N) r+ `    Stack optr,opnd;
: ?; J/ w  N' Z% |" S" ~    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;6 G% u/ t/ K* J9 ^. I
    char c;" l3 m/ e- L3 G6 N: l# W
    char buf[16];# C' I$ z" q( r
    int i=0;
9 O/ N0 i" `) s' ]   
4 ]+ D# Q5 |' m    InitStack(optr); /*用于寄存运算符*/1 j  Z* W! l5 s/ H" I
    InitStack(opnd); /*用于寄存操作数和计算结果*/' y9 o6 P  V+ m/ s4 |
    memset(buf,0,sizeof(buf));
  g) G3 }+ x/ w: u5 A. O; {( }    ! h5 R* ~' ~; d- N$ r( ]4 U: B" d
    printf("Enter your expression:");
) P: Z: C; E5 S2 B  E# ~6 I- o        5 v1 D9 R1 w  g8 @; e4 v
    opr_in.ch='#';
$ U/ Y" L! c  }6 P% b+ _( ~1 i    Push(optr,opr_in); /*'#'入栈*/
& Y  }! P( q2 [  S8 b' W! }+ u3 u4 |    GetTop(optr,opr_top);
2 Y2 J5 a* R- _! W. l1 Y    c=getchar();/ a! }. U4 F# W+ [9 a* C, T
    while(c!='='||opr_top.ch!='#')
# H$ b+ k$ z# ~( q1 [5 v4 R+ o) M    {
, N$ k; c4 Z$ C& x. [8 \% w. Y        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
: C9 y+ m* f2 f* }' j: I        {
/ m$ B/ N. n- I4 _( ^            buf=c;
' U  z) [! C+ s            i++;
' h- X7 q4 ]7 X, P& @( O            c=getchar();
; H) _$ [' Q0 p2 [4 {4 q6 ~, p        }4 P" h. y/ e! ]; U
        else /*是运算符*/- e" V, l# C" {9 B4 G# R; x
        {3 e! j) T% [4 h
            buf='\0';  F8 [# W/ P" m% m. v# D
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
6 Z/ C8 g: h% K            {4 A& I( B+ [9 ~
                 opn_in.data=(float)atof(buf);
* u4 s$ r% N1 R: K# s3 j; x# {                 Push(opnd,opn_in);, S9 T" }, F% E; E& i# {- j; [
                 printf("opnd入栈:[%f]\n",opn_in.data);
' X) y- Z7 I* I8 Z8 ?2 [8 s                 i=0;2 q9 g$ W% p, {$ ~: d6 h) }2 N) t
                 memset(buf,0,sizeof(buf));9 i5 v9 N: x1 B; ?
            }7 V3 }2 X) i+ C! R6 h) k/ N
            opr_in.ch=c;
0 ~8 L, l/ j0 ^$ W, I  F            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
& H4 L" N6 g" h, m- Y9 n. V  \            {
; e5 U2 V; s/ N8 D; s) n+ D: H                case '<': /*优先级小于栈顶结点,则运算符入栈*/4 |  ^6 U: E9 [/ g
                     Push(optr,opr_in);
5 I! D) v! I1 S0 V                     printf("optr入栈:[%c]\n",opr_in.ch);0 V, T" A% `' F' _% e5 b, c
                     c=getchar();
: ?' Z1 W' W( ?                     break;! W8 E6 m- k$ i; B8 M" k$ x1 U) l* \
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
* G7 t' n; V+ `8 Z7 d$ U, z& w                     Pop(optr,e);
& A% K- |; M3 ~. I3 y: W) m+ X8 n                     printf("optr出栈:去掉括号\n");
& T+ t, R9 D! b5 T' V                     c=getchar();
( Q5 r% w! |4 U& ~                     break;
8 F# O$ |5 ]6 J4 n5 g                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/: y6 Y' {/ @) p% ^# F
                     Pop(optr,opr_t);
! F( x/ C9 N3 {7 \0 h7 k                     printf("optr出栈:[%c]\n",opr_t.ch);
  ~; m" G3 w8 X8 E                     if(Pop(opnd,b)<0)
1 F0 Y5 C8 d% }6 R8 c                     {
/ P! X4 m) a3 w( e# E. Q  X                         printf("Bad Input!\n");
5 K1 }! m6 W4 H% A2 F7 T2 ^                         fflush(stdin);
# ^0 ^' S$ ^+ [                         return -1;
5 l9 m3 h% K1 Q; Q& V2 @7 j                     }
) i8 c" g* }- |8 T2 }- x# _                     printf("opnd出栈:[%f]\n",b.data);0 ]% `+ p7 M$ \0 H, b
                     if(Pop(opnd,a)<0). e2 R4 \% W6 o5 a; N7 Y
                     {
1 r" Z, L! m8 [) Z+ b                         printf("Bad Input!\n");* j7 O: N' L4 T  z
                         fflush(stdin);5 V$ H$ M  W: A, @. Z# S. [5 U" [! j
                         return -1;
( w) Z# i0 Z/ c                     }
) I: e/ N! p- P8 v, a5 t                     printf("opnd出栈:[%f]\n",a.data);$ a& L7 ^/ Q6 ]( b2 F7 ^
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
& A' }1 F1 \& o0 K                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; Q5 U5 |6 P. r7 E                     printf("结果入栈:[%f]\n",opn_tmp.data);* u+ n. o9 ^4 ~3 [2 q: ~# p4 j
                     break;
/ @( ]. e- ?. i            }; ?: {8 N5 G. z4 a! N% `7 g" D9 z
        }1 H, e& Z  o1 D5 i7 p
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                3 M9 V: E+ z5 \3 E8 o7 r  W, x1 q6 N
    }
* ~0 E  }1 P$ ]- Q: D: m% F* S    GetTop(opnd,opn_tmp);
; Z( V- ^5 C' d' `0 _5 e% O    DestroyStack(optr);9 _9 j" ~# \: X; ^, M7 p( g
    DestroyStack(opnd);6 E" j+ w1 ?: ?. X3 |+ k
    return opn_tmp.data;( C! S7 _( U6 {8 h% H
}
( ~% S/ Z, P6 [& X$ a5 j" P0 m7 T
char *killzero(char *res,float result)
$ z, v$ l7 v1 G, l- Z) i{
. w* O. o* |9 J% M9 H& c  P    int i;
, E9 U9 B, B2 S4 t# y- S# o( Y! ?* T$ \! |: P
    sprintf(res,"%f",result);
7 M  z0 G) @4 X  U    i=(int)strlen(res)-1;: x8 b. K* p% |
    while(i&&res=='0')
3 D; o2 T( @; |( {7 ]2 x6 k+ ^    {) g$ ~7 i. c1 |4 A8 ~6 ?4 H6 W
        res='\0';
; ~3 K9 v3 R7 w+ _5 _        i--;% g9 {4 u6 E! z/ j: z
    }
# |. W: v: ^) B9 Q; V& a+ I    if(res=='.')4 d7 t8 d& Q% t* |9 L: C
        res='\0';  D. V* n. F, }0 Z6 T3 u; y! p0 G* h; v) O
    return res;
; i$ X$ ]& Y* z1 w* F- H}
% K* T8 d9 @4 x' k% ?( o. ^0 R: ^$ L# b8 N' s0 ]8 c( x
int main(), u. P* A- D) S% C
{& q9 w8 c, }9 P" F9 i8 `0 a5 [+ |
    char ch;- w$ }1 |! M& f; }
    char res[64];9 ~, J6 v* p& c
    float result;
3 V, i) e1 e6 H/ X" R7 w5 Q) I    while(1): D  m; c+ _/ _8 p9 ^2 {
    {
6 V& W& A4 ]+ }8 ]3 Z, B" m6 E        result=compute();) P) l$ l7 K- R: X! \4 j& X4 `
        printf("\nThe result is:%s\n",killzero(res,result));
( L; `; r* M2 `, v        printf("Do you want to continue(y/n)?:") ;' E7 i! O" @% a* Z% H
        ch=getch();
6 q/ u+ l/ L5 ]4 J1 O1 z        putchar(ch);- `* O5 |3 N  [: ^6 ?
        if(ch=='n'||ch=='N')) G6 {9 @$ F4 {% I: ^& f
            break;9 v2 S8 W7 t; t" @
        else
) y# q& t* @% a- m            system("cls");6 r" W1 E+ p; q5 C% g) E
    }
3 ]7 X0 k4 F8 t! R( c9 N9 |+ o    return 0;1 w3 O  B+ `" v2 ^. y/ N; u% O
}

4 s7 _7 j# p: ]" a. j' s, n  c' g5 O% ~) y- b* I1 r0 k
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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