捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
PH a+w7m`5K 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
n F-lX5lJ3o5yGI3wjm /**************表达式计算器************/Ow![,w{*`
#include <stdio.h>jPs8N{
#include <stdlib.h>&Yy"^+a7m'VMo
#include <string.h>
1mgjP(W6R^k[9Y3l7? #include <conio.h>kpi#VA
#include <malloc.h>9m jQ]m]L4s

;Q|9O{3q$Cb3H #define STACK_SIZE 1004X%N |s%~,}Mw,Q{ }
#define APPEND_SIZE 104w+d)U'g*M B

kTO6O4P6fG struct SNode{
t a%szD     float data; /*存放操作数或者计算结果*/4},D3k^ } p Y
    char ch; /*存放运算符*/
}C:~Be };$F.~;[4Ol VR
i+pKO4Y
struct Stack{UwxL]hC+k
    SNode *top;
[0e8JBe8JF1@     SNode *base;
e.R NM*t9g]     int size;
q G0b8U*A#R3j6R FV };
mj|OC-M
S F*swWk /*栈操作函数*/
/J5p#?WRD9sd int InitStack(Stack &S); /*创建栈*/ \1Q?8gZ-l8HQa
int DestroyStack(Stack &S); /*销毁栈*/
s7@0}'t i int ClearStack(Stack &S); /*清空栈*/
rs)Ge$l:N1ne int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
r0Y7dE1OM(XO int Push(Stack &S,SNode e); /*将结点e压入栈*/
QB XNQ0m int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
j ?-[-uX"qVW2}7M
{)aA"Oh"fv {0sT /*表达式计算器相关函数*/
}!{Q3j&~ C char get_precede(char s,char c); /*判断运算符s和c的优先级*/cD.b R,^n!I
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
U6W-?f`+?5AAp float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/L$_#Q&za5pV4A
float compute(); /*表达式结算器主函数*/,]R&`Vt$J1@
char *killzero(float result); /*去掉结果后面的0*/
Lw(IP!biL
~#QNFAii int InitStack(Stack &S),S~I,I#To K
{
3e&Q_H VE     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
[ z8e0mRw/g%Q q     if(S.base==NULL)P#L yo:XC ld
    {
*t+F M$sh c3B@k         printf("动态分配内存失败!");
5e0x-ey M4J         return -1;
KpRr-K7P     }
g7y?%U0z5Q c     S.top=S.base;,hO J B8S b^,J*\
    S.size=STACK_SIZE;
y]?!wG6k     return 0;
Y$vmGjr p }9HDj _TveJ
[6x0hNkX}8~ZZ6Xm
int DestroyStack(Stack &S)g sXQ:U?gtU
{ W|] YT;B
    free(S.base);;fy,[G4^O,_
    return 0;w c2RI/A(e,rT
}
*c)_ Y Y/? M 8mu;k#BgMI
int ClearStack(Stack &S)O2B7E0S5xhc[$B
{vU_a5k1T$M
    S.top=S.base;gio"vME4K(Jk
    return 0;9[Ei/Y7HlC J-Rh
}
:r:hgjV+~+p/_7ZX
yMP.Kx6`S-} int GetTop(Stack S,SNode &e)!Bh0Qx9A
{
Z%T;a+N(CH0H     if(S.top==S.base)
|:]%@-V)Pw     {
6iP"v f$Z5AM         printf("栈以为空!");%D9L(U^;r#C/S {(S
        return -1;.{%^:e*S-k
    }
p8\{&SA7dx     e=*(S.top-1);
GY(~j#Y*i     return 0;
*hf)T,Wk8^Od;C"M#P }
6ZF6wF\n -V;{!ib1q
int Push(Stack &S,SNode e)F8y%D5i.HfY8xv
{
yp8q f;\.Mi&R#s.\@     if(S.top-S.base>=S.size)&ypf7o e9A:G;Q
    {^ @D;lsK
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));"_:b9o DeQ,Wm
        if(S.base==NULL)
XE_}l*P.~6Z         {B ~5|A_%e,PL
            printf("动态分配内存失败!");
EoH*O/y1RjLfF-J@             return -1;
a\bo s@         }
D%@*qnNF         S.top=S.base+S.size;
EJ~["`~:Mf8}         S.size+=APPEND_SIZE;
"z#^P;CjB}l W&w     }
-|9^7Y/DCj l1^{|     *S.top=e;
@sd%]Zrh ~? [     S.top++;II;w ]5JPb1I'_
    return 0;
?^I5f,v#W,R6q7w n }
*`#`2~z1XhF$do#jwK
^+Kc0@Y9P,l int Pop(Stack &S,SNode &e)
D3xC{,_?Mb {+{ T'wE/u;PH
    if(S.top==S.base)
H{!m"GTbz     {$qa%]-s z-^${
        printf("栈为空!");$f"Q"p$Q-f4I-U K9_'z%p
        return -1;)F.x#K,g1z7]%C
    }
(R }8U%Pt F7Y~     e=*(S.top-1);
H,_!y4Cw#L7Ym!G     S.top--;
*_HT8tX1fJ     return 0;
o Y5i O%[,SiE }
$b^+C;C \?(J
2wvN*~5cc char get_precede(char s,char c)
;Gl-EE3b_O6_ F(e {
4Vf3ml;v aI     switch(s)
&owd U7y6YS     {%GYf7]v5m:m4p8L"e
        case '+':                 
d@h:E#P)bFN         case '-':0dH6|+|R}_"f8N,i)`
             if(c=='+'||c=='-')
T0r!q6a8w3_K                  return '>';TSP(W!n$[1J5l T
             else if(c=='*'||c=='/')
-~;d3e$W4o7z                  return '<';#[7M|'?{1Y+pylqM
             else if(c=='(')
6a)G\q!^2b JI                  return '<'; kH'| o?8y6Gz
             else if(c==')')
7~|!TcoI;J%E!ke)?                  return '>';V!\XT*V
             else
a7Ek,DN K                  return '>';
YAf_-M         case '*':
x;Q'aj!zg         case '/':
5g}JjL9\              if(c=='+'||c=='-')
$Hxvo2| F!W                  return '>';9{;WI#?/_|T_3jH[$q0U
             else if(c=='*'||c=='/')
I lrUE`                  return '>';{-M0wFo
             else if(c=='(')Gh(^)M-f`{,I9D
                 return '<'; w1v0k7JV6Bq w
             else if(c==')')
$w"D1wAM`,Ot                  return '>';y!xH B+C/~Y/Ci
             else Y1f F8JT
                 return '>';VR$q[KV&d
        case '(':
.ci o9q{R3\gFt              if(c=='+'||c=='-')
{T!dE,I%B)KeK4q                  return '<';
0Uf'Kco!|+O              else if(c=='*'||c=='/')f%Xt7beKN.m]g
                 return '<'; }"@ecF5^6Vg
             else if(c=='(')
8MuVa z:C;~|                  return '<';xT(w8] [-`pH2I}.{
             else if(c==')')
#T0E4w*_/Fx m                  return '=';
5\ZG3c(] D{              elsex;u)bUK%Lj+S
                 return 'E';
N4VM7W_N;T         case ')':[YTxHDM*N
             if(c=='+'||c=='-')3s}@2eqgS(|
                 return '>';Z2bN$v8@
             else if(c=='*'||c=='/')
Z-w:n oam$k6b                  return '>';A\]!sB{'x
             else if(c=='(')1] rP_C
                 return 'E';
Ue}6yqw|RJ$d              else if(c==')')dM}JvF? @C
                 return '>';
{:b1nY zI T|              else-E@&[OS:d8`
                 return '>';P/O#{bx cZcc`
        case '#':hcdw/a&g
             if(c=='+'||c=='-')
6c,MvY"} rl                  return '<';
x)~eN&krF-h              else if(c=='*'||c=='/')h \N*C4@_(drj5rn2h
                 return '<';!?3J(e9O8H4U]
             else if(c=='(')p G*v-U~9? ka
                 return '<';*W#m/U`u!RJ+IM+P d
             else if(c==')')d5n"IM;ol0e'N
                 return 'E';
t8qp F {'ocyGT              else9h3g!P ix%{@
                 return '=';%ZS Bn*h^K6F
        default:
9S t:a5u3]XU-u+GBr              break;N]1l*lO}
    }
n%p2X!lf1iE/tO     return 0;   
i*Lco%T(` }0z ~%{W|$I2{

,qy#["z5un7K4s^o int isOpr(char c)
S D[%EX\ {
dS%p@f     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
z4B z%pV         return 0;
!W G8^gQlB     else I!L X{.}:],Hb
        return 1;
#q0`L9l*Q*P q.Wn"p }
H9{;P$rr"E l5{ sa/|q1E,PwD*g
float operate(float x, char opr, float y)
eEe b%}"`_&Rp {
m&s#X@D?6E'd     float result;`hEF$f
    switch (opr)
*K/\;{/U3O1]:T$r,K     {^tS-x^'cI
        case '+': 7Gw ^'G:\!ms
             result = x + y;%G/wU W7JfMt
             break;\ |7M9OU
        case '-': 7ECr/B,n
             result = x - y;r$us(R|p
             break;
0A5\4P)Q%jK)a         case '*':
"Q.@4r5m4j+Z O              result = x * y;
\-yA1aJp.GD2zA2h              break;
jU [V5vSz3dl         case '/': 8Cb4y;l s$Dt:P&t&L5d
             if (y == 0)
:ly*Fbv(\h              {%@O%W B~ kg
                printf("Divided by zero!\n");
'T9}4N}%u"|9Xl                 return 0;,o8Q_!x{
             }
5i1P%V8z [#A/U*m,a              else
.@*w'L{?u              {(p7q2Q"xU
                 result = x / y;*Rf+X%i%i*L'N
                 break;
| V4F2o6NimK6?              }
UyF1q%X\        default:
Q*H@R"Zu3j              printf("Bad Input.\n");
$fxf'{(x.uZ"DlbMG              return 0; S*dcQ+B,B
    }
"^.L+vH,m D     return result;4uG4~/nDMkc7}z
}    7x^!T6_ c|G%s'S,F
!U'z[2m8S8g)r2X I(N+Ci4~
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
C:A,gAD(g/D#T%w6J {![Qa8CU1veWk$z
    Stack optr,opnd;
pY0Pji nr6R@     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;1M*o&a `7XN
    char c;^ Z ?O `e,M
    char buf[16]; q2d{hm
    int i=0;
4_Wb/Z|#xG:`r     L;y/F)x PV_
    InitStack(optr); /*用于寄存运算符*/
N j}v|{ { _;Cw     InitStack(opnd); /*用于寄存操作数和计算结果*/`)i%X V+[)l.?(DaM
    memset(buf,0,sizeof(buf));o!\3Y m3T9d
   
p*FX WAz     printf("Enter your expression:");
4D$d9CdKz r8k         7o0kQ1_ gP
    opr_in.ch='#';
K3hF1P%l v g     Push(optr,opr_in); /*'#'入栈*/
W~/p6FV?/Y     GetTop(optr,opr_top);
,U@S%{0G4R     c=getchar();N%k)_D%Is+d
    while(c!='='||opr_top.ch!='#')
d:SxB,?G\u!f     {!K:uOt i\4Q p
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ham2m*{(D
        {
%u;W$~'uT0Y{'YO             buf[i]=c;
.[9n0r'R8P(zu5j+d s2Qt             i++;[n7]#U"N
            c=getchar();
2n!HR/P0D%nr         } q"jr:tsxkH([
        else /*是运算符*/!u!_X;~)n
        {
hN F4\+Mz1_             buf[i]='\0';
r1^`a;|L0^             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
#r-f t J e             {
!eX(f.T)o%QRo                  opn_in.data=(float)atof(buf);
~3h t1j;E                  Push(opnd,opn_in);
h2C \V1OH7S K                  printf("opnd入栈:[%f]\n",opn_in.data);
B:[:v#JM8Y {                  i=0;/YG [mq}J ?L%i-X9t
                 memset(buf,0,sizeof(buf));(Y B]Ql'u$m(\
            } d:@P9G+d W
            opr_in.ch=c;
E7T"Vg!V xM             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
c$Z0zCo/z-c$XX5es             {
3Cry?}'P x_                 case '<': /*优先级小于栈顶结点,则运算符入栈*/C1F)s7voR
                     Push(optr,opr_in);,Fg&V\E3K3di.f
                     printf("optr入栈:[%c]\n",opr_in.ch);(U ki|kfa
                     c=getchar();
#`&s|"Re@ aj,^                      break;
R;C,G3lA                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/T0xA9H*j;ud~8?zH
                     Pop(optr,e);
H.O6iYj6Z                      printf("optr出栈:去掉括号\n");
Q{/QEP4te                      c=getchar();
D kg{(xU GX                      break;u]{c8w%Q
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
fR x,W~#Odi                      Pop(optr,opr_t);
$US{)E"dAY.KLVaz                      printf("optr出栈:[%c]\n",opr_t.ch);*VYp)s)Ry3DG
                     if(Pop(opnd,b)<0)/[&F)v%pM$CX%Hn0d
                     {5E^ES3Z!iH)h
                         printf("Bad Input!\n");e-O.?/\ `%x y1w-g
                         fflush(stdin);iT/uEL~B!@
                         return -1;5g,R*TC'X
                     }6BS ^]K+o
                     printf("opnd出栈:[%f]\n",b.data);/pxtY*szG
                     if(Pop(opnd,a)<0)\;Ag-z#so_
                     {_3|ns4xO b.|mb#a
                         printf("Bad Input!\n");H4Xh)C/@&Q
                         fflush(stdin);
PS&p U)}t*x9c-[                          return -1;
F0H J P\_y"mHyJ                      }
#Ggdq s                      printf("opnd出栈:[%f]\n",a.data);
R ](RQ3k3we#?.G                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
2r'z.VW x!t o                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/'`:^nLD SF.~#] M
                     printf("结果入栈:[%f]\n",opn_tmp.data);:F"A!I[P]
                     break;
v)w#N(A2H.YSX             }
f c r z%q0d;G         }
kd ~,C]e         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
rZ Q(B&~8g[     }q0o_"V4^-P@:S
    GetTop(opnd,opn_tmp);
ns{m$b     DestroyStack(optr);
2yUn"k5HR[     DestroyStack(opnd);
c.]Xfv | Q_"W:[I     return opn_tmp.data;&m_nZ&Y1o
}b,f)M&mH/Wn1E
-se;R${gJgI*Ha
char *killzero(char *res,float result)
m _c9n$g:b)ZM6T[ b {w"g;v!DX+Na
    int i;
YF*`!U5S.j{ 'U0y+vZY1D
    sprintf(res,"%f",result);
(k`3Y{#dI wM     i=(int)strlen(res)-1;
;d,H:}W+Xo nd*vTX     while(i&&res[i]=='0')
"GI&u^|K     {
}&d {+Nd         res[i]='\0';W B v'I)B1P W
        i--;Ux@q7Z7o{
    }
9F @+d$umL ?     if(res[i]=='.')
7Q(}n0KC]3u         res[i]='\0';
w P!z&x&@/n     return res;H2s%p6P#x
}
Q v;u$NT$Io }A$J
cu2iv!Y(W.`)sIP)V int main()
NL\K.m#j;A!?E7{7}T {9b8lC3b1yp }M
    char ch;,j#F S)qct A4i
    char res[64];/l3c}F/F;HaH
    float result;e#WK$UM7r iM P
    while(1)"QBlh Nh
    {
Yn!`)mj:A]-P^         result=compute();T y)C:^Rf5S
        printf("\nThe result is:%s\n",killzero(res,result));QJsl&Q7k&h:U9M%@
        printf("Do you want to continue(y/n)?:") ;s\ {4|4lZ!Ab0C6V UK
        ch=getch();j G/|&|gy4_
        putchar(ch);
z+}*u3LK-d&s9B         if(ch=='n'||ch=='N')
PFbDg-a*nCu             break;J])nG-cC0o
        else }-H QYW
            system("cls");
8h.l,y;j3T#l9Iip     }
7GB]BX&Gs7Wn~     return 0;+}/v ~'l`8n
}[/i][/i][/i][/i][/i][/i]Y)s$i#KB
I5b*o~{,v
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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