捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. J9?;f0E7^gk7B
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
g|olU\+v9o*K /**************表达式计算器************/4i*X9}'V cj
#include <stdio.h>0Z+k}SW `*x
#include <stdlib.h>'v9@T(_ dIfi
#include <string.h>
n Qb[B+P b+D #include <conio.h>
s^%b*_'yD #include <malloc.h>4c7Wx3a"k*@q-r |

n3v|3oo1T{ q #define STACK_SIZE 100V Z%KVC1C-rf4?'^*r,^
#define APPEND_SIZE 10
3U*j*V+l;g$e#L mo:h
h.m2Z*j7iV struct SNode{5R0tTd QC3g&Z+vD
    float data; /*存放操作数或者计算结果*/ `-n3G)^"?
    char ch; /*存放运算符*/
0ke3KE/} PSt };qw`#Q Fh(C js

:@S.c-j,Mo-{(oT struct Stack{9Y%o@m(T?x'T&B
    SNode *top;
j5Xv3s"M @ C-}t@S     SNode *base;
p+v O6g4O3K)^B     int size;
-@ O_+S7}P:Y };
2I,RqSz[
k?WV4Cc /*栈操作函数*/
D3K1t7wG int InitStack(Stack &S); /*创建栈*/M ^y b O
int DestroyStack(Stack &S); /*销毁栈*/ H j/olTYS$uL
int ClearStack(Stack &S); /*清空栈*/A5Rm*Q'OHM,h{
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
~| ~s0c3a;~(}a G&M K int Push(Stack &S,SNode e); /*将结点e压入栈*/
;t4h Dq`~x int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
`}&Of)vQk.j
Ga7^ \'n /*表达式计算器相关函数*/8t&ST(aI@Ox
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
5P G(s1{5M.y:w int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/uj mx5d*PT"m H7[
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/!}I!y }m @S
float compute(); /*表达式结算器主函数*/
([/ngW!rs char *killzero(float result); /*去掉结果后面的0*/ 3J!My svn"Yv1d$\
(Wu1r.h ?A'e [0J
int InitStack(Stack &S)8W3b-_{ CRJ2d
{
4V*{ ~ c5l     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));S!l7Ph/IT0E'`
    if(S.base==NULL)
)`2FNg0P.\fIbD     {
I dI6U*m1B,q         printf("动态分配内存失败!");5u4YAKd$b
        return -1;
+g0X&?5Lqj     }%U3W9sx1XGL
    S.top=S.base;&~t4kw k d*a(aW?
    S.size=STACK_SIZE;
?1Z4Ye np cw     return 0;
W-QEe/he p \ t }
P5@U0]L_ ^:IeX DC
int DestroyStack(Stack &S)Be6Y4~@*i(Jf
{j/U\1o%Rn6X+x w,mu{
    free(S.base);/D/`5gztGB4F
    return 0;
#_[ w5M/J Yt ] }
-i-K}QYPG+^,\0v *I'P2_$lkifZ
int ClearStack(Stack &S)Nc*skng7Z"S?
{
YY#cX l_2]     S.top=S.base; \Yq;x:c R u
    return 0;]?'T { x6F4v
}
O/JF2\3G1u.kICrV $X"dm[,o#E
int GetTop(Stack S,SNode &e) A$`@};{$`y*h3dm%R4_
{Q]X _w&P
    if(S.top==S.base)
Z!A&oUy@5o$s~4y     {8Q:_"eKR"Lv
        printf("栈以为空!"); Sr'N${x;c
        return -1;
L H*q9m5N8y     }
A7Al E#@m0\     e=*(S.top-1);#OBp6rC!L(Ai
    return 0;'PLy+A1p"q"F
}}Ui*Uf$He
z7N$twF$k
int Push(Stack &S,SNode e):sTE$n#J B.Bhu[
{
z}bFL$e/s}\(qk     if(S.top-S.base>=S.size)x!`'z rY[ [f
    {
a@8g C7ve         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
;f(g;F+LMZ|         if(S.base==NULL)(W#i$W0x~1I3MU4n
        {
-O AS.N mdn             printf("动态分配内存失败!");
E-@~&g aF!mq             return -1;
1S \:s0mi         }
X:p]8qo6V@         S.top=S.base+S.size;
2A3SZ/GA         S.size+=APPEND_SIZE;cA kp@r[G
    }$y3Zr Ws`
    *S.top=e;IKtM3LmpD
    S.top++;s0_.m6Z`C1@"~ u
    return 0;
"U/J+AJp iF I }
QJ#H~GH}t /K:|IH#j.x
int Pop(Stack &S,SNode &e)2ec$z0xc
{.|4R&j*f [8UIs
    if(S.top==S.base)9|{Mz M:JR |
    {)T5w] `*f$`w
        printf("栈为空!");5`XO"Fh?(g2K Q6H!i
        return -1;Av0?JDe,b%z
    }e)U3j~.q xX
    e=*(S.top-1);
)`s'h~ oMIv     S.top--;
$MjH'|-I&z0d     return 0; U3B-V k4U
}M|,Un4TQ H

,G/] Au,m] char get_precede(char s,char c)
+gY sj|4bc {
?}0o fTdJ     switch(s)
-xc az@*`     {W8HE~gP7~C'EZ
        case '+':                 0A qi(f L3m5y'|8o
        case '-':
Q-v[A:wQUa9Y              if(c=='+'||c=='-')#VMlY \
                 return '>';
Q2LwQg#Y&~              else if(c=='*'||c=='/')
RGU/r%h(r                  return '<';
}`9wH-~l@              else if(c=='(')bG'H9T)t|E
                 return '<';}9tI9q8r"lw{^
             else if(c==')')
1BM[[_                  return '>';;Y MD'Y:X8k&}7g
             else )xc zdsdSY
                 return '>';nS/u S.G5z/I;KB4u
        case '*'::Eacv M0`$m
        case '/':@0}1cz7J)r$Q
             if(c=='+'||c=='-') c:W+d*Xp;xdR
                 return '>';
\;@T(rd ^              else if(c=='*'||c=='/')
)u;N#h w*`[ B                  return '>';
s#il{c$B              else if(c=='(')
7w9K7G z!S2Z1M                  return '<';
N3WDXqG6WC.tp @O?              else if(c==')')
M ME \$M3JE                  return '>'; a,T0W4q,}"m
             elseE9zD$Pg:[ A;Z&_
                 return '>';9k[y)]'Oo{e+M6u%IAa
        case '(':!U9M dAKQG:\#P
             if(c=='+'||c=='-')9We,B3t}#OK
                 return '<';2n I;U4yPp{3ZL
             else if(c=='*'||c=='/')k Gk6eF
                 return '<';
-HDz @s }q              else if(c=='(')
-B8a2xV)@%_rB                  return '<';
O%q2}0N4]              else if(c==')'):Z8OqV p,S
                 return '=';!Gn*H-G/uK
             else2}'`9I9G Z)\"w
                 return 'E';
|~!M{)Yh `q _         case ')':
L }+p.n$M0B I&w2i              if(c=='+'||c=='-')
*_y}+B3dco                  return '>';.N:JL*i5?M _
             else if(c=='*'||c=='/')
UZ'yc {                  return '>';j RQMT
             else if(c=='(')Dtx2D^5LL:E
                 return 'E';y;\(l a;|:Z,tx!U
             else if(c==')')rqA5g[8qX}
                 return '>'; n`AD;mv||L
             else
np$w3Pp@0}7Z                  return '>';
@N7l,r,P`         case '#':Ek\4K raZ%pcm|x]
             if(c=='+'||c=='-')
T(wAA^9F~|                  return '<';
xpc}EB              else if(c=='*'||c=='/') S;\g(^ U(Y3Sc
                 return '<';
2UW+{D6j a              else if(c=='(')
MTEe9Yj#UK&`%aq                  return '<';;yk`2k^LB,]E
             else if(c==')')
of,t:K;O                  return 'E';
9`0_2y&{q Q,]_6H              else n7SlgN!owK
                 return '=';`f&]c5Na6TA+|
        default:
U k;~9v6Q%q              break;
7W.S]D"ZnG%W     }
6m an/i ]_l/S.S     return 0;   
~I g H rakf"Jd }
`2? QJ(m8N eFU #H0U%T"l@6Z C
int isOpr(char c)
(a!GH+W*K.}W {
#@5h:szcc+C9J{     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
p6nM;Z1z6owC+s wX7f         return 0;v L?,Z1Ls;Bm;k'U
    else
3o6vdT y(_"lg         return 1; Q~@T%?-G*c*Bq
}
8O:Z.xP#^a PZNT/@0n
float operate(float x, char opr, float y)
X G5RLjL N8` {
m!b6S5ind     float result;Sp7|4A8D$R}
    switch (opr)
G6Z0W%O'@!@Iq     {
ZiB R!Uu]A(m         case '+':
1xr@;xF7L A+W              result = x + y;
x"xff't/\4c+|              break;
#zTQ q q!u;O'K G         case '-': $mu j)q:XW!FB5u*V
             result = x - y;
7tY5T Z5|3bnY              break;
%u1[J EC |n]2v         case '*': ;NC'iXr m%b ['qk
             result = x * y; I&sR8b0D~`
             break; q`|mu0_:M
        case '/':
*],Q0Qzd K              if (y == 0)
!ls#[A IdM9M              { La*x'f W#t
                printf("Divided by zero!\n");\-{*o]$ub*n|T
                return 0;(n/eZWJ @1S0c
             }_ W'_"f{ `M
             else
6wH,e%a4v"cJrx              {
P8L e)_+F6L V                  result = x / y;
3]9| E$Zn                  break;X wfL+h0tq;^
             }3}5N5_P:Q$pE
       default:
T xC)Ij8f%g              printf("Bad Input.\n"); #t F6g!k j{P {"a"U j c
             return 0;8S1g$bM8F6`
    }
JoM;y _?     return result;3O8bd r0^~Gwj'm
}   
{'wEKFjk %P"[4]PDKJN*H
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
@&~HX(E j5A {
l,Tj|W2H     Stack optr,opnd;
l j7N*a9i5j_Gqy     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;SQ L O*By
    char c;+]/Q K J*Lv
    char buf[16];
`N5TIO*z%P9m8HN     int i=0;
,L1@6iK"t.rV    
DCQ,A9Vo     InitStack(optr); /*用于寄存运算符*/
z9aH3A/E     InitStack(opnd); /*用于寄存操作数和计算结果*/i!N(eB'pa:N(rH3f(U
    memset(buf,0,sizeof(buf));
zT?%x}.e'E3r|H    
k5l D nn5H(sb     printf("Enter your expression:");
f V"DNG         
YAD"bsA     opr_in.ch='#';;my'WA3_-y b
    Push(optr,opr_in); /*'#'入栈*/5iu%jvLBp,f
    GetTop(optr,opr_top);
Q X(Qi+v+xu     c=getchar();
E3z$}o8UE7moGM     while(c!='='||opr_top.ch!='#')
F5l9s)}C2vQ9X     {
+f*]!n'RS:_$Mri1q"_4G         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/+}fV3NGkY*Mm
        {
CD*Ah%E"qQ             buf[i]=c;
J S(chk_/^ yc8L[{             i++;
2PU_#liV             c=getchar();
#w/E aG3i"i:r$H         }
a.g0[4mM}}         else /*是运算符*/
+~BJ{skVD`         {;?0g0W#G8E+Hk
            buf[i]='\0';
a ZwT4R^!o)A Y?B]             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/ev8qu!^0d9xKl#M`
            {
l-p.S|aF.}W                  opn_in.data=(float)atof(buf);J1me/~ y/yT M
                 Push(opnd,opn_in);}a:arq
                 printf("opnd入栈:[%f]\n",opn_in.data);
WfbDn g n                  i=0;a/c4jH^#d
                 memset(buf,0,sizeof(buf));
UI+s5E}-]a             }
:UfI!C"_f!x2o             opr_in.ch=c;PjH#Z^9B] f].|
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
9[ f\!u1`$G4l             {2G-T#j)au
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
qJmY.AN%bWta                      Push(optr,opr_in);;sI4{~)I5jc
                     printf("optr入栈:[%c]\n",opr_in.ch);2@ ATL(V-DUjO9N
                     c=getchar();_1a*_V ^5{m
                     break;
1qM"ni%s"tk-L#JBQ                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
jK5p n aaW                      Pop(optr,e);.J"~,P]W
                     printf("optr出栈:去掉括号\n");
sh#S$Myn{e                      c=getchar();3u8l&~u:rJ7s/u4G'?
                     break;Ok o:n Q"Fg:h3Q
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/:AzK m(r
                     Pop(optr,opr_t);WE K h f&aJ$[ed
                     printf("optr出栈:[%c]\n",opr_t.ch);o @2X M5r[
                     if(Pop(opnd,b)<0)
C:hO vS-`h#d8xk                      {
ty4v.ta[o1D)_Z                          printf("Bad Input!\n");
R5H-vM6n9J_-n                          fflush(stdin);
2W8j o(aMF;N*_                          return -1;
A;bv:f0g.nN                      }A;I4ER[^F:bj4`
                     printf("opnd出栈:[%f]\n",b.data);
,\,fuM;M                      if(Pop(opnd,a)<0)5K-O6eCWw0v`"y
                     {v/RF]3w} jm"NT
                         printf("Bad Input!\n");,q:] b Q.~M@
                         fflush(stdin);$d![&rU0@
                         return -1;
-?[RU6G ]                      }\G@-K$zO/X.w(C
                     printf("opnd出栈:[%f]\n",a.data);
$x,XB)M0U T3^                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/!yn&k t&k%i;cp
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
PNK?kSa                      printf("结果入栈:[%f]\n",opn_tmp.data);+egb2` N`f/o
                     break;
-t Rl3}+a*i!eYB$F4S*[             }{$[6b0x-B3Vi%C;B)R
        }!c"e;EL8]}]
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ldM^PIr^
    }(o9Z)CK | VLKJ+T
    GetTop(opnd,opn_tmp);e9B1`*\'J oM
    DestroyStack(optr);6OG6o6h!~X vJ3w0x
    DestroyStack(opnd);q-uU(^g.y6X
    return opn_tmp.data;
9])Q3L[sA? k }
K3y@(b.|bc
4H;I3oy TSuzq char *killzero(char *res,float result).x8|;@.i#C'i4Nf`
{K*ua:ktX4UG ?
    int i;D2SKee
-~IUNZc&Vh+x|+g
    sprintf(res,"%f",result);2o6LC&K2}0d:u
    i=(int)strlen(res)-1;
gGG i T     while(i&&res[i]=='0')
(zDvxxAy/~     {w V7Rs(}v`Nz
        res[i]='\0';P'brt c]
        i--;O,~N0A&P;|j"u~
    }jz H0IeHi
    if(res[i]=='.')
1drLK z4v1[O b9ZE         res[i]='\0';1cU&[U8a#OP
    return res;U)].nfBzd*v
}DZ6OsUn,d*y
0uj.J ]7}
int main()
Co"Iy JP0a {
-Y{[$q1PI4\     char ch;0C-D.j:X/D1m-`;o]
    char res[64];
#|+W-E(W0Lz'n     float result;
w^`9a\l     while(1)
_ay'li2dQ     {?1W2[9[d.rz[` m
        result=compute();9N;]]-}z8~7S6]4|o
        printf("\nThe result is:%s\n",killzero(res,result));:U.qt#^.w
        printf("Do you want to continue(y/n)?:") ;
!T[/POn:g         ch=getch();
Rh[Z9F7W Gf         putchar(ch);
[s*^$Oho+G u         if(ch=='n'||ch=='N') b+MW7\Q,sQ'Zl
            break;
'u3YS1NZ`d_@9Q         else
$st5Nyn3m c             system("cls");
#ty {Z7^J4\3d     }erC.Ex+d uR
    return 0;
6K4\8GM| }[/i][/i][/i][/i][/i][/i]
u$w#}%GA/d 5?H @/U gr0X1I
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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