捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.8k8S O/iOT
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=*R&wXB@(} WA*^.tm
/**************表达式计算器************/(X4D}0v V m Zx
#include <stdio.h>
0Q a$d;K!H7gI }*?,dp #include <stdlib.h>
\b og*i #include <string.h>
4Nqd i y8PV,E #include <conio.h>0b-dS0Nm;t
#include <malloc.h>
;u)o |%x6NsL5l
0q``R[*|P #define STACK_SIZE 100
3uz9ld6V"`"b-n #define APPEND_SIZE 10
%z|yt4ER.Cy
|X,{C#} u6ZN7D struct SNode{g|.ANm,Mh
    float data; /*存放操作数或者计算结果*/
M3B&G$bD0D:F.cn     char ch; /*存放运算符*/&c,hc3U+J?H
};
RUNu |`){'h
"}f7i l{ struct Stack{/M/nBV3C&x`*Wo
    SNode *top;
&L+u^+BQ"DN.J~     SNode *base;l#y&MVl4J%x
    int size;o/F_0T2Kx#n {v
};W%f(v6YP9k+@
id0R#Kr.@ f;M
/*栈操作函数*/*FF"moN[9m\2K%T
int InitStack(Stack &S); /*创建栈*/gp;s ?.[1?!q I
int DestroyStack(Stack &S); /*销毁栈*/
&unS,rM1|s'e o^ int ClearStack(Stack &S); /*清空栈*/
|k A*G\mQv int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/d'Hb q7j z-R&u
int Push(Stack &S,SNode e); /*将结点e压入栈*/
A5S x/bmD int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/,~!| A i#wDf

6ye1eAeg$k8` /*表达式计算器相关函数*/
2F6po @s+^5Td"mz char get_precede(char s,char c); /*判断运算符s和c的优先级*/
-e@Kk xy4y int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/uQ F M.i'vf.Z,N_
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
[CQ"h8gU o float compute(); /*表达式结算器主函数*/
eS9Z3T^+~%G$E char *killzero(float result); /*去掉结果后面的0*/
$x+Ip"A$c_'YL
l2D/qnp int InitStack(Stack &S)LH)H)q3D"S-K6BR`A
{sG x4Oo}Crz k2\1_
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); ^$H8]F'SH8j
    if(S.base==NULL)
4eo\3I,s]     {
wr0ge6ray         printf("动态分配内存失败!");
*H.p2O@(v(B9aeX         return -1;INNV0cC)x
    }
4G;E ma Q#A,K8{e_     S.top=S.base;
*W!g~2t#v     S.size=STACK_SIZE;gS&s{"wc9IPE
    return 0;
o }h3A:Le)l4DAv }sO'whj6w+b

h5I$MeI FU4X2E int DestroyStack(Stack &S)
Px| yO7M {z` Fnzp
    free(S.base);:u ~YoZYo@
    return 0;
T#z${ V7tyu }
'?r `YN WZG FP^
int ClearStack(Stack &S)
S$lkVLs:{ A)V {
|0QHMe8@,@a     S.top=S.base;
5?s8~B#_     return 0;:Xx lf_Usz*P7l
}1O)ID7mk
~4hHW"p;u
int GetTop(Stack S,SNode &e)
R BHX)O {+DQ"F5yq-d
    if(S.top==S.base)
rX3q!V!r.`6n3t     {
t)K_ Y)q{Z         printf("栈以为空!");
$ljbl8duL;`)R |.?         return -1;r6s)Y|H:F
    }WW"f:E%y7|N
    e=*(S.top-1);` I!j\MkIO
    return 0;pbQu.AT
}
w B }bz.Y
"H `j!B ]*D int Push(Stack &S,SNode e)8g2M b;O(d!W8]S%{
{$w,a,iM'cc
    if(S.top-S.base>=S.size)7^)Bz:g7qZ
    {b5V&H6\| [z'N)@
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
4Z,C,{5iif t"w         if(S.base==NULL)x,K,b4rx_
        {5_\nO`$^yR4h
            printf("动态分配内存失败!");.u@a MX#c
            return -1;%~QIBC L4cY/c
        }
$h(\'{@U_         S.top=S.base+S.size;
C4n%O#lzjR"{2u"z         S.size+=APPEND_SIZE; e\#w(Tu.pQ'n
    }
n|-Q%xj.T     *S.top=e;
1x'W-so7`p*?x     S.top++;
3z0Q&O$h4o-w8c!y/]f(F-S9D     return 0;
{My H.lbe }!z,T Z!c @iL;M(k
BH.Sw&mmL1g:[9X&s
int Pop(Stack &S,SNode &e)
'o*N+OPp9F0W {zj*T ~.k7^sf
    if(S.top==S.base)
w Y(nFtIG     {
G*dFE&o.}&P?         printf("栈为空!");;_VD;bk p
        return -1;
EG ZzonY     }6A6`7B*V$fl"|A:m
    e=*(S.top-1);
ICI-F1XT(H     S.top--;
k+z!Q]%l8Y0p     return 0;}7C-{Mf!n R
} v!|(Wg;~#@7pnA(E

0?I|+cJ*L9\O char get_precede(char s,char c)-{r)Ih3V]tB1n
{Mj7A)q vYl.u
    switch(s)
:~l4I[P*Z$v     {
&R9_U-c7x7c6]h'|,L5i         case '+':                 
,}'H:r J;F&a ou         case '-':
M^S _LhN              if(c=='+'||c=='-')pb-^h fd#r S
                 return '>';$U)Y\8[6An/X"q+A
             else if(c=='*'||c=='/')
DN"eF5gH){3so-K                  return '<';
7Gn{m5T/q0`              else if(c=='(')sF2~&J5tB
                 return '<';C oZf ~#V
             else if(c==')')
&\(b*KsR)Z_gz                  return '>';
^Y"PY!\              else
G'L)rw#ie\,Qrp(M"J                  return '>';
+u8n|$Ez ~         case '*':
wq+?m_         case '/':
G,u#A+D oC              if(c=='+'||c=='-')-iLWr$Fe
                 return '>';
#h:},{ kAt{              else if(c=='*'||c=='/')
{ T*Il"~1^                  return '>';
"EW"t4?6F b              else if(c=='(')XK ~r$?W$d ^
                 return '<';-o+d&N&k)cdz1ij
             else if(c==')')
i8s i;KV                  return '>';
a4vc B*v"^vpP              else
8M^-Jc5q]                  return '>';.OI}8]H,Dwe
        case '(':
yO8XX(d3V              if(c=='+'||c=='-')5B)lk x/}k]
                 return '<';K+v(ykRu|-B|
             else if(c=='*'||c=='/')F5onb~z\3X4n
                 return '<';
T6z#@/I6H,Z;kOj              else if(c=='(')N6X,w'\H#X
                 return '<';
-@Hep;H.N;m              else if(c==')')
8reM;V3s                  return '=';
$Mb7` Y }i o7bdQ              else
v!Iw.R U-t                  return 'E';"RS^:x4xP
        case ')':
K\K(I8V(|Q              if(c=='+'||c=='-')
uuHd#x q4f                  return '>';
pf@z P)T({              else if(c=='*'||c=='/')w!q$EQ5G7v%]
                 return '>'; VQi0G/VV?+R
             else if(c=='(')LlB Ip2mR
                 return 'E';
O1mh&qQ Vm&?Ln;p"k9h              else if(c==')')1`-?9t4nS.L-x1h
                 return '>';
*Z:QeXz5J6l(J"pk              else
6` U0\,H6?N                  return '>';
UG-D#Pq9^|         case '#':
9e#~!Dt i&l;G)rt3^1X              if(c=='+'||c=='-')
zEM Uyue'|6^E                  return '<';
*ta&X%v.o)ZZ] W [*In              else if(c=='*'||c=='/')2M2mA ^z6{l:u Z
                 return '<';
U&C?5|(NT              else if(c=='(') UW-P*P:v t%G
                 return '<';
+D-aI$_6F-B)?M _ Kp\              else if(c==')')
vK1D&\2? [ S T                  return 'E';jCM[ Y0bTy~&c
             else
2q f }$t6Z                  return '=';n C)tbEOT
        default:c-cTl5h$K,v0S d._ K
             break;
{;t$wh0M b     }a:b/p)F&jo2j Li4Ky
    return 0;   
$z0^f&rEU$l^ QB }+R!p#SO%Cd{kQA
P gRxf(O
int isOpr(char c)XtB1g2YQT
{c8G(ev_0E~`!z
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')gi On9Q BNN
        return 0;'Z"` JLh Fs `%L#Q
    else
_%P3P:{.o~         return 1;
.T*vK!WN2V }1uJ&@@ V3s$M+Gpd

-]'A:sE!Uj J3L float operate(float x, char opr, float y)fn(G#r y
{
a6WX#} fT'LC     float result;
B;T)Qe U,A#d     switch (opr)d`0Pny v
    { O |O]G4d1Hg(GrR _"A
        case '+':
p.[7HKf,|9r              result = x + y;/_D;k~ ` @+u
             break;qI|(Pe${!P8v ?
        case '-':
#}I)d0qh}'@Ea Q              result = x - y;g b5X!gl
             break;(\L9W'x4~?!Z f
        case '*':
"ZuJf-M5KU'j8AJ              result = x * y;*Ra,~F%_Tch I
             break;X&}[ma_!HC
        case '/': RQ.tK"U
             if (y == 0)
/}*k1AVgcax              {9W8g"P^6w&~9@B$@@4u{
                printf("Divided by zero!\n");
K|k-f{A+Q                 return 0;Sva_c-yg n
             }}ceA4c @-ylWW'R
             else7y {z1O4_2r3X7N
             {!C A3[n+[:[(?j#g
                 result = x / y;u'Z8OiN#p!RX
                 break;_@7u&zi.\Z
             } c0\ P/Pi
       default:
u7E"c4M-V_O `Wy              printf("Bad Input.\n");
,s~3Y hh)UV3oEF              return 0;u7j7kxQP&Oa({
    }
;E#_Ce"g.@E     return result;
KyP)MY }    %m.Y5t ?9P/p

T"PH\9qG5z7hpG float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
j S*p| cC {
/x2HTh J CK(Z     Stack optr,opnd;
2sm*]tu }1v     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
X(K7x2y2Sl4u{a     char c;7}5S|5Ea.b'w8Z EL
    char buf[16];6}+N3uRP
    int i=0;
:j9u2Vul    
@,lt:C vq:^     InitStack(optr); /*用于寄存运算符*/(EDh#S:w)Z#~uC(_7`
    InitStack(opnd); /*用于寄存操作数和计算结果*/
;PTw2BfIcXa     memset(buf,0,sizeof(buf));q'z~t\I
   
0v}$kD@|@Y b     printf("Enter your expression:");j&s DA(F-Y-BM]
        
"Z3a_'C [     opr_in.ch='#';|v2T?%z~v
    Push(optr,opr_in); /*'#'入栈*/
-`c&{o?O}G1E     GetTop(optr,opr_top);^ _*N|L6_Fy-I ~
    c=getchar();(lUI#O1C6n`L;`
    while(c!='='||opr_top.ch!='#')
B(S*sC:|     {
/w)]f.meyPvhYT         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/4\9b$N1@#G1]S
        {
d"^;VA3X9BIUi9U             buf[i]=c;
+L#`0VW g)d l9g             i++;L%hJ'p^W)c6xh3gt(~
            c=getchar();!ws:@^Ob@S#_{7{h
        }
G)e _1ALT         else /*是运算符*/Ob^A%L$f
        {
]F0?5|h5v%N\$D             buf[i]='\0';
-f wr`4A$`9l             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/N?Z2u/b)L%r L
            {
r EWCd m                  opn_in.data=(float)atof(buf);
+pw!pg-n'^){                  Push(opnd,opn_in);3] ^'`}M
                 printf("opnd入栈:[%f]\n",opn_in.data);-]Omp4N9|
                 i=0;2^)h@ xr.f(|!v)s
                 memset(buf,0,sizeof(buf));
G*jh4r+Z             }
;p/p nV7bg             opr_in.ch=c; c,n1t.mD"CTU
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/)vP/^9zF%^9M
            {
AC*gUD\/d1L                 case '<': /*优先级小于栈顶结点,则运算符入栈*/8jX&lfY @l
                     Push(optr,opr_in);.Te*Mk1oc {
                     printf("optr入栈:[%c]\n",opr_in.ch);
;\?2XRe1yt                      c=getchar();w7Q5h,Q%PaAS
                     break;
O.A'Do fR]9G%Y                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
4l*G)G |#E1RDf+I                      Pop(optr,e);
)Dp&t@2d)s                      printf("optr出栈:去掉括号\n");
] l7]v5N%~+D                      c=getchar();
n'z{.]6mK9p                      break;
0w-te_x2M,l/h%N                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/ML6ywG
                     Pop(optr,opr_t);
En9Q@`                      printf("optr出栈:[%c]\n",opr_t.ch);
d%q){~,}J/n                      if(Pop(opnd,b)<0)
lB_Kb bg                      {
v7edgzpz                          printf("Bad Input!\n");
2C {r2|S"]                          fflush(stdin);0Am"aEE#l
                         return -1;
T q Q a ~i mR                      }8U'JlL*c"w4\u
                     printf("opnd出栈:[%f]\n",b.data);
3v4z&K9Sq U]                      if(Pop(opnd,a)<0)7e*DT6M)\9fd
                     {
L(Tx%D%JX9]2X9h/]                          printf("Bad Input!\n");,Wo1YR'T7SJ,M"kF
                         fflush(stdin);
&n6y^+KDQtN!H:H                          return -1;
l5c`.b(m4h&A;I                      }!zGv$}(a:hE
                     printf("opnd出栈:[%f]\n",a.data);
e_z ns&P[2x!R                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1UD)Fvn`t,H1vC                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/([$i}K5j
                     printf("结果入栈:[%f]\n",opn_tmp.data);)VQO&th?hz
                     break;z5|!Xj!oX:F.^4v mT
            }
:@:q*n4M8{e-mv         }
lN|0I0m6H         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                .d/~-If7y tp@3SC
    }
;q:L5_Q!g!Z!Vg     GetTop(opnd,opn_tmp);5r@;L6l;z:KO
    DestroyStack(optr);
-^eR.| ^+c6j,nt|6A     DestroyStack(opnd);
V5s1}R"yM     return opn_tmp.data;#g&Z[LSr
}
+Itb }wc1O.M)f X~Y%`9iBl e1Z*\
char *killzero(char *res,float result)
1tIl-CX"V;BO0C { P@P7p9U3E#D
    int i;
&H K'pHf (o`8dO#TyU3Tm ?
    sprintf(res,"%f",result);gn clx
    i=(int)strlen(res)-1;
4R(aP t4p\Z w[$Y     while(i&&res[i]=='0') e$i7Y8L)x
    {)V4nn4Oc(l
        res[i]='\0';
c5W j~6C0S5x         i--;
?7Jo+@0~SO     }
"Ovk McO,q"uHJR     if(res[i]=='.')
Qhp6a6td&c         res[i]='\0';
'VO-[7D5JyGh     return res;+ru5i-m#_ R
}
E3iD1j4k\,h
I(Ze:n1Y|)kNSL int main()(~#C-i8b m
{
'VVk!NDy     char ch;
,@5g\'bl2H r+C     char res[64];
EG-a:o*n~     float result;0fch!HDM
    while(1)Z`,oP9iA\j
    {,@0Cq BWP~0_A
        result=compute();
-L*Jkc ?*IrC0F         printf("\nThe result is:%s\n",killzero(res,result));
KK7YwSJ;y         printf("Do you want to continue(y/n)?:") ;%S;k;V*}#Tp a
        ch=getch(); LQ8Fv&jbY6{M1T'df
        putchar(ch);
S-QG:R0F         if(ch=='n'||ch=='N')Tr4SKn{e
            break;F9w9Ma$V)X
        else
t xQF3R]bDr             system("cls");
ngb~v \a |'O:X     }~Pz!}8O)Vr
    return 0;
II'z4[wnI }[/i][/i][/i][/i][/i][/i] H^ N Lt|'xU1S

*}j:oT7@ [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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