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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5 O; P! F1 X1 l7 [- [程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=2 s) ~( G2 [/ u9 t2 m( k4 j
/**************表达式计算器************/
* E4 T0 M/ I. x7 X1 L#include <stdio.h>0 s, f6 l/ U4 @$ _# t6 l
#include <stdlib.h>1 i* G. X* H( k: K) c7 E" f
#include <string.h>. U9 ]2 R7 |% _7 g
#include <conio.h>" T' A( B/ Q- S4 `. x# _
#include <malloc.h>$ r- X5 v7 k: F, X; v7 v
, _( }/ L4 p6 ^% r& h
#define STACK_SIZE 100
" l! g& Q6 H/ x8 K#define APPEND_SIZE 10
, x# e& o3 z( j* h5 r' s( {. D' M) k% C7 ~
struct SNode{- _8 b5 W8 t; ~0 q" _+ ^
    float data; /*存放操作数或者计算结果*/
: q0 A4 y# m4 E$ q% |: w    char ch; /*存放运算符*/) u: F9 ]( t; N% p+ [. i/ I
};, C* w6 U) f! y/ o' h9 c6 C; |6 @
# i( x/ G& J3 M  H8 N) |$ [
struct Stack{+ L2 e/ F. o4 N& q' j8 s2 p" A, L, l1 L
    SNode *top;% c0 M  G5 x6 f- ?0 [; N' i8 V  u
    SNode *base;& @. d! B+ x! o- f/ F$ x5 Q1 |
    int size;0 A2 v! c% K) v5 _9 M8 n! L
};! s# s/ B7 I1 w  u2 u! f8 n

) j& E# o6 @' l/*栈操作函数*/6 E0 _4 ^" p; R, @" j/ p: s
int InitStack(Stack &S); /*创建栈*/
+ H; V! L) m# R3 k9 ^int DestroyStack(Stack &S); /*销毁栈*/9 T; a+ {5 S% a% H$ _6 p
int ClearStack(Stack &S); /*清空栈*/% \' R9 p+ ]# Y  Q: B9 v- @
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
" s; R4 v9 c+ q* w% i" Q* ?int Push(Stack &S,SNode e); /*将结点e压入栈*/9 g3 D+ \" Q) @% Z2 ~8 T2 m9 |/ m/ h
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
# _% ~. h2 y+ W$ B6 x" X! X& |1 f- ?5 n
/*表达式计算器相关函数*/
2 j8 |$ ^6 P+ {7 y& `0 H9 W; }, Mchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 D+ }5 C( y( E9 q+ Q3 c1 Oint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/2 v! W5 ?4 L8 j( }2 a
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
3 s! ~! B. f' a* `4 G1 W5 wfloat compute(); /*表达式结算器主函数*/
/ d, i  @: @% o* J$ tchar *killzero(float result); /*去掉结果后面的0*/
: x/ ^2 l7 h/ k# I9 e) Z) i  E& h+ H  H! W/ g
int InitStack(Stack &S)
* T2 T+ v6 L5 b+ l9 ]( N6 v{: d! R" O: S; p, ?
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
  l- j, ]" q4 {8 i7 L! W    if(S.base==NULL)& K% x0 j, m% r) t! Q- @& \- \, x1 i
    {$ g. d: |" R# R% a
        printf("动态分配内存失败!");
& S! [0 H9 U/ ]$ e9 s        return -1;
5 A0 y  j& Z9 v$ k# u+ n/ Z. o) x  i, b9 {    }
' a6 l  o/ s% U7 f    S.top=S.base;
7 L( ^( m1 W) E; }3 `* G    S.size=STACK_SIZE;$ p0 F/ F' \& w" @! q& W
    return 0;  a7 F/ ?" p  ?
}+ B& `2 {% t/ s. ^: W

& X, ^4 C" h% |% F& E* M% G! gint DestroyStack(Stack &S)  m- H  M  e! ?' K. X" Q% j: X
{
" h) r. P* ]0 ~0 b! \2 u    free(S.base);: y7 g6 _9 \1 R: \1 {2 o" K+ N
    return 0;' [+ R8 c* W. n. V& G6 W& S: n
}/ a# D0 [% f5 Z

& L( \* C9 B! Lint ClearStack(Stack &S)) N3 i$ Z% s# E1 }- T
{
% u1 q# a$ [2 T2 d    S.top=S.base;0 k" Z( v  ~) ~- O
    return 0;
% C' \4 N; z3 P5 y0 g- D}
( V, |" q. m1 n, \
2 N8 C! E8 {: ?3 Z0 _& zint GetTop(Stack S,SNode &e)
$ h, o9 ]' R3 ]' f, }% w{8 P% p0 N3 U" a
    if(S.top==S.base)
" h5 h% C" v2 {3 [; A    {
) z2 x8 B! ]) ~        printf("栈以为空!");( o( n- Z8 B, E
        return -1;
+ C9 _: u$ v+ N  R    }
8 `4 y; Q/ z, M. [    e=*(S.top-1);
, l7 `) J# v, _# ~2 l    return 0;
9 ]  b( A& S7 h  K7 s' O" ~% h}
$ x0 j( q( }. {- G5 |- p! W* v; W) j9 r2 Q
int Push(Stack &S,SNode e)
1 Z/ @) g/ b0 E" E5 k{! e( {6 V! g+ k9 h4 x! m/ h
    if(S.top-S.base>=S.size)" l% ^. G- G  I# i, |
    {: w* Q/ k) b* R" ?0 ]! Q
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
: O1 Y( p5 c9 v& n; E        if(S.base==NULL)
! c5 s" M# @1 r! d' e/ p        {
! a  O7 g) }# h0 g( w( B& M/ \            printf("动态分配内存失败!");
; [, d; p' w) D, a# i8 }            return -1;8 M5 z0 V" M! V
        }
9 o' R7 G/ S& o. D' A( m        S.top=S.base+S.size;& a9 g; w' \' I3 t- v/ v2 A
        S.size+=APPEND_SIZE;7 a+ a2 T" `4 _
    }
/ D' v- f' f. L5 ^    *S.top=e;
3 V0 y1 s( W6 j7 r( G! F' f1 G    S.top++;
+ r8 C: g+ a" w5 P. a4 F    return 0;
! m( I9 p% i# D' o2 g8 A* H}' A* Y, b) {9 e* E! l
2 y+ d$ I, _( c; c, u& [7 K$ T
int Pop(Stack &S,SNode &e)$ Z' v+ U! y& n' K+ }
{* I/ {; I- w: t3 u2 S
    if(S.top==S.base)6 {3 ~& L* r) u$ _0 W% w- R
    {
( x# f, P8 m; A, r        printf("栈为空!");
$ R1 S4 ^/ j' _6 p        return -1;
. F/ ]! r( \, D$ Y( D1 d: }2 s    }
' j( [; {2 s; i& d; F9 p/ k    e=*(S.top-1);& R) D& X3 y# N" `) f3 o" ~
    S.top--;
4 j6 q* ?3 }) L    return 0;
6 K7 q+ p1 Q6 `" f}
0 [  }( D; C* p" w! U3 J
1 A9 j, M' [' M2 Gchar get_precede(char s,char c): R+ _5 |: n5 i
{; T; Y  S5 L" {9 h
    switch(s)0 p! W1 k4 R, Q0 D: X. ?+ b5 f9 I" S
    {
1 H+ V0 F4 M: U( f        case '+':                 - H& \5 c4 i# M9 s1 q+ S& ?& _7 q
        case '-':
6 z  S! F& _. @- L8 R+ Y             if(c=='+'||c=='-')
( [0 P3 P/ p5 f% O3 U" h0 Q                 return '>';
7 M/ j8 p9 [) z' w4 X, k" a. K             else if(c=='*'||c=='/')' Z' s, ^$ i& V( [9 L% v" `  V
                 return '<';
# n3 x1 m# Z# }             else if(c=='(')
' k: [0 ^# c3 [" y; o( Q* r                 return '<';9 t+ _( i" _7 G* z' G
             else if(c==')')$ m; B: j* Z& y3 ~/ O
                 return '>';
' a9 J! m* C% A5 x             else
" p2 e2 S& h! |5 H' V2 m0 }( j                 return '>';
& {( C$ I2 m- l        case '*':
4 T0 `8 V0 A4 v4 R& ]* {        case '/':
) G7 ]2 m0 B2 ~. l: ^             if(c=='+'||c=='-')
6 U! q# X/ u1 @5 S. K                 return '>';
( n# c; U6 m, N. {. G+ u6 d             else if(c=='*'||c=='/')4 D. X' ^$ ]* g. X7 r, w5 c7 d
                 return '>';
0 T/ U# n8 Z9 |( ~7 b0 d# I. E             else if(c=='(')
4 h. v% p6 H' \" C1 r5 S9 Q                 return '<';" O5 U/ t# H$ A1 \9 L, o* Q
             else if(c==')')
3 E1 J$ Z  p, l/ U% \% W                 return '>';
* S' H& h8 s& o             else
9 h+ S- M) K) |0 j3 p# b7 p# g# l+ t                 return '>';
& Q# I# Z3 y. K* E, S        case '(':/ w5 I: p9 L) A: Q& _* N
             if(c=='+'||c=='-')+ O" x2 c1 E. i% n
                 return '<';  M; Y* ]# v; r9 k# n( o% E
             else if(c=='*'||c=='/')% \" J! S& E) s. D/ d
                 return '<';
& C# O9 B" W# U- ]9 ?( O5 y2 B             else if(c=='(')0 {2 a5 W2 t2 C: _& h5 [' _1 G
                 return '<';
; g7 p: F7 z; q1 f, x  O# T! k; h* i             else if(c==')')
3 ^- f. s) y7 d) \6 s                 return '=';3 b' k- s- l6 e- C. f7 }' M! R
             else0 e- g: D8 V2 ^* U
                 return 'E';& `' C6 I$ H/ B6 m
        case ')':
( ]# O. s6 c3 N, u9 l, l3 W# y             if(c=='+'||c=='-'): Y% ~! s1 B  l' d$ S  l8 U6 L
                 return '>';) f3 K" N: l9 n# L  H, w
             else if(c=='*'||c=='/')6 P# W& G2 F: e! a+ T
                 return '>';- k' W1 ^3 h+ ^4 X
             else if(c=='(')4 P5 X) Z$ Q: k+ A3 R  S/ |. p
                 return 'E';
. e6 Z) {" F  e. {) S             else if(c==')')
7 u: y4 X$ u' L! J# N5 j5 ^, p                 return '>';
3 Z( {8 W$ H) W             else% e9 M1 H0 J' O
                 return '>';' ~. s  b$ X. D  _3 g, D
        case '#':8 P" D* l) U5 a' Y. H
             if(c=='+'||c=='-')" J/ H: s  a; [" s- M
                 return '<';
4 i. w+ V  S& E% N" v2 A6 S! U             else if(c=='*'||c=='/')3 l! F! M1 N0 _6 M' N; K
                 return '<';
# t! r8 M/ @9 t6 V7 ~! Z             else if(c=='(')
: a& G! [( a( e- x                 return '<';
; P0 S2 a5 T, B             else if(c==')')
9 q& g3 G! z! k( H                 return 'E';  N/ `5 y" R6 Z7 a$ O
             else! l5 j2 u% ~2 k& O
                 return '=';" P  X, `$ v2 Y5 N. N) E( X" a  U) q! u
        default:
: K, A" g& E1 X7 e- e# a             break;
# C8 p' @! D  W' S    }
9 C3 a2 D( z2 h    return 0;    8 D+ x8 H- q+ a0 V3 Y
}4 k: L. P; Q" g7 a8 U

4 a; i0 w  [9 _. J+ I% jint isOpr(char c)+ l5 a" p9 h: E8 ?- C9 J6 j) `
{
2 `1 N" M6 I' x. c' `    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
, ]1 P1 o. I* E# E        return 0;1 n' b# r: Y4 p$ Z, Z0 [
    else 0 t9 M$ s4 l+ Q/ B) G5 M
        return 1;5 U8 D) L! V! g5 k
}
) a1 D" c$ y3 q. j" c, u+ F; h' X, Z. t  N0 b* a
float operate(float x, char opr, float y)
8 ^$ Z1 }' u9 w3 x{& u( j0 T1 Q. Q" |& C1 H
    float result;
* s) e+ X+ U8 K2 l9 U! A' w    switch (opr)$ n2 S; |& j% L* Q' G: F2 G! n
    {, F' e* {) M" y
        case '+':
8 H( R: h7 C$ {+ _# C$ s             result = x + y;
5 o) H! y  k) u' q" Q             break;0 N6 B! [6 S6 _+ I) O; P
        case '-': 1 G# k; h$ V6 R+ ~( }8 J/ d
             result = x - y;  S9 ~* Z! D3 N+ v' \
             break;
8 i: P* `( r8 p, n        case '*': - o3 Y$ {, l2 _+ D' J2 ?1 M
             result = x * y;8 K6 Z) W2 t% L/ W, C  [  N
             break;2 q9 u1 U5 j5 L, h3 ?
        case '/': , t( p* D% H1 s; Q" X
             if (y == 0)
5 J" R  n3 o( x: q& \5 Q; C             {4 r) Y8 n( U  O! j' ^
                printf("Divided by zero!\n");0 S1 }6 g2 T3 |. J( a
                return 0;: }1 {% i) a1 l6 S* [
             }. v1 z$ D7 S) D- X: o4 w
             else$ L2 S; z+ d' V) T7 P" \
             {
+ q# o' o0 {  W. F4 g) r& t! E                 result = x / y;4 g6 H  _1 P0 k6 P! v+ I( W
                 break;
$ P. N5 w  F8 C             }( W& Z5 |8 s- k8 V# D: u$ v/ z# c
       default: ' S* B) `7 U- C+ s( b
             printf("Bad Input.\n"); ' C# c$ ]" F  D" V, p# y
             return 0;7 b' {) ~. d" F, q0 y; h5 d1 S+ O
    }, ^* o* Y' @0 _" f: [# C
    return result;
4 w9 o& L  \3 p, L}   
6 |" g- K( C0 ^
$ w) A; P# f) i( Cfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
5 j- b, S4 c5 r{
" j9 y% O' e- X+ W5 ~    Stack optr,opnd;
' V4 t0 j4 a7 F8 \, R- ?. e* S    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
7 u: M8 J6 ~; C( m( j    char c;
% K2 M$ d' S$ n  \1 }    char buf[16];
6 s% ^/ i/ r0 M4 F    int i=0;) F, E( s  Y/ ~* C9 O
    / p7 O& t! h7 m5 G- ?
    InitStack(optr); /*用于寄存运算符*/
/ o- j& k& ^% D; |6 X    InitStack(opnd); /*用于寄存操作数和计算结果*/; j8 B' _+ k8 ?4 _
    memset(buf,0,sizeof(buf));
8 Y! z" w# ]  X# |5 Y1 `   
3 U" e: [3 o( v4 m+ m    printf("Enter your expression:");+ _& K/ G) L' M/ q( i
        & t% I- k; O$ H2 V6 N' q
    opr_in.ch='#';
+ M: ]$ G+ C' m4 [5 e* \    Push(optr,opr_in); /*'#'入栈*/( d6 |5 T3 l0 g  K- X. O/ Q
    GetTop(optr,opr_top);
1 G% b( O% R- l3 @) K( y: o( e    c=getchar();$ Z, j* B% K2 e5 O6 v* w
    while(c!='='||opr_top.ch!='#')- c3 D# I2 b9 q0 ~- ?3 L. [
    {
  S5 f/ v% b0 y* v$ B        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
" g$ @, b4 K1 ]  K2 M4 a7 U* O        {0 L# o% D3 Z* L/ u: i; @) E) p
            buf=c;' i% p% F) W( V  o/ q
            i++;
' b% V! y3 I( w- Q/ O8 ~            c=getchar();
3 N7 G2 m9 ^6 z1 S- {2 }        }
7 G! U2 r; d5 s$ P7 m) @; n; i) c        else /*是运算符*/
/ n# S1 s" X  _$ j5 s5 p9 d        {% b( ]* O4 x- m  U% q% ~
            buf='\0';
/ t  ^1 ?, L0 Y' j            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
$ Y( P" u# Q6 ~% ~& G- M, ]            {% V3 h! `1 r9 y6 |+ @0 O/ q) V/ Z
                 opn_in.data=(float)atof(buf);6 K1 B# ~( k2 p% B% _' _+ Y' |
                 Push(opnd,opn_in);
; w0 C- a5 n& t$ r$ [  X3 B                 printf("opnd入栈:[%f]\n",opn_in.data);
: y3 v% }$ Y  a1 w  [' o% e                 i=0;
" V+ g8 Y/ ^/ c' r/ \                 memset(buf,0,sizeof(buf));% r+ B, @7 `% B; N0 j
            }
* n  B% q+ W9 |6 D6 C1 U            opr_in.ch=c;) _3 Y. ?4 x7 E* @6 a- D0 N# ^6 g
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
# ]4 z5 _% X8 e" \7 V2 S- U, a            {; d1 \, a  S+ C
                case '<': /*优先级小于栈顶结点,则运算符入栈*/2 d. F( p- {! F5 ?/ k* h: ~6 V
                     Push(optr,opr_in);
( ]6 J1 A+ G3 c- Z# G, I                     printf("optr入栈:[%c]\n",opr_in.ch);1 V* D9 _8 \/ f' Z3 z+ q7 ]
                     c=getchar();' w0 N3 q) L9 E; }; N9 D* q- m
                     break;
% h8 V' V+ `5 {! A$ j3 o                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 @" `2 _& Q) a7 D5 ]! h' Y
                     Pop(optr,e);
& A" J9 B6 S5 |- p( b+ w                     printf("optr出栈:去掉括号\n");5 N1 ?: T( `! j5 d: c7 d# z
                     c=getchar();8 h3 e& ^! p+ D9 c3 B
                     break;% W/ z( r' r8 [) {" E( }, Z) y# `
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
, j9 R6 B- O1 `8 |                     Pop(optr,opr_t);
* M' L5 O" W* x6 V, ^- A                     printf("optr出栈:[%c]\n",opr_t.ch);
! j- x9 ]4 y( Y. q! Z& I                     if(Pop(opnd,b)<0)
9 `2 I. V  k/ \1 B1 a                     {
  z; ^0 b. ~& t4 B4 B                         printf("Bad Input!\n");
# e3 K' ^1 M9 R: h8 G. M2 y3 ~; D                         fflush(stdin);
$ Y* v7 {* D6 M" r% E                         return -1;% R! v( k7 D$ K& \
                     }! @2 s! w& s, y- c; |3 L
                     printf("opnd出栈:[%f]\n",b.data);
( x8 f  \8 ]% ^! J5 Y" a. x& `                     if(Pop(opnd,a)<0)
& N' o/ M; ~8 a5 x                     {! I4 C6 A+ x  J
                         printf("Bad Input!\n");/ f- @# A' R4 e6 \7 G/ ^
                         fflush(stdin);; U4 ~2 s2 E, E; H2 N/ ]) l, T3 v
                         return -1;
+ U; i5 F+ W# |- W                     }
# M; b/ a2 i0 L/ I# e                     printf("opnd出栈:[%f]\n",a.data);$ I8 J9 g3 s3 z% ]' V4 g
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/: B6 s7 f. _. q3 |0 S* r4 @& y
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
. j9 n2 q; ]9 H0 l) O                     printf("结果入栈:[%f]\n",opn_tmp.data);
! z. [7 g, T9 @% I                     break;
+ u. z, l. K6 y: i/ v            }* m  I) p# Z4 I$ a* Y' n
        }5 Y: E9 o! G# C. V
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                2 _' V" t' z. i- ]" g2 j" F; P, J; [' M8 d6 I
    }
; }) S6 n2 T5 G& M; L    GetTop(opnd,opn_tmp);% k. h3 x( {4 n8 ~
    DestroyStack(optr);
5 ?0 N( ]' Q% s2 ?; S6 C0 D" t    DestroyStack(opnd);9 a( j2 y% |( ]; w, R$ G) S
    return opn_tmp.data;: P2 H, q* \$ f& J- U
}' K) x! e8 a/ [0 D$ R0 m. g4 x+ j+ O
; V- y# R6 W4 d- ~/ v6 _' [
char *killzero(char *res,float result)
- Q0 P3 J/ `' Z  p{
, \: W* H, I3 ~. N- S, [    int i;
& ^) N( g1 {* H
, h! `; f* T; l% W* h    sprintf(res,"%f",result);4 o+ H  n1 w6 j2 E4 q2 u7 B$ l
    i=(int)strlen(res)-1;& \1 h+ \6 F6 P, t
    while(i&&res=='0')
0 j  h3 D, \! x' E+ B    {
# d6 a9 Q2 G) O3 O9 d        res='\0';, c' U8 T( }  h6 @4 |
        i--;
4 {- o4 _1 x7 b+ B# r5 p# _1 j) X    }
& _2 d$ [& r8 B6 b) H    if(res=='.')0 L" O  M3 w) T3 o6 j
        res='\0';; C+ _/ j# @, v; w
    return res;
  {. y* N1 B0 k% ~) L}; r4 M% b1 O: g* M( Z7 Y, l/ `

- L% M6 F- h- ~/ v" zint main()
: i3 E# R3 s# L$ y2 J9 b7 W# e{9 V* P. }8 x% x, C& }
    char ch;& J  Y% U( R. w5 i9 `
    char res[64];
6 i' O- C5 c! x    float result;) Q) N! Q. C* x. U! l5 u. Q# l
    while(1)
5 a8 H, M( z# v6 M    {
+ ?! q  K- G- o. q6 W        result=compute();8 |+ }. ]! ^' E
        printf("\nThe result is:%s\n",killzero(res,result));# t: ~  w) ]( E' |3 `0 O
        printf("Do you want to continue(y/n)?:") ;
) X- F+ N; _0 B        ch=getch();
; Y) A- `, ~; M3 k; R. S        putchar(ch);
) D4 X4 @# W' F1 n* ^. F        if(ch=='n'||ch=='N')" _+ y& f) X' m1 F/ q! A
            break;4 c0 X. N1 h. k3 i( P  [
        else
' p6 U  c4 C+ ]* p# `            system("cls");5 ^8 K6 A  [9 E) p6 L4 @% C
    }
3 \0 s% e% u0 L3 u- @: o; j3 m    return 0;
0 _: C$ o* m" ~9 b' y' B- B* g}

4 R8 N) N9 H& ~7 p# q8 \5 s! B1 j0 k0 i
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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