捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
,OD6IqF7L 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
La#Byu pS2Zk Z /**************表达式计算器************/
Vc |\/RXj*{+~ #include <stdio.h>
'dJ| u8G+Lh(~1t6\ #include <stdlib.h>
u-}'e'M]vS6Vm #include <string.h>I(M(N-Hpd
#include <conio.h>
@:s+K`#^C9M3@ #include <malloc.h>
"xoN0G7OY2G
iXv!U3j&x.a #define STACK_SIZE 100
Qv)hy/bg*I0` [D M #define APPEND_SIZE 10*J@PFP tI;l{DI`]

X/^8E@3_!DQ struct SNode{
1R0hHr l eP     float data; /*存放操作数或者计算结果*/ k^]&W$Y"OVj&]
    char ch; /*存放运算符*/
3e EH(W3j8R };
q"y^O)}7E g;wf0_V
%? Od2~i)qY ~ struct Stack{ fs1mP-P${ M N:ljw
    SNode *top;
P9J^Htn     SNode *base;%@DW)]/} s
    int size;
w%Y$QzkV_ };
mWTkl%b'g%GjZ
:i5@*rPv)H /*栈操作函数*/
)G)ZlNJ int InitStack(Stack &S); /*创建栈*/F{Q$lT~^.I
int DestroyStack(Stack &S); /*销毁栈*/
z x xllt;|Qo8w_ int ClearStack(Stack &S); /*清空栈*/+ws5Sj5{&\YT
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
5~7[(f SY}9^$G-W,XF int Push(Stack &S,SNode e); /*将结点e压入栈*/,s.? k3Hbf?.Ws*S ]
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/!qnt?)Hd4n6qQ9E
?(w2]r(q1I:}&g
/*表达式计算器相关函数*/
$t L&]RHH ] char get_precede(char s,char c); /*判断运算符s和c的优先级*/4Q_\#}?|I X
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/;N4Ec w x yb
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/-LkV'u&AVT5{c
float compute(); /*表达式结算器主函数*/?-sHFv
char *killzero(float result); /*去掉结果后面的0*/ Vw Yvgl
jx){%z2TN J
int InitStack(Stack &S)
!P.|0zV7x)A"|%W {
M Awh3i     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));{0PB D$P#zc)EF
    if(S.base==NULL)
&Q6GU4rNP     {
_B+?T(St6pV)d         printf("动态分配内存失败!");
2W Y]4I/P;e         return -1;
T|?c0_,|s'I(r4|     }?PB%ug/u6x h9u.Y
    S.top=S.base;wKSMn4W^
    S.size=STACK_SIZE;hg{9r M?4^u
    return 0;
o:zgn)X-h&CW6|Vx }5wj.Y/nO Dq
6t)Qxq(\I
int DestroyStack(Stack &S)"GF OVJS
{7Ze'Ru},?&B4U,G8MW
    free(S.base);
d*v@%rq,Z;H8`     return 0;
,F1|j;q3jY9OI [ }s} t*L cG
Lzrz-?'Z
int ClearStack(Stack &S)8^"Y\o TKlcR
{r tD,];F
    S.top=S.base;
h q[Cs7fY-L5Q     return 0;di4X}1@|bQ\
}!i/v-gveRU
c3@a+SsDVk}
int GetTop(Stack S,SNode &e)
od;F~U~ jd {
6yn#KgyU     if(S.top==S.base);n?'v)W[]-ne
    {s\$F^4|
        printf("栈以为空!");
bb [y0dHW         return -1;
Q p9|V`     }Gz]A2g
    e=*(S.top-1);p6E-Ui ~*oY2j
    return 0;
%O;`VJ7Z#a3dtt }Rt]&V)e_*d/b6^ ?

!j+Tvf9oiq(I @f int Push(Stack &S,SNode e)
{;b*uU+C N,]${x {
K$hIR&[&N!y     if(S.top-S.base>=S.size){z)pf$z3\*T+]:e
    {
J!eG"G7g5MV         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
RRxaD]A @         if(S.base==NULL)
fv i/\Aj6_         {
%l ]2^M"K,R2i             printf("动态分配内存失败!");(R0do/bA5f
            return -1;
#gQer&@q         }
:} d:{oXV%K         S.top=S.base+S.size;
[AHgtU ~         S.size+=APPEND_SIZE;
S0M ? mK$I1Q7T$}Vwv     }+H9\;|Tt
    *S.top=e;b3_Nm#{I#C8?:E
    S.top++;
7^9O9Q+F`*@[.t9Q.X     return 0;
W5p`!H Ij^#d K }e1bk$h nlY#T'BVk
`2k!r} u `g
int Pop(Stack &S,SNode &e)
f\'m(_ji V {"mn#t&]iFU
    if(S.top==S.base)
R/e5T Y ]Z*p E     {
~;q:r)d.} HWn1^:b         printf("栈为空!");lDHC_,aO'S(I
        return -1;#A} f*@Dp#@gFM
    }
1h!aKmD5yUl     e=*(S.top-1);P TA^h4M#B
    S.top--;aFckOe}
    return 0;
W0c&H5{ \c%] }
'q Pt'ZXm;_.T
KW$jM$G,g._ char get_precede(char s,char c)
D)u.N.^7bm/? ZU U {
pf2Ti_+H     switch(s)
0o`|B@ xs     { `4a` r xRI,j3^X
        case '+':                 
C&e2TUb)o w         case '-':i R's3exV i
             if(c=='+'||c=='-')
HO*K$[!o                  return '>';
8s2F'xR"U-Gj)z.g              else if(c=='*'||c=='/')i#HH e5Y7W#Z
                 return '<';
yl}r`;n+NFh c              else if(c=='(')
Y.D\!s.C+Z^4@.c                  return '<';T(U-|`E;k o6TG1X
             else if(c==')')/ct(O*R D!~(qd
                 return '>';2DQ:L.oJ]
             else
lwW c No                  return '>';
L l7u4Z"AHsr         case '*':A3eUIl2H6[
        case '/': P S6@H,[i"fW C
             if(c=='+'||c=='-')W.h&jpX
                 return '>';&S(uB1_i-K
             else if(c=='*'||c=='/')
X.oc'f-x B_                  return '>';
.m:h;C g DyI'q1B:d              else if(c=='(')
2e3[)d@ {d0A                  return '<';
}+Rd:IRq              else if(c==')')T6d!V-b6iyB:f
                 return '>';
Yc&z4yW              else:[1s OHKk6u1o
                 return '>';
#g%^?*M|         case '(':[4lHaNX&W5a
             if(c=='+'||c=='-')-B zZ"~ [V"l.q+L
                 return '<';
D V Lt3iu,PP{              else if(c=='*'||c=='/')
OJ0YOs                  return '<';u!a [Dng ] t
             else if(c=='(')
1Zfy1t{(z                  return '<';Pa._U_3l |
             else if(c==')')&Z6Hkyo9M
                 return '=';
7]/|$P'YK b              else
"ZAN2N#f6eS1s                  return 'E';x.q kR#a+zvGo
        case ')':
f!k5]}3Ab F!hZ-f              if(c=='+'||c=='-')
hf#~L5W~Ya%_$V                  return '>';
6o^{%^L+_7W D              else if(c=='*'||c=='/')
+V#N+J6f]gN@                  return '>';
(F-sL+g-O:P|              else if(c=='(')
7],OE{@,Q                  return 'E';
|O7W+n[lB{i              else if(c==')')
(PV9^%pxe3_Zw                  return '>';t;C d/cZB S:FV3Po
             else
:Q;on2F r3R~F6? @)F                  return '>';1k3m#hZ Z!yM/e{
        case '#':
9J)v*x{U:?&U c              if(c=='+'||c=='-')
2H+P BNK-R![8AT                  return '<';
Z6PLX%_5L1SZ              else if(c=='*'||c=='/'):y[ G6l,^h
                 return '<';6bffUR:kH8fMF'@
             else if(c=='(')
~:V{#I c7~                  return '<';n2x7_}%s.fV
             else if(c==')')
FR9E*y1{                  return 'E';;Z j7E,z7\
             else+T MDeV
                 return '=';$AJ]X7@9]0@FR
        default:
[]H*?v              break; RRz@~X!z
    }:XfiQQh C&M,D
    return 0;    $_ lQQl
} g#AMPE M,b/AH
3Btl1H p H3N8d3?J
int isOpr(char c)%d'? I)b8e5n
{:`B fksAU0M%c(y
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')j+MS0KV
        return 0;
7I+b V5}s8s^4N     else !O _+|u+@
        return 1;
^&P%K{?(p }
5D&}'N E0qW4I M2e
8tgE9[~ float operate(float x, char opr, float y)
"[|"b AT'z {1JZv5q*w {
(aTbOAA0G     float result;Z#^^ j)M
    switch (opr)MKJ#Q-E
    {yx'd)l:qL
        case '+': l {4}$zC.[
             result = x + y;
3WU1D h!@:^8@.Xk              break;
D5SY;h2sC         case '-':
'b2cu;O`              result = x - y;0RQzhoE#Q^*L
             break; gd0rn9z&G CB
        case '*':
Kp"D~ f.U A              result = x * y;
Dtl8TJ              break;3iZ8L r.L:b9Sh|
        case '/': 3D [2Xs[v
             if (y == 0)wR\Z8h.ov6J z+W
             {-B w1c:[0W L9{0Z*V
                printf("Divided by zero!\n");cO6w? {*rZ
                return 0;
pVC+y ^3l_*{C              }
(P&O4eNSCl$@              else
3B6};I~-qb8cl              {
+C+}&X](o:R                  result = x / y;2y.yc|nW
                 break;[1o6c8z;V,JvJcv
             }
PY A"wp3Yj9|4@%~        default: 'bDj8bZR(``!v8H
             printf("Bad Input.\n"); 5@ E5R$}U_!s?D{!L
             return 0;M4[Y0sF3al?2X
    }!f#l?r#d'Ks@&~#M
    return result;
Zy:n1f E`eB4}Z9n }   
hmf*HJ6zu
g6DV lb float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
/c7Z)R^m%J {GJh-M O e7P LJ
    Stack optr,opnd;zI)L-E\2Xs d8u~jj
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
QD&t#zy     char c;;r N$qj&Z G HB#[
    char buf[16];['zl uJ
    int i=0;
,WF/@/KmS%|     :j9l9KS(~_ B
    InitStack(optr); /*用于寄存运算符*/agT URXW h{ X
    InitStack(opnd); /*用于寄存操作数和计算结果*/
(_.iN.eaG     memset(buf,0,sizeof(buf));
UZ1h4Q~Sx8u     j+~ mQf'@`&f
    printf("Enter your expression:");kp m.uvM6}!d
        `cgIU
    opr_in.ch='#'; j AIf^7E9E%r
    Push(optr,opr_in); /*'#'入栈*/
b(a mAqX0t$dL     GetTop(optr,opr_top);
G}kU4s"sn4g     c=getchar();
/r/\,|;FZ     while(c!='='||opr_top.ch!='#')
BR-[T M     {
_'f T2A(C.K'w         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
di;oq1zp];Oz         {
`Nn6]e4h-I             buf[i]=c;
#R$V KY _1y+Ak ]w,O+V]             i++;
W%DHF`;r@             c=getchar();
5csMDo         }8Y)Uef$Dn}-h
        else /*是运算符*/9a!]OTp'B
        {
T-khf$g&Rt             buf[i]='\0';
7S@/I%W4F#@5G(W I+U*e             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/Hl}b4\mm
            {
n,cIfFV*Yy0ST                  opn_in.data=(float)atof(buf);6K!oA%Rae:O9B(X
                 Push(opnd,opn_in);
?*sN ~N8s                  printf("opnd入栈:[%f]\n",opn_in.data);
k[q$Z6KAH0I                  i=0;sB?_9@B'a$Y;LE4Dn
                 memset(buf,0,sizeof(buf));`qS)y%jB
            }F|/s_9Cl gS
            opr_in.ch=c;
*Uy1Y)y1Mts             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/;t+g/LOPO2Y U1^*z
            {T1ziw$F`n9B#F qu
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
S}s^(v$b7c)X;X                      Push(optr,opr_in);k-d+F/e-zv8P c[
                     printf("optr入栈:[%c]\n",opr_in.ch);
%F ]qEY                      c=getchar();
]ZmD;iF                      break;
(c2ccf"N(i,t{7a D                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
%Ws L-H&u*@ |                      Pop(optr,e);9[-]k-q]3X2d;n
                     printf("optr出栈:去掉括号\n");v%ZHM Y2F7`*Q|
                     c=getchar();
A:~Tm$G m                      break; m?$j4o6Q
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
9@~8u`n1J                      Pop(optr,opr_t);
V,g,Xi [kk+X)g                      printf("optr出栈:[%c]\n",opr_t.ch);
xn$o y(k+A                      if(Pop(opnd,b)<0)\zd6^OH;m1hQ:V$u_)h
                     {
Fhb:xuJ'k [                          printf("Bad Input!\n");c"I9XXD7nl
                         fflush(stdin);
Y)g9j&{nU-`                          return -1;
AC tD/kf*c8p%H                      }5qtJ d*c:g u7T0jJ
                     printf("opnd出栈:[%f]\n",b.data);L+x] Q"X"P _6BdT#m
                     if(Pop(opnd,a)<0)
o*P!H0rR,[%}K8l                      {
3A4jZG;a^3u3M                          printf("Bad Input!\n");~)qo8S/il'[
                         fflush(stdin);o0o)S2g l4op
                         return -1;+jZV3_[ Z-H E
                     } }utD7^&j.S|4i
                     printf("opnd出栈:[%f]\n",a.data);Omx*@gV
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/V5^~$H1K
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
hb a3@,V$EbBS                      printf("结果入栈:[%f]\n",opn_tmp.data);
k yyWI7pv!A s                      break;,P.gc9PzR3eaC
            }
f3r`3Ryj         }
/}_6@1D#u5p7vm         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                vHx;dz
    }lAc2SA1t.c
    GetTop(opnd,opn_tmp);
g!w)f!x ?     DestroyStack(optr);({Pw8P{YB
    DestroyStack(opnd);
| XUa;YF*T"z     return opn_tmp.data;
inS6|0Z }%rV%IXWwG,Ex(V
"p#Aadm4l
char *killzero(char *res,float result)
9`%l5\OLn:N i {[e]5bCE&\
    int i;
^,U:phk$H;r(g
2r1i'J0t1\T!G4A     sprintf(res,"%f",result);
c6V_;G-[*n9z!|X     i=(int)strlen(res)-1;,O |Pn0F3oN6V5]8f
    while(i&&res[i]=='0')GR*q+D.\8Lsu6z&z
    {5Kx*i%Rl#\
        res[i]='\0';
,t1{J n;_l         i--;
}Yu8q0G     }3[4ix\:s D{U
    if(res[i]=='.')#W:h(z4k-Vs4s
        res[i]='\0';0d L'} Y8Ye"`S
    return res;4eeXsI0k%m,c
}%}\ ~dN G a*G

&gQ`J]q ~l@ int main()5T_5KXX C
{*i1QHqS r.G*K E
    char ch;'w9W o5J@3R:XxK(F/o ]l
    char res[64];.`n8sot6Ov3m
    float result;
F)^ol;m%`+Q     while(1)j6jhs\WX,} Z/h
    {
bG@4n1o O         result=compute();k]'v p9}Wy%H.a&T,X
        printf("\nThe result is:%s\n",killzero(res,result));MH#^8Ej*M$Ms"Y
        printf("Do you want to continue(y/n)?:") ;
~f!|4t!f GH         ch=getch();`Nuy0VFK x u@-B
        putchar(ch); H4_8tZ0~$k%^e
        if(ch=='n'||ch=='N')y:qqRh.i"n
            break;
*P I*`O;N         else
,cT8a*i @6Zn }G+P             system("cls");
a;{y @lc m7G3P;K$G     }4NDq#b;V O
    return 0;
)nAa'R kK]'k5x4f }[/i][/i][/i][/i][/i][/i]
a$W[9vJ C3a5S)L)H \!A{"Y1od0V
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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