捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
(b f ?)J*A.d[zX7R 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
5P$Z&z p#P'F|@ /**************表达式计算器************/
/J0O u+jz Q*~6ch #include <stdio.h>
w;BG x jj,vZ #include <stdlib.h>^ccE5r-}vx!y%eM
#include <string.h>n*zDSK.i%l
#include <conio.h> f*ALZ$\E
#include <malloc.h>
o} V$Wz *e#S6S(X(g
#define STACK_SIZE 100
3^#t&D a A y0yq #define APPEND_SIZE 10
y|9w1X}Z ph ^b
~o,Hw:r,x@ struct SNode{
+ESRuYi     float data; /*存放操作数或者计算结果*/q(_G6l$[5I.lt^|
    char ch; /*存放运算符*/
G&H7k foN h e };l3zW~5tW D

sM9b5o _EC struct Stack{
!`/SZ[Q/UG3w/pP     SNode *top;
VSTP'q?es     SNode *base;
mw5U2bH/b ?`     int size;
4oadX1]3[;~}A };y+lNm A
&H2N/wI;Y ?5Q*jX Q
/*栈操作函数*/'Ec D ?3O$E
int InitStack(Stack &S); /*创建栈*/
h!}*^bjy9|z int DestroyStack(Stack &S); /*销毁栈*/
pOJ!y`D5oB(vq int ClearStack(Stack &S); /*清空栈*/
cuR&o `3U L'oj int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/@)s Oio u
int Push(Stack &S,SNode e); /*将结点e压入栈*/7I`-YB0i+fe%Q q
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
7w7TI*`0D:c*\
B-u V"j b#|8M+h /*表达式计算器相关函数*/
hS#x Lw%{ char get_precede(char s,char c); /*判断运算符s和c的优先级*/j6m;g)k RE;@ ia
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/-od:U5IQ K~ r
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
y?w2B0ju yp5G float compute(); /*表达式结算器主函数*/
%whQw E*m%i-g char *killzero(float result); /*去掉结果后面的0*/
0jrI_d:K,k,MT "X%r3gb?~!b(d@
int InitStack(Stack &S)%FN!d?+I*`7g6g ~l0C
{
:q|(q&p+W;t3v&l W     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));4d-x `,VdH4p
    if(S.base==NULL)
?fD)]C     { MZ P9r2iV*Q q)}W
        printf("动态分配内存失败!");
6_u'H,[r8Yr         return -1;
$dH@0[{ or:[     }
9^ D\7BQ3M     S.top=S.base;
sGZMf!E     S.size=STACK_SIZE;V ]}^fY(N'qm
    return 0;p0\9ZTK rXf
}
o%{R_] |@ }BL%ayD yL9b
int DestroyStack(Stack &S)
BGqT(mX ? {
u wl+Y6l5NHa     free(S.base);j l ?%[HJ'`P!K
    return 0;\ YC)n)o/A
}%a&C^}:k3J.Y

DRE8A,QTz-q;_ int ClearStack(Stack &S)3o*s$?gh d[#O'P
{
V5i*z c6U piU     S.top=S.base;
(u|KU2M"AC     return 0;
&fqlj9l-~Gh;vF }
,hT/|Uj is ;XD Kb1y"W OK
int GetTop(Stack S,SNode &e)D1N0Z+hPc:X7z(pR;K
{-ypkXJz4[pq~(E
    if(S.top==S.base)
/Pl;`Drd     {
L@t"JDt:F         printf("栈以为空!");.ub8t NS1q
        return -1; yr)i6y5u/A4d;y
    }
vA~{;H"_     e=*(S.top-1);
6m\V%P,X6u%w7iW     return 0; gMJ/C]8t
}
"g&FnIk$t_p3Od ZW?"f;]x
int Push(Stack &S,SNode e)Y(W-R2c9jC6jeo
{
9ok7]Ph{wn:f     if(S.top-S.base>=S.size)
`'k.\#e K     { P!{[#u;i
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
.k `z3p)i         if(S.base==NULL)Z/a+n$UI rg6Q*k
        {
H$[.x g] yy.\}9@r             printf("动态分配内存失败!");
{1c)?1_6k/Y,[e             return -1;7s S7f4~#C
        }Jf*L)c/K0fO
        S.top=S.base+S.size;w M*^'Q?9Rr(mT
        S.size+=APPEND_SIZE;
"yI6W S K.Tt _'M I2Y^N     }!Y8NH%^t0JB
    *S.top=e;
:Soz~f9F I(u     S.top++;1H'ED6p^2x1?k$p
    return 0;
W5pFc$_ }
] N(gwNg.Ep N8D d
l@)v[;UR2Zu8A int Pop(Stack &S,SNode &e)
8]j,b%`o5cK*W {
V6f!R9M/fB(DK3~/N     if(S.top==S.base)
bQ Y'^F X,R ~     {kXu l$\E {
        printf("栈为空!");S;])j&m|
        return -1;
E5uQrK%ZB3^     }
w bTe#k Qb6T*V o     e=*(S.top-1);
S&[7m1m {Y     S.top--;Tb2t4U?t Xv
    return 0;
MH"BKfw0? }
3V6@l.XC b
R-}$WY]`Ws_ char get_precede(char s,char c)
? W \I`k[tVz {0S8Q]$d#\NrXE$B
    switch(s)
'Z4MfS8D#Gh l     {!G9H6jqAn*ct
        case '+':                 ;? d:\*d&M,clE
        case '-':
AqH3^uu Q              if(c=='+'||c=='-')
{5]3}}+qkx:x1H                  return '>';.jb4HB(n4V:~^3d
             else if(c=='*'||c=='/')
M\o:q7J(N.p                  return '<';
t#RU$mF              else if(c=='(')
V.X$j/ox+o fU                  return '<';
$g)} vDF e"Ek"G              else if(c==')'),m2}6]*\ u3s)v
                 return '>';
a)TfwS0O7U)c g              else
F7GIBT"N/V                  return '>';
)H+wD_}5nK/~X         case '*':
6p*p3TY$v$o H+UyHH         case '/':/y/Mxq:@lJ^;[`c
             if(c=='+'||c=='-')C1V)nZ E:E"z X*Y
                 return '>';
r5v[|+b              else if(c=='*'||c=='/')
iO)K Cc                  return '>';
~8gK2u4m)myS              else if(c=='(')G}p;N9];l*p9c3\N;w_
                 return '<';,A.ZR0gN)V
             else if(c==')')k$^ Oy4M%L
                 return '>';
R H/WOL Wx t(o }Y4h              else
/u%]6YS:r                  return '>';hz K!lxg
        case '(':
P [(AR_ X6D              if(c=='+'||c=='-')
iG?5|$|$O                  return '<';
$_o~} ER*F%e              else if(c=='*'||c=='/')
_dgSl0v|[                  return '<';
]q/};a h              else if(c=='(')
vNT~M:hth                  return '<';
`1Tx | uConu#Z:b              else if(c==')')
uZ(b j:oZ                  return '=';
X3L3r*\:g Aem              else
?s%_sOx,]#n j'?                  return 'E';
l8Tb1rW _ ?l         case ')':
)g!O mfjK L              if(c=='+'||c=='-')vRx){ {yy'{
                 return '>';
1U0c5Yk&]%].M9l              else if(c=='*'||c=='/')h }+YF8xv
                 return '>';
8wgP`n-]4~a l              else if(c=='(')8}A0}1eyBAp3N
                 return 'E';
3|{!GZ/r#Vn!q b              else if(c==')')
sa.kI5^|}@                  return '>';
*jAvb ?W              elsef$m:UwoW
                 return '>';
9vOp(m/{%EP         case '#':~I~/Rx9c
             if(c=='+'||c=='-')6g,vN^3c] | Zk2g
                 return '<';'`kXQH)T5cr2G}
             else if(c=='*'||c=='/')
2oH*b!W1B.YFQhViF                  return '<';-USHlm*u
             else if(c=='(')
0nH7D(TU2v                  return '<';
v!tq~-Tk              else if(c==')'),BaYil,^P'N
                 return 'E';
J+h5RjPy)wq3~^mO              else
rH'`L]WMw                  return '=';
vl ?9oPS         default:)kq N$o C
             break;
j~$ebzp&g     }8s"|QAJ
    return 0;   
` G.q,n/U R };l5pkXO?O
;xn7CGP@
int isOpr(char c)
v3l&\:L)d1G {
mb x,Sae$|     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')MkF&Vr/o-R?J
        return 0;
#A k"W C}*I     else
4k ?6_!l D$ar5@         return 1;
[[V"ep8M }n"cFo4F'D@
H3q(p|P3h
float operate(float x, char opr, float y)]3PP/r^H
{
-PtUAi     float result;
f xV_OS#V     switch (opr)
7~-{T4kV;ov-V/S     { |X5P4o)U5Z0Y4wI
        case '+':
u'w_f5u2j/M+tY              result = x + y;
-dM6Si0d C6q L              break;
F+x"aR+ne2W(O4g         case '-': /[&FrQ$p6lD
             result = x - y; s*nO)lz)dAa,V
             break;6H R/Gu4Fg
        case '*':
(s3M6t R ^wP:J              result = x * y;z I S.L.Z0?`e
             break;
~M!L8PG$YfpT         case '/': #ILt pNx:jq2q
             if (y == 0)tip&U6x5l9c
             {v%Kb6xkxK
                printf("Divided by zero!\n");H,k[ ]@
                return 0;
c |"t L_W              }fmc3gw0m
             elseR&w[.o;a v
             {
pO]\FsBB0w P#G                  result = x / y;(N,FV Y}s"L
                 break;
-F!V5s[WW              }
LOb/Q7ot+y*BD;a        default: 3}wb&J P _#Y
             printf("Bad Input.\n");
d!Zm$xi!B1]              return 0;!MO#O sDe
    }
t8v a Vru     return result;
WMTbI }   
] U9~}%`WP1Pi s aa;b],n1N:y$P`;M$y
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/S#[\ hV9h_
{A q7s/uh
    Stack optr,opnd;~t8^2F[1voc-M
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; ].oB*^a L:G
    char c;x0` f;D%J,W3u
    char buf[16];'^:i @J3m#_6f*~ [
    int i=0;|&}t'Q4Te
    "q;m:J P"mG+nG'f
    InitStack(optr); /*用于寄存运算符*/
ZODS9Y%`     InitStack(opnd); /*用于寄存操作数和计算结果*/
(v ^:rtUl^0S8\S     memset(buf,0,sizeof(buf));2\9{)]Gd
    "k ].debn
    printf("Enter your expression:");VC'Z/KSU3p
        
VKdN L@Ji     opr_in.ch='#';
s9Eo)Tp1J,E     Push(optr,opr_in); /*'#'入栈*/
T'S c&P-U+Ss     GetTop(optr,opr_top);
k6n n`_M&?Zy.j     c=getchar();&Ki(d^3hec
    while(c!='='||opr_top.ch!='#')
[)d:y H9lf5l8?     {
}T9cMG'rV         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
v,N*v)]})Yv0X"A)v         {
%W0T#]P3S             buf[i]=c;
:Df0jr,S,_r             i++;1n.BQ[7B9u6bX
            c=getchar();
%`)_]'z"?&x         }
R6W7D&u |YL"E]         else /*是运算符*/3g"L/c,tY6}"c+GJM
        {8[R2~]0mL?
            buf[i]='\0';
N*Koou a#d Q             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
?e^k S[.X p[             {Pbd0Ea2v6WEb7L
                 opn_in.data=(float)atof(buf);H:V YZF6j(qR
                 Push(opnd,opn_in);
S+B9d2d2k;[}(q                  printf("opnd入栈:[%f]\n",opn_in.data);$zK;cnRh
                 i=0;
"V`d"` k6B/s6[[                  memset(buf,0,sizeof(buf));
fdw!Q-Y'?(jV             } | Z4p.X!~-Pn1`}+N
            opr_in.ch=c;r)oiF``
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
Jl&\X_Gv;?:u             {
CB]v7f(mG;?+bn                 case '<': /*优先级小于栈顶结点,则运算符入栈*/(~Sx!M5y!bE
                     Push(optr,opr_in);
j [c?(m_4u                      printf("optr入栈:[%c]\n",opr_in.ch);
/j/hb0T:C9x!D#tO                      c=getchar();%S0|o:tU3yxD)a
                     break;e ~R8a'b3Z"B
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
t%w7q:F;\4p'y2~                      Pop(optr,e); Tsun"o'u&B
                     printf("optr出栈:去掉括号\n");
)HWnk6r%f/Y                      c=getchar(); E/L1n8p}s
                     break;
lN+?H7v-v$C                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
WzN]B                      Pop(optr,opr_t);'X3Gl K!w7Yq5Y
                     printf("optr出栈:[%c]\n",opr_t.ch);/P y3}yp2{G9l
                     if(Pop(opnd,b)<0)?6m]N%Q
                     {
;K RG9Z-T*Aj6P1N                          printf("Bad Input!\n");W:uP~'Oe"?I
                         fflush(stdin);-Q6O"SG{JQq,~
                         return -1;#fg+p oLFZs*M9P B
                     }
0lF vH,D |'l                      printf("opnd出栈:[%f]\n",b.data);0Gh1g%VQ;^H/H
                     if(Pop(opnd,a)<0)A?qzU!N
                     {
?1Q{S}%sQ3H+@z                          printf("Bad Input!\n");v9KKO9Hb,]i [O6U
                         fflush(stdin);
F4I/K"B5d.[1K                          return -1;#v}7L(F*n"e)Gl
                     }5]-@l&~,[~i
                     printf("opnd出栈:[%f]\n",a.data);
"d?zZ;K0r0V                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/,lmA6e9a Z
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/8M~@)stal I[
                     printf("结果入栈:[%f]\n",opn_tmp.data);
0|i+h.x,OI                      break;z3sHS)F/g|)QPC
            }n:L;yR/]1U!DxC2{n%o
        } t ow2T8{ G
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                !R$e#beV P
    }9Im]3v}
    GetTop(opnd,opn_tmp);
]+_:z7eJI3|     DestroyStack(optr);.}*r Hu+h*F
    DestroyStack(opnd);
'H({,tIA3I     return opn_tmp.data;
jw'Jj.U.e1? })e4Dt R8q6j4B

#uAF*D3Wp1fu6] char *killzero(char *res,float result)
Q$]4T?E4[K {
;U,[8_:T b!f     int i;
cDH,{'b0t7xg(T .JfRN(BA
    sprintf(res,"%f",result);F)F_)ri q?&f BF
    i=(int)strlen(res)-1;{G`` y,f,YN\
    while(i&&res[i]=='0')H-~q1Bg,Mh^P
    {
$q$f%p?;sq;@?O         res[i]='\0';8K wKC6a.a?8[X-n
        i--;
lD"I6O/e\0vyl     }
#K9js(P!J4h,@K     if(res[i]=='.')M'd'[3hKWnd
        res[i]='\0';'MMFxZ.bL}2A@
    return res;f d)j7WJ)Q,w
}
k l9Y:~9L5_+N3u X7jf:[,v?Kk
int main()E6[%x6A'ds%F x
{*hx {P sK
    char ch;
(b:V&i&_-r U     char res[64];
@)XAyu     float result;sAQ5jB&P7I#]P)]3q
    while(1)0l_,XhB'Y o f N;p
    {
6SD.E e&}R!I+i!v         result=compute();
JD.i9k{.[&?q         printf("\nThe result is:%s\n",killzero(res,result));
;J,r9_L1{1P:Y)`%D         printf("Do you want to continue(y/n)?:") ;
V&a$]hK&w         ch=getch();
|WU"hJ.q-Z+O         putchar(ch);y5s*Mbko
        if(ch=='n'||ch=='N')
:DJ8V;_1WE_             break;W#JU$?"x:_7t2g0A
        else
IRC _"ms E!Z AC             system("cls");:Cfe5vH
    }eFxrZEI
    return 0;
)Nwi6H#x)x+FIz }[/i][/i][/i][/i][/i][/i]
8^2JCB,v T r6? E&{\#q l(G
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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