捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.4|qQ:k3~ q
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
~(~i1e5\ /**************表达式计算器************/
?!I-`gwy #include <stdio.h>.c)kgl;haw-@
#include <stdlib.h>
&f"@rPW0EV"\C #include <string.h> i2Sn-z-{M CW&]pM
#include <conio.h> Y9p:A6`$}u*S~
#include <malloc.h>
Z'C'x&|j%u7w
N)U$l(X'E7KY #define STACK_SIZE 100
B ZV@&WkL| #define APPEND_SIZE 10.PWO*?oP4y

/t0H1[Yg4f%m5S"P struct SNode{9XPr)_!N@
    float data; /*存放操作数或者计算结果*/ y2H+Xj(W J
    char ch; /*存放运算符*/
YG0xIk.lP*^P0DQ };
6oJKn,ZZ
EiHo(KZ!w4v~ struct Stack{
!aY7A9A ~!Y&mu     SNode *top;
S{ Of6n     SNode *base;
K.O8[c8{mL)AU     int size;
q o@6p!TUl };;j;L.X0O5Y5I#D7f
,w8|*g9I,b7G/x v
/*栈操作函数*/
3M br {+lIvk+n int InitStack(Stack &S); /*创建栈*/
p$LU2as2j1?*D+R$c int DestroyStack(Stack &S); /*销毁栈*/)A` x6dy!s}sl
int ClearStack(Stack &S); /*清空栈*/"m.@'eX*fT3`*O
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
1|Q Q!j~J int Push(Stack &S,SNode e); /*将结点e压入栈*/ Uq mx%g?2q
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
+_#i'xpaU
BxE e:[3j /*表达式计算器相关函数*/
4_1p2u-G0eh char get_precede(char s,char c); /*判断运算符s和c的优先级*/xmBq+wF[-Op
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
0G[ T*^BS:WE VSd float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/Pu-fix_O
float compute(); /*表达式结算器主函数*/
OWU8p[ R char *killzero(float result); /*去掉结果后面的0*/ f.W0T:mi
^ iCtoV(YrC^
int InitStack(Stack &S)'sQ:F5Oic HMG
{!Y4ud8Vm
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
w:QJ`u     if(S.base==NULL)jnf(i0yj*}H
    {
^q2p%X,nV         printf("动态分配内存失败!");_]Z Ju%o)M
        return -1;
;YR J5O4oP     }yH,`2z~Q,|8u
    S.top=S.base;
,b7g3pz]C2Lc     S.size=STACK_SIZE;
XtDs TRG ~     return 0;
J @A*I B D }
CH:f+?*M^%Yo t5[7C'`+v\C.U]4T
int DestroyStack(Stack &S)
3j:Q:q!pL-r {
JVXW(q q4V;?     free(S.base);M5?/e` DC!?
    return 0;1lO s ?5qV)T,]/v7K!FE
}
;mB.r0{P T2|+X
R8r!{W\8s j.U5F int ClearStack(Stack &S)
c7NhZ2P1]1E {$lDP@/O!SH
    S.top=S.base;6{f!h4e ob;_vcxw
    return 0;
h-pld5r#wO }:ok&q8Q%u@q

p[.\_ j d5J@a(^&n int GetTop(Stack S,SNode &e)#c,I.E+O(S{4I M6vfJL
{
e'](d)?{:gT     if(S.top==S.base)KZ2g|)^]9I
    {a%pt'?:tf
        printf("栈以为空!");
8b6u@ ?]i2a.v         return -1;J] @l#V\W/]
    }
~:KWaWLZ     e=*(S.top-1);
NfoM\_L[     return 0;p }$o ?+gOcE
}
.N$Tc-y-h1Fj Z 1~6k{/h^5`4fWM A
int Push(Stack &S,SNode e)R0E6x5dd? ? ?E
{
6f)yr ^ I5b`$M     if(S.top-S.base>=S.size)j0V6NI*dh7Y
    {
-?3Kz]&`3hJ9[         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));7Cn8\ C~ kQ ~ }6j a
        if(S.base==NULL)P,\;e-e B3fbo0L$U
        {Y5gz~V"J0[
            printf("动态分配内存失败!");
B4n X1x KN             return -1;
VC4G5xv9~%w?         }oio6u,v#ds\
        S.top=S.base+S.size;
"bn6nPI z)H.V         S.size+=APPEND_SIZE;rYGKT#Me#AmKx
    }`jL0R~.w;xZpX q-h
    *S.top=e;
k/odP k1v-kC     S.top++;
x J7W"y7c{9B     return 0;7Zw qe5M:M0w |H ^
}
0R MAg"HD$e*M4|
9[0KzzE+\L&BI@'p int Pop(Stack &S,SNode &e)
(k/c6?qL%o {
:wX0@:?II9\_     if(S.top==S.base)
p;C'}3GS~,j/[j*sx3H     {
O"n^0h2Y?x4X2s         printf("栈为空!");.mqh*z}3Q
        return -1;
z ]-Z;j&Q#aC     }?{w2m WDLJ:p/I
    e=*(S.top-1);
(r6x;M4_h2c5?wA     S.top--;
} Xu+ydp/a     return 0;
#h/B??1^#` }F8_3^HYmtF_
d9I lNP l j9c8v!T
char get_precede(char s,char c)Y`N+O hu
{
1g0V p*D,k(v     switch(s)
.M^r1J,o"i_'C     {'j8AY7|;NN
        case '+':                 w:Btn2J
        case '-':~!feUu
             if(c=='+'||c=='-')
!z{4bv_@3TgZ'F4?                  return '>';
A#n+U1Z2Pc              else if(c=='*'||c=='/')
| q/g9_k5KIW w_4C q                  return '<';*}LC?%p'S;Gh
             else if(c=='(')
3vVQ"Q9rF%}6f~/h                  return '<';&?#kT&xVr
             else if(c==')')
qI P!|mI)M!N                  return '>';!k"\'P2v+d Pv
             else
b(_U1t#w+K a3l|                  return '>';
y8y'EI A         case '*': N8c~/} Q^*V_
        case '/':)W;b:}wX*D,I
             if(c=='+'||c=='-')4x"s%z:_}A%xV3j
                 return '>';/]"k TW.ZLN+C
             else if(c=='*'||c=='/')+H!r.GW B]X:|
                 return '>';
U$OIF u$~F0n(~R              else if(c=='(')
"[-o:\2n(i4V                  return '<';
2FC6d tn0ZF7w0f"z              else if(c==')')[9KV8b"ejw v
                 return '>';
q ?Yg+Wj!zEj"n              else
6g;p#dE)K H:RP                  return '>'; {(Px TY B#L;I
        case '(':
P1M'qN'Rf6J              if(c=='+'||c=='-')
;I3MU'bY,H|'Uy@                  return '<'; t4K.sP ]2sK ~
             else if(c=='*'||c=='/')
*UcOw1L2kac                  return '<';
?U9_x1I;Tyo)p"K |              else if(c=='(')
kT/[&Q6c x                  return '<';,~qrhvab
             else if(c==')')*S6[,`dj
                 return '=';3_W?2m.^
             else%VSLnT:C-yo
                 return 'E';+[*@9n9y.hn\.~6B4Lz
        case ')':
ud,J1ys o[              if(c=='+'||c=='-')
n6dSV5C3j$}%r                  return '>';2Dq(}%]fV*n
             else if(c=='*'||c=='/'))wp(x)b6Z"| y/AD5I
                 return '>';
X.c-Rw:h$Q              else if(c=='(')0W0hp0p(W.s:~
                 return 'E';gp{1}L5@4^Q
             else if(c==')')
3uV9E!QU;W?"NAP$w                  return '>';rp`-[+H
             else Mc~'G7I}.~
                 return '>';q ]%l }a!M4a
        case '#':Kk&hmU)YI\1e
             if(c=='+'||c=='-')%@rM2][!k^_
                 return '<';
cP2A:v3Ef(A              else if(c=='*'||c=='/') Gp+|w,Q3s
                 return '<';*kz"Seq
             else if(c=='(')
!V1s6Boy                  return '<';
clz:R@0\Q V4Y              else if(c==')')/teD6o?Q wT0N
                 return 'E';
3[&E0w5OM r              else.~*TQ XS,P!ZX
                 return '=';
v_9Dr3hk#]#V%p$lX         default:
.ML)S@~/Z              break;!y0fA[0Z)S!N X
    }1q!g!I]LS
    return 0;    g ah uPy3q(N
}
]E3}})A "BM8pU T U,dgv
int isOpr(char c)
-q\*?7Z&|d0b {
4g){3X'w|[U Z1p     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')\,T(Nl,E{;X-S
        return 0;HX$?9V/n U
    else )~t aS `#K
        return 1;~m,i1DL;eG
}2Y8iOg5y
/nYlFl p
float operate(float x, char opr, float y)
$a2r;C]v{ {
&Uw,M/UZ+P8u     float result;
r&W8R^W}%m"]     switch (opr)
R^'zTw_v     {qGV mHj{[
        case '+':
,u(S1~5Xr              result = x + y;
Z-s"X'ibH              break;$Y`Ye/T.N q[T
        case '-': B SaP$X#TI
             result = x - y;
Abt+D+t*PB0kT#m*z              break;jdrdj'W7e3V
        case '*': aI4hX z~$d/A
             result = x * y;
[;m:m yg"T              break;3lw$P ?*A F"D'g
        case '/':
F j7n)E Q,PQ#~|Kp              if (y == 0)
P eD RS6K]O:qx              {
?Fo'Z V ~                 printf("Divided by zero!\n");+X8TC_2CoL7t
                return 0;\:w6f#Z)d ?
             }PAJ)GqA
             elsep |y+R!G0uCu
             {'Hy&l/f[Rw1x3p
                 result = x / y;
)w}%xe!EyRt                  break;
~?@6Izr.C g              } w"LS$w*l{ n
       default: )R/k8x.X_A&v
             printf("Bad Input.\n"); 4kk9?3E:b;`+u@#V)}
             return 0;
*V;O|;c9Z     }
1tC;@%fL5?+A`6P     return result;
n o`7\,tl0Z }    5|&f/u+n,b/_f

7MY1m? U(` float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/%c)hES!W
{:u#VGP3`Z4p0W n$g
    Stack optr,opnd;
ZvhQ_ ^DQ-P+K)p     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;9ZKQX]V_
    char c;%@5N"i TEuF B8g
    char buf[16];
7iJ+x;_\$T.~     int i=0;}!p9V V4Aq0V
    0j2{ C2WI4}
    InitStack(optr); /*用于寄存运算符*/
H1iP4wL*G     InitStack(opnd); /*用于寄存操作数和计算结果*/n2V1gLf%Q
    memset(buf,0,sizeof(buf));g\0uB{1c ?3q _7]6y l
    ~%e!V!o!d$_$o)tc*v
    printf("Enter your expression:");
w^M$O*@*za]`         %Ycbr8Vz j
    opr_in.ch='#';R8O k\,D
    Push(optr,opr_in); /*'#'入栈*/
^S8}B/U ]Q     GetTop(optr,opr_top);
'I]3T8M6p/br     c=getchar();
S R4n{v/[/TD@     while(c!='='||opr_top.ch!='#')
!G\^W8c;@w     {
9W5cMm-H,DD&Q         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
oyr_|T@e         {
5i$X9pdr%YZ7mr             buf[i]=c;0~#fZ"Vp
            i++;
q+x W4fr?aC5|3V w             c=getchar();
L9|9\!I3hR u2p,Y%x         }2?-c f*SCY+yKf+Xk
        else /*是运算符*/
Cw#QD+j0DR7T         {&o'O4IV,g:w|
            buf[i]='\0';
n+Q0_l/aX             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0i7P5L:pc4j
            {}.SX} Ov | Nr_:Q
                 opn_in.data=(float)atof(buf);Vv,OJ m_V/x
                 Push(opnd,opn_in);FE$h)xhz
                 printf("opnd入栈:[%f]\n",opn_in.data);;w/e%D"Hq1j
                 i=0;
3@;A2XB { m u5K0d                  memset(buf,0,sizeof(buf));9K-] N.~N
            }-G;?)O6oe.R[
            opr_in.ch=c;
ql3wLb             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/aR@!Y-\R%U4S \K/Y
            {*j+bnC6D!Lh$}
                case '<': /*优先级小于栈顶结点,则运算符入栈*/Z\^p i
                     Push(optr,opr_in);
@._!VL/S_2P                      printf("optr入栈:[%c]\n",opr_in.ch);2D Xme!n/?mj"r
                     c=getchar();,c ^R)a9Jk|H:g
                     break;-R l8D.O|c-nP S%c
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
_(O vNvi                      Pop(optr,e);z6t|n~:i8w
                     printf("optr出栈:去掉括号\n");
-BXJ9O9]EiU                      c=getchar();M1JGm$hp\
                     break;!gbd4B9h
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
l2U(j{`                      Pop(optr,opr_t);
d v8wVh\m1a                      printf("optr出栈:[%c]\n",opr_t.ch);
sW?szL2{r\0I5q                      if(Pop(opnd,b)<0)AN'T`BZ
                     {V*Wz(}l&x
                         printf("Bad Input!\n");f/k;H-j#e*b
                         fflush(stdin);6pLq&sa7y{I
                         return -1;
5? A:KR R                      }:|y$c`MH;V
                     printf("opnd出栈:[%f]\n",b.data);Wu9V+[6m)z
                     if(Pop(opnd,a)<0)'z M5E_7G"T/[
                     {*RMMLhFM
                         printf("Bad Input!\n");.^/n D~e4hJ
                         fflush(stdin);1sB Hn HVL
                         return -1;%H^v-iQ"U)oNd-x K
                     }Ui&P%H-C
                     printf("opnd出栈:[%f]\n",a.data);'Vn_7G.Iz%k
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/&WJ B3~@dO6fC+B
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
V6KNI [                      printf("结果入栈:[%f]\n",opn_tmp.data);
e)~2U6a+^ Z ~                      break; E{!Nv,E`8o0l$b| f
            }(~,EeQ;VB
        }
|D%O9P)z2v|8ur%f'M         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
:I:Y/cR+r7{'SX8~k+i     }U,rUj-DYO s:t Kj \
    GetTop(opnd,opn_tmp);b$evDDlx J$j
    DestroyStack(optr);~ d1S0g?
    DestroyStack(opnd);x@D U h*e-_+gO}UX8B
    return opn_tmp.data;
*da%b]CCa }Z:r]2r3BH

z-mX~~:O] char *killzero(char *res,float result)
$eW!b)S(X!f2Ql {'Q@ ~ t'P;lr N4B
    int i;
(n&M2IGe6pM
Y4]&?K.jpXk(r     sprintf(res,"%f",result);
)]1zP^1l     i=(int)strlen(res)-1;,@W_"?(s
    while(i&&res[i]=='0')
I0ROL-j;j {/}.D!f     {r P(Z f:Ad,?'e/A,t%KV
        res[i]='\0';
-c7Ktf-EB         i--;g2E4c6E6`}"s!t(x
    }^'AI\cs%`tK,s
    if(res[i]=='.')` tJ-Us
        res[i]='\0';
F;ub0WZtz y^     return res;
{VBn Jt3q }[a+Uary6t(~
'wA$i-RoYDB
int main()G)z.p#D g i+?f:sf3f
{
as5xn2{K2X*E     char ch;
-[-E:j+l2f     char res[64];\$g K4k-sx fXzv
    float result;FW-miV v5zF'y3Uc
    while(1)
F4d#b8FU6P1v     {`3p#Ypj:~~
        result=compute();
la%ca#Hp/qH*[1d.}]         printf("\nThe result is:%s\n",killzero(res,result));jn5aT V W[
        printf("Do you want to continue(y/n)?:") ;
4B'^P8xB2f G%r&c         ch=getch(); w"HN Z5RB[
        putchar(ch);!N eU+Oan@ bP
        if(ch=='n'||ch=='N')
|Ub M [};H0@             break;`-m(n J1T%][+jb
        elsels'o}OK]g
            system("cls");*fV+i]*NDBO,G F
    }
@8GK,S/I4ap2k.f     return 0;y^-zj6{6d~$Js
}[/i][/i][/i][/i][/i][/i]2F Y3@+i,S ras [3q8v$Q

*jR\H J [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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