捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.4nP2viUiJJ
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=/g^)C9d0g
/**************表达式计算器************/7iGO3B;\4?1d
#include <stdio.h>
d&K!@w4Yu #include <stdlib.h>&liTtud&p
#include <string.h>
I1l)J8L!}.{)ym #include <conio.h>{%J mD{
#include <malloc.h>4}"jL ]E4q5RK,H
G_A$VgOI
#define STACK_SIZE 100 w]$u9m~1|Y {)\
#define APPEND_SIZE 10 `:UUf`_y

'Z?h9RX;xgd!yF @D(oS struct SNode{
} d0ZkH     float data; /*存放操作数或者计算结果*/8_Q7u"ji;m#?&i
    char ch; /*存放运算符*/
l?f-Rr };+l,zB'L"e&Ru

)h2x)x_&vj struct Stack{6_;b2D\Os4F
    SNode *top;
\5BE l D     SNode *base;8xD \:K'E9sS[N!y
    int size;]J$OC9Vr8C)dJ
};UQ}$Y7a;r2L

{Y1]nc^E /*栈操作函数*/o/Q-A6x7P)Z^0m
int InitStack(Stack &S); /*创建栈*/)Bl]F~^#E `0CN"I}sT
int DestroyStack(Stack &S); /*销毁栈*/6f+@6h#qr O5q C!]6_
int ClearStack(Stack &S); /*清空栈*/"E,W }*s$u
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/1ycSc| U$B]WQv4W
int Push(Stack &S,SNode e); /*将结点e压入栈*/
$L%H/f Os T int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
,sT N!Zk b5m-b$kg*_)D -x)X8Q+`.z$t t/~
/*表达式计算器相关函数*/
`1F*[ th,V7Y4m char get_precede(char s,char c); /*判断运算符s和c的优先级*/
-K'wy G%jc;x Pz int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
3? K6A,lT.e float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
5v2G7rS h&c.r;R float compute(); /*表达式结算器主函数*/3iH N:qyR;k
char *killzero(float result); /*去掉结果后面的0*/ x2bH/Cn Pm x#cD+[
q6['}m+v)F2T
int InitStack(Stack &S)(Mq}4`"p0z!hu
{NkM0X{c
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); ?s8XA,Kd[1Y
    if(S.base==NULL)b?5x;^5q
    {
pL [dnl+C"Z         printf("动态分配内存失败!");
}~`-R"Ut         return -1;
,w9T.G*Gq@'IPn     }
[m8ee1ik'c:x-Q;A     S.top=S.base;;e`$a2d MfA&w
    S.size=STACK_SIZE;
7y1qM-WY3?;H     return 0;
6I P S2A1g }
w]HBi!c"sp w \)iU.El;r
int DestroyStack(Stack &S)2Y:_ZfZs8c,R
{
!C K|8Z8uwr     free(S.base);Y7R8F8s'}5S|
    return 0;X{H$eAE/Rl{6k
}
C"s`)~'_
3KI!~ OBTa.z int ClearStack(Stack &S) `Y?y+^Mq
{
d+wj'n^K @i     S.top=S.base; q+s,uCS*u,h"S)o
    return 0;
J sI8Z~ }
C0}3iVU |d R!S-E WZ]c*r IY3R
int GetTop(Stack S,SNode &e)/LuuE |V
{!Z,TDP%I9Rq
    if(S.top==S.base)c8@F3i g1VH
    {
O~HJt3U}[+P         printf("栈以为空!");!M;]p5O3|*_f
        return -1;6}7I"Tgb Ek+p
    }
J8_f/iT0?6h(G"J     e=*(S.top-1);
0k6FrW gLZ&^5NY     return 0;0k4B-{ h#y4u W_!n @l
}
;lbve3qo
m/OB(]~O%})t int Push(Stack &S,SNode e)Oz l4n#l#~F9C
{
x$VE"h:igOb5? G x     if(S.top-S.base>=S.size)
H-A/P o.o;LM     {5Wi,VX \mo yp{
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));_/n1](z}
        if(S.base==NULL)
y0n)D[vHEn {8j         {
/O4v4GS+n             printf("动态分配内存失败!");
2^?#f7A;k\ ]b;F             return -1;
h6~M h zuo8?2@         }gL4t)r h&awPy
        S.top=S.base+S.size;|#F-t ],RP
        S.size+=APPEND_SIZE;lmON[Hd(G
    }?5@1C2he5L
    *S.top=e;
eJ5c oYa{     S.top++;wh4o7MV!~
    return 0;
*?F]z I o/Cj }w fd$Q$q!q(]Vv

5X.Y.m"N7d"q\:d int Pop(Stack &S,SNode &e)
ml9q]#b t O(D2o0s {
O-c'a LZDZR     if(S.top==S.base)
*i*b9PF s$Vl     {
6Rm\zn d|hT         printf("栈为空!");]0|wHv4D,_
        return -1;
'Y~8R ~a C%E_     }
tKgig     e=*(S.top-1);
M?8C/^t{     S.top--;5d+G;t+O\!d
    return 0;
*wrH5Nxv }
Qu [%QXp;j |D ytj4vU%j
char get_precede(char s,char c)
4enS1V9H$p$Vf {
/Y/H9~yx)c     switch(s);Yv6?n8S"c:M#\Z
    {
\bX0a5y tN(h         case '+':                 
Ceu*_*p4`         case '-': P3j7YCd
             if(c=='+'||c=='-')
#a @P8Xo+F+a                  return '>'; C&{P B|GT
             else if(c=='*'||c=='/')t rJXq&}l
                 return '<';P,g,iH\
             else if(c=='(')
j.ug0g Q2hv8R/i                  return '<';
L+]4It;@!Q8in4Iys'x8IK              else if(c==')')FYmJ d[} sk
                 return '>'; QA Dy;D Deh%r-p
             else "aI3r1U4F"k%d#j
                 return '>';`.g$\4}N0p v
        case '*': vxz uw&J'O
        case '/':*LMq$_ AB
             if(c=='+'||c=='-')
E,k`2s&vN9V                  return '>';
#]:u#xLS              else if(c=='*'||c=='/')4^(] Q*AtD-DlF
                 return '>';
.r#A$ek p@              else if(c=='(')`8`BHQvn
                 return '<';7a mM1`D U
             else if(c==')')
(P nk!I8[                  return '>';
{zn yW qq              else;\ c;L-})Ar D}3KQ
                 return '>';
eM zO6H OV3`         case '(': q%CGk#R`7|s
             if(c=='+'||c=='-')
|As Wz5Pb1s                  return '<';
gG-tp(~ g              else if(c=='*'||c=='/')
K@]w,j9X                  return '<';
7vCR'GI"K,l              else if(c=='(')
V v?n"`                  return '<';
DYS$j~p              else if(c==')')2J"n3v%[i A
                 return '=';
,A| C:W5y;k$E$\L              else
BFA4x6}4h F4B                  return 'E';
${ji8tScGQ]u!u         case ')':&j!Y5K2iCyb
             if(c=='+'||c=='-')
%JE/H RiM?Sr#d                  return '>';
%k}I)l|(]              else if(c=='*'||c=='/')
*a4p;wY0[f4^RV                  return '>';
W r!p8u4H&N w Z(d              else if(c=='(')
{-]/cT u.Z2I*He                  return 'E';
p+r,~/OV"Hs              else if(c==')')8[.f!l\!H*F+{B3i
                 return '>';bJ6G F"`E/^3u
             else4o1B|#OG]8nU
                 return '>';
Ls1~#n(f-j)u         case '#':Z3IZ4P0Gk,L
             if(c=='+'||c=='-')
&wb'?4U(LM                  return '<';.aY`zpn
             else if(c=='*'||c=='/')o-IL:Qt
                 return '<';
iFJQg*@ x:C.K              else if(c=='(')r*EQ'W{:]"X4` J
                 return '<';
#a9?,r^%G p_O?              else if(c==')')
1lx U,UQ0@4S U                  return 'E';7^ mBH/MTJ~ W
             else%y4I't9f s
                 return '=';s Q1t x`I!x OD
        default:
Yys2d3K:i*u%} v)x              break;*U8N7d Zq m c}
    }VK$HN*P
    return 0;   
.G'\4da^Jd]K#w }j+{RoXl:q `C

YZ ^2V)X(uJP(? int isOpr(char c)
K,?!g6rns { t7szW4f9f(zt
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')G8u/T@ i@h7W
        return 0;
5|*s:mU Nr'TE     else
0e*n PXX mVV5H.mX         return 1;
M3Y\f `n*L7j%|'T(n }{4lv2c3n#p AONm

.Tm\XVF_n-S float operate(float x, char opr, float y)Q3nQkA
{*tg*T"mWR3a
    float result;0q iI l yNI
    switch (opr)#e\q&bM#tK
    {
JW8zTF9G ?P         case '+':
H%C-I*r}~N2O              result = x + y; `!UaJ|#rrk4uW;]f
             break;K"_6J_S{
        case '-':
%yJWo.[!mK              result = x - y;
FX;Ns y;U_              break;"]1t$Y Ksm
        case '*':
aIF @'C\S.md!mR              result = x * y;4dvL&?5^/C-C
             break;
*od"SwzrS al         case '/': :t!rw&\r;v c6~8K3d&f
             if (y == 0)
OS K`E|-E4@ g              {
m7B"t3q*KL.PF5K                 printf("Divided by zero!\n");
vR(N4sj"w!YG+j                 return 0;7j0dW0QxI4i
             }8@A*E*@L,i3^`;rh
             else
-?3a~8BYt              {
/gii6X+]                  result = x / y;&]DrD0Cv\/LA
                 break;
R m4o7r0}J#M              }axn4^q:r } V
       default:
g5i%^3Br:H              printf("Bad Input.\n");
x0o{ U5M              return 0;
}$rOEM&CK5^ J     }
nt9~V8r     return result;(W%Wp,h e3q%@y
}    wEF%[ u
hgM/RF/aM
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
aQ^ A"Vk"Zjr {
rB5EF{ TX     Stack optr,opnd;_[o.| e6ha
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$Z.j%LvXg's*R.d
    char c;)v2V5ga w8|
    char buf[16];
@wO%q)@Q     int i=0;
{)s;bW O i#_u%yK     +q4bB iL,\|k-A
    InitStack(optr); /*用于寄存运算符*/
l!Z cUhkL O)Tw     InitStack(opnd); /*用于寄存操作数和计算结果*/Ho[(AB-x Y!J
    memset(buf,0,sizeof(buf));/mA(Z#^GK!W M1t/{
   
k8SG#F0o SQ l     printf("Enter your expression:");eU0c}8I+V#e
        #R?W.kG*k
    opr_in.ch='#';p(pr3@U&Q:}
    Push(optr,opr_in); /*'#'入栈*/
3zTrC3b^O6_     GetTop(optr,opr_top);;zl heE*|
    c=getchar();2d!`L/x8[Z].dT
    while(c!='='||opr_top.ch!='#')
p['zMi:j h     {
'^?)jYi         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
-g z3]*] O$A"a         {
,B%@'Y3W8L-^%hVi             buf[i]=c;1xnO h*Ag'Ik
            i++;
"k0A[ Fu#U             c=getchar();
]Hn+u KP2ZV         }
'[1k tm#p'i'wAo6Dil         else /*是运算符*/M _#])k3?0A
        {
!c E9k4H2i             buf[i]='\0';
&i4H/]4m+S             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/1HD fS;GE!?.r
            {
'n@!J ~%P$NVc M ?%o                  opn_in.data=(float)atof(buf);
Eva d:`N([                  Push(opnd,opn_in);f/`5Kg_-i
                 printf("opnd入栈:[%f]\n",opn_in.data);#EZ{8p3ba6O,s0aB'_
                 i=0;
T3Jo|9s;c!A+|]$Xy1|b                  memset(buf,0,sizeof(buf));Nsq Z;Pu
            })m}!GxJ"V
            opr_in.ch=c;KW3r~8n;l/Y
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/Z,s-o dx_9\
            {
qD!bG}8|                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
l"k#V,z:Z,S)V#prq                      Push(optr,opr_in);
u/?C:?gd0T-|0S                      printf("optr入栈:[%c]\n",opr_in.ch);"S,}o'wn@c
                     c=getchar();&L8hC1IGAU\*H`:d
                     break;U5}8FaRC@;AS(c5Nq
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/S6Ev1L|)cq
                     Pop(optr,e);i dtMo bm%J
                     printf("optr出栈:去掉括号\n");
#T?po,kx                      c=getchar();
:m%bT+U&\m6O                      break;
Be*gN L                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
I zv L[C"Z$G%}                      Pop(optr,opr_t);B;q3dYV'Z2T;?
                     printf("optr出栈:[%c]\n",opr_t.ch);
x!Ea:Hn8p/CF+AP                      if(Pop(opnd,b)<0)
.b UpLB*C                      { w!d1lP%k2B
                         printf("Bad Input!\n");LA^#] }0x%d
                         fflush(stdin);"A:^d%]U,_
                         return -1;4KBg+@5SS;uf
                     }
&Y,Su^Im8n+X                      printf("opnd出栈:[%f]\n",b.data);
.KES_?:i\P+T                      if(Pop(opnd,a)<0)CiC,LY!i!`^ c
                     {ay P c ks i:_n
                         printf("Bad Input!\n");Qo'Ih1A^-H G
                         fflush(stdin);
Xi3Gr,n%`,Dza                          return -1;
,Q9?n XP"E4ik                      }']x b y~1L-@ ]U+i,LO3o
                     printf("opnd出栈:[%f]\n",a.data);
+}G]4d*y G+h6A                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/3T,b/wEr
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/i$y6U'W2X9A K
                     printf("结果入栈:[%f]\n",opn_tmp.data);
T,M4r Xy^g3I                      break;9\!s3uPuu9r*J
            }
I1?+^A/c,t te5N         }-W ]A7F6lC
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                b{4B0c2K$b"R
    }
p"N)_K,}     GetTop(opnd,opn_tmp);
$B1q3o!c O} |S M     DestroyStack(optr);
}6q8IWs{     DestroyStack(opnd);+Ji y}5A;o-G
    return opn_tmp.data;_F"H5h]B&r L
})c-DY3QNE9E0X7q`.A

8Zv-f(L9b+_ ? char *killzero(char *res,float result)
u NG8~XMO {9A'g;h@#_
    int i;
W9[T7S!l{&_ 8v0X ip_!No
    sprintf(res,"%f",result);,\*A8F#F\+N
    i=(int)strlen(res)-1;
C4jQ6^5ckw     while(i&&res[i]=='0')s0lt6}$GftkGf
    {
0s%Qs"f1{cH^2A{y6~         res[i]='\0';
dq0S Xj Q         i--;g"Sv(l1|J;?
    }h;d6xA:x {[
    if(res[i]=='.')
!_[(|H{^?         res[i]='\0';
&K:W+|rAv     return res;
OYxMI2k/i Tl }
2n,Q6p$tq.sO 7X(]G-O@]C
int main()"?d^&P%|.OV6F^
{+Ss_.^S7EFI"r)A
    char ch;P(t X!}*ya2O1UW1Fu
    char res[64]; j)VN0?/X,o.g n4J#Z
    float result;-vrb)U0g&U
    while(1);iY0|]9c F)T&gt,Yy;H
    {;f0G-\Tvj)q
        result=compute();8_,P&|!N#XR+i3Z
        printf("\nThe result is:%s\n",killzero(res,result));
BIz}5T8B         printf("Do you want to continue(y/n)?:") ;-K;g3M(~0S#^4H/jq
        ch=getch();
4LMmU(L+TV*| aC ~         putchar(ch);
0q H`XY;@ UO         if(ch=='n'||ch=='N'):{3x;R+f0I _
            break;wm a,r B*saTf Rw
        else:}OsV nw*gx&P
            system("cls");
m)U1pBq5O     }
8t#Se{ R l     return 0;
E*H0\3IUr N;~ }[/i][/i][/i][/i][/i][/i]n9zE)T,p f

zL a&w9P Q [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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