捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
s+~Ep2L tL"J!^%F8I 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=5Hh'@@$I6FG
/**************表达式计算器************/[*e)L_3]mni
#include <stdio.h>
!xDe+_o:g T #include <stdlib.h>
,NLT G9_M)N1eR #include <string.h>
g-XW9C'a5K #include <conio.h>C;|Sk-?)o I
#include <malloc.h>_kS4A'J3J+L
n/W|7g-]1YT9`;LK U
#define STACK_SIZE 100
kQ`c)D(K!Bu @3r #define APPEND_SIZE 10
C;Y r8FbQx
n3| [xf&o{V struct SNode{\/} z;G{/y2d
    float data; /*存放操作数或者计算结果*/k"OPg0O,t5BE&v
    char ch; /*存放运算符*/
(BZ3y'M:L6wA z} }; T['k pwL$q0c

n z t[%ue struct Stack{/ekE DF}"RF
    SNode *top;(|jt;V]ow(X
    SNode *base;IH3vBX4[0E7|
    int size;
%qMIcQq!u"w.PC };ZV8f8^S9Aon(W

&aJ+X*CJO3S0Au /*栈操作函数*/
(\)A.Kb7az|-] int InitStack(Stack &S); /*创建栈*/e8oG!kO2c8k\*p0J/Q
int DestroyStack(Stack &S); /*销毁栈*/
0tOAd,]j$s int ClearStack(Stack &S); /*清空栈*/
.Q$hRi3v8w int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/I1kQN&AlP ZQ
int Push(Stack &S,SNode e); /*将结点e压入栈*/Q-J([9PL9w&djz
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
+D$tx0W4n GF#ybw |
4_L"t}R1s /*表达式计算器相关函数*/ S+c I!y+X)U*l
char get_precede(char s,char c); /*判断运算符s和c的优先级*/ ar&q y)y/O i
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/Aw5cegT*D
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
c,oCF8Y float compute(); /*表达式结算器主函数*/
(Jy;Nj ?+v char *killzero(float result); /*去掉结果后面的0*/
9fS+z.\ Pf
P,Bf'z0r6O int InitStack(Stack &S)`:S8g8]V$H
{
W"Q&p0Z3FT     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
6Z)`eP(z'\,SG~     if(S.base==NULL) z3F#Ft6h
    {
rj&X+a6?         printf("动态分配内存失败!");
3XZ u&fn)KeNY@r7q;D         return -1; UmDI S4PJ c;h
    }3A"a(Rx6cA;Qd9m
    S.top=S.base;1[$ZN&T/[ZdCkmT4f
    S.size=STACK_SIZE;7poe @Q!E"Ce@ B@;h
    return 0;
S"H` i7E }
#\4o,C2d:\ X
8J+](}d\ k.?2~ int DestroyStack(Stack &S)
R,E#n!s.|#A3t {
H*cV f2[9E6^ C$R K     free(S.base);
3W5?p,k3t0ns     return 0;v `3uc*^
}
(@{[L*v~!A
8aJi+K;Y0j/l3b int ClearStack(Stack &S)`x`D@
{
.ry[HY     S.top=S.base;
G G"^i9w6k*@8Ud     return 0;
"s&F Sw$r,~([$kr2z }
#K u8tQ'~_
l9E tyN{ int GetTop(Stack S,SNode &e)"l1I1Fqj
{ S;fE4MBO
    if(S.top==S.base)X5x4K2z%\.Y'x
    {7E)~] iV\0K5I"\
        printf("栈以为空!");
n:L/d-_-JM:NCg         return -1;
w+SDM-c@+C     }$\IZ7h%SF/h
    e=*(S.top-1);
d5[pB{2S[o?T     return 0;
Jb(t;X/J JnO y r }
;XSY9d-S$iw1q
tT Lsj?r int Push(Stack &S,SNode e) L:nD(UyE9O
{
PA#E$c?UJN     if(S.top-S.base>=S.size)
K"PJ2q6M+mc     {:I's&o+NJ Q`_2[6J
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
gp-U0a B-o3oK         if(S.base==NULL)
qLx _"A'V6F0[(k'C         {:u2J M;U0D
            printf("动态分配内存失败!");
I G @Aw0L C`             return -1;
~0o1`L)]*Hy         }
#Dqo(QeaZ#b$R}P         S.top=S.base+S.size;
fF/j~v J         S.size+=APPEND_SIZE;
;?}&S4N6J(I:_K     }
E%~T$G6Z0k i A&TR     *S.top=e;^:\`p4V1yC _},t
    S.top++;e|Mah`"h"V-P
    return 0;
` L] q;cRBX Xf }
7f?$\t!{ (df ^,kN|]9{"R
int Pop(Stack &S,SNode &e)KW&U3D*}#_
{ae-g7V"t0nj!w
    if(S.top==S.base)C+I5qs6l+?5W
    {
;J1nB!e"y |9j         printf("栈为空!");%e5N2}AR O7\}
        return -1;
yN8bi1@     }
HO!eX!U     e=*(S.top-1);
J#p&qe`x}     S.top--;y9Zr8X~~(A
    return 0;P8G9Q|nN
}mG$a3GA}2zJ/w,m0C
js$@%K%d6d*F o
char get_precede(char s,char c)
C|9k2[ o8SNm M {F#YFl/g [#K*Q
    switch(s)
m[9gU(a J]     {t;a;@f3?h l1w
        case '+':                 
EoiY&u&Cv7xI         case '-':e3jM.w C\
             if(c=='+'||c=='-')cxj(lbrT
                 return '>';)\l u'{"m:WH5nKj
             else if(c=='*'||c=='/')
@,b&D1H k^                  return '<';
*\$B9y? V _b              else if(c=='(')Bs0AAei6^hC
                 return '<';2H8Jy m-@WX)_
             else if(c==')')
0nD$n f2GkQ[~;OT.?                  return '>';Us C9\PU
             else
6G1|Qa] s0L ouQ                  return '>';h}*](s'Y
        case '*':
'k~8| l O_8I         case '/':*GQ.~o(E*}1e&`'Kt+R
             if(c=='+'||c=='-'){g$^~[ hdm:?0m
                 return '>'; Emr8bc5T/n.X9F
             else if(c=='*'||c=='/')
C8i0Nn&y!i Y~                  return '>';
Ro'e5H/o#^a+v,v              else if(c=='(')@0r(pZ*XF5q*M`
                 return '<';c+BWmh
             else if(c==')')
p7p]8y [!P9i s%o                  return '>';
Pb-`W$t,N              else
)Am+TEA^;VP0{                  return '>';],b2fuZ j_W,]
        case '(':
"xm!b0f+v"m/Y9a&AVQt              if(c=='+'||c=='-')F:VZz'd$C$p\9J\
                 return '<';p d'K5StR.u4Q3{ U
             else if(c=='*'||c=='/')
$L${s8q2As                  return '<';
j s Z.S-v(XD              else if(c=='(')DD$r:ABh3c
                 return '<';k%@&bS1eF g`I0D1V
             else if(c==')')
Ot8H"y DM0E1my9Ki                  return '=';\vO9E+A@0mR
             else
b6c/A|siSQg8t lm                  return 'E';
"r&{bn\Yz~5[}         case ')':
hVy e iK4D              if(c=='+'||c=='-')
F!c"I6g}:l                  return '>';$s2N9Q`yK uX%U
             else if(c=='*'||c=='/')yw[3r8vf
                 return '>';"j`8cyh3DJ0s
             else if(c=='(')*v!Q*E"Xl6s$z%^
                 return 'E'; B.W#m V'ii*dCcf4r
             else if(c==')')hwC AY!JJ
                 return '>';sD+e#i:AId].A
             elseP.]/f?z$yT U8tX o
                 return '>';n'o#cum;\
        case '#':$i"cE0`*N N]3SP
             if(c=='+'||c=='-') kJm7aK/_
                 return '<';R)`s^$E_^5xb
             else if(c=='*'||c=='/')
h2WL&wnSCo                  return '<';
t4[JALbn              else if(c=='(')bti)W%d[9_
                 return '<';
V[GBok5W,k`a g              else if(c==')')
]n"fu0` N                  return 'E';`5xw"uqx'gul['|X
             else3G Xhlz6~
                 return '=';qYd+w)z;M6Gb*P2L Ol
        default:
y2yeZy\              break;
?XL$\6W)q3^ d#K     }
*X6j$j Vu~     return 0;   
;?;M"B ]6g!y }5l i-r;p:p
H [J2w?E
int isOpr(char c)
g;\P f2Z|!R BH {
"cB$G9U*T i4u     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4X6j$| s h*g(YZ         return 0;
,Xw'k2Y0{     else
L{o:|)jo%d         return 1;
#`0s lu3p6T$K }
9\L#N1x o p P"A2~(?$jKpWvA
float operate(float x, char opr, float y)1mH2C4q.Oo*y
{ E4r1v?8}.\ c
    float result;
EpqL MZ{ O     switch (opr)5QOS#w}&w5k/Nh
    {
E S9V h\&\-X(g3B         case '+': 8_-@-o%?.JX
             result = x + y;t(Im s:h [@
             break;
1G5@ w\PR         case '-':
7q%^U nkL)bJ+L              result = x - y;
-L:J+l9rkr*a"g `&f              break; b1{t7q]
        case '*': &{[Y*nqtq#`
             result = x * y;
6ty a(U0c7@)S              break;
G}2Kf~ b5y[4L/{#o         case '/':
$U$q'k&w{EF~T5`              if (y == 0) }2OA|[;Or5?*w
             {
q&s4]K;@ ]t3{1F                 printf("Divided by zero!\n"); b'C-?3H*m;VQ
                return 0;
2BZAluiS Y              }"X0Q8|n7T]H1U^
             elseC!il6nQ
             {-{q+ETEmb
                 result = x / y;
axpxa~ h~b?                  break; M-n8bC c$S"Bw
             }2?7v'e']:cF
       default:
Go S,|v s*Z              printf("Bad Input.\n");
1Ak,t1p2],x2V\`X              return 0;
;k:V"L"J D4d.| X     }
#UL:~E$A,WN$n-y/h     return result;r#^P7NId _k
}    {\0AH"u qaW M
]3DPTA#A-P4uu
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
Gcb'q` Z9W {
%R(zp&YQ0g/V     Stack optr,opnd;
(ZCl MJ     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; cgL#?vr
    char c;:p`y9A)K P&@"h
    char buf[16];!CRk)sKx"j
    int i=0;
7Kf)J;J'L     MQ:NR7^:?%`xv
    InitStack(optr); /*用于寄存运算符*/T c$fN O
    InitStack(opnd); /*用于寄存操作数和计算结果*/
;UYFXt)k3a6sA l]p1g     memset(buf,0,sizeof(buf));2HGVX n"B[-`
   
]J5U1}Ud],N0u     printf("Enter your expression:");
`){*I [5M-n:Q         
i#jV5I6d     opr_in.ch='#';
B_3}3D6}6A2z     Push(optr,opr_in); /*'#'入栈*/UX{x t6OR{
    GetTop(optr,opr_top);
5c)}c5jV1Xn     c=getchar();
KeNX7tV8pSyd     while(c!='='||opr_top.ch!='#')
;`Z2c4E)TAcTd     {
w M_8p3o.Hi/v\ J         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/KQX)waM
        {a z@%_J#Y$^
            buf[i]=c;
)p/i4ns b             i++;
JoR4}?$vwz             c=getchar();
H0O%S*O"],{F)J         }
2V&pQ*`Oh|d         else /*是运算符*/
$FC_7J1y#LI(L         {
#MxyRs             buf[i]='\0';
7ug$t Cc.f#^5dU |             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/"db(_M'TqUbW
            {0VS^:@?4v A'C
                 opn_in.data=(float)atof(buf);
[Zc8WDt                  Push(opnd,opn_in);)j2Hzo+~d
                 printf("opnd入栈:[%f]\n",opn_in.data);l!NBDpE&{-q
                 i=0;
3}4H6hwtNm                  memset(buf,0,sizeof(buf));
GVa3t6\             }0?U1eZG7m'`
            opr_in.ch=c;*r4I2ekj
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
{]U^|P!b rr             { [7V r5Y3IL2zh
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
,^ISd/L.Z2T|B                      Push(optr,opr_in);Ek fJN.f g$?X
                     printf("optr入栈:[%c]\n",opr_in.ch);
-J-mlqDJ%f q*~2@                      c=getchar();E fG7V-V4u~1g
                     break;
tRgo)?U\N5F                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
!j;YE6o m0vOx V                      Pop(optr,e);
aS c{o+RXx7Z$e                      printf("optr出栈:去掉括号\n");
2?B@?3Dr6U                      c=getchar();2AN*\u_.F.r%G4KB
                     break;Pz(~[Q,bVK
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
Eo&oE.mQ^v*}                      Pop(optr,opr_t);y,x#s5Cv:N?&G}
                     printf("optr出栈:[%c]\n",opr_t.ch);
z7|*w tGI{s                      if(Pop(opnd,b)<0)+l$W!zV.~,X
                     {
A'\"Y+P0a"Jh0M,z|                          printf("Bad Input!\n");]{ T;^dl/K,r
                         fflush(stdin);
9K*}FZ0g*c                          return -1;*]0Q`R;hva C5i
                     }
7\/p7gb!z*d4p _u                      printf("opnd出栈:[%f]\n",b.data);Rq { P,Y1w-y _
                     if(Pop(opnd,a)<0) l+`J3p_ |Lc
                     {5ko L,wNPP(i#v"{;U
                         printf("Bad Input!\n");
&i^.O{M"Nn}B5i5V \                          fflush(stdin);
YN6P I8d"O                          return -1;
&fd aG4y6v,J/`P0y:]                      }
5os"L0L,Mj7n$H{                      printf("opnd出栈:[%f]\n",a.data);
R.|-~:t|-j8` B&W                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/FMVOI2W \&ld7F
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
E*R4W:d/MZ2@cp"\                      printf("结果入栈:[%f]\n",opn_tmp.data);s X{g"r6B
                     break;
`T&]t[             }
@5v-Y&?yy)rK@!W         }
p {f3S!bw/XaC"M         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                {j,\J o.tNy"X
    }7IaH"D3fM%\IpLjh
    GetTop(opnd,opn_tmp);
(Xa x^E,R M }8\     DestroyStack(optr);
k3L_:P3dL$t2X     DestroyStack(opnd);e|R6gUz
    return opn_tmp.data;
xtuh8E)t @-Y Z5S }/U/g/_l#j whI,Go

R;u/^Dl.\at#K^ char *killzero(char *res,float result)
uZ[o4[(~#Y {!A]QYQ
    int i;
'[&BfZ;P$K$O;QLK7M
uT!K;W/\7LH-t     sprintf(res,"%f",result);
G+x*Nn rP| TP     i=(int)strlen(res)-1;
EE.{;d-[m_(E     while(i&&res[i]=='0')? \:mpqp Kqp
    {|$C0kL3u e!k
        res[i]='\0';9dJN*|\*I@ e @-Gx
        i--;
mDik4sq     }
#`,Z+ZIn     if(res[i]=='.')
j.V0l-K:|         res[i]='\0';e/YL0Bp B(ku
    return res;
gc-\ j e'f6D'm }up/e*e,PA6n:I"l4K

mN q Wi)^$P8qM,} int main() b6?rR7r
{xxeW`u ps&v
    char ch;/I&Je!x.[
    char res[64];!\3Vk|m4b
    float result;
+m#a-s-PYn     while(1)
4L1Y"m-j^ k/O     {
8bf Tj#X[         result=compute();
Jw-z*].J3zG B         printf("\nThe result is:%s\n",killzero(res,result));t1k }?%?
        printf("Do you want to continue(y/n)?:") ;
pY"BN5HC$u"WR         ch=getch();qb ~\4x'h
        putchar(ch);1P%t'y"S4x PIMR
        if(ch=='n'||ch=='N')
W\fV2xw             break;OrX}*g
        else
E*Js!L+N LZ             system("cls");+x5Q t6z'm jb
    }o5@o an
    return 0;
9L1n)B/q2L }[/i][/i][/i][/i][/i][/i]'U+tUD b I T
.r&blBDB4[h
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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