捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
(iPuP0I*T,pO 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
Gg*^m6Om `^:t8H /**************表达式计算器************/GEN"s G,N oz
#include <stdio.h>0Y2]KXrd'x
#include <stdlib.h>
[3^[k3Y[(J #include <string.h>
_A3~,mE l #include <conio.h> Sj oA `{ZX
#include <malloc.h>a M9^&C3o
p)`%L;V{i)a
#define STACK_SIZE 100@k4EEY`A%EC
#define APPEND_SIZE 10)B0gx"~|["PB(s\
W2ZmC+y&W`J
struct SNode{
"\9t Ix*]{     float data; /*存放操作数或者计算结果*/u!m%Yz8?!w|D
    char ch; /*存放运算符*/o2N8c"Z?!fk6z-{
};0][ w&w.i:q!t
1L%qcu&P A8@
struct Stack{6A.K!E-rB;S{P \2G
    SNode *top;jl8t6K u"Ko
    SNode *base;(d*L;?*f*nJ
    int size;)th~%g2Ar
};
$fa1`;r s}s
3T;@ TLw /*栈操作函数*/
4B,K&eP'pXY ?8tbP int InitStack(Stack &S); /*创建栈*/
Y;Y%o_ @-^{p int DestroyStack(Stack &S); /*销毁栈*/ dnL ~2c$h@.w
int ClearStack(Stack &S); /*清空栈*/
#Vr3g(@{\ int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/b(S {;b3f#T2P.v
int Push(Stack &S,SNode e); /*将结点e压入栈*/
Bg}2qj-h&PB int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/9C$]%_&aTJH
dZ/Y*s `3C
/*表达式计算器相关函数*/
0T}sXT p char get_precede(char s,char c); /*判断运算符s和c的优先级*/
~ `&W `ol/h;d int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/c5_z4R$tL;{
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
q%Tr'ekb1K^ float compute(); /*表达式结算器主函数*/
8[&j7NJ n C char *killzero(float result); /*去掉结果后面的0*/
6eP aP'Z(W? PQ aNe7xb ]2\
int InitStack(Stack &S)-R4^:J(r d
{
"A3e9kv M7FV9X     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
P3}+\LlY)b     if(S.base==NULL)
+\ \K"U$[A9m     {
0[_?*n`8?x         printf("动态分配内存失败!");
:[#LJYR-mIMq~ @u         return -1;
U[.vq*Z&d a     }xh _$iZ;F
    S.top=S.base;
D.j;H"PL P X j     S.size=STACK_SIZE;
)x(qe#X p~     return 0;{r\:E(c U8O9tL
}xo%S0Q1R,Z P
3pi$`7K)L"_}
int DestroyStack(Stack &S)
Eh2~#U MF b8Kd {/d&Be+J9xrv]-S
    free(S.base);lt_ T `.L z x5{
    return 0;
l])yo(z$mS*w }
m[+KZm v i
Wvz;?*s0[ int ClearStack(Stack &S)
lL4n$B4I/OH4C@] {
J;]#]fW5y6@     S.top=S.base;
%D ZNL4I td.x*W     return 0;
1a D9S$R'Y:Ov EQ*?Q }`x$UP"[:z9ym N
*Fp iCzxe:k
int GetTop(Stack S,SNode &e)
M `` J%CL&e {
eGi4Y0W?'SA?     if(S.top==S.base),O+Uk2YVg4v
    {
POW }Zg7@"vX!P/w         printf("栈以为空!");R[]!Kw+Z8P!y
        return -1;"SZ;XU%mS-[0i
    }X0l&hxwyp LK"M2G
    e=*(S.top-1);
)s'_"V a#[X7jyU     return 0;
hpp5T m3m bFV E }pe`vnC

Shi!D9W [%`a int Push(Stack &S,SNode e)2@xF J[3^ O!y t F
{dR w UM5b
    if(S.top-S.base>=S.size)
*V+f9Bq)v5F j:y     {&D(\tE6M"m+WK)C8H)v
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
vd#Q5a l4P$r         if(S.base==NULL)sjo,Z U|
        {tml.VW+KS2R"jl
            printf("动态分配内存失败!");4[#Hz r7N s
            return -1;
M1Ne C!n"n(? ix         }
PQ3] q-R2h_D         S.top=S.base+S.size;N#I2moX$YJ
        S.size+=APPEND_SIZE;
+LvBd:m!O     }i}#H3~(c%~
    *S.top=e;
_rE&h2x+oo|     S.top++;7V:Q-i#Yu(T,Di%p
    return 0;$o'T Gvl
}_ GBGW0Y
tFJe2a\#AP6K+WqE
int Pop(Stack &S,SNode &e)
`4M,e/G!~ I {v(` cWU qi
    if(S.top==S.base)
_d.@Wi*H3]     {
)B0OH}@A         printf("栈为空!");(~&[QU r#Q\8D
        return -1;/[d7N:cy`x2j'a6x-Y
    }
.H [I:m}0L[     e=*(S.top-1);:W:O#d$`_i
    S.top--;H2C:o}[5_2t+Md P
    return 0; D)S]VG1B3x:k
}
eO\.Y^VG"x cfg;g+J0u!]
char get_precede(char s,char c)v!~l h%V.`
{.T,QYo&z_5v
    switch(s)
_%by|&wf5H     {S#^e'pw7B Q N t8Yd
        case '+':                 %\n#u{ r-Y
        case '-':
+^9KtDJO              if(c=='+'||c=='-') R[{'? [j
                 return '>';/\;r Q$w*kjQ#~
             else if(c=='*'||c=='/'):~*?K_#^5Q5X*l6En
                 return '<';`.TK!{&{ J e;~X
             else if(c=='(')*^y pg%u9MX.l'Wb
                 return '<';5M Y8d`{R;@*`;V
             else if(c==')')
P n K[G sc$Q                  return '>';
4R.L!nL$P1XB              else
]G7ZBS'k!w                  return '>';
MMy/i)x `H[x:]         case '*':
5wx c3S [ m         case '/':;g;T`MCT*u
             if(c=='+'||c=='-')
WK fF c,]'zd?                  return '>'; _vV TD
             else if(c=='*'||c=='/')
_s6PY} z zL                  return '>';'zqz @| KZ V)K
             else if(c=='(')
}I"bO ~1aC                  return '<';
-[%?*b#^6[Qt-F              else if(c==')') [P9Bq.h(k+I2{
                 return '>';3unL @ y
             else
UB{h(X.B2o                  return '>';
C_9|R+eSh         case '(':
u T.z.v'j|9v S              if(c=='+'||c=='-')C K5m7SA%D4D_
                 return '<';
Ld+ioXW              else if(c=='*'||c=='/')#f!S0{zlkK1nW
                 return '<';3N5n-E|6O Z%Y)`
             else if(c=='('))a&qFSe,Q
                 return '<';
iWoP/y-t4^              else if(c==')')
p#tH5`7@,u                  return '=';
E"uO`]r              else
7wg Za`0w                  return 'E';1Td hH-X
        case ')':/pS4Y1sG v-u-K6Z!J
             if(c=='+'||c=='-')h/rv2i+u0h!bS
                 return '>';
P5b~^(? JD pA d"Z              else if(c=='*'||c=='/')
j}*LMd*~z                  return '>';G(t"|&C@
             else if(c=='(')
4z:ay'H2V!n-G                  return 'E';
"\9C^v&G [j| S              else if(c==')')T!l.rgm#q
                 return '>';
pp&a"]Rr6kE8^y              elseOhqWOSVfK1?
                 return '>';
6U Bc+AhxROW         case '#': X.?_]0f#W!DS6n)_
             if(c=='+'||c=='-') j3h;C&K1vO
                 return '<'; i(tD[v!^:W5c
             else if(c=='*'||c=='/')
]|PQ*f                  return '<';AR2Y:l#m9{
             else if(c=='(')
V/w bbUFHzy\                  return '<';
#v Y tYHBK              else if(c==')')pJPqN7JaQ"n
                 return 'E';
N5\(I5h$N c)t'w              else1DT~zd8q
                 return '=';
o+d$G%M J-fWy9r}*z         default:U"Xo T { Y(qjCeE
             break;7h2S,a/g*X!~)e${
    }/r0]vP dsH
    return 0;   
F aZ2`L0[ }
Q*[ H'Z:E r/f+]l,@&t2d G{
int isOpr(char c)5\B*U&q}%{,d'C C3Q
{
&t.dxm6o     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
&l+[$av8xM         return 0;
0IBdNk&D|     else
*Q&{0z^#q;U9c         return 1;tzL#y&~/Nt.t_(]
}/~Mc7\5~4N ]4a

,?E_ Wz8K float operate(float x, char opr, float y)
X;Uw:g E {!VrH2I2P
    float result;
;@|!w6|j3@     switch (opr)
~7m^*o)C v+F     {)t}Lu {#njH A
        case '+':
y L#E%My\gk8V              result = x + y;
0f+~d;A2{U0V              break;
&?HK{8uA         case '-': ;A9A? iL Hc a E
             result = x - y;S-`&o$}v/M gRoi
             break;
HZ+\5_c*tn         case '*':
o5^0mn.[0RlS              result = x * y;
O T8BQ O0fR              break;-epIV)P'U6`
        case '/':
~B j7X HE              if (y == 0)
/u8{3K;BNn,oa)v              {
#Y,G-t,ZOJ1M+IL                 printf("Divided by zero!\n");cT uF^"L
                return 0;
0?Q8by {.f-W{7H+[              }
z,P/l$^4?T_9l4Uo              elseO WN3aX?~
             {9LCM G.TE4Z
                 result = x / y;4\|a{Y5q
                 break;
o k$k6^_,G({              } D/x*P"Z6^R-L
       default:
c#I{2Xm&`3C%b              printf("Bad Input.\n"); R[!u H{0N:F Fq9S
             return 0;
2g&`3Gqv'ptA9O     }
/t.M1vU8Y/K!J     return result;PBkHv+yi[
}   
T)Q$U4Sn fv*j6~}!?6HJ G%I
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
Z?2w^&m {
on/v(N@B     Stack optr,opnd;6ClDf!Z
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;eyu"e${![_+U*x
    char c;4T sD `!y"I'GR
    char buf[16];
%m!l(L#u7cB+z!y     int i=0;
/EX(cn-N kw%j]2s ]a    
W&v(rZ)j@     InitStack(optr); /*用于寄存运算符*/
(Z)O(SY4h     InitStack(opnd); /*用于寄存操作数和计算结果*/d_k$f&v~:M&y
    memset(buf,0,sizeof(buf));E4g'x;k"K/z{'{]k
    6l~*JB.MvQn
    printf("Enter your expression:");_]H:@,f;AG zg
        a-k&J Rf(BR+g
    opr_in.ch='#';
6i6Fi$jHQ l ~Yb f8Y     Push(optr,opr_in); /*'#'入栈*/
Sq/L2Nmaq     GetTop(optr,opr_top);
&jZ!vb'A?     c=getchar();
Z/Gx'}k+Jr     while(c!='='||opr_top.ch!='#')L`l8b@
    {H,[1ha!^A"^
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
N.T%t U*Od"U9I_         {q(Ud:`@o
            buf[i]=c;
/uH]$NjM}mV3^M             i++;
A ^K-i T/EG8H:h             c=getchar();
:_-i i%W0i*C"LZ2h         }
B3pG#[1cv         else /*是运算符*/]6d1Q J-L2x,C
        {
#i$l7y0e0N,P7r'il             buf[i]='\0';
BZ"E+E3F-s+A$pT6V%J             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/R/V}&Vj
            {
6s+i9S6tL3C Y0HH                  opn_in.data=(float)atof(buf);$r:n:^8Aa
                 Push(opnd,opn_in);
6ncf|-{v                  printf("opnd入栈:[%f]\n",opn_in.data);
5U{%mA9P2lI                  i=0;
6mQ$Kdv gDP'q!r2g                  memset(buf,0,sizeof(buf));
Et r(\3P9D;q             }R @ zd p9B
            opr_in.ch=c;aBqIfRgU
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/&M4?#x1Mf,r5W7s6iEW
            {
C/z r9nMd#~$B\                 case '<': /*优先级小于栈顶结点,则运算符入栈*/tv.i3v1E)r
                     Push(optr,opr_in);
m)W4@X Uqd                      printf("optr入栈:[%c]\n",opr_in.ch);*|K#C T$GW-T
                     c=getchar();
m9?xO!S t%@                      break;
+^@1s.?O~0M                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
l,xTgz'Y@1v ZI                      Pop(optr,e);
mn$y2w#B6Nn                      printf("optr出栈:去掉括号\n");Q W|D,~I5KYiXw e
                     c=getchar();.lr Zj2z+fj1rUu:U
                     break;
` hupC!iBv2`4g                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/*m$zy|L
                     Pop(optr,opr_t);
"^C.[M;`@ ApCI                      printf("optr出栈:[%c]\n",opr_t.ch);$z W?0z aO
                     if(Pop(opnd,b)<0) ?7w/N7Q_
                     {
#w K| Q {\                          printf("Bad Input!\n");
q0r0Z4Z|                          fflush(stdin);
_z@ JK'H:A:c _                          return -1;4WBd m6}q-^(?
                     }
m&S-]Y&i1]:JqWa.Q                      printf("opnd出栈:[%f]\n",b.data);cgu6AA _L
                     if(Pop(opnd,a)<0)!fr8GRpN
                     {
OoNCQY+Tc                          printf("Bad Input!\n"); K%AAwP9s"W.J{
                         fflush(stdin); N(~bI8m
                         return -1;)i)u Y8`+}yg3n)Q8e
                     }
#Y Y"Smn` d/n                      printf("opnd出栈:[%f]\n",a.data);
MY8s)}F$q$c1]ov                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/$K*{ s an(Y4U*Bl@2B
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
q*wC `aT[;\mq                      printf("结果入栈:[%f]\n",opn_tmp.data);
o'{(]WI~&` JM                      break;}H7T-a\$K+R
            }'c7Adu(L @}W6_$H
        }-_MM]G~P+X
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                6Q\Ad C h
    }
LBL5zs3y1F     GetTop(opnd,opn_tmp);]4a J&^#R1^+H
    DestroyStack(optr);
T(eM s0}5pO     DestroyStack(opnd);
"A0w OS0Q     return opn_tmp.data;
5L?vH(uj.V }
d*`+E6G1rd;UHKO
}O6a g2T%C char *killzero(char *res,float result)K v EeA Y[i1|
{
FC/[2U6TQ     int i;4iuW#cq#w*B.@9x
,]i1uvRb
    sprintf(res,"%f",result);
d:T)NM)be     i=(int)strlen(res)-1;K(f1Y\?2n7x!T]
    while(i&&res[i]=='0')T.[h BM~iS
    {}#UlO![Q$`#n
        res[i]='\0';
p\m!aZ&q*N3~&\N2?         i--;#g r3V+G'Os
    }rKR lf3C
    if(res[i]=='.')[&o vbr(h~aL
        res[i]='\0';
X$by5vw     return res;
&])[&FAD}p }
N9]$r?MP
-Q(~d6b~'Rt"@ int main()
b$o!u&WJ S4o {
m(O.a&Ub-VK[:Hn     char ch;
%xQB{6^ @ M     char res[64];
2^7}bmE6P+JT ~     float result;
.Wq&\"ha     while(1)(M2XQZG ^ex{`C
    {.w8S{i7qS ? [e
        result=compute();
"[EH A0a6ZW         printf("\nThe result is:%s\n",killzero(res,result));
4B.Z"X\&P Euc;e         printf("Do you want to continue(y/n)?:") ; E$\'d;lv
        ch=getch();
J4D-N+q I4HW%J         putchar(ch);\/V r3M:pD.DV-L
        if(ch=='n'||ch=='N')*a{|}`m|3FA
            break;
,RP1IcC9lr'CYQ         else2S)z(}/] ]Y a4vV4f
            system("cls");9jK;{VxR!E
    }JBi@O\3fDk
    return 0;
&f,S/{!YN }[/i][/i][/i][/i][/i][/i]4P QQ'EB Hk
z V/I;Ql/R^/Tf
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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