捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.7C SX-M}1E.` A&Z
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)="M/DY s:x1yhM
/**************表达式计算器************/)uZC-dM9b D
#include <stdio.h>g g,E:}7u g0j
#include <stdlib.h>Q:e5k(O5J
#include <string.h>
$k)zmyo5\ #include <conio.h>
;n.k"mC-`H o i #include <malloc.h>,Ngd9y Jtu'Xq G

\.R @(f"@kYX #define STACK_SIZE 100qt,d3k J.yzv-_
#define APPEND_SIZE 10 _.\g i0l9B]3~KZ
e QD2|RgP
struct SNode{i O(H \:n
    float data; /*存放操作数或者计算结果*/
!^ |i3tu-vP$F4r2?f     char ch; /*存放运算符*/9lV-J?1Ur
};
F(P2wUm)i&N0@
z3ag!| Q+P)J N struct Stack{
,@)@.hDm]A     SNode *top;
b m]?rrT     SNode *base;
|9JXHiK6?:g5s     int size;z5N)n zk
};
;q.`0^F0d.Cun$vu
/v"FvEP zkZP&N /*栈操作函数*/
2m G9X3Qx ] int InitStack(Stack &S); /*创建栈*//^7zb)]&fsX
int DestroyStack(Stack &S); /*销毁栈*/0d+d;EG4j ]xa|
int ClearStack(Stack &S); /*清空栈*/%u/Jf/fqJ
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
M S yFX3R int Push(Stack &S,SNode e); /*将结点e压入栈*/
v,fe9kH#D int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/p*A4C nG+kRe
#K\$x3_2u8UU h
/*表达式计算器相关函数*/
hDr)aT V9Gzc char get_precede(char s,char c); /*判断运算符s和c的优先级*/W v2EA"k@g
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
2A |p"|p|J float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1g2TUg0[!@ float compute(); /*表达式结算器主函数*/m;V"p4b ][!x
char *killzero(float result); /*去掉结果后面的0*/ H)Hmi!O^+~,Y/[ uP

L5mm/p;y{E#X int InitStack(Stack &S)Dq,WiP ~n4M
{$|+C3y](d
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
M6~k R*s&i;O7w*W     if(S.base==NULL)
.X)}$mn Z^     {
6^ muAvGf         printf("动态分配内存失败!");
z9d%W"?tAdKQ         return -1;t-F[MrP'xq+l)~c
    }
)d.e PP4EQV     S.top=S.base;
h"^"Q8RZ"E.HV     S.size=STACK_SIZE;-f Y#tAW T$o
    return 0;]c C:zC
})u8Wr,Y/mIr-m8C`

_ T`@ C,L)Nh D int DestroyStack(Stack &S)#N{|T&TE7@l gB
{
JlS'g W }9b'kf     free(S.base);/{.L,yMwU8v
    return 0;
6L%M ZbU Ne3{,jA }$mX ?i4X D5a%U$f,b2Z Y
\/]`'y8v4yt3c
int ClearStack(Stack &S)T6I3N7n8k4G!k+|5l%S
{
WI a)jj,\mK,f     S.top=S.base;6Snr0c6a
    return 0;
_1iO-Sy;ha }
-p.h-nF ?
!x:Ty9n4~'z!]Of U int GetTop(Stack S,SNode &e)
yQA ^'p$a {G,W2t.}(E:r
    if(S.top==S.base)8IN `1E$g4}K8y
    {
P,C2k|h         printf("栈以为空!");J.KTKY_d"w%c
        return -1;
!lO#[|4V0Q2yh5_     }
jD8B-NM5jYT d     e=*(S.top-1);
)e!|b"U-G-C     return 0;G9E x9}P@
}
px k B"Ot 'fnG\l9b7a
int Push(Stack &S,SNode e)%c_#dE#G l
{
'iLxKe6u|     if(S.top-S.base>=S.size) PN+q g;S#w|"Z
    {N EVutb1^ q
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
;Jl|!Z,nBd*T%}1j         if(S.base==NULL)av|3Y&I)mMg2Me#L
        {
+NH{8{"s!x             printf("动态分配内存失败!");fas)u X8wU#g
            return -1;
oR!@T)l`         }"ub$^R }
        S.top=S.base+S.size;x@E)u$vq$d[
        S.size+=APPEND_SIZE;
hl e"W\uoMI;dL A     } N,HaN\8SF)}L
    *S.top=e;
Dm`l"Qn]"Q     S.top++;$o5S(Kg:RJ,kl
    return 0;
d}3o-ZR%Ajxa x8J }i.p7po-h5h*a?Z
%UGF#ep rd
int Pop(Stack &S,SNode &e) I$I,o#L Z;GIR
{
vbt#fTH2o Y,M;? {     if(S.top==S.base)
-K"zf&]%mck     {$j@C.EM'XG1S
        printf("栈为空!");
*] a7j0|N&]&L2y W         return -1;:m&rG@ T6X2W
    }
w]QD8X)`{     e=*(S.top-1); q/V2N3ctD!z
    S.top--;F&K!C] Z#{\
    return 0;
4Gs$x"KMyz@ }
W1x E;v#N.h&m)ciqRj P9j iW/X'd9I,b
char get_precede(char s,char c) G o]2W)C%y$V#Q.P
{
I5G.SdJ)`4])y`     switch(s)
s^#C} A*I(p     {
4[ V~'N6hA         case '+':                 
Yi-L8EA a+Ft!w         case '-':Z^ r/IM!U[/s
             if(c=='+'||c=='-')
)d:FE8Y0v2]                  return '>';
C#HE/Gvj n3x              else if(c=='*'||c=='/')
X*O1u(m%F!G/L                  return '<';E'`7i sl,p#gb7l
             else if(c=='(')fD$R)i:f;fc Jz
                 return '<';}"Y,\!~2f0uN
             else if(c==')')Cy jx{)l
                 return '>';,FO_C/rtPh)j[
             else
F{^vJTh/C                  return '>';vW I-y C Io
        case '*':!Mz1V!^OV'` K
        case '/':$D[)Q q e T#Pb
             if(c=='+'||c=='-'):V-M5k[ k$v
                 return '>';
PCN l3J:EB~              else if(c=='*'||c=='/')2\${aPDqTR2R%v
                 return '>';
^+ci ^R              else if(c=='(')
K8zf(V0h6lJ'St8U2Oz                  return '<';
QY&^u J['l              else if(c==')')V6QTw+I6w7zV n
                 return '>';
L2oVN6{0Ne0c#V              else-|8t c4c1Mr6c5{+v z
                 return '>'; E)s LJyC5P$ED?/G
        case '(':&R1J8{gKG8C
             if(c=='+'||c=='-'){-R%|7q'Q
                 return '<';
u#fjMwo              else if(c=='*'||c=='/'),_uA%|9R6oCB\
                 return '<';n#p@#~Y z
             else if(c=='(')
Bs |aJ9]q([U                  return '<';~h9xb;oI ?hm
             else if(c==')')\,x mbw~p$UD!@d
                 return '=';1e!S)il }-bc
             else
Jl8l,py T                  return 'E';-SS*?Q9W
        case ')':Pu$K X;`
             if(c=='+'||c=='-')
-dG]0z"P0Ip                  return '>';
9i2h6UFC+j+~2SQ My&Y              else if(c=='*'||c=='/')
,NT.YL,`1t0[wV~                  return '>';
*[2X+p(d9cZCe lr              else if(c=='(') h7Al$E&R'zf&Ft u
                 return 'E';F!V*{4S X*w7iV
             else if(c==')');c3?/aM%|
                 return '>';
S)v Zw*U I5H6`\              else:k;dE.vBk,b*M
                 return '>';
!z8S9c*m8F'@         case '#':
]D|0w(Zlyy4xY              if(c=='+'||c=='-')5U+C(e1g_/n(X/LQ
                 return '<';
2o6Wi6tUfN              else if(c=='*'||c=='/')aI0CT7~9pv?%L
                 return '<';)f:\6Cz%@&sn1el
             else if(c=='(')?a+z}6@ mtQr
                 return '<';Mm3ly WD+p
             else if(c==')')9h~0U"XEKb] rlD2`rK
                 return 'E';4TQCw._,\8zG
             elsevcz8V:k)RJ
                 return '=';
,W pF:q3[4a         default:
oNPx^m0~              break;,m"G:i/c J
    }!X8L%c%u&~)_)y
    return 0;    zFIQWAw:xw
}K\i(}:M5zm%B

+~-TiA_@8JI&y x int isOpr(char c)"w,NQ5\$D ]'k T
{ V A(vFAc
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
!a;\ jjkO         return 0;
'I~Q;M Q,Z@]8G6f     else IB!{ P6n$gA W+L-o
        return 1;
F;G;T*YG,v&a&zSf Rw }
7G}.I8peM s*W 7tI(s%}+p6t2A |
float operate(float x, char opr, float y)
d%j5cq*`S5] {
zbzH4\$QZO.I;XJ\J     float result;
%oj4dr;X1O*pKW     switch (opr)h y/S \#Y\
    {4pu-aRh#t-j
        case '+': #D W&@6lbF,CU7bq
             result = x + y;n2XM2bOH j*{Lm
             break;-Y{B2i r
        case '-': 2K3WC5l4@+]tfu+o
             result = x - y;3rYb4R*vZ
             break;'{_P'Lw&x)b n2_
        case '*':
4Z y:e}o }qLk              result = x * y;"T lzNv5\7ya
             break;
:e/o)x*\)} _p         case '/':
w'u0H\SI5U9Vb              if (y == 0)I7}%N4hC'Ay
             {
'C^F,r#^[Id                 printf("Divided by zero!\n");
[^;k!t"e8C8b]}f                 return 0;
4]J.r2~~h              }f*rH%mVobL
             else
ZQ(WQh5Czt5]              {}6c"@aM)lp
                 result = x / y;
KpU3eTT M%B\(Z/A                  break;
uMtL&O4~.eB8e x4E              }
["Iz0u1bI(]C V C2_        default: #n%^.gJK0i z;zV
             printf("Bad Input.\n");
[Eh+jdz PT              return 0;
%]D8g4`X K9q     }H6u\W%X(p
    return result;O9V6OIY!j [:s3o$s
}    "O R&i&qL
5F K/\fW'G0O
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
? ` q'T3J%Tb {7Jw:?m~X4Gh1q_*~K
    Stack optr,opnd;9|b3w \%x;I*b;B3{
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
Q\:RG ~     char c;4D2bA }G
    char buf[16];u5hXm r2R
    int i=0;
9\yA$Z*gD$h6_     F r"}0F/oSq:ac7R
    InitStack(optr); /*用于寄存运算符*/
/j'@F9No]     InitStack(opnd); /*用于寄存操作数和计算结果*/hF4rUx)kx.u C
    memset(buf,0,sizeof(buf)); \'E,J3b7gU
   
;DOLlE?|,b     printf("Enter your expression:");
? \6j&tE"h#nKA         *e#`Va}9S5`P;\
    opr_in.ch='#';WVX/A&d]XZ
    Push(optr,opr_in); /*'#'入栈*/
z F;r~;u ~     GetTop(optr,opr_top);)fQp/rp
    c=getchar();g&]XD-{
    while(c!='='||opr_top.ch!='#')4[a.d0M7O*f
    {@Z h%`g4\5N Y
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/M%G0KgO#a
        {}2P&l DO
            buf[i]=c;#R3[]n5nLPO._
            i++;
M}(u"w1]1I r             c=getchar();{yotL^e)f%K
        }
~R+T A_         else /*是运算符*/
&L!sf b2n5x/Y'i         {
"|r}tf             buf[i]='\0';I[1o8e^sM
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/'_V ISXK%k:l
            {U edQ w0U,Y
                 opn_in.data=(float)atof(buf);
-sXm}O l8t'Fd)QA                  Push(opnd,opn_in); B8[8yzU0[]/`
                 printf("opnd入栈:[%f]\n",opn_in.data);
D {e5Z.z'NO                  i=0;9g#Y&kHb8H!MxjZ$Y
                 memset(buf,0,sizeof(buf));c.TY]5_%[
            }
P+jvYj+Mg             opr_in.ch=c;
|p;\`(G$?-P             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/Wh b `uP L)S&C
            {
Tm zhqef.~                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
T-r&qq0GZ1A                      Push(optr,opr_in);
LYI)L7b-p'g)T4H%C                      printf("optr入栈:[%c]\n",opr_in.ch);y'K`/z$A/cz'e"F
                     c=getchar();
[)\9~%S"vu                      break;,q Z(V e@:iE
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/w*}%W5@r}\y]!c!@
                     Pop(optr,e);
@8K}X8`s                      printf("optr出栈:去掉括号\n");
W2{)n*N,G2~                      c=getchar(); DW St;dA/[4S y0N
                     break;
&Jeu fJ Q                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
!lt1pI.{o tL!M*u                      Pop(optr,opr_t);
k2l)K#l)h |%E"g8wI                      printf("optr出栈:[%c]\n",opr_t.ch);}"RDM8J3WlN
                     if(Pop(opnd,b)<0)
+O*f+F&VX0B)e                      {
0G ]i.g-w                          printf("Bad Input!\n");2Hwv:MJ
                         fflush(stdin);
r&x.T5P'OF1V$vj                          return -1;6M;W gl l$l~ Z-D
                     }
9NsG)e]*Bw9WO                      printf("opnd出栈:[%f]\n",b.data);
OGH8L.vT                      if(Pop(opnd,a)<0).a,}n x8y3g ]a
                     {
7Ee u.T(Q|6wB                          printf("Bad Input!\n");#G-Qa!v'[(Lg
                         fflush(stdin);6bj5v*Z)Tc(a1x
                         return -1;
iH-pPz(l0O"d:Yt                      }
t2w.} L E'K H                      printf("opnd出栈:[%f]\n",a.data);
h y}7g(x                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
7kkL fu6oj                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/oF%~0M/o*^
                     printf("结果入栈:[%f]\n",opn_tmp.data);
mw#pK*i.U.m'Fp                      break;M|G{![(Oi.F
            }
i~u4Zf;b| R(x         }
L*x8].l(q0T;i         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
#PfBtmJX'o     }
Y?)`n+E0_     GetTop(opnd,opn_tmp);E a"PuPL Z;VNi
    DestroyStack(optr);
DSt7ly8|     DestroyStack(opnd);2SP7_2sjA;Z;[m
    return opn_tmp.data;
I4xp`s`,I~ };`UL0BR%\

q u,c y"L7e char *killzero(char *res,float result)
4F u SO:a _%ve {
s"It0]/ie-{%t2j1@     int i;
O*{Cp K:l:^@ix
l S^-[T$_8j     sprintf(res,"%f",result);
9k6q3_A Q)_H2U     i=(int)strlen(res)-1;
`f[y A     while(i&&res[i]=='0')0bc5uV4G{{ ]
    {
$k4\ru _#ly;Wf         res[i]='\0';
'b/I.Q.aaC.G         i--;
'a"C\&z\/P [$Z q     }
{?3HYXq#NQ.d)H E     if(res[i]=='.') C^ Cn\C^
        res[i]='\0';
l7Q h%rc~;X(W6E     return res;
3X C ?"^9t`+Ry?!} }
jz,`lYTN#a3A iBRj1}}
int main()'rv7i$ZK
{
t|O/A n*EA5|"H#YR     char ch;1S["Vx4d![D3VVx
    char res[64];
h CkhF     float result;
m@A'?\T6|;cR i#[4e     while(1)
8}.@Z NX'j     {
xCUXS~{         result=compute();4U5E AY`O!OO
        printf("\nThe result is:%s\n",killzero(res,result));
N'ok;F5o |Q.R         printf("Do you want to continue(y/n)?:") ;
ED(\.K7? fj6a         ch=getch();H2N1|A7[
        putchar(ch);;F-Gi8OC5f
        if(ch=='n'||ch=='N')3P L"^zH5}
            break;?[1l!Zpc
        else'i7F6zq?qsO5o,_
            system("cls");q/{ A4j'i q V
    }7@F_$hkm.y
    return 0; G6I ix!X#aW(k7q
}[/i][/i][/i][/i][/i][/i]/L&E5Q et-V ngs$x
og9d%C)l^9~ l
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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