捌玖网络工作室's Archiver

zw2004 发表于 2008-1-21 17:17

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. r}-~ {2Z T}r
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
3x#A$o\M Ut5v*C-m /**************表达式计算器************/*B-q%xr0ETq0i
#include <stdio.h>Cs$]8|N Q q}J8|T#@
#include <stdlib.h>7L.qLsD&yxH
#include <string.h>/hl3}xo$L
#include <conio.h>1kr"mw3}yW3Dme
#include <malloc.h> L2fc9B:[f [9iY;e
+u,NR?V7o6rOa
#define STACK_SIZE 100 R6iDh)~
#define APPEND_SIZE 10
8r){,^rN(s0R-@V;P (i,k3}*[0a*oC9M
struct SNode{_R0K U+R A2d g&\
    float data; /*存放操作数或者计算结果*/k|7e}B yh
    char ch; /*存放运算符*/"\L4B1f,w'K
};
s0W5NUs~ (S6w{7sm"p-K%y??8T
struct Stack{[-\(t{P stm-D
    SNode *top;'RFj%l/]-G:m4u
    SNode *base;cquK'UF7SL
    int size;Vb.KT/U C/T2W-e
};
-RJ GoT 9NR.OfG \+N.fW5M
/*栈操作函数*/#KY} QB4lH
int InitStack(Stack &S); /*创建栈*/
#wiv"q Y*g int DestroyStack(Stack &S); /*销毁栈*/[/@ l ip|
int ClearStack(Stack &S); /*清空栈*/}r3S.j~
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/$hwN-NG
int Push(Stack &S,SNode e); /*将结点e压入栈*/LG$H? S!j+O-K
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/$G.b,r-I RM? A

*}Z&k1o7X@2l /*表达式计算器相关函数*/
;K bdF3` char get_precede(char s,char c); /*判断运算符s和c的优先级*/s yIg_M#u
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
,f f zES7h float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/0_pA6hl(Xr\_*y
float compute(); /*表达式结算器主函数*/vB P'eLwM2y
char *killzero(float result); /*去掉结果后面的0*/
-C}|5}7^D
%A"k"flN }q.N int InitStack(Stack &S) i7?4D+ajyp!v
{ {3ZB7~2~[
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));lfM C cZ+[
    if(S.base==NULL)? ~,Pr?\T
    {
@!zn6u-{/b-cq         printf("动态分配内存失败!");
_H ~;c&g-N:_         return -1;6K+w {!kS6v(M&T
    }
,F!| M/N1^]S     S.top=S.base;
3q q&TMw/G     S.size=STACK_SIZE;Nl,s;VU1A
    return 0;w5y)_'O2JH0q*d
}
$P*T-NV6CaC9ypI
(w$P{u%n3dj.a"| int DestroyStack(Stack &S)
!f!w[a.d,uypqKN { _s2zd?6Wj4D
    free(S.base);(m9H&P/PPhL
    return 0;
l b&}P'S3\6Ba7g }w8s[*t}p4bO

/Y/[ M-Z-cP]:lD int ClearStack(Stack &S)
R-c;bg_*@| L { R F+iw'^T rR
    S.top=S.base;(X4_1OB&QL o.{+p6|
    return 0; F}:p*i9]h
}
1S$J!r z!pB8dz)z 3oP Jm_+Hi
int GetTop(Stack S,SNode &e)
/e$z ek0L+o\v9vie*U {$l#uej R&l6UL0J.O8g?
    if(S.top==S.base)p;Z2iC4B
    {)R-x{U;q X,q,Oe
        printf("栈以为空!");
l!}'r"]~ gc         return -1;
U'u+_"iSs     }I U4BRv6@
    e=*(S.top-1);}@!]5aC E~f&I
    return 0;
ovk~-x(git }gW7? _9~QYpw

{e+ev@ Ag8~ int Push(Stack &S,SNode e)
-]0Yl@:W6lw3s {:`-~*k+D*g'F
    if(S.top-S.base>=S.size)
h(kj{ Xn!gM     {/C:YjZ4x5Y P?*z
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));~.x*i9A[
        if(S.base==NULL)$b%aFr9fO+y8t
        {
:sN5DlcY0|:O0B             printf("动态分配内存失败!");
T8L y{/v             return -1;JB~%SB
        }
F\4tdDB)Z2o         S.top=S.base+S.size;
v9GPH"}0Z(i Xs         S.size+=APPEND_SIZE;~ h EF#k-Z|$w'X
    }
d {)m6od4`X`{     *S.top=e;
;~9N.w)x#R F `F Zt     S.top++;tO3?2y%c1A y
    return 0;
5`il5dM!I*W@8qT }
X%bT Uw)?JJR E W w[B0?*Ag^
int Pop(Stack &S,SNode &e)({(sE.ch^
{/?]sj,W kAaGE!yO
    if(S.top==S.base)
*\_!J%WDH {(b+px,J     {
!f*aGf;N         printf("栈为空!");
l TiJu Q         return -1;|)}7|5s8]+w-n y ~
    }
1R?n)C@ G&zX     e=*(S.top-1);
Z'cQ5ll5o     S.top--;
;E"W/BuQX@wGq     return 0;
@ @ a;M'g~3W S }
'nX+nm Q +\(b`3G^TX
char get_precede(char s,char c)u,g:Xn3zrW u
{
*kq WS#W+GTX)Q     switch(s)
p_&~&]U CCK     {+q oU^!LI*}([D
        case '+':                 
-c-\)W?p0Z         case '-':m DQo7E+M5tT
             if(c=='+'||c=='-'),q_s\5DE#E?U
                 return '>';
s8E)t/X.B)W6s              else if(c=='*'||c=='/')
G |J#I0~'?xO                  return '<';5KP i/xx6v8c-j
             else if(c=='(')
#iCOj @sc8{                  return '<';ov!u:["}fa,O)?6k
             else if(c==')')
~%H6Lpgi5l#Mi&k9[                  return '>';,e*BB-sQaE
             else
H'`o1y,[Q"c                  return '>';Em,\l@
        case '*':
0X[l8Y ?-O&Q&s![         case '/':
,w:OQ?{0S"T              if(c=='+'||c=='-')
v\i+]{{DP eJ                  return '>';
_!Nk zXl1G g              else if(c=='*'||c=='/')
*\ZTr(UNR                  return '>';,QH(n3]IIT
             else if(c=='(')
8QKWoO                  return '<';v-_` n2I"W W
             else if(c==')')
A"esT([)@%G                  return '>';A3SHE+x
             elsekc(OJCWu
                 return '>';
q^GA8aG-UM         case '(':
#Z9xA[I%lXa%H              if(c=='+'||c=='-')
{!o(N5IC6I(a%p                  return '<';
;khA:X6M1A0S              else if(c=='*'||c=='/')7D,n$w4g)v K ag R,b
                 return '<';0B&aqz ?9]fm
             else if(c=='(')
|g/[2HU+@2p)Y\5s                  return '<';
lv|$V/n              else if(c==')')AG{hgp
                 return '=';0E9R!dPJ'f['W7R3X
             else
]3o D/n+l+n `'?                  return 'E';!e5X7w1UGZCr
        case ')':
JI@\"@P              if(c=='+'||c=='-')
6w8Db,b5t$[ v/m)e                  return '>';#o0} Zkvu2?
             else if(c=='*'||c=='/')
NNA;l.mg0r                  return '>';.mujS5Q+T
             else if(c=='(')
)JIvjE,p"? ho4N[.LD;@                  return 'E';
'Xm*A:J$s              else if(c==')')8@FL.Cg-Z
                 return '>';
Z!^a1b at              else5eC[LZ3P1?0wN#T
                 return '>';
_wVKq4rb         case '#':aIC\ RYF
             if(c=='+'||c=='-')KP zr&{f-F
                 return '<';
(M@s"B`'A              else if(c=='*'||c=='/')qY#Sd-seD+kh|
                 return '<';
)]R WVPM%^ o              else if(c=='(')
J*WsALjp                  return '<';
4y1S{2m'AXj^              else if(c==')')+K$\.Idv
                 return 'E';Ff1Jqm(H `|
             else
#V [p7O%?,Z]5]                  return '=';
}[6h$Z-o         default:e9G:yd2S0v5r
             break;
rz4@-]u.T@D!T     }] oz,s zZ
    return 0;   
Cg:cpp/uaF#R.s$u#b }
'y;z9hb"p P
9N-GA x,os)h int isOpr(char c) B;zy;D0t Fa8L(|P
{Mu&D%b f\
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=').L&`aiZ2n)b
        return 0;
^(H*mMs9n:F HK     else
*~8R @ nCxcFY!i         return 1;
9?6L-J5LvI5Y I }4~ F-_p.Y-~ s6O8JT

i2kQW#xLf/](t float operate(float x, char opr, float y)
W2H_1A:@r Z { Q?4R/e7qU-X\
    float result;C5F3}2v n/s
    switch (opr)9m g D&h\EU rqcA
    { I5\ dd H]b
        case '+':
6j9W|KJ j              result = x + y;e(o9J,d3m*?x$?a
             break;"HlK wwjm RT
        case '-': ~(I:B5L{ XT
             result = x - y;
!_Bl!Db              break;h pFuk0\OMUJi MY5P
        case '*': "CbGD/aB
             result = x * y;
h.w^Jm6_x              break;{M\7S_.D Bx/w
        case '/':
MtUiY5m              if (y == 0)3W e1c\Xh'U'A9A Pl[8h
             {
d \Gvz4IP(L.uc                 printf("Divided by zero!\n");
0T$~+g$Ba([9?                 return 0;
$ip@ k0|eyN              }t^ {&`n~s}-FG
             else
f`;qGX QV%z              {
o}[2Tsy'vi"zYVA                  result = x / y;L?Ea$T2s{6h
                 break;
1c,G*qT*n              }
e[ z x+e^5N        default:
}m MW@ pfQ-c              printf("Bad Input.\n");
H5FN?#M;J              return 0; J*k}"z4L!uxx YO
    }
*b/aY[tj)}b,J7si     return result; LB)va._C
}   
cMAu;?s.zQi
L(~G/B m3b float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/#z[9Nx1_i8x\"A
{f|!Vj8DU}&h;l
    Stack optr,opnd; }KV4_Wq.}+CJ
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;E;}&g[b#p*Pf
    char c;r+W!Z,a k;V
    char buf[16];
*|;iB'n j8@ z     int i=0;$C%lVNg5j
   
TZ3i.FD7ws     InitStack(optr); /*用于寄存运算符*/R-V(lf:F
    InitStack(opnd); /*用于寄存操作数和计算结果*/ X)TO"C9w
    memset(buf,0,sizeof(buf));n`Q4f,?
    "`~]{5lO)b
    printf("Enter your expression:");*Lv7H/ZmK\&q
        X']%m#[.Bw TI
    opr_in.ch='#'; iU/}p;_[L\
    Push(optr,opr_in); /*'#'入栈*/
4trUX5C     GetTop(optr,opr_top);;jDhv5K
    c=getchar();
8O6?^~)?d     while(c!='='||opr_top.ch!='#')+`1G%P \/R6C!`
    {6XDvf:F
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
P/|$k uov.\$d ZS         {8Kg|*D1V
            buf[i]=c;
#k+fU'S@Alf N3oo             i++;
I7vA3H5K.WM]0o             c=getchar();SI]n%d UQ
        }
$k?lxs7B\ z"?         else /*是运算符*/
-paIu n U!D         {6v0Jes_8\#X
            buf[i]='\0';
`SMy @9y4Z             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/$Rb6V%aV&j
            {1r M,dZ&s+@bN
                 opn_in.data=(float)atof(buf);"_(di.BhJ(]$dR
                 Push(opnd,opn_in);K kARkU0o[
                 printf("opnd入栈:[%f]\n",opn_in.data);]7v7_!Q8o
                 i=0;Qr{d*b"?;_4Q
                 memset(buf,0,sizeof(buf));z;WAQ9e%@ Rv1y
            }
/@`$ee3Dk             opr_in.ch=c;;g6a,t"l"[o
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
?\+r9a@Y$d             {%~*K}$S@i
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
l7vLZ.}b                      Push(optr,opr_in);
*f-@qH];r                      printf("optr入栈:[%c]\n",opr_in.ch);{[!x1@v{
                     c=getchar();v1wr5v"l K&A ^RY {
                     break;
nG5`9i)J+` W(l                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
_"U:Y-n}+\                      Pop(optr,e);
?~)`%TG#hYML\                      printf("optr出栈:去掉括号\n");
1e+AX(^3Q_2n-jI                      c=getchar();:_1o)S$z2D&a!k,zq
                     break;
"ay \0h)f{`                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
!A k8t0w/H A2?1}Ky                      Pop(optr,opr_t);
?\z,w-wT5vB1G U,t*L                      printf("optr出栈:[%c]\n",opr_t.ch);
5J#W9eI:w-pXQB.Ms u                      if(Pop(opnd,b)<0)
jZvQK[                      {
6S3d;[6`V                          printf("Bad Input!\n");SK?bYT-[ dW
                         fflush(stdin);0O s"ti&t/@hD lh ]$I
                         return -1;
,h-Z3nX&Id_j[                      }
%mf#v*H_A;l                      printf("opnd出栈:[%f]\n",b.data);#M{2[:S)_ht-TXL
                     if(Pop(opnd,a)<0)
lu3fGEH^7w                      {
e/BDW9^h)e/C.m                          printf("Bad Input!\n");
/S.vlI"y#o8c                          fflush(stdin);
9] u_$Uf!lw'xy                          return -1;
m(?8H|$|0SUt!u                      }8Q1Rmiw2v0^ l F
                     printf("opnd出栈:[%f]\n",a.data);
zW~%~ u/kz-}h                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
D,X\1z*P3u+K                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/:_&Q;t~W2a FSv&e
                     printf("结果入栈:[%f]\n",opn_tmp.data);N%F9hA&M s3n#GE
                     break;5V.Ey M-E
            }h\f7H9^^wvR
        }0{D"e S*S&i"yAT
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
P*`?D7L6i     }
#p)sS(w(_'Z     GetTop(opnd,opn_tmp);W&E3d0D8w"ke\G}
    DestroyStack(optr);m0j@'RWV{(_ p
    DestroyStack(opnd);
m9V%EP2[4L"]     return opn_tmp.data;
yLy6r V]o }
{Ta$a$c!q;e8~I 7k8yU"[B s
char *killzero(char *res,float result)
E|Y)G)d4|I {
+XP7OQ!yg Md     int i;
"r3G2C.?%J
~Q!z8Ls)T&n4B2H     sprintf(res,"%f",result);
6F"J3]@h+A     i=(int)strlen(res)-1; UD!J,w D9x
    while(i&&res[i]=='0')O'BU {4O PKb"s%Y
    {vH q"bA SL
        res[i]='\0'; fe!Yg X&p&U
        i--; cI;Y;cW:g8h
    } @4{"G8Qh
    if(res[i]=='.')!A-o~ jk,a%?!?2P
        res[i]='\0';.r;qUOy|K$R&~
    return res;4X9Rq g V-uBs
}
\UIag7H~E&h#t tLhL9b5}n+jb
int main()
o!O6R0bT F9G {(g%uz5p2M9].P{r5p!z
    char ch;n(F6h7B-j$Ad
    char res[64];+F I0h#c7V%tS6u9{v
    float result;
r8|6@qX0o V$E&s     while(1)"s@uA`c LW
    {
cR0[ OZE4z-vL         result=compute();
`Y l We(Rj^5u i         printf("\nThe result is:%s\n",killzero(res,result));o n2t)X3~Re A
        printf("Do you want to continue(y/n)?:") ;Lz;o x y8C Y
        ch=getch(); [$R.j7K yaxD
        putchar(ch);6z9jnUy
        if(ch=='n'||ch=='N') U h6Y,\E m\
            break;-w8x@5OI{2z*yz
        else
&x5x&V!of             system("cls");
0Rx$[*}6@/Sl5V4A+n2[     }
T O| n-[A(H     return 0;
a"o8\\b@8R }[/i][/i][/i][/i][/i][/i]a9|w:TBt
:EblJX,K L0N4wTq0t E
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

页: [1]
【捌玖网络】已经运行:


Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.