捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
$l gp&K| 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=%~yI p(sg d
/**************表达式计算器************/
6Dh7a$p!`8suS k #include <stdio.h>0c&l1]6?bB
#include <stdlib.h>
I1?s/_iB\n'k #include <string.h>
'C,` [XO Q`(B"]m C #include <conio.h>
S)y+avw #include <malloc.h>:s W }[ rc
&`%l]p?
#define STACK_SIZE 100
TU%`.Z1QEu #define APPEND_SIZE 10\e5E!o"d v&MB6{
#ZBH]M8p^(V
struct SNode{
quir(`     float data; /*存放操作数或者计算结果*/d+\ Y-m(w&]0~b|\
    char ch; /*存放运算符*/t!{;v4A%j
};
+sQ8b OJ$p1t `3`%Qm6a4in3g#k
struct Stack{beiCJ'Oy|
    SNode *top;
vs3Q&^(\ E},}     SNode *base;9E7_9p R+Lr6lg%r
    int size;3e-v9EnL;H$H
};
\Muxf9N
|-k H[3F-J /*栈操作函数*/
Isk C!r%g ~%b2i int InitStack(Stack &S); /*创建栈*/
&Q6F_,X hi ^ int DestroyStack(Stack &S); /*销毁栈*/5X6M5lnX
int ClearStack(Stack &S); /*清空栈*/
L,_g8DFe int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/ |}*R*^:C9\3A
int Push(Stack &S,SNode e); /*将结点e压入栈*/,u9\;L2kq
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/h V1D%XxKr

Q'IXQ'G5h9{_ /*表达式计算器相关函数*/
I3^R{;x2T char get_precede(char s,char c); /*判断运算符s和c的优先级*/
(w8`^Z%j{c*KG int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/U@1v/w6U7a
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
!xY'WPZ6`-i float compute(); /*表达式结算器主函数*/
:u@ K;k[,o char *killzero(float result); /*去掉结果后面的0*/ xDK7w#{*cu J

Nx0@5V7IT int InitStack(Stack &S)OBq#j;@x2R+_)b$q3g
{
Vd DnhH#t5Ps     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));)@7g#~4K3e(YgX
    if(S.base==NULL)*U0R G:T5J.c8p7L y
    {C\fS C H
        printf("动态分配内存失败!");
]8~*J@:yRc+A!v9A         return -1;x'H&I)R;N r xk
    }"Sk6T8V2pR
    S.top=S.base;h"JsU#mJs
    S.size=STACK_SIZE;
Tav CT;j3^!]'M     return 0;
v&jd o:oM }
:d ex-}wzM{*A
*U3~3I$HcmlfDP int DestroyStack(Stack &S)
M4Z;^m gr'G {&fTZ9DU$\"y^
    free(S.base);
]}A!{"P7W5t@:N     return 0;
m-VhT6ofs }
{ m7sg$_tio Q#P )F3i*w;c6id
int ClearStack(Stack &S)boI?s#{NyX$A
{
"V rPYs     S.top=S.base;Mx]8o.QA
    return 0;Y}I5\9Z8uW
}
{,X/\-F t9G#gg
OKo/q6`7t%Hv6e int GetTop(Stack S,SNode &e)jyd/Vu
{b:]u&|]$zz
    if(S.top==S.base)
\.uogN(i.c     {
j2D-F]^M#FhZ]c2b         printf("栈以为空!");T%D S4xl%C!Z(GVr A
        return -1;$? OV)u`BV
    }z`Pw2z4Ruh
    e=*(S.top-1); j.A'kUr|ky)o
    return 0;
(x:H |F3Dp M[w }
Pw0uZh(uy @H%}3gU[6Y2E\0k+^1sy
int Push(Stack &S,SNode e)@ kZ$j:|N4]
{#jq`l3V@T5EKt
    if(S.top-S.base>=S.size)
A-`4k9_:@3H     {s6@-NG o;bs[
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); n5D8U Z F
        if(S.base==NULL)z^l0N/R
        {(sQM*]$HHZM
            printf("动态分配内存失败!");5t:Cg a-p
            return -1;C+t+z`2aD%w1p
        }
.n?ZER3Iz{f         S.top=S.base+S.size;9tZV i+Y$U!n
        S.size+=APPEND_SIZE;+`+n4}Q*i"Nq;j t!bX
    } y4NA]$W,OtO1W
    *S.top=e;
4E^ X8@*|u'TS     S.top++;)W {mI4Q?+f,|G
    return 0;Wp|f@-d:fh4a#u
}$R5I3?S+B%M
eM {4Y YVx_{p
int Pop(Stack &S,SNode &e)
3[K\ @+a {Ww)ej,? dH/w+~
    if(S.top==S.base)
$v*Y5H7|R&L0F     {
.}$RYM4zLT*C4ZEnV         printf("栈为空!");,g4Wj&dV@|
        return -1;8P6hr,cDdTy_0H
    }
k|BVJy~5\V     e=*(S.top-1);/g!K'W+zKIS'[
    S.top--;^q7I#u-t
    return 0;
c@(@-y2}7\ b }`}o"xE0X3\ v

R-@s1ej$asT&ih char get_precede(char s,char c)4H-mw#Z3x'I
{
+ru#n"\bd|     switch(s),r!o;x!EF`
    {
vS]GNj         case '+':                 
KXE't i ~X'f         case '-':
9~A{?idaCS4Bw              if(c=='+'||c=='-')
{w!D;|4I+sz`                  return '>';-l.X"N5Pw4y
             else if(c=='*'||c=='/')
i"w r4fH                  return '<';
w0V pXYd}              else if(c=='(')'q5x Ll)gft {
                 return '<';4W:HM(J6i
             else if(c==')')e(C K hgs'H]{
                 return '>';
W1Z1R$kR*o9r7]:Z*F(~ v              else ;{P S;NhQ,hB{ zm
                 return '>';7^6i G[N B
        case '*':!bU,{4V.DE v
        case '/':)h3F7yZ#H$Q
             if(c=='+'||c=='-')/V?'Y\:L7E&I`3emt
                 return '>';2j)a U6r%VL7K
             else if(c=='*'||c=='/')o `a i8WU0xzBc
                 return '>';1iO.BIH$_
             else if(c=='(')@ A$XiqX$c!_j
                 return '<';
V9i DHk PR              else if(c==')') QB1BkHs| \A
                 return '>';Xx+}!AWP;}
             else];f+`;a2T!|9e&TP dU
                 return '>';
2Y:Hes5yc!B"T)@         case '(':
.g7JA7k?5s              if(c=='+'||c=='-')r B`?:[
                 return '<';#x)yMCt^
             else if(c=='*'||c=='/') Q%?-SK$s_c
                 return '<';*w1| Y|+^'S V&z
             else if(c=='(')
n4`|"z1QO2_"d                  return '<';
1Wx3e!W G D,d              else if(c==')')
R u.bk7w8}1Q f1kP                  return '=';
[#sD0F3v G wo7}s B;P              else
p7ry`Z5Sg                  return 'E';
hm Y{(Y+w         case ')':
X^qq]x2V:nSxi#su              if(c=='+'||c=='-')
2j'Qn]%d                  return '>'; q zOQ6}:]'J2N
             else if(c=='*'||c=='/')0L.ei"XFW6|'I"e
                 return '>';|i%\)m$f^
             else if(c=='(')
2[:l|TAO\ vA                  return 'E'; @t"W*u*_`iw
             else if(c==')')
]i+CqL0lu vL _                  return '>';
.oL*h2q0\              else
Mm"P&m!rNG&x Y                  return '>';
6ud5o'c:l5jw         case '#':S Z%OAj5eoK
             if(c=='+'||c=='-')
z:fPS#C.Y&])M/r Ql                  return '<';
7oPh,u9]+{G7B{3I              else if(c=='*'||c=='/')
-t'n]/]Rw                  return '<';
'Ce"Bo6s x f,^              else if(c=='(')-Ls k&Z^!N3R1H
                 return '<';,?\!X3mC:K
             else if(c==')')0tFbN S
                 return 'E';
+?&]P"s4[*e4Xk              else_6ga3YBM*j
                 return '=';*[ t*qnK$a
        default:GJl._#[,ca
             break;
vk[r,j ]!C7Z     }
.hN0~$T(gl2fm     return 0;    by6i\8oA
}
%J-S{am\
Bhf?tG7K,m*V int isOpr(char c)
"PD t;Z.Z(J$mQ {
tD!A2qyY[     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
x8Y.\_#d         return 0;
C8|K p].|     else
-d(U i)}ep5tP8x6BE         return 1;l!O/B`R4W
}"y b5Qrd&g
'[ ^!O K_ v8_%{![.Q
float operate(float x, char opr, float y)g5A#`4l iOR"g
{O+wU4_{_z
    float result;A6` e2I#xg S
    switch (opr) Pa QHPY)~$i
    {8q;D ?[~dJ
        case '+': [*Q(BBM?YT7}T
             result = x + y; b.x&L B?,s.?2A
             break;
dX'jRCr5h5a         case '-':
3oOe'C$~+D              result = x - y;1Nb]"e+K~s
             break;5Y Tq9b0Th~
        case '*':
q4O8?#r+oq              result = x * y;
%m zO2az"gX              break;4[S!s&Sj acAGI
        case '/': P,rcK2G#j&t
             if (y == 0)
0`&YSu/F(v{Q7L{              {%v&tJ"lq'm
                printf("Divided by zero!\n");.^?'@5Pv DQ)S0UJ
                return 0;,W!cby6a|
             }L1R(etT8D]W
             else
V+U Mc M+A _)u              {
B#F.Ut z2HI*c`x z                  result = x / y;
.E:e-}K3L6c.h+w'wd&Oh                  break;
4QLK B+N Y&iO              }
#bo.xx^%\g        default:
+W,_ T!\ Mf)F:hi              printf("Bad Input.\n");
_GZfM _L              return 0;
5a6_'A.QY     })[1IUk3]
    return result;
8\0lr'@M.k Z o }    Z;YhS`#]
wPm;su m'^#LS#l?
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/P]/s2pi3u,] vZ
{
)a1?AGQq     Stack optr,opnd;
ut&l)Y f     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
Au,\ c,k3xA m     char c;
R3RW)j5U5[!Wqb     char buf[16];
W+?u @M,i*]     int i=0;^r!IW;s&v*e*b;f
    y0_] D%@1p/\
    InitStack(optr); /*用于寄存运算符*/9jJ8y"Utr6b
    InitStack(opnd); /*用于寄存操作数和计算结果*/0l[AEcHm!n
    memset(buf,0,sizeof(buf));
PqD@5b \I    
k)Y {&` iS     printf("Enter your expression:");
g [8v:JhM\         u2[9`\@(c"A
    opr_in.ch='#';
"M4@lxWA1Kj     Push(optr,opr_in); /*'#'入栈*/
/wC+sj;aSCU ?+O     GetTop(optr,opr_top);!v!Z7r5N J7p1]
    c=getchar();Y _G5mY
    while(c!='='||opr_top.ch!='#')7v"a.G#^Rq0y2q*@
    {.}+|T4ef"u!py~
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/J7V]n@k'a
        {)B:y wY A0A Vfb
            buf[i]=c;?'X/alo9C%e9O5L0P,P
            i++;hB r"R s+\;^ a4e
            c=getchar();
Gz9T2vYdwm         }
4x4I e!E[*t$[ b         else /*是运算符*/
$V3l0j+{ a6CJ B         {
ly#@ o.U#~x             buf[i]='\0';E{]m hn fH$F
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
/X.LIy5o sw             {
Rgv!J ^X[Ay                  opn_in.data=(float)atof(buf);1_Z o@e'~"W/p
                 Push(opnd,opn_in);
R/f j x!D c5A(AoO                  printf("opnd入栈:[%f]\n",opn_in.data);
'H PZQL El"N                  i=0;L@)B9W)G3E;~
                 memset(buf,0,sizeof(buf));K6Yh @X'`
            }
k+C(a9[q&N c?p             opr_in.ch=c;&|kHq3`Q
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
uc!i1Y\             {+vFo8n Y
                case '<': /*优先级小于栈顶结点,则运算符入栈*/6F,c I k4O
                     Push(optr,opr_in);d#x0w]M-yB5D t$c
                     printf("optr入栈:[%c]\n",opr_in.ch);ZDIX&RLz M$C,^-E
                     c=getchar();3Y#F i N'E Ndh
                     break;neRZb
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
*K4Rrd0Y0eH7N2H                      Pop(optr,e);
Kzf&A t Q?(T*G                      printf("optr出栈:去掉括号\n");
3p x4Xt2?X_                      c=getchar();
|I(^"b4s                      break;
A;m_ E%V+ua-nq.a                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/1?eFDBScC C
                     Pop(optr,opr_t);}D;qJHli
                     printf("optr出栈:[%c]\n",opr_t.ch);
;g8r`r y`%D+}8x                      if(Pop(opnd,b)<0)
}#V`;mJ)N6L                      {jZ0bt!opjz
                         printf("Bad Input!\n");
1i0X C(pt{c}L                          fflush(stdin);v2GA-uqv2RK%b*rJ
                         return -1;
tSb,yo;H[g                      }
q \;oySw&_                      printf("opnd出栈:[%f]\n",b.data);4A;S$M XJp;^.B
                     if(Pop(opnd,a)<0)
8Q7OIv{ u'E                      {
l Q2OJF Dl                          printf("Bad Input!\n");:r8w0un$IZi y8C
                         fflush(stdin);
A vsui4n                          return -1;
B&w(E!XO%p&r7Yfy \                      }
P@1O!Z"G.@DL?                      printf("opnd出栈:[%f]\n",a.data);
o7Z?ig9[;r                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/[j[iO
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
9M3k$c*s`3S2n#eu                      printf("结果入栈:[%f]\n",opn_tmp.data);6\ymG} i
                     break;!n0r-i aj%^ j
            }4UkN E c
        }
m)|go.KP         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
!K-\"HU1]9G{9p P5b     }
XR;c(iTy     GetTop(opnd,opn_tmp);| J{/u(~3P
    DestroyStack(optr);#U*AF MlD
    DestroyStack(opnd);K&l$s*D.?nB
    return opn_tmp.data;
v/f'Z`-{e8i7r)e }s&s U0x;E-jF1](S5Z$~

|+L-^*~d5\X%W char *killzero(char *res,float result)
8?.bI7W^JJ {6K|"D2[4uN7C
    int i;)T Ek-Z'mt&? Y.c
Y'}r,bg2mtV
    sprintf(res,"%f",result);;_w+pJ_ ?$^B
    i=(int)strlen(res)-1;
&z(aIqq(i2Gm     while(i&&res[i]=='0')
u/ING u&\[u8ESJy     {Y_? b!@ZN4pz
        res[i]='\0';N3S"p"SJ1XQQ)dS*R
        i--;
_v!QRx%n1m ~     }5Qr/z.U q
    if(res[i]=='.')
"Jk i.T4k.G#{Fc`wf         res[i]='\0';
#Y-z&L|/Qt     return res;
*IouD.n'jeJ }
-E8B%YC}T&?1O
@'@ Hs!bLW$W int main()d1jU O-Y/g$W3k#y
{6U)ThC1dGV1{@X
    char ch; m9y$tC2@#r%w!Uk;K:s
    char res[64]; n*T%j _)];v i)`0E
    float result;'D$`8L5yo
    while(1)
Y7X1XQ:} j     {
Y5g&C$\5r:w/~ p         result=compute();y \\+i1Dm WQ M
        printf("\nThe result is:%s\n",killzero(res,result));
H+My\ _A9ql         printf("Do you want to continue(y/n)?:") ;6fN\;W!kN| }dp
        ch=getch();~s6@BmwA%I*D
        putchar(ch);
L h5fVR         if(ch=='n'||ch=='N')
:N7K.bm[^bp             break;k%HCoG;y!W
        else @w6]e0fz*G
            system("cls");
:YrF1b2syX     }
+| h.M1V+}x?o0W"M6X     return 0;
Bh#W*vL(S6H[:E }[/i][/i][/i][/i][/i][/i]
*PS%f Cu!P,D;ZR L M2V 0h3l#NMp[ W g9]6T r-k
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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