捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.$[ S1a2uj
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=7~0X#Pu7B8eA
/**************表达式计算器************/
W$up1K4k&m^nI)d #include <stdio.h>
Ty8A+O5Y #include <stdlib.h>
Ju6|[AYA Z Q v #include <string.h>8L*H4sN.[M
#include <conio.h>
tfp[y ~.RnC9c #include <malloc.h>ly5by0\6@0t#_0T@

5yq"tj+wB #define STACK_SIZE 100
Z3A8{-\;|&ndON #define APPEND_SIZE 10
/YE{5x_3FV`
yJ;hN K j'P struct SNode{d L g8{:GG'`Bc
    float data; /*存放操作数或者计算结果*/2M:W6?3Hb$p]'k
    char ch; /*存放运算符*/
1P*ycB:F3C };5e;e0G8q9EWY(z3C

|_EakW%g2y&L struct Stack{7i\ T9m,M)S2j
    SNode *top;k Kq|zS
    SNode *base;
2B h]3N;\V$RK]6iXU     int size;
(Ib3ur$s5s[,].U9b };
%d2Xj'a5a
km9^]*TE-@ADF /*栈操作函数*/3b'C*}&`^/Y4o$R rm#q
int InitStack(Stack &S); /*创建栈*/7W oO*K |v(x
int DestroyStack(Stack &S); /*销毁栈*/Z4QG8O/iJE)}
int ClearStack(Stack &S); /*清空栈*/De%x5b6JR+wp
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/lx3] xC_zG
int Push(Stack &S,SNode e); /*将结点e压入栈*/
4IJ,N#i(K int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
gh/?I#c$S
zu;g!VsA S /*表达式计算器相关函数*/%D)qHG|],Of!rX8f
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
z~_'I!QsR BUH int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
&]x TC4d6T float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/ g"A(Q2W WAi)mi
float compute(); /*表达式结算器主函数*/ s6y)B@%Z(u}\
char *killzero(float result); /*去掉结果后面的0*/
B4Wd S!@D&r&s
fZ0py7y int InitStack(Stack &S)$P&s0f+S q PW3[
{ ZO(t9I}1l N3jk
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
X Y,u.p7YbJV&e     if(S.base==NULL);iD{ M*y z0Q Mf0_
    {
9G c:zjr&T+LL:b         printf("动态分配内存失败!");z Jce;v
        return -1;"j"`6fAO9y
    }
~7Mr.AAM5A_,g&q     S.top=S.base;
#O7g6E-s6] `     S.size=STACK_SIZE;d/C'O-FUz%iC U
    return 0; T/hF'JW3bffgeM
}5XsX.IuC3y
y3iAv3}N[N,r
int DestroyStack(Stack &S)
T\'g zvS {
`/MXYo^M     free(S.base); CbP uw hv+NJ
    return 0;!t$ri_3i MDY
}|5q v3j9W(N$t

O7`bF!Vk&J int ClearStack(Stack &S)(w*_l5e ]q3[8q
{
4P[%DRHK@qL     S.top=S.base;9?-WZ-[:@;g!`fS2t
    return 0;(L*Dc0K6lvo3O
}
/_,c/m:x k b#VT
1P.Hus/|E*@ int GetTop(Stack S,SNode &e)
JH-? Tt:v:]"dZ {
"w"wCo q     if(S.top==S.base)p3~;} B fo%`a"y
    {t]0p:W [A%X$@
        printf("栈以为空!");|Y/@;`{y'w6Fi;U
        return -1;([;bT B bZ
    }
3a;WRRt|r     e=*(S.top-1);
:_.iz^&S?     return 0;U"[x m6Wij
}
pG7K5s K9MAtO v^&vX`
int Push(Stack &S,SNode e)
,?+O|Y+v"P-? {
/|v-Ry V-Dey     if(S.top-S.base>=S.size)
N:TlJ2o,pW{     {
;] Y/f&Ddc         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));y|T1{3O:n&jS
        if(S.base==NULL)Ns#v,ym[
        {_g{?:A1e8xU]
            printf("动态分配内存失败!");'Q/MNK%g `:gs
            return -1;
Y Y4Q4ID xK*C4U7V         }z+\G-t:ec-o k
        S.top=S.base+S.size;
)D2L/t]%@%yT B         S.size+=APPEND_SIZE;O3Y c$C&?_uV2w U#q
    }
d4GaD Z     *S.top=e;
-_.YoTD%N!W h(q5]&X ?     S.top++;Bp LuS
    return 0;oS"d2@$B8W;K;sC
}%x#vm/B/`9t1_D3S9Xe
&eP RK'u
int Pop(Stack &S,SNode &e)
k ]&Z]n#Sh8U$d])Y {cI:uJ/yH
    if(S.top==S.base)
5N&fUI!_-s     { N%DjSAw)M~
        printf("栈为空!");
9h:S(g7PKI         return -1;6wN5Tkf4Y!{#lu?
    }0u*n6c%cb4V!BsV?f.U
    e=*(S.top-1);7i4^*qw Q H#ix }
    S.top--;$mfg6}3H
    return 0;
k'oS/[W }w?9| }
$T'rm}TV5U'c!y
db%kn CC char get_precede(char s,char c)
Rn!_7e J {h;DiL1m7yC7V*k
    switch(s)4Q-_8~r)E|@'H K
    {,Ul/zln-l%Q U
        case '+':                 
;E'Gp^0T F ^         case '-':N#j,Kf M [ SA
             if(c=='+'||c=='-')0o6_RL)M$B.HHs0F
                 return '>';6Gg-I_p fQ%Yy
             else if(c=='*'||c=='/') `aR-rIw lO3e*`:s
                 return '<';x w1}c3f)N+lN
             else if(c=='(')(ny?5H&y
                 return '<';r-}#_z4KB-}-f#DI
             else if(c==')')
0`(LM_(q%r                  return '>';6f"oLn"b+Q
             else $W9N/B-@)c+{i
                 return '>';
g.TM XSs,~R,t         case '*':4u9d*S!o&G@/|-k7V,h
        case '/':z5@ o4M@
             if(c=='+'||c=='-')
qMwE+l|                  return '>';"| [az-^+s@
             else if(c=='*'||c=='/')
.\ Z;mO9Xe                  return '>';cXN dT5?6E c
             else if(c=='(')*o&n&s:v%I7mT+h r
                 return '<';A$XX;q4CC1o
             else if(c==')')(p$F6g,?;jm
                 return '>';(C[SI K$Q0M/uM#O3m
             else
`e0^CB!SA V%P                  return '>';
W P8p!AH7Ry*B         case '(':[ Zu R}0`-j
             if(c=='+'||c=='-')Em] E _X8p3Vb
                 return '<';?i3}\1R E`_^
             else if(c=='*'||c=='/')
6W4xKrh7|                  return '<';
4Ue&uq$A!S.g*~Lg              else if(c=='(')
f6EOP6E Vv9[1s                  return '<';
w\'a/W F5]+~N,|              else if(c==')')J,lH3q$RH d,b&C+u
                 return '=';
%@;v#f}z:C[.A5Cy              else-}d nda,a$F
                 return 'E';8F{TgR }7T
        case ')':*~MQm a%V
             if(c=='+'||c=='-')
aE?@6J}y                  return '>';;|"O;z.}f
             else if(c=='*'||c=='/')#lw!hR!uJ
                 return '>';6WUcN$RY2Srp4z
             else if(c=='(')Tb%Z b*Z
                 return 'E';
1FJp^ H ^I]H+@              else if(c==')')h*s'jv2q,u
                 return '>';*_ \t Ce
             elseH4aQ+w!b
                 return '>';c2_jy+FX/w
        case '#':
4F#TQ2OG{(A1h              if(c=='+'||c=='-')#I0S&H'r+{i'V
                 return '<';7^_5H'XY,UNZ4y
             else if(c=='*'||c=='/')"h^n zlzc
                 return '<';
y5X[bEh              else if(c=='(')
sH I8yz                  return '<';
])X,i"^FL K              else if(c==')')
8qAC1Z j9?J                  return 'E';
Os'U7V] jo}              else@ ae'kLm&t/E#Ul
                 return '=';9?'D,x&lm yf3Hk(K
        default:&i/y}%Z3mBb7H.M
             break;
(R ?+J#}j{     }WFu2fB5~%n7qix
    return 0;    3A!|5diM6OJBJ r
}_{"r6B4`2`qY"q
fyq1squ~%Z0W
int isOpr(char c)&\1qDJ9F d,Bz
{ WV J:m$zv0l/`
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
-@c)J1[5@*@(]         return 0;%n(~P"Pi7q B W
    else ~,oWbqx9K {-G
        return 1;N tS`R*H(` tK
}
q B P)S&B b jH7E
iA ^I9n9s float operate(float x, char opr, float y)
k JUFeH^6f6p V {,K!P0F l|{
    float result;
F4@%?u~b&IT     switch (opr)F8T Sro$P^7pw
    {
j T^:DA_/W&[3x%A         case '+':
W[)X0J#^%CSH              result = x + y;
fG0i8yE,jjB'd              break;
"nY:VGHE J.\7E         case '-': +l5UR]W_
             result = x - y;
k!g]j#q E#c$b+cGG e              break;_7]2\t0@%u(V6H]
        case '*':
+tU2p${6f?$o G              result = x * y;F!bw z#D
             break;j8F S'{6@i
        case '/':
;p4bESG!N              if (y == 0);x`L\7F
             {
Xx(ir"z"h Jl                 printf("Divided by zero!\n");5c@ hW4g9K Pc y
                return 0;
O%N VfMb(y p              }6uJ7[;x"y0^;pg
             else
V\,G VN{              {/^4x'h o0A&`
                 result = x / y;
~\$A#d+V0E$xF3[                  break;w)Jn@6kB/w
             }k%hA;xL8D8HE*aqwX
       default:
6luWG+CwC}              printf("Bad Input.\n");
"[$A1rhuQ/wp              return 0;9P lHa;k
    }ZU+Ok{
    return result;0PC:l"@\(^x;r [.V&?
}   
jSq't"N$|j~
T0V [(V%iF2E float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/*DL0I7iOb(_
{
YwBG;Z4_0M9_WoKc;H     Stack optr,opnd;
4qB b&oE     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;"Y*RH"y+[B2u8Aeb
    char c;
ZW}$r"@gtX     char buf[16];$}1oE&gMIVq
    int i=0;b$n%Y+iI~[3J
   
ma*maGc@+\     InitStack(optr); /*用于寄存运算符*/
,K ?W9?] T[ ]     InitStack(opnd); /*用于寄存操作数和计算结果*/
x b,|5V/`     memset(buf,0,sizeof(buf));
iu-\[Ro|     t'IA#@!J8mq,P
    printf("Enter your expression:");
cW8o?G+x         
:rFPLU ?l-bX%[     opr_in.ch='#';Nj]r;H L:b
    Push(optr,opr_in); /*'#'入栈*/
8R:EV!e7oAN\~     GetTop(optr,opr_top);1O?9v,xQhMl M
    c=getchar(); ]mlXqh
    while(c!='='||opr_top.ch!='#')6AEf.m:J fb-d
    {4?}6Z![%T"f0srZ
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/{d9a f NL
        {(TZ+]p#aV
            buf[i]=c;
"ATN#P3g(zw;Z(`F&@s             i++;
i/x#|5j&A kh?o             c=getchar();
Q!t.Y%f-d-F{,a)r8M         }9p}1Ig+k |$w'}
        else /*是运算符*/bM [{)fkq2A3|
        {)gU w+e$q&AV
            buf[i]='\0';!Dn!g!I1c-Br;f
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
I.nJ,i x|!U             {
1VF }7Z9Z                  opn_in.data=(float)atof(buf);nJ8_1A6W1n k.k@
                 Push(opnd,opn_in);
1d1JO+^9ep.oEG                  printf("opnd入栈:[%f]\n",opn_in.data); k1NS+V"I)ha[
                 i=0;6i:B2r LCy;@]D
                 memset(buf,0,sizeof(buf));
3Xn*azFQ7Q)I             }
;n3HxK}/uk$d             opr_in.ch=c;
D+vc-~ s ?T x1P             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5L$` n1^([4QR             {
z[a[%k`%fB v|                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
7BG3D+^3X3m`$r                      Push(optr,opr_in);
Ff0yw)P*K                      printf("optr入栈:[%c]\n",opr_in.ch);
;y~/j J@6[(x||2zz/p                      c=getchar();
n.S"~ y\L!\                      break;
@X NhM I {                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/(hA E |Rx+Q5| n(P
                     Pop(optr,e);2C.h0e$`,\I;X
                     printf("optr出栈:去掉括号\n");"N6nr I H
                     c=getchar();
/VL's&s bD+g#n                      break;ODB4h0b YO
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
[WDZ}{                      Pop(optr,opr_t);7^ u p O5T9c(D
                     printf("optr出栈:[%c]\n",opr_t.ch);uD!W}@/e+G2i%j9{
                     if(Pop(opnd,b)<0)6hqb2e5L2K%j
                     {
:BE;nhz+S]2x                          printf("Bad Input!\n");'dS3Le4Z&h
                         fflush(stdin); }8u!u r0C
                         return -1;
C4_7u+p aK.zxi{                      }%io+B b,p)K0S/p
                     printf("opnd出栈:[%f]\n",b.data);
0q_^]o2JWw                      if(Pop(opnd,a)<0)
z+eK"z ey0n                      {7z8h!US b(f^x
                         printf("Bad Input!\n");O8rY/B,m3o6y-h
                         fflush(stdin);
jk(^![Q                          return -1;hX3P*JI*@@*T.z
                     }
V)l2E;QKqW}                      printf("opnd出栈:[%f]\n",a.data);"{| }D%\
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/x-wp-I"d
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
` u:Y C5g"K                      printf("结果入栈:[%f]\n",opn_tmp.data);
6F'N(U+}'j%h#b                      break;7U&lN]j)h8o
            }:uP(U1L ]QtnAg7V
        }
3L Y*V s {(U         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                t#g/A0x hh
    }
[6R-Z1eZ{]Ie5z     GetTop(opnd,opn_tmp);GH O^/s _{ Fc
    DestroyStack(optr);
B(a0Q'x Fk     DestroyStack(opnd);
:Jcz-h q8@     return opn_tmp.data;[%}8_1k*q!j5O4pw
}
*ic*jJdB _jb b,nN!d0U$\0F
char *killzero(char *res,float result)
ho+]k6vD j5D {?g%fi#|&l
    int i;
X1KdaF8nIZc
#ui0l-vh~E     sprintf(res,"%f",result);6I!Y^3Wz3z
    i=(int)strlen(res)-1;.EOA.^znxvA
    while(i&&res[i]=='0')1S(q O;_#B#@
    {F3~5wd"B,w;lt e[9a^
        res[i]='\0';
vsZc8O%\P         i--;x!j|/[8j
    }
F7it1YnVZ     if(res[i]=='.')q c)at.u6QO^r
        res[i]='\0';M vH:U_,VX,nXw
    return res;jL uo(ET$xz!l"m
}
Z8z4ns Z_S1a @@PG9X7M
int main()KX:}+qtG)c
{7~0AxS:@v]:w
    char ch;
N(M ?@-gV8?@     char res[64];w!Opf;qe
    float result;
&NC] Bb y0W pj4_     while(1)
;c5E5h2P"`$Hh.G     {*n9h%]-Y7Y[y,Fd
        result=compute();
UX~mhet0Zm.VO4{         printf("\nThe result is:%s\n",killzero(res,result));
|b9xu]'q'v*t T         printf("Do you want to continue(y/n)?:") ;"w8g.B-J)R
        ch=getch();L RU T2_3Q4pax
        putchar(ch);K4~*v-v H/VnU_P$^u
        if(ch=='n'||ch=='N')
;u0|z E?             break;'H@+I^3ZH'E` E
        else
-\"\ j!@wRV-V             system("cls");j/T1\LM4E6do
    }A{,wU @#K,W5Pv1{
    return 0;7u\ r_$v
}[/i][/i][/i][/i][/i][/i]!E'D*AUw I*x A6V
oj_z-~,j(@v
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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