捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
_!R a _.}7|8t 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
C#\x5D]2` /**************表达式计算器************/
m#v2b M}xt #include <stdio.h>
6p0r.e g,Y/J #include <stdlib.h>
I1yY9qlO R #include <string.h>
:A/oo yw3~-hIL.W #include <conio.h>
3o2zvA IXG #include <malloc.h>,w}@4a jb
.Q8{M _9w-O t
#define STACK_SIZE 100
%?\+?+w u~3c #define APPEND_SIZE 10
-r+l+v7d8Z ~]VY2t
0Q Jg:^"dhz struct SNode{
~:\)r O&]~ E2Z!`}*V&W     float data; /*存放操作数或者计算结果*/)p"Z({'aIA_ki
    char ch; /*存放运算符*/4^O$r3A_4^i
};,?4u'_hj r
*j ? qM/rT.l J&aX
struct Stack{
$h O{*])g"Ah     SNode *top;
f6V~Bu%bC)mqk     SNode *base;
9BE/?cc3R     int size;
o K2u9r(U:[7j]!uQ };5TW!Jv'^;H`
S0x1\b#A&w0H
/*栈操作函数*/9mJ{3Ne5Nz&N(F `
int InitStack(Stack &S); /*创建栈*/
Lk1[hNO7yIC int DestroyStack(Stack &S); /*销毁栈*/4W nGe ^5Kh
int ClearStack(Stack &S); /*清空栈*/eDcU?8]
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/2c5^9ij*fFQn%W
int Push(Stack &S,SNode e); /*将结点e压入栈*/
(c8kiLU@-^6Pl int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/]#z*ve6V1N9A

T[{a.kI e2oV /*表达式计算器相关函数*/&NvXGM J9ax
char get_precede(char s,char c); /*判断运算符s和c的优先级*/#q7}+vQ2BiQ+p
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
ac"D EF m&b float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/#aRBh-@Cl!\
float compute(); /*表达式结算器主函数*/6@Tqf3fE!V` ?g
char *killzero(float result); /*去掉结果后面的0*/ "}MHZ*@2y7L{
0n a6m4b3W _b+c8Z
int InitStack(Stack &S)"gonv? Zv!X,SU4z%g
{
%pA;NZ|     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));KtLc5`o
    if(S.base==NULL)
~&S ^qsfm(r     {ZW}U#_3qc _.a1~
        printf("动态分配内存失败!");
_ ?/} ?7h6G2e)W*Y         return -1;3h6}-e%_J
    }qHX"J.lW:f
    S.top=S.base;
[ak)lpz+a}     S.size=STACK_SIZE;3PH @ {i5J1jS
    return 0;
|A%A6g} V1AlF-L-q }#`'Qs$Y.ug
)W ~&M8a J
int DestroyStack(Stack &S)0n/Fk-|3@
{
J.M"ob-^e| j     free(S.base);)jJ.Y#ABK^'Q'@
    return 0;
X(G5`-P'v@-I }
!a;Vv}cH0C&b "K og!f(|WM"R2\
int ClearStack(Stack &S)"\"Z7i1{$Z jv Dp0n
{
;a-I&n-tE     S.top=S.base;
QNe-T/m,`+}     return 0;
O(L QQ'ZFdo4r }
&^'mO:N"lDl D HO^0`*E$[D4vI
int GetTop(Stack S,SNode &e)
g h}{FMa {
-v+|/Ju@$wV-d     if(S.top==S.base)*k!l%e [X T,P4L4V-a
    {fd,FTD.s
        printf("栈以为空!");~2cuT n,e"x:?/o|
        return -1;0e7C9_#Y N7jZ#rZU:D
    }
XN5? ]d_8_2g     e=*(S.top-1);
R/E+m#o7c|8L9N     return 0;1o%uTN.hz
}:Fo!s'S^1R%v5D Ec

k&C/N g n1e int Push(Stack &S,SNode e)
wc??*l$^ {
1R7QW6h zj?9lP6a     if(S.top-S.base>=S.size);s$t%o#Iz)IHr
    {
!F _u n,BF?u8Y         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
6El VuD)E9R9y0j         if(S.base==NULL)
V9HNN$~|a         {|'P7X/G)l%y
            printf("动态分配内存失败!");
uUn ?$j1U{             return -1;3ccFXpWv1^
        }
o7T s0Kc         S.top=S.base+S.size;/L6hE)pzB/k y$y
        S.size+=APPEND_SIZE;
{ u?#G*}/GG s6_     }i tem(l)\ J;f"c
    *S.top=e;:{ JRK)R.prlI
    S.top++;
$y bf5dT'y     return 0;
c'Z}%Q8C D_ }
zI:P-I$D
4W)}EnO^ int Pop(Stack &S,SNode &e)
Ra6a \gNu {4MrwLHu/O"_
    if(S.top==S.base)g_xX_Qi1f.v
    {
1lXH|R'R1u         printf("栈为空!"); A,r!vXQ9y#j/f s
        return -1;'D3vpP;u
    }
+DP7M;^C9~E&Com0?^     e=*(S.top-1);
7w0FCT!k     S.top--;
(e*S7YB&B:r     return 0;v;|3]%DF$yK&dTO
}/f1`!_%m-\AzL,E
S,W$qjtVu*gO&m
char get_precede(char s,char c)
GJ#V4DrX @6F Gx hM {
d3|i3?V&{8AK     switch(s)LH9Z4s/dw(eYm
    {$qt`OvRT W
        case '+':                 5RjI U5xV:w:G6x e
        case '-':
Eq*CAc,W              if(c=='+'||c=='-')1nW.sK|
                 return '>';!?q u nvH^
             else if(c=='*'||c=='/')
X$W(?.vU                  return '<';
0C7Q!_w5g v8X              else if(c=='(')
T4Stz_s0X D                  return '<';
4`!y?:t(QB              else if(c==')')X v!InTV
                 return '>';
R2B7}@7Lo*KvW#O/a6a              else
6m(p-Q4m;\Ki                  return '>';\(j RX,i.o3^
        case '*':
3~$C8Zyl T,~O l4cx         case '/':@b*dQ oP
             if(c=='+'||c=='-')dL^.DQ_9v2w5c LE3S
                 return '>';
Xuv5Gm{'EA ir              else if(c=='*'||c=='/')
O#VU;C^ ae+B1S                  return '>';
Gs:de3dS w3_?'z              else if(c=='(')
Q/n:f Q6pS                  return '<'; Xr,MYXg"\5Bv
             else if(c==')')ssStvD4cJ
                 return '>';bm7S m'D l^8K(II
             else(Rc R+I.yG%]J
                 return '>'; Nd?/m H a`4l
        case '(':
Rt%?K"Hh:Me              if(c=='+'||c=='-')
ql X.@0Gm@*r                  return '<';
SoFTi E              else if(c=='*'||c=='/')
+jG3l|*}V                  return '<';
%Y6L"ml d[YAk              else if(c=='(') Pa*{~*L0E7Up
                 return '<';
3Q ekYz8gz              else if(c==')') t,P3HQ3Ej2~
                 return '=';[Y+m2KVN!Xm R/U
             else6W"R yjwoX1^,V"H
                 return 'E';
R4pa)w$t0Bud         case ')':0Jl{ Dv8r z2W3g z
             if(c=='+'||c=='-')
~'qW^r:u                  return '>';-t-^nAmu
             else if(c=='*'||c=='/')
T,b} k}d Kj                  return '>';
f Hj2g)I"pF              else if(c=='(')
I+P0X2m8z5s                  return 'E';m'~ r0v(x/i
             else if(c==')') _"c.V5vD B H,m3~Q
                 return '>';7Xmp0ud z
             elsep+Q&z N%_#F
                 return '>';S5nqM2I&Q
        case '#':8?8dJ/tUm [
             if(c=='+'||c=='-')QCS*K:@4^:a3qV&k
                 return '<';
!N.@!j5|)shh:Ul c              else if(c=='*'||c=='/')\-j$_/Ih!J-F
                 return '<';p$a7O IEC:Y'u
             else if(c=='(')
-y"L ?2B0{A!I^} J                  return '<';y!lCa0z?h\$U
             else if(c==')'))bM)aA L ]$vv
                 return 'E';6mY4}2} xC
             elsek]KV2F(g"P
                 return '=';
ee*y:PAX         default:Ze:{Im pq@/L&M
             break;!Q }#A lLnc!v
    }
oTlJ)o4V     return 0;   
,iEnBe+oit x O }'ZJw qY:N,?
1p K.q5Y7b6?
int isOpr(char c):SUd-K Xs/m_
{
!n`@dbw     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')-Fs9qn(A5X1t
        return 0;
4A O q@+HWd     else
3N8B/kXzVp         return 1;rJJcO*K(A:l2\
}
(D?,Ev`
H0R9Pj1pe float operate(float x, char opr, float y) G(s&VR!|
{
-Mn!ARd,K|Z#@     float result;|NOWyQP
    switch (opr)
%ar o4SL4cM     {
V1j(c1g-c-XnZl         case '+': LO["j3wE
             result = x + y;
|gT@y              break;$?_(mb.el2C/O#Zno
        case '-': &\ ^`Vv v!{z
             result = x - y;#[ G;IHJ6zue$j
             break;%j0ncH J%}t4c
        case '*': i4_e3sf*kQ
             result = x * y;c9K8s!St%r$e'[$Vu
             break;
U,\7DGW         case '/': $\kH0W+rV
             if (y == 0)
dz-N'A#jI@Ob              {
7lp7J.|z/T&L@ W                 printf("Divided by zero!\n");
)HdYF |#o                 return 0;$b|2w-V$v
             }
W E(o;R0xn              else
0\xYBa R)CZbuzZ              {
-N!J\a8[V                  result = x / y;
:[0v,T0m P5W                  break;
q4U&_5H2KQ              }zX:b4QD Wg,Kp
       default: g#Q[OEbT
             printf("Bad Input.\n"); q1o`R!a'X*}
             return 0;
O:F!B2lcub     }VMkb/t:v
    return result;;D |U1Eq3{d4u#V"k%n"X
}    :f7V6W]q-hH)J;V
KT7lyW4\8E.X}u
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
's ]mx3ex^'hx {
DIAZy D8\     Stack optr,opnd;
F E GQ&`'l+[0L,s`0g     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
D+v,^'qO     char c;;UQ5v&sGcR
    char buf[16];&`d*Pi Ns!{3eDe3u
    int i=0;l.Dt;g E:N
   
4GQF1W%l'O_     InitStack(optr); /*用于寄存运算符*/
Pb;Fg5Y,d&k     InitStack(opnd); /*用于寄存操作数和计算结果*/
Ctl*a%X9K!v     memset(buf,0,sizeof(buf));s0S#N!MB W
   
uag M4hx;H     printf("Enter your expression:");3B'Vsa\g
        2SO1B0R*][3Z3O
    opr_in.ch='#';(b VHuj1yy
    Push(optr,opr_in); /*'#'入栈*/8v],f(pfy
    GetTop(optr,opr_top);1J'r_E,U&ec ~T$t5BB
    c=getchar();
(\9IyEU6x-f to     while(c!='='||opr_top.ch!='#')
"}i0G#S]     {
9H*H#x({.o inw         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
U4rF"A6b4BUTK&W         {
1k}6c:S"G!x             buf[i]=c;
&f;`G6o}9z             i++;
N1q"G:E^             c=getchar();
x+b)FLT{+TW         }
2OV2c o9]         else /*是运算符*/
K-y-Nk!W*y!@ ] \K6wA k8?         {`uf"{B^^
            buf[i]='\0';)zWy%blB
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
{!V;]*I JJ             {P!Wl7_)NY"E$JP
                 opn_in.data=(float)atof(buf);
1e8h4S,m3M#Lp#Ff                  Push(opnd,opn_in);z:m|#y,^N
                 printf("opnd入栈:[%f]\n",opn_in.data);[+{\#A}4M'Q8E
                 i=0;mtm nW/W0zw5?Q
                 memset(buf,0,sizeof(buf));0v-PT S&p)~%M }5D
            }
b `6nD3m&^^             opr_in.ch=c;
F}/K R Sl;b3R             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/&x6R:VxA`?;K
            {O^uf|AE/a2m
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
d L/j)m.FQ? CF'h                      Push(optr,opr_in);
V"x6MOz!U                      printf("optr入栈:[%c]\n",opr_in.ch); s([UE}|1Kc
                     c=getchar();UH Edw;X-F0M:m
                     break;%o&MIl4c
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
KpN?8pEu;Rab(|                      Pop(optr,e);
5L"s3@jO;V"_'}#Zut                      printf("optr出栈:去掉括号\n");p$Wm9A`a6c7@
                     c=getchar();6^[.Y:w gd,j pF
                     break;%c]g?!P
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
dVV9d tbD$zu                      Pop(optr,opr_t);
,N0_}3\9S                      printf("optr出栈:[%c]\n",opr_t.ch);'`*`+x)PP
                     if(Pop(opnd,b)<0)?}b0|F0?1DD.~
                     {
sb xLd-PsO'?6W                          printf("Bad Input!\n");(h7|X"K6pMM
                         fflush(stdin);
"UX1|1Z;Se{                          return -1;F*nhDuR
                     }w:~3G~ nD
                     printf("opnd出栈:[%f]\n",b.data);'h Wg"r\EO
                     if(Pop(opnd,a)<0)
wjL4v _)E~v1s                      {0P)J,D F[
                         printf("Bad Input!\n");
6|(g0kn6J,O0M(cBDa                          fflush(stdin);b/XHY'T]5j
                         return -1;t*tp y%O
                     }p ux W'pcn;h {4F
                     printf("opnd出栈:[%f]\n",a.data);0Z1|1~9d(X$E2n
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/mTN&L z$p!b
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*//gIex[7|F
                     printf("结果入栈:[%f]\n",opn_tmp.data);2eL7dH2\r5AH
                     break;
Dr&Ky g\Fa;D             }'xXdR\-G%q
        }
,NA6ov#Y         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                'lZ#Cs;c)xH qL#Q
    }6e(T#CjD(d
    GetTop(opnd,opn_tmp);
5G:rq%t,hg     DestroyStack(optr); my-p`,P0X({,N
    DestroyStack(opnd);UnAY!}%h
    return opn_tmp.data;1y!y0v;Bv7k!r
}
EmL6a$f#CK"|D
_.o+EWuH"w char *killzero(char *res,float result)
K$fk:PR {
-{.m$F HB     int i;&x|2OU;TD%L&v8H

9vm3Q [(\#t(m     sprintf(res,"%f",result);
wU+s2m_     i=(int)strlen(res)-1;(c'hhE8]QZ
    while(i&&res[i]=='0')
(`3h dYMd     {L1Vo7K(D%G3S D5@
        res[i]='\0';~NJ ^j9Y7i
        i--;
P%{T2r-D;b     }
gK"\R(cn C D     if(res[i]=='.')/RST}T[3q/g
        res[i]='\0';
P7o7n*w&[:\ c7[     return res;k[:E4lr/g I
}
VW4NqM-b/R2@%a6I!L6v /HKdLS
int main()
#W.Y3VN0O#j:q1[{#\ {
l/hvg!f*pdw Bn     char ch;
_~r6O7t ~X+Yz/C~     char res[64];/b+ta'X m/C
    float result;jy^_:c
    while(1)h%\2yx1J.Y {
    {
]"g'^[5a+i         result=compute();
"e3MJrF t         printf("\nThe result is:%s\n",killzero(res,result));
R8w^~gm9I&G+_'h4y         printf("Do you want to continue(y/n)?:") ;]:PWW}qa
        ch=getch();#? M8c3CP{:f)x2iT~|
        putchar(ch);
.WYkZ7@q,f~:u         if(ch=='n'||ch=='N')
,~@ B7cZaL;x             break;
'u;x"k*rf jp6A         elseW-q|KgH
            system("cls");$P"NC;H ?i6u ?*u
    }:Q9ZZ$W_9b&e%T"v
    return 0;(g ox'n'I xy1x
}[/i][/i][/i][/i][/i][/i]
N M {@ Gn7| AM Y 1`t%R"o:].Z:o
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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