捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
^2E9H%r*Kl;iv(L 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=?.Z8_3hu
/**************表达式计算器************/hB5PH$dY
#include <stdio.h>
\!O-G8_#H"u #include <stdlib.h> El F|T
#include <string.h>X`I!B SE {
#include <conio.h>
0~Lh"M]$VD#a@8U #include <malloc.h>
4|G F n$_VV Mo|Rs
#define STACK_SIZE 100
fd1o:n y #define APPEND_SIZE 10
,d^o3y O,S)|7f.yl-Ih 7V0Bz+jpi5`GN
struct SNode{@)NCr2g-A
    float data; /*存放操作数或者计算结果*/
P7dH&[+m     char ch; /*存放运算符*/
+i7E'u/?h~n4GM };(d3X f7vO
4@j%Kkvm3PG
struct Stack{E*F _LL5t
    SNode *top;msc3?%Ie
    SNode *base;
_8F|+Ov0ka     int size;
Z#WgIwK\(W };
;ldG!K%O7Qd2m 6E/I-V&j`p,A
/*栈操作函数*/
"WLtPv.^ int InitStack(Stack &S); /*创建栈*/.Eop+o2cB2R4j~ Z
int DestroyStack(Stack &S); /*销毁栈*//z?$L)Vr+Tj [
int ClearStack(Stack &S); /*清空栈*/
cE.Ay9lw1H int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/P S0@l0KY%v1D
int Push(Stack &S,SNode e); /*将结点e压入栈*/ }!}9E'[ c6E| iK
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ R!zA U#~^qr

nQ)n-L"l6o-mX /*表达式计算器相关函数*/
SWjH H^(`n:B char get_precede(char s,char c); /*判断运算符s和c的优先级*/
*H'ySv9` h'@h.B1Q int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/h[[*{L0?8{:^Y
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/-Xf"A G r
float compute(); /*表达式结算器主函数*/b6? _&A'@_/G8]
char *killzero(float result); /*去掉结果后面的0*/
J?UuX,^^1K:C {G(ap ~Q9}'a$s
int InitStack(Stack &S)
)fyfmMBF/U)s'u {
hp4Cf)a:}{-Uj&YK     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+I,vD.xA)|6`wt*^     if(S.base==NULL)
lb x;[%wh+^YKDL1H     {
x)lMA7z v         printf("动态分配内存失败!");u1`q Ta7Y;ke;vU/B!S
        return -1;
8OHY-agt$iO"l8O M/z     }
Q\"q2T,M c!{&DX     S.top=S.base;yr5f2r8A0i.Px;~
    S.size=STACK_SIZE;;BGw3uUjlw*W
    return 0;
qh z Ol"ZcSd(C }
4ti)x[tl
#t+R$p$De;s@k F int DestroyStack(Stack &S)$W8E!H#|G#v;^
{'DLA}9[O"\(Y
    free(S.base);:F xbQ+F ] ~
    return 0;~:nHjp0wL)W
}
Pqe K m;^4N(ca7c AI)x@3?N4bbT
int ClearStack(Stack &S)Qp/\7cd#Kwf+J5zjf
{i9Q{;F/i2f:MB
    S.top=S.base;Xc$Po$qt:]@3v_
    return 0;
!A#O){&kO$_!x/y3xSk }
6j p}&{3yZ7bW 8\i"gq7i'W
int GetTop(Stack S,SNode &e),G7iko4i A R1u
{
O.N8gq Sx     if(S.top==S.base)i#\*KXE
    {
2I.z'FGQ2x8u         printf("栈以为空!");
k'u'LW7sW-n         return -1;
V,l%{+u.K'e7M     }[9Y)e6^{ y-q:k
    e=*(S.top-1);3jz(y1D1wY7D
    return 0;-j]ScX)~3f@O'\G
}$EG"fi5}

$U3F6|2|,i;I int Push(Stack &S,SNode e)\w!e VM b$k _G
{/OZO7I(s2fL#Jz
    if(S.top-S.base>=S.size):U*c f2T\8Pr9l3p r
    {
[.HG%Q5arNl_         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); WrDlm4j[
        if(S.base==NULL)
J.^~ I'}         {
g'v8WU(G6~]*Ou             printf("动态分配内存失败!");
h3H{N&G.G\             return -1;GG\Y U
        }
YU)T%@&G`U         S.top=S.base+S.size;
xW!PT"m `o1V         S.size+=APPEND_SIZE;
P%[n \@!xye]%d     } |'K@d;^ q
    *S.top=e;
)djBs%VKD     S.top++;-N#B"];};p0\
    return 0;
] [-Nm&d$a7m }
;aT"M a e7YQ8_9[
(Trs'~(|,t3a int Pop(Stack &S,SNode &e) p$@/N'}s
{ c-pRZ:J,ZW cj:S
    if(S.top==S.base)6wg b;a wg5M
    {
1Hg CZ#xX|m         printf("栈为空!"); _-aV;F'];e;G
        return -1;
FF r \j.Cz*B&i     }
'@3IpU |&d0_C     e=*(S.top-1);7pJwE zF
    S.top--; ic+\.i(o2m^ v
    return 0; yC*C9_#skVy)i6{
}
+D8v oSC)wb{i+O6T"tYo )ZGh'| ?LhD UDl-Y
char get_precede(char s,char c)
RqfB5d1ur {
L!Fn+y-Ki5E,q4T     switch(s)!N/jjA%]h
    {
DUf1k-YQ;Wt         case '+':                  `e2f7\j"]SpG
        case '-':+V6L2p Uc$HM
             if(c=='+'||c=='-')
6`w ~ y#_d1arQ)b                  return '>';9K(KJT`
             else if(c=='*'||c=='/')o%F_&q+Y"F6Xd
                 return '<';
3W L U*^~              else if(c=='(')
n0Yl)bzgUk                  return '<';
2OV?|"r}I              else if(c==')')n1AaeAnYZ]
                 return '>';hdT!zp
             else bQ%oK'x n
                 return '>';(si!I,kQQ N"V
        case '*':b.R7{ktJ H:s
        case '/':
u6y]'Ef S              if(c=='+'||c=='-') LLN?Hm)| F e
                 return '>';
"k \t3onW              else if(c=='*'||c=='/')
{c&]ko'Pf                  return '>';+G+Jg8x4ZTc'AT0F
             else if(c=='(')dG5m*Ss4H
                 return '<';
3xit9`,[ p\              else if(c==')')!`'WU2y2E
                 return '>';
V P|:~ z$O8c0W6FF\\9l              else
0T#k,BD~8|O                  return '>';
l:`:e2TclI         case '(':
S5I T*PDMo4`              if(c=='+'||c=='-')
$}r{$]E4y{                  return '<';3r)g"j6B C7DoT9W1p
             else if(c=='*'||c=='/')zp\9oY Q;fff6q,yq
                 return '<';/wCP0i E$cw2|
             else if(c=='(')
2P-tA9y |6p%W/d                  return '<';
0N1tZ4J6F3a-P              else if(c==')')e1Rq%aM.m'X'|6P
                 return '='; O@ Pa7p,lu#T_{
             else
dR h+DI5l                  return 'E';
2x&w u B(G4\r1M         case ')':
HA$r,v0J&T?              if(c=='+'||c=='-')
N ?8E,k B4yq                  return '>';3QxL!v]JKR6A%_
             else if(c=='*'||c=='/')&VJv~;`s k1f
                 return '>';
-l7VYR,K:h S              else if(c=='(')6r S%s/q(s/s1@
                 return 'E';
;y]2@Q'W?S `voB|              else if(c==')')&g&KMjj
                 return '>';
I H'f9xdmx(p,S*v2o+n              else g DkMI
                 return '>';
Mn2|"B4t@'v         case '#':
`$S*hD;GcPE'K;^5XZ              if(c=='+'||c=='-')+jm DI*~K U_
                 return '<';
4tTvKq#E              else if(c=='*'||c=='/')
's/Bv%jd!G:K${X                  return '<';8M1c#ZWm C3D6\3{$l
             else if(c=='(')
7p@H4tTC @&_                  return '<';k~'g2v0`'zB]*Y
             else if(c==')')$rq4t0_;H9c
                 return 'E';l5B-F)_#Zes(L
             else k2{rkS9JA)^
                 return '=';Xxr F6by`
        default:_C!P RfWr"Ke
             break;)Z1L0M L?
    }p.T:W"nw]-w3L^Oex
    return 0;    gl\ H s"?
}P-W#R-T~"\({Y

W `.J)L,A&| }9Z int isOpr(char c)4b ~ S)`8b/oE/Bw#^'x
{
lu.p*\-V7km5L     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')z,{qm fY#lcx
        return 0;
M0Fj u&w     else .kv)TUWUwW#t
        return 1;GUl`/b3l T
}
C^#u*_ o9ZL c j.].P5A Z
float operate(float x, char opr, float y)
7S8]+O/P~oXc V$r {%L/X~g9i
    float result;
3z$s8Lm7F2`9v     switch (opr)B X0NDH1o0C
    {
9K5i%Ctv[x         case '+':
o-L$O9Y'UPD(`              result = x + y;
:Se4z0`+_              break;j`/{KL0` c
        case '-':
d O$~&Fn6x4J0N{2pB#v              result = x - y;
)sV.C8? I(g6Q1Zg              break;
'K1vzV^         case '*': fq| N/Z&Y:m]
             result = x * y;g4l S6V{/A
             break;
JR1t&@%z         case '/': 2IsV+_ v!I$Z&tXM
             if (y == 0)
m s`t:[+v] w3{-B              {7B$s{7sPZVS
                printf("Divided by zero!\n");
zsEB!U7V                 return 0;
$zH%FL7?%W p j              }
3[hy-q%u8S-Qa              else
I3X7w5R'N$` z7^              {
#ghx.@ t                  result = x / y;-r.i"Erj:Pl
                 break;
"R5hs1d5]Z@              }
X5K3n0zi8R        default:
5FRW+kl8Cta              printf("Bad Input.\n");
@g5@/L^$YV              return 0;
*Si%IT6{'k     } T5Nf+t"blaj?
    return result;
9n!n0|R*b r7I[&d }   
{xWt'U!gM P 6J-C8TvW e
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/.gH7H R$D'@7]+nO)q
{7u-f I"H6fj^ M3@$S
    Stack optr,opnd; a5iF/n)hK d\Yie
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
5QmdS)@,K P     char c;0M)tUq${ i
    char buf[16];^mz1K o(ouh
    int i=0;
L P_F(P:kD0[?y     .n)XCbL!l
    InitStack(optr); /*用于寄存运算符*//C,BO.n5V/HL9x{
    InitStack(opnd); /*用于寄存操作数和计算结果*/
1pP6_&_9oO(}&P     memset(buf,0,sizeof(buf));kG y d o!j
    d_"nN9e.bR
    printf("Enter your expression:");8Y cQ8r$a^d
        w)_r~7^1Pr
    opr_in.ch='#';"f\rU-s6j
    Push(optr,opr_in); /*'#'入栈*/
"xE2]5[8V `/O9];Ueo g$s     GetTop(optr,opr_top);
Gd p@(E_+O@2J}     c=getchar();
D0O_:U+u(j     while(c!='='||opr_top.ch!='#')4d9] G{ N?
    {
(Y1z7u&zKd#kH         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
]?ph!_z&o#C         {6AM/y#P Kd v#x$X
            buf[i]=c; ~rN] ov;e
            i++;+ntgjt8@)v
            c=getchar();4_SO`#W!`$L
        }5L+C.ne%a
        else /*是运算符*/i@~.O1c~ x
        {&C i!b(n&xr9Z
            buf[i]='\0';
?WjS%Fp.~R             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
;O!n.f:C-F ZP3U8|             {[Z} A1~u9zCu
                 opn_in.data=(float)atof(buf);l-y)La7y3h(hx#yd
                 Push(opnd,opn_in);
6L{B0z2[9d                  printf("opnd入栈:[%f]\n",opn_in.data);#zlX(`sYH
                 i=0;
Jo;O(I!f1A                  memset(buf,0,sizeof(buf));
1P/Y9MLf0x7L             }7dA l BpA*\~
            opr_in.ch=c;E)DI/r$H5Y\
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
?.IlP6]ZF             {?L+ATy
                case '<': /*优先级小于栈顶结点,则运算符入栈*/O{!]3v3rji9Oi
                     Push(optr,opr_in);@[{~1sy6s^
                     printf("optr入栈:[%c]\n",opr_in.ch);
q$v%T5LnG n-xWq                      c=getchar();3pu9_&O,q\#L
                     break;}r-t0v A
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/J3tf&yut2fTt
                     Pop(optr,e);
4b&wGC5IU                      printf("optr出栈:去掉括号\n");`E]^4E d|S
                     c=getchar();
LTTf`Q                      break;1S-Y4f Z9Sx;j+e
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/_YzGTv*R%Gx-f
                     Pop(optr,opr_t);
:kgjk+]                      printf("optr出栈:[%c]\n",opr_t.ch);:P2T/e;rVr ` D-@
                     if(Pop(opnd,b)<0)uTGE yl2CK/ajL
                     {,? j4G q8| O~8m
                         printf("Bad Input!\n"); h ce`.{0z
                         fflush(stdin);
L#v;m OL2{e                          return -1;@s(\| j
                     }b9r#a!?$h } n U6X j[gL
                     printf("opnd出栈:[%f]\n",b.data);be&p-@/YKhd
                     if(Pop(opnd,a)<0)
Y ?ZPoY(h S*Cq8x                      {
/b?!x1JJ+@)FBu                          printf("Bad Input!\n");T5u'l1Jo#Eq
                         fflush(stdin);+J RJ*_X@`j
                         return -1;
d|Hmf                      }Txm n(N3^]%A!e
                     printf("opnd出栈:[%f]\n",a.data);1u!s5R:D@y u
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
&t]5G+o#o                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
v3CE Q,C#d                      printf("结果入栈:[%f]\n",opn_tmp.data);
F+iC/p\2q{3uL/\ Ga                      break;SA8FU P;\-A
            }
;lL8lqa         }
*f.^,CBXL6PW         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
#J-bJ"c` T0?"g     }2ta ~$N_4s_
    GetTop(opnd,opn_tmp);/?"d[Q#F
    DestroyStack(optr);!Qn)u5Y&~{C\k's
    DestroyStack(opnd);Y]:ld3h[}{
    return opn_tmp.data;
9w&N FJ$K/]:w%x"P? }F%MZ#@%]9R*t!q
m5ZJfO
char *killzero(char *res,float result).v{.Y6t7o(e
{
/E])iK'mS     int i;
E;f o1Hk{;~h 7kE2`oZ`u8X
    sprintf(res,"%f",result);&V(G-N[lU
    i=(int)strlen(res)-1;#`*ve K:k2z
    while(i&&res[i]=='0')-ak}IR ]^o
    {V6L"L"v avG
        res[i]='\0';'MC%ZZ^!M+q
        i--;
b#d8D;w$H o Z|     }0P5M c.iK7cn7|&Q
    if(res[i]=='.')
r,y R ^"M_Bn         res[i]='\0';
``Y!C g't'h8|oQ     return res;
-@&g hl$`MK*q }4Gct3B~^'i6}
OQ!f U#y_
int main()
?#gw)n5f9H4w$L {vm"K} k)d-F+E
    char ch;
S6fOi:N+u     char res[64];K;M}_?]
    float result;6L@!mv)Jn(j
    while(1)H z!Xa)[?^
    {
(BWR,b'Bb4i~         result=compute();
G-^o` K P rE         printf("\nThe result is:%s\n",killzero(res,result));$Qd|*@ [ a9R
        printf("Do you want to continue(y/n)?:") ;-gT} FP
        ch=getch();r&f | ] azNl)W
        putchar(ch);M,Y:q n%WZ@`6}d
        if(ch=='n'||ch=='N')
izJ$~:\a%E l             break;:J*k;TR6ld!z,~c
        else9C)N(R"w!J.o
            system("cls");
1rb Pol q     }
D"~rH|W     return 0;
t(oe*{8IDWf,{1~ }[/i][/i][/i][/i][/i][/i]
8mi(__ }'{)h ~z9i)on"NZ2f
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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