捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
&W9JL/D%|4ab4f[ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=5g$D%t VhvC2e^
/**************表达式计算器************/
^ym2yrN #include <stdio.h>,cm6daO s7muWNX
#include <stdlib.h>
;^a:n"_%T #include <string.h>{.n _c#m;`7R
#include <conio.h>Ybwi%SubiK${
#include <malloc.h>v;]z7U'i$a.a(W
G |uF"CNwP
#define STACK_SIZE 100
Y8G4i!{obe #define APPEND_SIZE 10l j7]@G:^
7Hk(\Mi0r6^
struct SNode{
;^'U{%G }z9v0c     float data; /*存放操作数或者计算结果*/1v,]lU}Q{
    char ch; /*存放运算符*/
LG%d"q:r b u };
})Q"k5s%i K$I
}{(a@F-| struct Stack{Wi[x6[;}
    SNode *top; R%CRoJ}j
    SNode *base;
epb)CK     int size;
*Zz{e"z,B }; u*g$qz#}+uJ
3N.z F2j/^-b
/*栈操作函数*/hPr)F/ah
int InitStack(Stack &S); /*创建栈*/)Cu o3p z
int DestroyStack(Stack &S); /*销毁栈*/Y&VW*ZIG6ju U*g
int ClearStack(Stack &S); /*清空栈*/8D*`v}1pO{/z#T
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/q3vEM.l2u
int Push(Stack &S,SNode e); /*将结点e压入栈*/
m(KQgW-h-O int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
9_?,Kij+P@beV
R`8a!izF*x /*表达式计算器相关函数*/4]p Z)EAgG
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
"bTY(oukr^:f~ int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
Y-S6D)VMr"l7a-Y float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*//yR MNRX"aTH6R7a
float compute(); /*表达式结算器主函数*/^B ?Jo }-A
char *killzero(float result); /*去掉结果后面的0*/ 8N\`i)J\ HaJ0\2x
"l s.lHf)C
int InitStack(Stack &S)V3p1d0V MY
{
{{ ]X_]b;{     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));Ec2D.JuW9n+i%F:z
    if(S.base==NULL)4d3[*jH9p)]3]
    { cV+?%Kc:uWM
        printf("动态分配内存失败!");
#p i ^1qg         return -1;f%UGY4LY L
    }d4_|}5ysx/v
    S.top=S.base;
dYOL?DQ     S.size=STACK_SIZE;
+bnO i&wTg!Z C     return 0;
6S1{ Na)}2q }'{w7I5bO`9t6kHU5W
p2E"j)aY,P
int DestroyStack(Stack &S)
A@"m a/o-u,Mo&CP6_ {
(VTJK1i+q5Na     free(S.base);
8W$j:eal;I)Y+?     return 0;
G;IfU7| }|};lGV*A7_)V,G
t+AzF*GF_
int ClearStack(Stack &S)
)I@p*Mk^ {
dW0q*YN     S.top=S.base;
vt%iZf0i }     return 0;
L3pU w^&?'U iC }
j O,k"^3Hs%^I AnB PD+s~5a&th
int GetTop(Stack S,SNode &e)B^*GGEz Ikm"u
{qF8Q,]LzSbD
    if(S.top==S.base)QvO5R7hg*a1e
    {
z _A3rVt}         printf("栈以为空!");
N Eg@ j*}Q)k Z         return -1;
HY{}{.J6yY,Y.i     }
1\@ fG9a2Z;d*V!Q     e=*(S.top-1);
#f(P}3|2t)FOw1Lp     return 0;
-o\!gt |VB nD&T }'`-do v2aEB

1z2F!ANU4\Y8^1^ int Push(Stack &S,SNode e) I9|%Qy2mT;Md
{
L}w9na}     if(S.top-S.base>=S.size)
9_bBI]     {O'g5v@|
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
k%Z Jf)dr         if(S.base==NULL)
}Ha!r ^D$t E         {E(em5W X y
            printf("动态分配内存失败!");{.g9I)_W
            return -1;
$mv"E3n6f b0A,R+q         }-l N0_ X:l8C#U\"T
        S.top=S.base+S.size;
2D x8CHC p o         S.size+=APPEND_SIZE;WoA"w4\6Ifo
    }
R;W#BwT?3u9o4uM     *S.top=e;,\\4V"n)H3l
    S.top++;
fI*s(Xc dI'[6d     return 0;SIXmS3uX `
}
?"L-DG n rci+m,c*{.q M
int Pop(Stack &S,SNode &e)
ZjfXBzS i { B@:^ {8g}
    if(S.top==S.base) `)c$nu c|7N[4F
    {
'{"_&o7IP1X `         printf("栈为空!");Q7SJC1k/H$V
        return -1;-UgR[T!M;G+e9Y:bI
    }*t2uIcl!f
    e=*(S.top-1);8oCrI)H4X-T!w
    S.top--;3I%`Q0u0T*gqPn%M
    return 0;%u,D,d} ZD LL
}'C*UF4q0tVW*R
~+Eu$^O)_
char get_precede(char s,char c)
5B,?#~rFK q4R {R:{4Vo(E0P3@
    switch(s)
h0O J1?e,DQ"O     {
_#\@+Lhh+u!b'u"Fm-f         case '+':                 ;N#ln{;? Dfx4kh8?
        case '-':
%yn,]%~v              if(c=='+'||c=='-')'^s'U{ Jg)gQ%m'v
                 return '>';X2Z/O(j s5Wx Y
             else if(c=='*'||c=='/')G+VH esVg.f
                 return '<';f)~X:yO$l c
             else if(c=='(')7f%Y k)U;PSGbQ,S
                 return '<';] \']3h)G~2UF
             else if(c==')')2R k8P*n"K
                 return '>';*FN#n%t4Q
             else
z+q'S xHQ N.M                  return '>';h*[Zqmr/}*X
        case '*':,dD"^*F9e#_0bO
        case '/':
~-nna6| \;qj              if(c=='+'||c=='-')
9l!hA8`G%r'aS:D                  return '>';n9d m6yL&g
             else if(c=='*'||c=='/') }p$?;p [5L
                 return '>'; w T+_/]Q6a3i
             else if(c=='(')
4B `1iWk$|"q                  return '<';
xP0V9\P"W              else if(c==')')
;`v-b1xZ                  return '>'; Q u y3v}d k!f7a%j
             else
:j({] wm-t6[&D5p                  return '>';
&qd-j"X|1D}/xs&|.c         case '(':
-EfGE7U              if(c=='+'||c=='-')
n-n8} ] ~)@&?&q                  return '<';
\ qT |2L5U0h"{              else if(c=='*'||c=='/')1o T,p!`tx.{ ZO8~
                 return '<';
V2| _5d,[[W              else if(c=='(')
4H6k"Q#~n/t^7s                  return '<';] nef*Q!lT
             else if(c==')')G#Ox8e0U y}!u@.M_9q Q
                 return '=';"Q9O'_{$Y?'Z
             else
5R \5h J3z0Q                  return 'E';]2r4h&TG[ o?;jzj2Y
        case ')': dX lFWX8X
             if(c=='+'||c=='-')Cp9ke\5v
                 return '>';"hM4~w;g6c.HJ
             else if(c=='*'||c=='/')
{;n)^&tX*Z                  return '>';
VR oBs2{$^              else if(c=='(')o(qQ:p!U-?,yE
                 return 'E'; p0~!WE:vjm
             else if(c==')')q#S Z.e0U:wT0t
                 return '>';!z/?&AI{+z6I;i:aH
             else
;}'YXy bn                  return '>';kS mQr{n;?^
        case '#':jK _(c)nb
             if(c=='+'||c=='-')~_4k:v4Y1Jl#KL~
                 return '<';9S r5v2E(X
             else if(c=='*'||c=='/')dr!L3v/Kt(E;jOw
                 return '<';
Zy({Uq2_ X              else if(c=='(')
(l} yGl1z                  return '<';
pB E2]RMO|s5R @;U              else if(c==')')
7Cd8aaPS4TWX(v                  return 'E';
e~cyfe(MJ              elseI1yl4m)vi ~
                 return '='; xUu6}\!i3i-^
        default:?+xo(C+W!M@(x
             break;
+xMOR9g `     }
&~a8s[#['G(k!b8c     return 0;   
&gQ+_6e p} ~&s^] }
Z#r VW/TQ ] ~ S-yJ%_ XIvZ jc
int isOpr(char c)
%j?@V0Tmr&W {-bux)mS5FY
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
0n'D ^ \/t,u!f         return 0;
A r/\ }h1L     else 9Nu0UJ|&\
        return 1;vV$rSV3x*v+v6q$M
}
S5G j~:[ a/Ta T'A3h S:}\"yE!{hd H{
float operate(float x, char opr, float y)](C$eb7O5r
{
q$b'qnc     float result;Jg!K+}rF0B8X
    switch (opr)
4|2S lD_N     {l6Dx uL+@SE
        case '+': '\aP$T\(gi
             result = x + y;Z Q e0Zz i0I
             break;9p/f'?*]Be4B c
        case '-':
1|2\$\ uS9u+tC              result = x - y;{.og*` ob:`
             break;+Sg4x{)EOk
        case '*':
GM J~~.J-z{(k              result = x * y;
-lI&zR%Fo              break;
c \3o7s d$zIYO         case '/':
0xw,S F![;A]              if (y == 0)2zT'q:y!I
             {:y3dx'O/E1`/Vu?
                printf("Divided by zero!\n");#w I l"r t5L
                return 0;
#y4?vjX2h$v)S7Jm%op              }o xvl1S y0~C
             else
)@*x1G pp`,}              {
R!Pc3x@                  result = x / y;
|~\yhp                  break;B&I ^)G#N Y
             } O4p{{M%lv
       default: j\ KW"Zu
             printf("Bad Input.\n");
V[_V s%]v?              return 0;9f"`5juE9^'a
    }g$ejwD,m4D)]T
    return result;,nZd2L-ONN
}    5t%d;@c.T4k
z+q4f$ZEQ\5w So
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9x]+f4iJV4I1h z {
\,J0r*nqC     Stack optr,opnd;
A v v7R,^k4L     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;(T"]"~ e+jkE5c%r
    char c; HQ!W+`S\7t
    char buf[16];'XP@3zTj*RS
    int i=0;/u{p,_|
   
hG v*\ ~ kT     InitStack(optr); /*用于寄存运算符*/r4xQ8\`l%K-Z%K\A
    InitStack(opnd); /*用于寄存操作数和计算结果*/H3}%P V j
    memset(buf,0,sizeof(buf));C#W#k_~oRl
   
gi g.s2h&g     printf("Enter your expression:");7T5i^+uLO&[
        
c:L?nG     opr_in.ch='#'; Vf G;|bB XR
    Push(optr,opr_in); /*'#'入栈*/
%Gk5Ck)~kHszY     GetTop(optr,opr_top); N5ziV o
    c=getchar(); fWGE%TeP
    while(c!='='||opr_top.ch!='#')
1MV|0W8B1X(ue     {
.Df9T h+}eU K         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/K~~'}'h?W
        {lA"f]!g|*X
            buf[i]=c;
_:e+ki3E'oH|0j             i++;V*qJK?s H(c;l1V
            c=getchar();
sR J#NR aU X4P         }
9q5gvLf         else /*是运算符*/
&X0k:z"xeUO         {"j `%C-e:s kX1S%j
            buf[i]='\0';
%GjUNE&q'Rm [             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
)p R x&`!aUY P             {
A5`!]q? Q*g                  opn_in.data=(float)atof(buf);
.i {,tr)S                  Push(opnd,opn_in);`mS)t,|1rE
                 printf("opnd入栈:[%f]\n",opn_in.data);.w2S @z]R[
                 i=0;
h5T fWI M/N d                  memset(buf,0,sizeof(buf));XY"R q&B2Q
            }
L&?*EypI             opr_in.ch=c;$P'S ~ QF
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ H0x ~4ll8_$I/{a
            {
:J [gK f)Y7??                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
'C5N7n(a-M4n                      Push(optr,opr_in);C'[-?8~(zF
                     printf("optr入栈:[%c]\n",opr_in.ch);
^u `7v'B/qI-r                      c=getchar();q} wL}']
                     break;$S#u8w [3r Q b
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/2ce ?6yr+Q3w6w?
                     Pop(optr,e);.K:I h]Um%Ej`
                     printf("optr出栈:去掉括号\n");
WL2bg&eK4E                      c=getchar();5zU)e Z7ss&Q['s
                     break;
l,G5?Q y*`+N^                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/ SGe?3^
                     Pop(optr,opr_t);;~'HZ3D*KG.f/{
                     printf("optr出栈:[%c]\n",opr_t.ch);C(w mH$G*r
                     if(Pop(opnd,b)<0)
o-kX3K"I1O{D                      {X'RZ6['l5hV
                         printf("Bad Input!\n");
@%k} Sz^^                          fflush(stdin);
;^ L?!i%] c2N                          return -1;G:BF ]M$q*y(E
                     }
b;G3^AF1l                      printf("opnd出栈:[%f]\n",b.data);.b`X1F([c8seX
                     if(Pop(opnd,a)<0)
"WuX4^7HLZWA                      {
x9CbO:l                          printf("Bad Input!\n");
!T B j F9r }b?4U                          fflush(stdin);P/M}'fXI
                         return -1;L"T5E#j!tsJ }/U b
                     }
\9H"A6AP!H6B                      printf("opnd出栈:[%f]\n",a.data);
`4}I;Ci c$yJHYf                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
B9H,]Gl                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/X-Q'l;\"bb:[
                     printf("结果入栈:[%f]\n",opn_tmp.data);
Nc!y;Fq"iz                      break;
+?L}V F             }/A&pMU*w H
        }
/J$q)qX ZT;J         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
:ncu6NeD:f r5K!j"[k_     }
&X_k v`7{TK     GetTop(opnd,opn_tmp);
et&|:Yv:Ej'i     DestroyStack(optr);
Y;`2nFo?Q     DestroyStack(opnd);
.TB c!w3y6v;bl~     return opn_tmp.data;x7G4r/j BRz E
}
~esQ@!Ad*n 0fH2}j-q5c0Y
char *killzero(char *res,float result)
b$y*t5e{QD {
%l Q9Rg$e!c"U     int i;
Y3w)rF-u:G1z\R U#l/|-S+?(Kr9X L o[U
    sprintf(res,"%f",result);
#[%n7N2KG Ao[ `     i=(int)strlen(res)-1;8K3OAb[m$?&|/hB
    while(i&&res[i]=='0')j8]#d8j"b/kDu6]5]$H
    {
mUTl7{!pV3w         res[i]='\0';!I-j hR8?lB
        i--;
LK4B&v1B     }!l OD fY,C:[Z]
    if(res[i]=='.')
D)ax s9l9w2^+J         res[i]='\0'; K3?:wC dRR\d
    return res; I"]P fD
}
;NW7J4cF 4D,O},[2@ ]
int main()
!Erk#p kb {
w*J*^$j,m;{Pv ?W9lH     char ch;
"b\ mN7^9z$T$Or     char res[64];U+z*[:W6r%Z%X*P
    float result;G X/qQ z4R cN"a
    while(1)@ jO3dk&s(n$[C j
    {
F%b!R%UR r$M         result=compute();V? AGqS2k
        printf("\nThe result is:%s\n",killzero(res,result));
$OJbI(rQ         printf("Do you want to continue(y/n)?:") ;
/AO{6^8G ` \         ch=getch();4fz6r3j%M%J%sFN
        putchar(ch);-{ yl%M_1E
        if(ch=='n'||ch=='N')
Y@ o\0g             break;
|5mBA4l FA         else P*Me2[H,v/lW
            system("cls");
6f'hGN~)X\"Z7l`+hs;N     }
/@N(c8Y S/S|n     return 0;3n,Bxva:p1H
}[/i][/i][/i][/i][/i][/i]/T$Fa {4b7VM
?;i8o^8J X2Ee
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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