捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
v:V3Q)_-zQX D 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
{t\.GT S!fy8SJ /**************表达式计算器************/
o8J,Ek P/o!~yiN #include <stdio.h> S IRqj
#include <stdlib.h>
@p{*H'Hs #include <string.h>
.a*Z7o'{,H R!|%t #include <conio.h>e5p9H? mO8U s;@)GG
#include <malloc.h>6v,_~L8wq
C5m2v7o3l
#define STACK_SIZE 100T\#`*A$|(U
#define APPEND_SIZE 10#kZ/y&W]/L;~L3T
c+d_;LWKU
struct SNode{3g}%O;Q&\1Y
    float data; /*存放操作数或者计算结果*/D-{[_#b4g}9EC
    char ch; /*存放运算符*/
+L1gLY(o V };] i RT'ZiUXP+?

-LSu1GA struct Stack{
?v,L~"k:{+S u     SNode *top;8nf$w"^ K
    SNode *base;-Nz2x xoo
    int size;'n)_zB%Dpd
};
!IT RW7x|O;s
~h`vCcw1Y"X /*栈操作函数*/
"G6Z:gyo%P;T,v int InitStack(Stack &S); /*创建栈*/U2T+}t)k'[Am
int DestroyStack(Stack &S); /*销毁栈*/
c9W0wc"C~_ int ClearStack(Stack &S); /*清空栈*/^jvV'L+S-H DU1ln$]
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
8m'|/Z5L\N/L int Push(Stack &S,SNode e); /*将结点e压入栈*/j7z2m'k+lu3uk
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/,PG3L|"M.v `8T2uv#E0[
+L&c9[G0rDig
/*表达式计算器相关函数*/
:|f#ov,^0H2Y char get_precede(char s,char c); /*判断运算符s和c的优先级*/ ]&hKN%K
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
Q6Rxz5dK:v e6a float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/p.j:R3L JCT:T
float compute(); /*表达式结算器主函数*/ _$D'G0S e:@ Z
char *killzero(float result); /*去掉结果后面的0*/ 'XU[X3I.L K5h3D'G
w-rRa[S
int InitStack(Stack &S)
s B UV k }6Y1} {
+~)G,SS5V     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
4Nb&GH[.O&h     if(S.base==NULL)*ee n-zz}~hye;p
    {
K] J4b.LL         printf("动态分配内存失败!");
d3x5g*~:Ko(T#q         return -1;
.J0B#P7t2H)A     }
+z"W0Z4[)PX7|4L^a%c#~     S.top=S.base; T;iUSm M(m,B'g4Y
    S.size=STACK_SIZE;:omU/Rbc&bGB h|i
    return 0;;\!?UNJ.[
}co @ Y3bP{
8k!K[9l!j
int DestroyStack(Stack &S))iJ-Nk0KC-eF
{4P\0{ k2w&F} J)f
    free(S.base);
4{ \ q'B*]o4]P$jl     return 0;Vn,vb M5` j
}#PW%S#u5D$Bu s@I
b5u4PTr{#P7c
int ClearStack(Stack &S)
2k-_D L [3UJIh'h E {
B;mRB8Wc Zg     S.top=S.base;J+wT.C D?1q4J
    return 0;
i!v TE]r[#r }
r'J8u$S7qQ9A!iLD
+GWJ/T%a} int GetTop(Stack S,SNode &e).E^.m*xa R~
{
/MA4F![?IY     if(S.top==S.base)
8b4r d J]*G;@     {
'k]3v5B^^2yQ         printf("栈以为空!");-Z#X7|S"Mo
        return -1;
#GZ\ n@$IUq?8m8s-SV     }
G7_M0N9\!?8F     e=*(S.top-1);
\7y-taY.h     return 0;
#[#csB?#w8~ n&k }
8`6^'l4Do4x1[}8J q:{Xg kZ
2P8},s)A}${J int Push(Stack &S,SNode e)
s D/D+BZm {;hnMp&Hu| P"k G
    if(S.top-S.base>=S.size)
pN)sqf     {.vaJ5}\a$BvR
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
UE+S0oX#s[         if(S.base==NULL)
3\A;F$UUZD/e1]         {,mv(fi*@u/?.az
            printf("动态分配内存失败!");
m8h2q|Q(MkUv             return -1;*S@&E7AARZ H
        }:ST(iHpP/j8^9G
        S.top=S.base+S.size;
'uvnZ:Iex4U x:B         S.size+=APPEND_SIZE;
GD.zoOWHe     }
wbk!kA|QE3^     *S.top=e;
'KN;I,Y;K!E;eq(y     S.top++;G8[$Fn-?
    return 0;r~9kE7^oO
},g6rB\#Lu

o5||ZZ int Pop(Stack &S,SNode &e)
JU6h N7pv m}2h {
4b*j"r4E4h.eGd(S hA     if(S.top==S.base)
"M7}#NIG/Yn     {T5aYjvl
        printf("栈为空!");
#Q3}At ^&t.Uj         return -1; y:^ CwDd/c
    }
6l9kY\'E+r\f m     e=*(S.top-1);C:a:U,jm$\bc*H o,I
    S.top--;
GF9Q]:["b     return 0;
vg)I\k~[ }
c js7\b(IP%u4GV/T t&F&v MC xr?w
char get_precede(char s,char c)
'c0s7h6Qi(y {$wlGAn/g`
    switch(s)
r fA{u%xh6p)`     {2|{'G,Ul
        case '+':                 
"HdF\W^ zx6e         case '-':
(N.R'j C!CAn@              if(c=='+'||c=='-')
E"l-\_v/p                  return '>';
4F*@(iV2b              else if(c=='*'||c=='/')gY2c ~ m9S
                 return '<';U+I,F9H'i` N3`4~ j
             else if(c=='(')
/tUkKz(q8~&Bu                  return '<';h#l/t&rDt"r
             else if(c==')')
y#i|&s8l]N1X"u oW                  return '>';
mQ&r-G a3l(G:JT5b              else
.gS_/Pb2N                  return '>';h J+Q"H-c%fX
        case '*':
wM5zh3H W0A6Q g         case '/':"?)a1kYW4j&f
             if(c=='+'||c=='-').E [X}[-uFq_3z,}
                 return '>';
T~c#Arul              else if(c=='*'||c=='/')!H6\J?#FGIHJG @.n
                 return '>';*^2e%wC(K(hP!\
             else if(c=='(')(B%dw%Q3f/`6aw^
                 return '<';
G|9w]XPEb2Z              else if(c==')')
@9Y} U J lx                  return '>';
2`.z(nNX              else'sM5l+S g%?/v0Vq
                 return '>';
4u%b QInK_X         case '(':
T W R|*U oUFK              if(c=='+'||c=='-')
6z g@8~5`(My%K8x                  return '<'; {Xw3U;?
             else if(c=='*'||c=='/')I,TH6FR$TE
                 return '<';$H O4NgR |k
             else if(c=='(')9Y5CT7?2X"?#N
                 return '<';3o R3L1we'bcE
             else if(c==')')
&Z [$P#G;v PYg                  return '=';|"o&Tf8{ @C
             else
yNvE3]$U b5d                  return 'E';
"Uxa `i:i         case ')':Ab9[2R2Z!UpO
             if(c=='+'||c=='-')
yl3FN#t2Br                  return '>';5[o5rq^+gi+{3@
             else if(c=='*'||c=='/') ATt,HsF
                 return '>';
io W \O1]{ y y)[              else if(c=='(')J [ m1jL#i,}[
                 return 'E';IU)A{)eK]
             else if(c==')')R`ufb"b,i
                 return '>';
:x*?uOd              else `1HL'KT*t)kk|
                 return '>'; t4}C^~TPk
        case '#':
? xMu t@P              if(c=='+'||c=='-')^ }q;N-O:{r VGp @)A
                 return '<';
,gM2t/FXL0?U              else if(c=='*'||c=='/')
j"aqi-^'{R                  return '<';ZLuw#Ch,Z8Mj
             else if(c=='(')-L+Yz:bn2y1ZF2P
                 return '<';
0EnM{0jU6`r1O              else if(c==')')
j _v&EKk                  return 'E';|;DG"Tf^
             else
2G n9i A V#O)D                  return '=';`$pSBd0L8R
        default:
tZ:NY NkF'e              break;
3F4x0c y5@4yQ     }]'B6r])wfR,Nbs#j
    return 0;   
i?/{ R!Kd'B%G }
(t;UL+kEYF (YG4H!? ?8V
int isOpr(char c)-w|,Q!g9RC
{
W"?r*I\L:SFQ     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
*FH;O"W(C*f1y5w:QB         return 0;
@,`Uom3O     else
"x%I8p[Q7W:h         return 1;
Zb3e[e7U N @ }
U LqHV
H:x(C\7A \U float operate(float x, char opr, float y)_pf _ y+|A w
{5W} y7^i
    float result;C o_"S(M
    switch (opr)zs5u F3pg
    {
C5a"zP/Vr         case '+':
~f,U!DzvQ              result = x + y;6imd?U8|
             break;o%o)T.g6p6b_
        case '-':
mr)k T~ QA x              result = x - y;
"p^'i Xy+O+jp,W              break;
(N W:Uh_         case '*': 0L \ Ipe#_[y#g*?,Z(z
             result = x * y;
im!JoP Q~              break;
e(BVa"D^p!v'L&B         case '/': ,alZZ4R
             if (y == 0)
]R L Y/X Ni Jh              {6e+|.bZ5B`B1y
                printf("Divided by zero!\n");
`VIM#X!t(r                 return 0;m1?\s't%Bd I^
             }
#C \aW,ca'p7u}              else
f|fgV}$JQ#j/fb[              {
w'W5q;d:}q!Q+d                  result = x / y;
#U]Q?M#^FA                  break;
w0^ ^*hJ}q7S              }
y2i F!TL%Ngz        default:
XzA;t'x6rm d,BRT              printf("Bad Input.\n"); {)\3^w?_9z
             return 0;
6L;[c-~1SrLZ     }N XdFTf0W c
    return result;c3h^*Y)De6]K
}   
jFZ7}Qu o5\
@ sZ2A4qw m2k float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
1s+^fM,go5O?;X {UDF f%W
    Stack optr,opnd;
H`D'k&p[     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;V)LlT!a |l
    char c;
Z'YrH He e     char buf[16];
w0v:|t8\     int i=0;
1j*Zw&_c)u]    
ED2I0`8m0t     InitStack(optr); /*用于寄存运算符*/L$Z;yQp4MR(I6Ew,y
    InitStack(opnd); /*用于寄存操作数和计算结果*/
#_G7H!["a     memset(buf,0,sizeof(buf));D z Ws_#f
   
e3u9LQJ|@d4i     printf("Enter your expression:");Go kb mC/V[ `zM7S
        
4EcNml,a     opr_in.ch='#';e{`hu6W)Z
    Push(optr,opr_in); /*'#'入栈*/qC0^|3vl%tF%wL*i
    GetTop(optr,opr_top);
mut$uggN     c=getchar();q9y Ry}P
    while(c!='='||opr_top.ch!='#') |5Q0rb N@L'E
    {
v_ @ qy6?)W bB         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
0Cd:q)y"c Io         {
,C TE a-nj             buf[i]=c;
}.Tv ~{             i++;F}p&^/h!nos
            c=getchar();
[ `Z+x,xb(`D         }
XK,fL2L         else /*是运算符*/9v3KCO \ V+d
        {
(O$A&|)M;x.Zj{El3wX             buf[i]='\0';
{V+H%cg2y d             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
)F9?!I Vb@6X Dn             {
-T/| gN{/z                  opn_in.data=(float)atof(buf);
1Z"Lx KdHE2f                  Push(opnd,opn_in);eHGX:z,A#ABE
                 printf("opnd入栈:[%f]\n",opn_in.data);
TZ0|2n.e0@#n(| Baa                  i=0;
'~},z(k#MD q)z$["\                  memset(buf,0,sizeof(buf));
J6GK"Tqf3D-H             },H:bzc+`:xe/Sj7{
            opr_in.ch=c;
u0J%{-Q[s'TG             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/*IB qfZ3H
            {3m-@'SRjj
                case '<': /*优先级小于栈顶结点,则运算符入栈*/OU%G,^ {
                     Push(optr,opr_in);bgM ?)f]&rvg-yq
                     printf("optr入栈:[%c]\n",opr_in.ch);
[Q4J a9g5l:_U\"?                      c=getchar();F'o \ I |6?%l
                     break;
"B7}$s|;C2]                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
#q5A]S5D0rZK                      Pop(optr,e); T!h6?K$Z E*n)n0o-n
                     printf("optr出栈:去掉括号\n"); ~O/i K7Y!P(?;A
                     c=getchar();`v.Fd-[X
                     break;BS5_z8B8[&~
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/j$m4^S6c/_"G$Vku
                     Pop(optr,opr_t);:H4] zE-xU?8~:{
                     printf("optr出栈:[%c]\n",opr_t.ch);
LfFA-{;uM5a*^                      if(Pop(opnd,b)<0)
/Rx5E q5S"Q                      {?+@JX}']0Mp^
                         printf("Bad Input!\n");
.jTmULs                          fflush(stdin);
nh7Fw2d9}-^}#n                          return -1;!Ys aHb+Lf4[
                     }
|8pFw2S\cb]                      printf("opnd出栈:[%f]\n",b.data);
6sww Nvf                      if(Pop(opnd,a)<0)N HxN3n`
                     {9o3a|O1~7c c,k
                         printf("Bad Input!\n");
b C$|| mv"v`                          fflush(stdin);`CD9?J&G3D&f
                         return -1;
b*Z3F'} Mf j:Y                      }`+c NW3F5ZNX}pYh i
                     printf("opnd出栈:[%f]\n",a.data);
6JTx,A2o%~J D                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/Jz O8gV B*j)I
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
V8ooI/I*Z{                      printf("结果入栈:[%f]\n",opn_tmp.data);
f/? Z(l z3Lh                      break;{%H0Y1n EM0a.H
            }
6H0]`1{x vFg         }
oc{_z-{ Q         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                }1|X;d[Q8xS
    }9It:@l~
    GetTop(opnd,opn_tmp);D`| qBc
    DestroyStack(optr);
2X:Q5cA.ez!`     DestroyStack(opnd);
;` xPx^2UB)l9u     return opn_tmp.data;
\ \)p M&xNIy^Q }
Z0[ m$|SD4c
(\dIIo#WA^D char *killzero(char *res,float result)
YmFd4{u/D {ZIwC$@5n;`5B^
    int i;d2f#ak,M/@|
0yn,Nh0k Y
    sprintf(res,"%f",result);
,LM;A ?#CR^!K     i=(int)strlen(res)-1;+\F as%cu*^sH.\
    while(i&&res[i]=='0')
:Ik(t4F3pk1Y P6K&y     {:R\[cn0s2ob B
        res[i]='\0';
H'}2x+\~ v'N         i--;N-dCu@)`'z
    }
nZ)yW[c2O     if(res[i]=='.')
L2C&Ahb:P7\3F         res[i]='\0';
6l7A&qo\X     return res;Bbw L nN1rj"U
},JN4o%UMC!R

p0Ze%Y^9hU]:s int main()S6\R2G e~h5|"^B
{.?;_Mzk:L8O
    char ch;*^e"{yu1S@g
    char res[64];Ng*P4vhw[
    float result;F+Q'i3bw*w
    while(1)n*tc'eI
    {
V'|-~Jz,dN         result=compute();
@[f(U;l*h         printf("\nThe result is:%s\n",killzero(res,result));
,d[ hu$Xy&s?3n|         printf("Do you want to continue(y/n)?:") ;
Pc1H.`Z@ x5Ics         ch=getch();|(I kTt/t-X q1Jg
        putchar(ch);S(h"NiOHz$^"bga
        if(ch=='n'||ch=='N')
z,}[$k$c m             break;
x!Nu4hx/X         else0pWG7VJ ^T
            system("cls");
w)| r*m W     }
!g$w SB/hCkb x     return 0;x p:e~+N8L `
}[/i][/i][/i][/i][/i][/i]x,q5}{{8YP

7c*K1Ge%AF3vU|9T8b9K [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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