捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.U9i6n7\L:_1b i(? LPTe
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=(rX0zp1A r
/**************表达式计算器************/ g+R,~8A;i
#include <stdio.h>|zD+| xeG,k |8Fz&g
#include <stdlib.h>
Z1n @#ku #include <string.h>
Ly:K Z#ogu #include <conio.h>
jB5?6H(j7wZ { #include <malloc.h>e{9f?a/k%]-B

"id2G-d;RO:S'X Bvs #define STACK_SIZE 100j:IY-I(^9_9E
#define APPEND_SIZE 10R;r+K&aQ~1e\
,l-a{X N
struct SNode{~i|$F.Ek+u6c_){
    float data; /*存放操作数或者计算结果*/
cbe'TQY\     char ch; /*存放运算符*/
Dl\R V4m9_ };
j!{ U7s+L+x&|0x D#F*K9K X ]
struct Stack{
"u8f`W]mZ;w)W-b     SNode *top;
8u2W5aH1F.I     SNode *base;-|;Y ~T0[
    int size;W{_2ZwW:`f?
};'Z&E'e$CmPT
Mlq6Y}^G:I
/*栈操作函数*/
{ib8c4_6F int InitStack(Stack &S); /*创建栈*/L#G~:P ~hw
int DestroyStack(Stack &S); /*销毁栈*/?BN1]h
int ClearStack(Stack &S); /*清空栈*/
f WCa{ u5z int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/eT!j } A
int Push(Stack &S,SNode e); /*将结点e压入栈*/t.l*U3Uc%qJU&Ee4{L
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
&I&q~-u YTm {#P;@
*]G+@5p@&J+y$b /*表达式计算器相关函数*/1u:j4z4dYX)s2f
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
#lgH#Z'q*x%w,e int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
N/Hew1b8Y6fI u float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/:s$fK0\Wx1}#go#e1y
float compute(); /*表达式结算器主函数*/E*[Z/hDS P D3P
char *killzero(float result); /*去掉结果后面的0*/
d.B&l`p:dPX
z0{FR(P/GB1T$J int InitStack(Stack &S)
*lU1qb,Ju ky {Y-V6|G&l lxE
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+v!|!J/O1i+f'x'Y-?
    if(S.base==NULL) rB,D4S1p1U&s
    {u;C!vwaS7I
        printf("动态分配内存失败!");
FL8^,@t         return -1;/U3k+r Ita8s fw)q:Il
    }W{_vI4bHdO
    S.top=S.base;
4C7f8w6`t%r     S.size=STACK_SIZE;
~P L x2H3F z     return 0;
mw h,u*e5t/gL }
P6^ Dn`-F;j*r+W
O~,F_? NG int DestroyStack(Stack &S)
g$q RNg? { y/x,oDw,h U.sS2V
    free(S.base);
5c#Y0B#Yt0ys     return 0;
W*Nl(wu6K N }
u$lMhi$rjw
4pK)mPiDTR int ClearStack(Stack &S)
2O;GnW:y6o {J)@x'w0rmk
    S.top=S.base;L-m{Q!`
    return 0;
y/g `*a;H!r,l~ [ }
UId8|'PL9AB
l^,mq Z int GetTop(Stack S,SNode &e)6Q'v I&j/V3l%PwF
{'Q;tZB,P
    if(S.top==S.base)7l |+J f3P`
    { v"rZg tqJ
        printf("栈以为空!");
!zh2JC [7z         return -1;
k'q6|!O h#{4?C$Mq     }
2_/K+|oiNj x     e=*(S.top-1);
r^!YX L     return 0;
m8z^#n:p:I1hd K H }
-sg)FI`q)B s$x^ ,s+e}kWM/@:V;W
int Push(Stack &S,SNode e)
2i1{"lz,d*kH)NY { qu%_A3qE(S`
    if(S.top-S.base>=S.size) b]0UG)p _b
    {
6{ Hl-rv0f/Y"Ip         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
*G,aD(LL3o&v+S         if(S.base==NULL)D\B ~%{
        {
[Q0u4?q9qi3o             printf("动态分配内存失败!"); _w(XY7W8{6x|-}
            return -1;
+D/k%TFj         } G&ny"]7fvF
        S.top=S.base+S.size;^3aPdx
        S.size+=APPEND_SIZE;%R,\m-ki
    }Ok5J v Vj
    *S.top=e;
@3e;~ Ow     S.top++;-jY_-[R#~8a}CI
    return 0;
t,f-]GJ2@p5P(B }
!TSu L]o4w6N3n
YC I UmLY~2S int Pop(Stack &S,SNode &e)
@i.?2n-h@7f {Z0@$n(Z!RI]
    if(S.top==S.base)
0[1_,a)h$@ a6["l     {q{cH W7F:z,w
        printf("栈为空!");5@[hJ3~\
        return -1;
w\ _u[     }3` I(aw!H.x
    e=*(S.top-1);
Cl/HUk[O(B5[     S.top--;
*H#x2Oe;r$Hq     return 0;h ?f fG`;d
}
7C]0Vy"^%`/v
3x'yL4C6Ig4X char get_precede(char s,char c)
.]0f2}Tr {l [#{-|J%Vk
    switch(s)
!U&e,Oqw]     {
w;HO'zH n         case '+':                 ze p3y V-p*}k
        case '-': W-k*P4G9N8s\ F
             if(c=='+'||c=='-')hs}}Qm6t
                 return '>';zm6p7x Qj@/r#G
             else if(c=='*'||c=='/')l-FHL3vZ
                 return '<';
5J\!|W z6{/N c              else if(c=='(')eWf1q ?D O#n"I
                 return '<';&z|A/[r bT$ZA
             else if(c==')')6}t8x,` `'o.Q)I(BU
                 return '>'; N I~!~r6V
             else 5B r9l:U MSK)P
                 return '>';
S%F&}X0M         case '*':U L `-U]
        case '/':
`p|!sc6{LR/t _+C              if(c=='+'||c=='-')b{!l)]G"_ a6S
                 return '>';1Y u.xVV\5f
             else if(c=='*'||c=='/')
0f;esO(C                  return '>';@s?7t6@6x]![:l
             else if(c=='(')
-zs%h2\ N-b@J4eG`                  return '<';RpN'q!T)j
             else if(c==')')
?4{udE*@5{L                  return '>';
0XE I TQA a}              else
(n7u&H,\&Y(WnU)YN                  return '>';Iw5@V'tT0Z
        case '(':E'u2rzW8Z+`:G
             if(c=='+'||c=='-');y` W8?-N+{9CG.F{(P7k
                 return '<';:zJeE(gK Jp
             else if(c=='*'||c=='/')
1O2G;F"@;_ E)Q @In                  return '<';v:fd^&E ij ~;[I
             else if(c=='(')+@J-Lq'k
                 return '<';
cq!WZlg0oC5s              else if(c==')')
r y9n}t*Y} L}{(v0E                  return '=';
E z O+L*Gg,w[L              else
#~WS.m#G"A                  return 'E';YA'[/V)k-kf
        case ')':
/Z]2D_j              if(c=='+'||c=='-')6f}|]w1T{
                 return '>';"\/E){+R ?8|_
             else if(c=='*'||c=='/')@E#WN%LE] k;t
                 return '>';5`rG4c,]I
             else if(c=='(')8HO M|7M^n,a
                 return 'E';/Q#V@4GbC*i6Y;~
             else if(c==')')
Pls*C z)y^                  return '>';OF(k dE,g
             else
,W/ZzvSs N^n                  return '>';,]6L+e6W4PJB_4z]
        case '#':Z1LwFum
             if(c=='+'||c=='-')p4S)Px1l
                 return '<';
6@_&Bh2[r              else if(c=='*'||c=='/')Ns+lf4o2~'@
                 return '<';P:g#}"m#?H
             else if(c=='(')
QQM p&Q4uH                  return '<';
)Hr%EF1~              else if(c==')')1W/`[ I7j
                 return 'E';M c w}+dH4K"l8cnx
             else
\%@:d ?*C(aE4p4^                  return '=';
? @F"ze,W         default:
^E!X|7L jz:R              break;
_8_q6_] HN     }
JE|7?8Pw     return 0;    $M"`xel6Q
}r0i,a X hG'_

:|)S UP Z O5V int isOpr(char c)
"e-jv YV~ {|8V7F r`n0E oG Ok:OM
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')}ho'k[D3~ S OdJ N
        return 0;AKP c$o/u j3g
    else
'V{v)InA*UOPg         return 1;
ZY_q} }1[-r*R5R6|l l1l }
L9L|^3PgT's(s
float operate(float x, char opr, float y)
.s"z9p1t-HL {
B.cG5@t;T+H     float result;
MD)G+qY\"Xah     switch (opr)
Ia+bH8z0r%{     {Ht+d%h+O1CT"cz
        case '+': s IDl-p$jIlS[4t
             result = x + y;
H*lK*u!fa              break;
w/gt+v)~*Q-my4m         case '-': ^E s#V|"z:t*f
             result = x - y;m5ha7c0jGA1J| k"F
             break;
m]:_;x k-K G         case '*': /PR@C4qe(L&h
             result = x * y;E ]1BO/b}'hxe#\
             break;
Q8y:fM8F|-l         case '/':
6m}$u2C-n+U4w6f|              if (y == 0)4|A{-v)MyBg
             {Y'G?{*x"}O#S
                printf("Divided by zero!\n");
(t6\6]g b~ t._*T5J                 return 0;7y;f$j.P;Q
             }
xA'W c$eCl              elseZ x)~_R0LSI/zCd
             { nYm&W\-{
                 result = x / y;
r#O+zb2n0P#gu                  break;
/Y%hh^EU              }
$u2J\E1n S        default:
{ r5ffVA/e-g              printf("Bad Input.\n");
.j+\'LN9@;D\u              return 0;7Z Oftl7Qs
    }
k7PZ t)kKH     return result;
4\T3z.zq8B]:K }    N0ST3@#P8eB^

4q7_c[}v0]wgK float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/.s K%e rv'F8LQ.O
{@ U5tJB?1Z3Hz J/@[5y
    Stack optr,opnd;[ V)lfg;d3G:e1b9T
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
1}b#m-\M5b'f]     char c;
7{e+b"U j{xXX+Z     char buf[16];
mt6P4t7o&AIq     int i=0;Gx_z%rl-z,O
    &Q4A)n8n ]~C8k ^%P.X
    InitStack(optr); /*用于寄存运算符*/Apm)q7m}7{V
    InitStack(opnd); /*用于寄存操作数和计算结果*/)kjNA*ekgv
    memset(buf,0,sizeof(buf));7Y |*Y2afR5EB
    1h2Ymx,\1y/B
    printf("Enter your expression:");{E+KPv{g
        
!mc6E0u3j@     opr_in.ch='#';
:iyyZQd*TL0O}     Push(optr,opr_in); /*'#'入栈*/u3u&y$e'[8RU7LXe7H
    GetTop(optr,opr_top);0^ \ Vu6N Foe&@
    c=getchar();/m2U0[ x1B0Ih
    while(c!='='||opr_top.ch!='#')&Qm,D9G0s;a
    {
o/la8Ksc2N         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+y _K O#]7i+a't         {
Q^:k'cTD`             buf[i]=c;
3\Z,\L0k`J+ay2Y             i++;9H\2wN+| THx4C&n:q l
            c=getchar();
vW3Dhm(xu4`         }6W`yoi fJ
        else /*是运算符*/WN d\1D&M)]
        {AG)H?,qJyuR
            buf[i]='\0'; {P9G[w1v:K?lO'|
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+\%_5AnI
            {
o+P'r0S"LSf                  opn_in.data=(float)atof(buf);
#JM+r rAR+RRSk?                  Push(opnd,opn_in);
f%]hScEU$|/e                  printf("opnd入栈:[%f]\n",opn_in.data);
O/q? SA@6P8{                  i=0;g,E.TJA7z O|
                 memset(buf,0,sizeof(buf));5hMXO1R
            }|T4`k/yp7C@3H3nU
            opr_in.ch=c;
jf0e(t m5m#c             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/2H0~ sM*U"u4AuaMxZ
            {!y2k*?5}sN:~E
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
t7S?]&x                      Push(optr,opr_in);
c3y Z(^,AeZ#a                      printf("optr入栈:[%c]\n",opr_in.ch); Z@%z,C$@#wiAy M
                     c=getchar();
H9C#l0Mr!i%Z,z5A9L                      break;
Rugq;n5V$m)B i                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/.}){QF'l q
                     Pop(optr,e);
p-[5e:q&M}i                      printf("optr出栈:去掉括号\n");S-? [Q5O
                     c=getchar();d ^:q+W+Wzp9j
                     break;
n]g#h[1e1?;TKh                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
w5b?qzb WEh'm7e4p[                      Pop(optr,opr_t);
XTmF k"v2P%b-C(P o~i                      printf("optr出栈:[%c]\n",opr_t.ch);
d~8N8VO7_]h                      if(Pop(opnd,b)<0)ezn;I_ w9\-^6D
                     {
Y~ jV0LHJ4f8J7{                          printf("Bad Input!\n");6T'tp!lP{@IGqj
                         fflush(stdin);
I0B!|b8\ ]@                          return -1;
Vu1JUx                      }]"I l.]5\6C?.Y#R'b
                     printf("opnd出栈:[%f]\n",b.data); U*e2M:Q.J5y W [
                     if(Pop(opnd,a)<0);r4v3M x.h!Ay
                     {NQ&R ^zn
                         printf("Bad Input!\n");
a9M\7s gK+Nm                          fflush(stdin);
JR'OWpX                          return -1;
3Kk"|5V;r                      }
@O'GAy3k'f,B!`Z5t                      printf("opnd出栈:[%f]\n",a.data);j\ Tg#Ny|8S"D
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/P6bnJw0F
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/*@ @J%u6Z4mN
                     printf("结果入栈:[%f]\n",opn_tmp.data);
-] u1` ^Wq                      break;} ]TojmEG\J
            }-`"p(q:a6Z{Oz A!Bq;Q
        }
8?6lD7QF$uf rSf)TN         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
o2{qWI;i"W     }
4\`j"cy     GetTop(opnd,opn_tmp);
2_3\j0L$O1^ CN     DestroyStack(optr);
n$?.p%].VP J{2y     DestroyStack(opnd);
LUBHr^ Yu,\     return opn_tmp.data;(q5f*VrU1m
}
)?3KI\:m~7U7A
"Rw/{ ?1d;N \ char *killzero(char *res,float result)Q9@KF\5~Y@
{
y4G @,w}p^&h     int i;
9J6F+U q9Q
ml9zfE)@[     sprintf(res,"%f",result);^kkA2c~Ls
    i=(int)strlen(res)-1;
!c@Z%\/c2`[     while(i&&res[i]=='0')1DqT'\j|F u
    {3kITCcA*m/Z;Eh*\
        res[i]='\0';
2{-o|Q%el` o)p         i--;
5qRB9r ] l5G!] u,e     }
+b:|+QR(Qy)]w     if(res[i]=='.')5s%c?k FDj
        res[i]='\0';@8^%]yB:nnNWz
    return res;
Fa2j D6U4} }
"~2{/J4y-P6^ E cQhbO1CB
int main()
6Q;T-b x2m/]|2f { _|? | k
    char ch;
.x-L!C-o2S     char res[64];
M8z2oq |rFI     float result;$k S]a%_y
    while(1) V @ }7j$}(l+~A$A#Q
    {1TD0G)A pb
        result=compute();
Y1\p3V"bqe1T         printf("\nThe result is:%s\n",killzero(res,result));
7hR(x j7m L\;DG}         printf("Do you want to continue(y/n)?:") ;
%[p"s,X0bO:K6e         ch=getch();
.l[FB,VR9R'sdL         putchar(ch);
%mC~3SG         if(ch=='n'||ch=='N')
2h%LX!Pg6I]1J!FbXE             break;
)C8j+d#Q/l1U!zT1h         elseY*upb(S7~
            system("cls");FP0X-`&R K F4R
    }sH;J@%y%Tp
    return 0; l U@ QhHH
}[/i][/i][/i][/i][/i][/i]VaIT-I_ K2H

M-G4t6~5^Nrw [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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