捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
N(dM:pX9p 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=5F y)T!U5koTY
/**************表达式计算器************/#XNv2X_W5M
#include <stdio.h>
[w Bo)G #include <stdlib.h>H/j W$]X&bF$}
#include <string.h>
dC9I_.?4QPr8T #include <conio.h>
)Y#MEI dQS~4l #include <malloc.h>J#`.vZ/yD
&i6@)XWS:Tv1b
#define STACK_SIZE 100
XG v7sY!HI(l6_ #define APPEND_SIZE 10
N W!c;@9C ]di g9QO&m2i5d4~:c T'F7x
struct SNode{
'_@i*yJ[ZoA     float data; /*存放操作数或者计算结果*/
D^O/[u/?tm ~     char ch; /*存放运算符*/
'U~P'{){@Q2S };Ugjz(k` IU

tT2QN:V5K']!U struct Stack{']KO1Y0Y-AwC C.{)B
    SNode *top;ciK-F-I^-t `
    SNode *base;,Rh4sB%hg*l!w8X
    int size;
O n~ roP'm };
M3cjh9a Gn,h
'mq}7Ec,Ql8d4a /*栈操作函数*/
(ny ]%?Q/pE int InitStack(Stack &S); /*创建栈*/%iKWr%K+H
int DestroyStack(Stack &S); /*销毁栈*/
kX zb:u@ int ClearStack(Stack &S); /*清空栈*/
]p;b:LU7c int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
|^Ob rOc0? int Push(Stack &S,SNode e); /*将结点e压入栈*/
v4j"xnR!f#@C0NL5e int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
~ ^*Z IxI{6X,mE 0I5i8|6N\ X1TA"M(fz5s
/*表达式计算器相关函数*/
@}#`"@%Uh ToYS char get_precede(char s,char c); /*判断运算符s和c的优先级*/T;k%a*yG1a!@H
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/0{RS\(V|S
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/d NG0a)p.C @
float compute(); /*表达式结算器主函数*/
L7@ };V&X1R:O A char *killzero(float result); /*去掉结果后面的0*/
6fg)T:a"} `aI
*H5ZOZ}E int InitStack(Stack &S)
#r$u,Q1m2I {!N@2p"d&Y
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));#c [J?o ^h
    if(S.base==NULL)H!h#Xb Yr(r2aA
    {p r)D&^l+s2[z/r Pl
        printf("动态分配内存失败!");
;}m |w F R!xO L         return -1;WF6O(vy6Q:b&s
    }zU FU N roH'|{
    S.top=S.base;x-C4}$nH{}5e/E
    S.size=STACK_SIZE;
Gv'Le5~!P-e     return 0;i8GS$ged
}s/]+Lhn

JT6Q!S9Q*UR:[ int DestroyStack(Stack &S)~q7SF&w vL"uS2E
{
\E6oWk;J     free(S.base);&Lknj:} YB4_)V
    return 0;
I$O p`U&{u+Yd!w }8@@ Or i u} |
@v,k8n6j` c c%V:N
int ClearStack(Stack &S)
JN R2[8^.P}2M { L#MtB.E(ii v
    S.top=S.base;
-~ K["C9c1O!S     return 0;
&|XJ?f{ q|%]/E }+P|*^g5o2pT
CJl8|'_P ~;J%C
int GetTop(Stack S,SNode &e)b)zWrzf
{ NZ8W4r/j
    if(S.top==S.base)(A'G l+X d2D
    {
|'@ qgWQeD         printf("栈以为空!");-Vs+[6m(jf1p
        return -1;
p0Q,H1g j1y4r;u/{S     }
8wY"?$I)[.U     e=*(S.top-1);PtA8\lIA
    return 0;O$O?e0F
} ukh.I#uqAv Dd3B

G3G"`Z:VDz0y5_*z+P int Push(Stack &S,SNode e)
2u#i.Z&pg/W;r,A$D {
6IN0IogbZ7X*s7s     if(S.top-S.base>=S.size)
A}3[D'o%N1XU R     {(H)F2vb6U zC!y y AX#[V
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
UA&j,xr7Fd         if(S.base==NULL)
(N{/B { CGdLP)b         {
B4v4mx8@1n8_Y             printf("动态分配内存失败!");
%M6n4m4z2M!`z/y f             return -1;
&uc U7b'M2}         }*J7?Y\+R{*I
        S.top=S.base+S.size;o6j;_kx'mm
        S.size+=APPEND_SIZE;
r$u6U(GWt(j3A Q     }7G2tp2D*j9_
    *S.top=e;
%IOS8K!H(~9f kz     S.top++;
!Mqo7W2g}:W0@{1P     return 0; { I!J)Rw#Q7o A
}My)_5^ fR

R(X U!CN;_!Q int Pop(Stack &S,SNode &e)
,JW*j'b)\ W8Y mC"Tq {
_M0E0O4B4~&h^     if(S.top==S.base)i;xEf!}[L4|
    {0P%pO%N0sF7e
        printf("栈为空!");
Gs(|*`4nj\Vu GO!~*}         return -1;
`_ad%K`t/{     }+oC$N | t4Q5R{
    e=*(S.top-1);
M)[fGV[%A{&A     S.top--;
b6ku9|Y)S0\*K     return 0;
7c*^$yaoN%Q9m }2n3?1d9d6q b
+P-b_ mE0ntM]
char get_precede(char s,char c)
(C @0h}&}/X {_ D{{3[&m tQ
    switch(s)
j!^.jLIxMQ     {
H!YA,~&X         case '+':                 -R8Rcf o n%eK%U.K
        case '-':
9SY.Pm |              if(c=='+'||c=='-'),KJsw2O#O R
                 return '>';
n7M?"RPc              else if(c=='*'||c=='/')3}6Xh#F?]"r-x!v4}
                 return '<';
hQ]!vWW              else if(c=='(') E ] s:\.V8WQ
                 return '<';KA}\;e9Fg Rw\)c
             else if(c==')')
ua vr A2D                  return '>';
'V E,SjQ7AO#^9E `7Z              else c*Co9`)Bsw
                 return '>';
,v(M&]_.n         case '*':
"lH/z br/F"^         case '/':k n*SM8OP4q R
             if(c=='+'||c=='-')
0}uiS4RB:y                  return '>';
4ul)J;eZ8s              else if(c=='*'||c=='/') p?D8e_ b8S
                 return '>';G T0kA/lVl'D
             else if(c=='(')'C#C `3D#G!V\nQ
                 return '<';5z6iEk7?X,t`?2yz.T
             else if(c==')')X#Ut c8sT1sF
                 return '>';"c E0`#k-KR
             else~j4]y e;bY0J*X
                 return '>';/@H b3J4e&Rp3I
        case '(':
.C,sA3h;B)D v'R#L              if(c=='+'||c=='-')
)I HM0\1x!a2CR5Oo                  return '<';;t3Xn H h x
             else if(c=='*'||c=='/')
$r SKL R qH                  return '<';
C P8PmC_4B)yD              else if(c=='(')o5fpd*nf,^8\T
                 return '<';
0? lX/_+O              else if(c==')')
|4r`%W7~TzU                  return '=';sMC&}O5WO)@&C4Cb
             else8o{%Jy8w ^p)j'h!W
                 return 'E';
wuz{O         case ')':EuYa)Y$mL
             if(c=='+'||c=='-')2Ho$g5_1c/V
                 return '>';j&jo7@+pcX#m![/^
             else if(c=='*'||c=='/')
3k7V[&r$m z                  return '>';L+A N2U(HEo
             else if(c=='(')pH*](BS
                 return 'E';&_;L@fBg[
             else if(c==')')
TdG2n.j0}r+z1I                  return '>';8k h&Kat
             else
"l$_ M5D)PvZ                  return '>';7W9Y)Ek5n(p7i
        case '#':FH1T&F K.`E7x\
             if(c=='+'||c=='-');ta7^6k9y\Rv
                 return '<';
"L'kv|,i;y              else if(c=='*'||c=='/')Yobgy!B&u
                 return '<';
9i ?0z0@aGU9Hm              else if(c=='(')
` U L-D4k3F;|R                  return '<';
-?2G*{7b:oDN4{k              else if(c==')')%HXG Sr
                 return 'E';
gu!Ao:he(}:i]P              else^)o;b\h?`e
                 return '=';OH^ SZH;s
        default:8ZF:tsa
             break;
!L#lrjU9RT"j8q     }
9w0d!Aj`(r     return 0;   
9\~*u1Dw8p }7b1\$jR/U
vs$Y,Nnd3ilF~;_
int isOpr(char c)i_c ni,@&a
{
d*N|+bS1er#H#i     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')!G RT`r.q![
        return 0;
nI*N4p:Zw'`     else
];{;Qb4r-ABs1G         return 1;
s|4eX:~(x3Z^Y }
dpUL/q 7sBVP*qO
float operate(float x, char opr, float y);LX s%q6i
{
f8w*G1K I}     float result;6Z,W\~ s-r st Yo
    switch (opr)*yp.L:Z8Ty)j0c4e
    {
%e,j JA+wA6PaL_         case '+':
/N9BoE5bG/r              result = x + y;
5xd\#L[4W4s              break;
W1S C$\:\U         case '-':
nQ%?o6Fx"~ b!mvX_              result = x - y;&f4QKj0D(rz8gw
             break;
^xY6_#HM ]         case '*':
e@om]iD1R4Y)d              result = x * y;aY$e,};fY@D*|
             break;
d v0NyX+}5y:~V"O M         case '/': V"^&H8{B5w7Cr
             if (y == 0)9h7E s+pU3d6e|
             {
%r9M$C#R+D3[ m                 printf("Divided by zero!\n");
CD9Tb;u                 return 0;N(`9VwL9TO!I
             }
v$y3z/K'ReiV#i H/z              else
#[9c-R3Ee              {
DQD4U1b`w                  result = x / y;
7Hj6z.`q"?`i                  break;*Cu+A;`2x
             }%c\"z*J9k"o W_
       default:
;vbm*L M              printf("Bad Input.\n");
E+O3@P'a m6@              return 0;9ddP4kiBh?N|
    }(g(w@yrv3V&H:v
    return result;8q2q/F,yg4?ifn
}   
{yF:IH
mZ/Y.D9Nu"J| IT float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/NWs1F(W(fE2P
{K&T.u6P*X8q},|,_
    Stack optr,opnd;!UO/xRJ![d;Mv:H
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
j1{B(K1\ G#[v.F8h     char c;
zGj~fP1Jb     char buf[16];/d1nB.U yfS;V
    int i=0;
b7T2x6_B{     ,P|/y R7wd
    InitStack(optr); /*用于寄存运算符*/,wM$m'o-H b0M1o[
    InitStack(opnd); /*用于寄存操作数和计算结果*/G%W\ v`,L7f `]$`
    memset(buf,0,sizeof(buf));
^6Y4}-a"MK9]5] y6[     u1aK'u(bBH I
    printf("Enter your expression:");/r| Y k.~%n
        
)|#M&Jf3?P{0f:z q|     opr_in.ch='#';
J6zd9f @W h     Push(optr,opr_in); /*'#'入栈*/.CLIWb4cR,Xp`
    GetTop(optr,opr_top);8\(O+k(k)LV}
    c=getchar();\c-m4Ha h:GG
    while(c!='='||opr_top.ch!='#')"[G \ Lfdxx
    {{:_:C'?|6iC
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/:noY(TG%h;J
        {
:ns)n9r:q \             buf[i]=c; G*k}s$ng
            i++;
@P5j1X.Z             c=getchar();
Hn:o5~b wB2f9c^H         }
0Pv(N$@\&?         else /*是运算符*/xp,Pkk
        {;qv[*\?5Q Y
            buf[i]='\0';
v:d7m7K1yw}Y E|             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3BeI%wJ5z,Q
            {
~,w$H jQ@$Ps5Z/Z                  opn_in.data=(float)atof(buf);:MZ]!CdB
                 Push(opnd,opn_in);$g8QJ7hFU]%h
                 printf("opnd入栈:[%f]\n",opn_in.data);x;knIdX
                 i=0;
)j t{'Z"oDE                  memset(buf,0,sizeof(buf));#Q6kH Rl
            }
*NGOq$^#{QVp             opr_in.ch=c; wqw4`*?/KdeA&GO)l
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/*LJ1j0\c9mt1lp
            {]j0zp#y GC9IF|
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
*bZ` T)~WNcDE                      Push(optr,opr_in);egL9|.r rw6jV
                     printf("optr入栈:[%c]\n",opr_in.ch);
I?n:T!a!Y6k8?Z                      c=getchar();
A'G:xr.^                      break;*_w k4k/Z'tw
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1@z {7jxWEL9C                      Pop(optr,e);
JdAA`Qs                      printf("optr出栈:去掉括号\n");
~+{;l1F(Hb;fu"?}                      c=getchar();rhM?._t_
                     break;/O?O'sV!@
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/ h.Xk({ y6PI%Z}.o
                     Pop(optr,opr_t);.?U9gT2o
                     printf("optr出栈:[%c]\n",opr_t.ch);uw+R!j2OyFxi#@
                     if(Pop(opnd,b)<0)9b%M+``;l zn
                     {
OQz$\Mz*j,?                          printf("Bad Input!\n");&Z(m2X*J-T `*w.O5D
                         fflush(stdin);o$LKt+XT
                         return -1;S0Rv(L%u1f
                     }/dxXy%a6^
                     printf("opnd出栈:[%f]\n",b.data);'o"Em"hG!R
                     if(Pop(opnd,a)<0)
F9h*Is rm                      {1?yTCG#Va
                         printf("Bad Input!\n");
%c|"M8kJ:G                          fflush(stdin);!F R"d V0D)R;@
                         return -1;.W){CL8w*{#BzK
                     }
k`3U&N;E~/~d:um6|                      printf("opnd出栈:[%f]\n",a.data);:@%KYpF
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
(XqR5^t/F2n'c F `\#x(B                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/,C*]w Q tC C
                     printf("结果入栈:[%f]\n",opn_tmp.data);j L+F;C;x w\m
                     break;
"eVn Y `             }
S!U!M CWtZ3U         }9`8NRJ @"W)g
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
*Y8|r3Cw"N.@/a_?     }
k6z,yB;I h0kDiD)H     GetTop(opnd,opn_tmp);/yP \'\:P9DO:W@6XM
    DestroyStack(optr);
o@0}aXb     DestroyStack(opnd);Mel8?Uo X'U8I
    return opn_tmp.data;i/W'V(c"}6yr
}
+H2Sd6Q^,_O#_,_ 4s@"NB%M0h&^Wj~
char *killzero(char *res,float result)]!T8n}7ck|V
{
1RaU J mw~     int i;'GcD+|5__
c@ f@ qVj
    sprintf(res,"%f",result);
s&jO rXAc     i=(int)strlen(res)-1;
7kk(s7Hfw8r9A(B     while(i&&res[i]=='0')f#E-b [*Mo
    {
*M w0P)ZB!O gMQ         res[i]='\0';Vxk~P1}x+D!k
        i--;Z4[4eDVS
    }
P-W4M-@3_4sy5}     if(res[i]=='.')y4}f kn G@b Aa k
        res[i]='\0';
9h6Zvl1GNH{w     return res;2X @,rG(Y1YF
}z9HQ#nO7}PU3k
F;O6FT!U!Ftm
int main()
5vj-_9W_PMk {
5t {-P s0u7nJb     char ch;,c u9{RbOZ+~
    char res[64];
Dai'@OZe     float result;
UcfsB     while(1)
o~+`!X$j!N1z     {2Mmt~;f,cu:]
        result=compute();:`-W7Q4Cqwd K ^p
        printf("\nThe result is:%s\n",killzero(res,result));Q |7|y\9e
        printf("Do you want to continue(y/n)?:") ;6[Qh!|&H
        ch=getch();
4xZ'LY2V[         putchar(ch);
Q9c7F?H|;?_         if(ch=='n'||ch=='N')D gY_p9_4EO,?
            break;eh7s saS
        else&O7}}8K E/W#n0G
            system("cls");{0|B XO*gI7x7Q
    }
O{(khC Xyk     return 0;@3DK3pZ+Ps8[
}[/i][/i][/i][/i][/i][/i]+W F[0}/}gE
uw3|4l:`uVw+{
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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