捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.e TZ-d@5}
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
e6m9a1j ?X9]6h"^ /**************表达式计算器************/
+XBCtE \ #include <stdio.h>
qH1Qo'z{1VZ#Pj #include <stdlib.h>
].HZ?:W^#W9GS#d?T #include <string.h>
1} ~!CV$G YAq #include <conio.h>O,nH!eKB{F
#include <malloc.h>X1h2S'N(V0?Z{

h dVtpx_*v:?3Y #define STACK_SIZE 100
e*Z*xi PN&_$y #define APPEND_SIZE 10
@6Tt2jmC:H h|
;G|;n.D$n2Da2g5\:Yo struct SNode{
~,XK4l7LY e[I     float data; /*存放操作数或者计算结果*/
XO3{!c K)`9F(qB _M*_     char ch; /*存放运算符*/
`$l)@V/tG"b };
t.};S8N.QaF+R *l9X+L5{b'z9q
struct Stack{
x+b(f#m3? W8L*u     SNode *top; [%cV bZ8x'v
    SNode *base;tX5k(G*y-Wj
    int size;,R-uL"y$f9x |
};
$?S6|BH5]?:w }W:e/Sf'hx'R5l
/*栈操作函数*/
l-i1p!}%C int InitStack(Stack &S); /*创建栈*/
{q'm+{"j int DestroyStack(Stack &S); /*销毁栈*/D8h `S&U%U1t}p?
int ClearStack(Stack &S); /*清空栈*/
8p"a|'yHoS1Ss int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/y5J |2b P`Z(c r&^
int Push(Stack &S,SNode e); /*将结点e压入栈*/
^T$l{6lT int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
T3nxj'C !M4\5Xp!~X4||
/*表达式计算器相关函数*/
w u7lW%{ char get_precede(char s,char c); /*判断运算符s和c的优先级*/ y(aOl1T*MT_ W
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
)y.r%`3g U BW+K float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/B2q%ej;~
float compute(); /*表达式结算器主函数*/ K xu0Y'`9UL
char *killzero(float result); /*去掉结果后面的0*/ )D V`c DP4u
+ll2}I;xT\"A8k
int InitStack(Stack &S) W5[K&~by
{5s&]*c+rK
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
"J$N$m@2`3N$s"I     if(S.base==NULL)*T%r*G;j0w*j
    {
0X%y RhR |'d pI         printf("动态分配内存失败!");3vLi+N)O%q&[O @*Z
        return -1;
D!c#~e ma     } Z9ZnlSG
    S.top=S.base; C`w(A!Fp
    S.size=STACK_SIZE;W0lm%KI
    return 0;3W^5z eNc
}y W\aE&qg"W
p0s(D1Sco2w-h
int DestroyStack(Stack &S)FwfH)p9~5r3w
{
sw!tgR%Y_     free(S.base);*V`!|#lg0Pmz1B
    return 0;
,Z"E9c^ ^&L)o }
)X7S;c _4l.K q6s:hS S v+ZL(_Kd2c1u~U
int ClearStack(Stack &S)X\'jSZ m
{,E"h K/T,D!CRoH`@a`
    S.top=S.base; X(aF2n%L&x&d
    return 0;BQ/e1@`
}
dTf3Q4{wz j9B0Z1n,v^"U$\
int GetTop(Stack S,SNode &e)
?4[(\W bvb {
DSI]ZmS     if(S.top==S.base)NYj$lSY
    {
tx){*_6@ me1sM         printf("栈以为空!");:Ly?yH7?'F8`$[ e~
        return -1;
jj{-p5po(e:{     }
y|Q/?$l?!j*lU     e=*(S.top-1);NWo_Z%x T@Z
    return 0;
;N T.R`9A-vf-Y }
3_n3u9}o)Ok6q1c!j W)slkE?6V
int Push(Stack &S,SNode e)7C7VDKH'T9a)g8| T
{;r8m r+{5L$|
    if(S.top-S.base>=S.size)oWa.xq9p
    {N6Vq$~j6`|
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
$rra i:I.r7|9d$J         if(S.base==NULL)*Rhjle7G
        {
6FA~ xY+|o F             printf("动态分配内存失败!");
s BR7J4k             return -1;
,@^'G!n9[8n.sI(A         }
Dl^h0Qg         S.top=S.base+S.size;*k bo{5V b3I7N(C'ai
        S.size+=APPEND_SIZE;
1kM:}4\2^0BA YY     }
J*~'rg+MFI`     *S.top=e;:[~m2}6\&`)V P
    S.top++;n+_1i%O&S
    return 0;
5?m@a*G(b }:s:q6u} a` Y

6[I[U8sF int Pop(Stack &S,SNode &e) e.w{,\(TLKM
{;aX-Pxi
    if(S.top==S.base)'D b7a$ApwA%V\
    {:d5}g+RJ:pC
        printf("栈为空!");T&k)tC|[?~
        return -1;?JXv,ny)m
    } K.v+zr'_!u$V}[
    e=*(S.top-1);K;kJZs
    S.top--;
}^ p]N]@fQ?     return 0;
p+{(NU |L)dep }2@)B Q9l/U;eYvOh

R'xa'? gZ char get_precede(char s,char c)|7en@W3qq
{?2J$X6L$j
    switch(s)
7tp\?9IwIiZ~A3s     {B:}3i'YX,f-nP
        case '+':                 
nU]v:D(JT*s0d         case '-':k*}1JF'`:eH+k^HR*b
             if(c=='+'||c=='-')_*QY8L:pB R5n-@7x5Z
                 return '>';u/]5};I(m
             else if(c=='*'||c=='/').]1AQOcN+[
                 return '<';
u3i ?*P,S{.i              else if(c=='(')
w6v6I9}4h?/ek ~k'UDBv                  return '<';Z0g7kIP
             else if(c==')')'No2n.Kq4Q2^
                 return '>';o'axY*T'C8@k} l
             else 0Z5Ql1Z(a?@A
                 return '>';#V(HuUHF6l!\
        case '*':9|(i r _t'hAk pA?-PT
        case '/':W%UY^e3E
             if(c=='+'||c=='-')+TM@p*G$heR;\f
                 return '>';:PwEUx3D9oo
             else if(c=='*'||c=='/')#G4KO`vp x;TN k~+\
                 return '>';
U f;f0Tj2D5J&E              else if(c=='(')/gfg Ht9{I{
                 return '<';
4O&c8ZL%z0zfde+K              else if(c==')')*S$sFIj6}O
                 return '>';j)_zQ8kBo:{
             else
l5Pz!V.[1Xs                  return '>';
h:|*tNzb6bF\         case '(':!M+C"~C-cg]IdN+u
             if(c=='+'||c=='-')%ekB qJQ(v*f t
                 return '<'; i9`/p0j,b o&j+w
             else if(c=='*'||c=='/')S$rG-N'z0B|/C
                 return '<';
k9F4b6Z z.H              else if(c=='(')
@%?A yx-o7p                  return '<';9K g2i~!h7o(r O
             else if(c==')') ?2_]Z4c(I
                 return '=';)k~+w&I/Wg'? gIe
             else
a0~ @"sT*QK;@ n6s W {                  return 'E';
WY([Wmx:fQ4n         case ')': ov,DF \V N2~
             if(c=='+'||c=='-')
~.?ufvf m                  return '>'; ~V!^;W`(_ ^
             else if(c=='*'||c=='/')Xa*@Q,f0pd odQ
                 return '>';Ey/L%t ?zz0i
             else if(c=='('))W,S T~ @
                 return 'E';V2{*g9f _{
             else if(c==')')u,St;Nr'f[F2k\
                 return '>';
y,P.X?)B h4X xo              elseX Ri G7t6Z(E U
                 return '>';uxe.Y/w1xh+|#E6Tlet
        case '#':
s1r2nj6J4D(n'?              if(c=='+'||c=='-')
&vn3\j c-x$g                  return '<';
$o m-w*m \_%tg4Nc              else if(c=='*'||c=='/')
$G+d8QK }&i3E                  return '<';
8?+T` O`tVr              else if(c=='(')
%[elI!S f`                  return '<';,r't,\ j PV$b
             else if(c==')')E&j$W!Ty1E8P
                 return 'E';
9AH5aP}]X \"t              else
}"l bJ)^(RA                  return '=';
Kv(Tu"_!S!El R         default:
gz9kL]m              break;2L#v4IR7hSk `D
    }i"C bd!H4dp'y+|
    return 0;    M`yc6O1R X;FFA
}%nVKu9M P-Km4o
(] g\ B(d W*W
int isOpr(char c)3LYi*m3L+D
{
*[x)WL7adX;j8o5b     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
5W#?PF];B         return 0;Z[;u2W D`rvWU
    else
3\JUI:q&eN0T         return 1;/Zb3R%HG
}
O `\9?E!L
W kM;@G]5A float operate(float x, char opr, float y)@x [n{RJ} R
{%T@G-x~hq
    float result;
^O#D&Z2iE+e     switch (opr)
8R1b[$I0]FH;B lK     {[+I Wf-B][
        case '+':
@(|j7B_9_`WW              result = x + y;
:t4};S0sA(o3G/a-v              break;!q5lfz:[7p7T3O
        case '-': &G1m'F+F2k~D,F
             result = x - y;
O(h;} dx#GI'Ru              break;6R&H.S.]O
        case '*':
#Tt4y Vc$i9t              result = x * y;!D*lDm})v|
             break;1m9Z@2V3f,Z
        case '/': c9Df*I9]
             if (y == 0)#F9|^Jnp8q3p
             {'?Aw$xq
                printf("Divided by zero!\n");
$Mf6~^6\ \9Fg#i                 return 0;
!P$O4}.gSO7w(Z-b              }T2g/vn!v+y H
             elseX\U,Dw"dr:JJ Q4h/SG
             {
.d1m0r'oOwoW                  result = x / y;
n,|$D'c ` O{6L W^P                  break;9MQ2|r!i-Cum h
             }fY(f)kC-m9`)z
       default: Q6[X[p
             printf("Bad Input.\n");
2UW KrYK_| A              return 0;
Y(A?/uSm"hG5Y     }1_:V"B#R'm
    return result;
8M a{8]h:N }   
xs$UeP$QJ !RU2OPKq#U
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/0Oze8q-S jn"_-NI d_
{
'd7y~PS"G     Stack optr,opnd;
(U#xjFq+k*ZIf     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
'aS(K-{ ?!pr/b     char c;
]a-@8G3k6~ ]     char buf[16];~E]5@!d
    int i=0;7?W9L2nd x#q
    _9Y:WZ9]g/`V3m+N
    InitStack(optr); /*用于寄存运算符*/d?!?$L5N G]
    InitStack(opnd); /*用于寄存操作数和计算结果*/!p+EEA Bg y c ?
    memset(buf,0,sizeof(buf));
$[i7LTT#Lu    
V"It p(wi#Qj/[     printf("Enter your expression:");9qYTjv"Ss5O;R;s
        
Uq5G7c8`[K     opr_in.ch='#';3V.y cT _s%gC
    Push(optr,opr_in); /*'#'入栈*/;J I-o.WF
    GetTop(optr,opr_top);
0BMM,_~,GO     c=getchar();
L.Yk|'p3O2Br     while(c!='='||opr_top.ch!='#')
&w1|$Vqyl9?8tp*u+T     {3qK#SU Vaz.?a?
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
6p J B%w&Cj/s'_iq-F         {5dg|s+[
            buf[i]=c;
5Ls6h0j? D@             i++;0s B0f'kB!F
            c=getchar();
@g+pIs3Z^%w-B{ s         } O`9iSM[Q(W:@
        else /*是运算符*/:H#r#Dp0yI
        {"KE.]t p Y2n
            buf[i]='\0';
!X E&s?3T             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
"~4O-[ haZo             {1Hpy{}p HD e5n
                 opn_in.data=(float)atof(buf);
Sdn$Z7}6C                  Push(opnd,opn_in);.h,d"g? Q[ K8\
                 printf("opnd入栈:[%f]\n",opn_in.data);tbux]Y
                 i=0;4T zebD
                 memset(buf,0,sizeof(buf));-ym#[(O^e4y
            }{0Ga;GMO3va h
            opr_in.ch=c;
J'rSp5?+t"]             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/%jj _]*`;Lp^R
            {
p }"qf9AW                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
h+\R-X T7b7|S                      Push(optr,opr_in);&n)CS$Q|HQ/P
                     printf("optr入栈:[%c]\n",opr_in.ch); eBQ @[8ltxE
                     c=getchar();
-x#b8E1l%ar5F                      break;8_2h5e\'M8D&?/t
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/7CM s VQ\1o7q
                     Pop(optr,e);
1FTn p5X'j]:j@(D                      printf("optr出栈:去掉括号\n");6d-j$]5BQim
                     c=getchar();
ywx-x9?F5S4M                      break;
5~.an _w.}                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
1y+c0@)@*n!y                      Pop(optr,opr_t);aP WC9\a
                     printf("optr出栈:[%c]\n",opr_t.ch);
i:LK ph#EX+^                      if(Pop(opnd,b)<0)
8Y%u R"] jP                      {,T [b-C}R[K g8B
                         printf("Bad Input!\n");
d^GfP5s                          fflush(stdin);
:tiO!_#U n(T0J` P%I                          return -1;
oz5Jy1kg4uE&t                      }
{ z&Gr6d7sf                      printf("opnd出栈:[%f]\n",b.data);
5W-~QYdh;b                      if(Pop(opnd,a)<0) G,p,X.TD
                     {
8u q7U$z$D4~                          printf("Bad Input!\n");J9Q8cx[ ?7F+X
                         fflush(stdin);FkO`NN G/D+b}
                         return -1;mV8UYLd
                     }
TC;J'oGt                      printf("opnd出栈:[%f]\n",a.data);#@ ]"d:RRl@] KM
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/$~(m-tX0^j`8C^
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ QsCK M}3y
                     printf("结果入栈:[%f]\n",opn_tmp.data);Q o!CI1l f"q Q]
                     break;&r2i5Bx ]c0^6B;J
            }
;s\ iZ#Fzl i{         } Pe$q.j o
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
d:oX's.qR1Ec/Z3c$W     }
)wU0K#[-ro/E     GetTop(opnd,opn_tmp);2I5sG5kPQ*C9q~'z5kx
    DestroyStack(optr);
8B;H.@3~`     DestroyStack(opnd);4Mjw%c"M7t[4a6Y
    return opn_tmp.data;
JC i+l!W }
ve+eO}Y(Du.\A W zc{(? ?-e3H
char *killzero(char *res,float result)*kI;p4jk
{
!H;P f#_j'|9o     int i;
5h)A3`xUY ]:Ke])] Zg!QJ~Ctn
    sprintf(res,"%f",result);
[2N.i f!jB4\ Gv B     i=(int)strlen(res)-1;
&pem9u-D.M     while(i&&res[i]=='0')
B%Tv P9QQ1?     {
Z O;bW"]N(NmEgi         res[i]='\0';!F${I?*alt1n;[
        i--;k*Qm5bg6U5NU
    }J6ZK7}Gr6_'KYd
    if(res[i]=='.')
PO#V+?7W{R2`         res[i]='\0';
GxFN%WxJ     return res; \!i G*}p
})qe6k1f4E]
_{4m|4w HLe2?W5l
int main()OA6\9xJ+@? F4x
{K'pE'w3ZFLT&F
    char ch;VJ)EF yML
    char res[64];
N(S].tU-G&\\     float result;
9\Z,na2S&]     while(1)
Y pF h,c\j     {{8HY&mt1bLB#Z f
        result=compute();0Et(`:c#MqC
        printf("\nThe result is:%s\n",killzero(res,result));AZw(|O4s
        printf("Do you want to continue(y/n)?:") ;
-d)T9\k*pfQN7a G3m         ch=getch();
7M/?4MO]AH         putchar(ch);.a8s%AH|]bJMs
        if(ch=='n'||ch=='N')`k/?4{ p9DQ
            break;-X4C1|#Vt.O
        else gIp:q.oM
            system("cls");yUH q B?0d
    }~ ^dzs'x"`8z|
    return 0;[ G }^x Y
}[/i][/i][/i][/i][/i][/i]
ZSvzu QZ Lt${ 7` N+K.MWsUC
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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