捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. RE6P_Wd
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
m"r+Kli4{ K{V g /**************表达式计算器************/
"pofv@;Q T #include <stdio.h>
`N+Ga(V(EH!w #include <stdlib.h>q6M:]%yH;P1x/T
#include <string.h>
2P3e{j*g(]v4a(tM2_ #include <conio.h>+hFy @v ]N
#include <malloc.h>
2S.OJ3??9VV-t(P$T
}X;NaT #define STACK_SIZE 1009IRL2V;zA2H?
#define APPEND_SIZE 10
+N&Y2Z3ms,?V4h[1y
;_!A `'PdP1| struct SNode{
H5h-?C0g+No1jJQ     float data; /*存放操作数或者计算结果*/
'l{4?sjhV&B]     char ch; /*存放运算符*/*PW[jt~A'G:W4v
};C GN2YmKI?(R"W
)R^M,@p
struct Stack{!a1n(]'wN^F
    SNode *top;"K#O%@M`$v1I|
    SNode *base;
H6qU]-IBE6^*p     int size;+I+vQ1{_
};#h k7A` ~.l)y

2G mI{6lg5TQY /*栈操作函数*/1jAN$r-M)YZ
int InitStack(Stack &S); /*创建栈*/
,F7s^"y$EP8a2lv&n int DestroyStack(Stack &S); /*销毁栈*/QYy!K7S,F
int ClearStack(Stack &S); /*清空栈*/
s(wx C*?twQ m:U int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/;n2X x"ZY/@Wn3?
int Push(Stack &S,SNode e); /*将结点e压入栈*/\+{ L7~Jjo
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/nLw:x9J7FT AC
T_TMss~ZL
/*表达式计算器相关函数*/7g7s_nJE M.?V0e
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
XV)^(i2Zqe4g int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/1@#OG&DO6P*_
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
;m8r ]|4M`9{|$Wp float compute(); /*表达式结算器主函数*/YC7i9y;_1n$`.Zi
char *killzero(float result); /*去掉结果后面的0*/ ayH N| U+jNAk
,c,M2o-CP(f6@A Y
int InitStack(Stack &S){by9m0lM:Oc
{
(B"H$Lr`C/|6PM/l     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
@*y T ~(G.OghI1K     if(S.base==NULL)-O|KP4J5[3[s)J
    {
:fi$PR$F0C         printf("动态分配内存失败!");-v#}EN*v#eIq&KI
        return -1;1PEJZy:C\
    }
WIH*Q5Q iKc/J%M;WY     S.top=S.base;
/cDz/E W:sc     S.size=STACK_SIZE;n&nF5X?8K6tj
    return 0; H?`1F9f J'Q
}
"A'C5x{I5q$s
QI1c\rXa int DestroyStack(Stack &S)/\6]!e$[Lz tp
{1[C%lx n
    free(S.base);fL/F,hO6c CLJ
    return 0;
1u8pw5^ N(Y } Rb/BJG:d0nj

(y1j)K5SyS/r int ClearStack(Stack &S)
@ n"a|$QA_:X {
)a&~H#p|U'`7HZ     S.top=S.base;
k+V)Z s-q6IE     return 0;:M5\5sv)s5GOB|
};sXD5K#Y)Q

&Lv:r~7wj'ixC int GetTop(Stack S,SNode &e)
I6o/p9R[ uf'_ {#o0a'I,QB3YK.j
    if(S.top==S.base)
S;C8aqTKE     {#[J}9yJB`#rr$|
        printf("栈以为空!");+m@p f,Aoc d
        return -1;NlV {v]
    }
.h:}AS&kC`[3Z     e=*(S.top-1);fm/`'h!dj%wx}5[
    return 0;
-k_2fv f.] } B [+B$\3f

:zvAD N`!C int Push(Stack &S,SNode e)
G%U%a2p3F*s Y {
u,l/Y.}2jcfj3T6WJ     if(S.top-S.base>=S.size)
)@LU @@%_'Y     {
5~:mbE@'cd         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
2b}V m+| QD         if(S.base==NULL)
Xc6S)JR3?         {
+QX JmH*u             printf("动态分配内存失败!");
-M*Q o8d:F3U'f             return -1;a+o!~mZ{?l0y
        }4UY(s"A9Q/NH/f-{
        S.top=S.base+S.size;3L#CZ[%A)@3A
        S.size+=APPEND_SIZE; {9w \p*tr&Z|n$\,Z
    }
Q%ci q9|KT.b j2D3B     *S.top=e;0Z0S[|${+L'[p
    S.top++;
BM6X5SCO     return 0;!F(_'Lm vr
}(zPNX-XQ,e2D7r

[1{dK:m{"{ b'Bg int Pop(Stack &S,SNode &e)*dP-Xm$P Q#Z&Qyn*Zj
{
%GC lB(H(_E Ha     if(S.top==S.base)5T8~)f s3ff
    {
MTUa#w a4U         printf("栈为空!");"M(Hj0b:V:DH
        return -1;N$_$M"b oA*Iq
    }
MX-R }a?-B     e=*(S.top-1);^]7UJ;ku
    S.top--;TLV^#v^i{
    return 0;
7|~M}r,l })YDm'AM%q*[
#|Y4bw1s
char get_precede(char s,char c)5U A'V"]4l2b]La]
{:L&s ^vCs+_^
    switch(s)
C~1w2\t\     {(V;w3a"VF@k;g
        case '+':                  @3x:U+S+Xgwy
        case '-':
(y:VZ BVq+bt              if(c=='+'||c=='-')
r#x.n/\te5oQ                  return '>'; V&HXh(k X\;p(e9J
             else if(c=='*'||c=='/') u"x'd ` VU
                 return '<'; K+U5K8x'S&u
             else if(c=='('))C X'H ^;dH3\
                 return '<';CVU/v(nI0H8Wj
             else if(c==')');H+_`C3R#s'A
                 return '>';8}8v$P5S;T.w&LU8e2{/Q
             else
7KQ0?a O}p{                  return '>';
buWV8]C&D$G?         case '*':
w;E,F9g9P/L'D7D9h         case '/':
1l| H[J9G              if(c=='+'||c=='-')4y1} U \8S-~1j'h
                 return '>';
x-S%S(](x'a*Z!D              else if(c=='*'||c=='/')9{A/A#G-_5y
                 return '>';wSy!q[Y
             else if(c=='(').St"l!l(xm
                 return '<';
WU$g~!Le'\              else if(c==')')
O Y.H?a$m+}                  return '>';
SbRA~T[ ?\              else S5v'T-G*R
                 return '>';
lTm})c*{+r8k         case '(':
W(SG\%a?*C!B              if(c=='+'||c=='-')?h;r`#n }
                 return '<';c z^h YN
             else if(c=='*'||c=='/')$eprpYCs+y
                 return '<';
/Z&v:MsHS$^7A              else if(c=='(')
X,@!_8[B8M&W                  return '<';
1ux@o_ jF              else if(c==')')
q~}fd p                  return '=';4U9P/e1r%N G"r!y
             else0X3k5Fvx/^
                 return 'E';_}*hFw*n
        case ')':T o0J S4eEVRzd
             if(c=='+'||c=='-')8q#d/H4~}:wp E+aF
                 return '>';
:G Y"dwe1e~*L0_ a              else if(c=='*'||c=='/')
}v,`)\;M8^U                  return '>';4A1`B[r
             else if(c=='(')$N_9|Udm2F KMHF
                 return 'E';P)M9Z*P J#]5aY4Z2F'_
             else if(c==')')
(_&R2njqB.b                  return '>';
0@6^4{3n X7T.iJ$^              else9p @ JK-e6`#_
                 return '>'; ]h-i1[*`(X!U@
        case '#':
Z cRbDex              if(c=='+'||c=='-')p N {k$`cV ] Yf(m
                 return '<';(hF@`^
             else if(c=='*'||c=='/')
F/p C5M!pSi7_:w                  return '<';B P8?1]C*Hh`I
             else if(c=='('):kZ(Cq1_
                 return '<';J1YUg _#l
             else if(c==')')K Qf}f1[s"O2@ Y
                 return 'E';
$o%l)@%j7J+u5h              elsel*VXZ,xV+Y|y
                 return '=';
;V`7x%jI         default:IqF6MIY9OA Ck @
             break;
{F4d C5g#c%]C7M     }
(uM}O(i N.^     return 0;   
D7F5t(Y/gu O }
kBW%gsD)H Q*Q4OE&I ;X0C5SCy_
int isOpr(char c)i PU T-c7L
{5Cn-K-xR*~N A#RJ
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
Y1IV3T P6[d5Y5m$~#M @         return 0;Li_Ua]'m
    else
6l PE5AyrN$\b         return 1;
nGS8}?zL ?~ }6xK5SWU(|
|6`-g"N P} _;W
float operate(float x, char opr, float y)
{:E"v.[ g W {
4J+cV]Xl     float result;4w+Vy6m:Q$y tD8O
    switch (opr)
$Zk4Ocpiwc'}     {
D] C3d&q.K2Q         case '+':
3v#h-?v4G |p*t              result = x + y;T!PEiu
             break;
RU p;w.E1@e         case '-':
7jJM+Q b              result = x - y;
3qZp+R*_5WMC              break;
Zsfm7Oyi5\r         case '*':
io x4};AD              result = x * y;
j$@6PC1r7Oz%PXo              break;
$Zg#BH[.Oo*{         case '/':
P,i*|E0WZ/vI              if (y == 0) A'Y8]MaB imtx [
             {
HBCpf"S%B                 printf("Divided by zero!\n");
az]8jE&MC[],\                 return 0;L$c4blJ
             }-rrz NBrnd
             else%K/m_p0] d
             {
Z*u-Q hn%q                  result = x / y;
2~q*yff4s8m                  break;SrUpYR0G)h
             }cZ,l/G k _*]*Z
       default:
%g+F4c7u,z0[,kVZ]X              printf("Bad Input.\n"); ,T Qq vI x+K2r5E o
             return 0;
P8M.C1mK_     }
{Hr/ZH1\     return result;
wB1P Y [4D"h~)x }   
#o9K;B:d(D/bHj Ir
(|iB#Uc Au` float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/Iez9Z'`"qT
{
9y mi:O_     Stack optr,opnd;"At-H5?XJgm(g
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
5WV;L!R:}5~^+D3M     char c;
XHx#@$K     char buf[16];
!|{7m7I7R     int i=0; xdk,i~BX)I;tv
   
ZT1RW1\2]#n{     InitStack(optr); /*用于寄存运算符*/WU AM8v
    InitStack(opnd); /*用于寄存操作数和计算结果*/
Z4L,DT"y^)O*vm#s     memset(buf,0,sizeof(buf));%Z q6eLV`-kwm
   
6OLB3U`     printf("Enter your expression:");u k u#CJ!nY
        
~E0Id y:A~ c     opr_in.ch='#';Ca7r*C8A]_7s
    Push(optr,opr_in); /*'#'入栈*/"en#]e1hV1j
    GetTop(optr,opr_top);e|B#[a3xPQ2{
    c=getchar();
d Q(~G0mj&GY!e$m     while(c!='='||opr_top.ch!='#')
(h8V!RQZh"F,lT]     {
%}3gn I*V         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
L$kb&uxc q&eb&YQ D         {8V(ApW&Z"n ]
            buf[i]=c;
`"~7f?'MWL k`             i++;
R hX]6G             c=getchar();
6vte[(v0g         }
K/kyW0uCI         else /*是运算符*/
(` A n-NPP#Oa"}         { n/W0I@N5B8Vr
            buf[i]='\0';
.tBhS+?P             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/S"V.ag6_],le#@/l
            {
8g0S1p"p)_2L3L+M Es                  opn_in.data=(float)atof(buf);
+^'D8MTw1d2Z.h                  Push(opnd,opn_in);
'cP8I,r(us$iA                  printf("opnd入栈:[%f]\n",opn_in.data);
q2q__?Vn                  i=0;
[y Z ?Ncj/e6c                  memset(buf,0,sizeof(buf));
*T A`xkpP%h             }
-P6y)mLgX\)qwX             opr_in.ch=c;
?}0{&z+i+S(|0n             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ODunN%t%o2I9^ {%F w
            {
Y P|c/]P%dViq                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
"` v-|\+_z'u;L r2[                      Push(optr,opr_in);
"v}CU TJD1U                      printf("optr入栈:[%c]\n",opr_in.ch);
W*N xnun                      c=getchar();{_/uEx3MwN%X
                     break;
+x a+OxTzTm.X                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
~w drIi q)m                      Pop(optr,e);:L!i0R9in%mL+|E
                     printf("optr出栈:去掉括号\n");v*B;HV"z+{
                     c=getchar();Zn.`;V_T\5P)B
                     break; }3FnB ],b9b4@,@0W \
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/X4i6fM;B2Rj9p t
                     Pop(optr,opr_t);
\-k(zHy O+g7hp4xQ                      printf("optr出栈:[%c]\n",opr_t.ch);Fg yp Lg1f,] I:r?'k
                     if(Pop(opnd,b)<0)5@E p0f3y!g?
                     {
-|!f,E(SX `                          printf("Bad Input!\n");
:@6Q-y8Vu k o                          fflush(stdin);5k0o"n7w5g+^YJ;J
                         return -1; BJ)Ai9ykM"_r
                     }7I9u-GPSVr'?-I
                     printf("opnd出栈:[%f]\n",b.data);
,@k k9\&H                      if(Pop(opnd,a)<0)3F0bpPBB
                     {
nTM'D3{[(\*P M u                          printf("Bad Input!\n");
k.ZGAxj                          fflush(stdin);
YI~2d4w;C                          return -1;
%S:F|8Ir U:{ z%K                      }
'ZJe~S,d,G9G                      printf("opnd出栈:[%f]\n",a.data);4{ y ~`-gV7B A.S
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
\-e"JJ%Rd                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/a:B;a!qlR
                     printf("结果入栈:[%f]\n",opn_tmp.data);g._yplD!CO
                     break;V"q'v~3}#x/\`1j)U
            }\n3MheZT P
        }3D8da!|t-c/Z^
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
-oR(ZkM-F     };gLV/E v.N
    GetTop(opnd,opn_tmp);
$T{A:U%_     DestroyStack(optr);
c%Ue;rc XM     DestroyStack(opnd);
1t!g0K m-upVX     return opn_tmp.data;
GX-[F_ A/v }fxbg M+Qt-B

M6f0N2q yQb"O char *killzero(char *res,float result)$Eyg2_ |:}@
{/KP(HYA
    int i;oYq-C0Z0i [ ]

_,v,y`o ZUov     sprintf(res,"%f",result); phrk3F
    i=(int)strlen(res)-1;*cB;`0~2}wk"q%sN
    while(i&&res[i]=='0')
Hf$b"M,P0nE     {
&H| W{m@:L         res[i]='\0';g7kI LU4}P
        i--;
"] T3CM4W9|o$Ntg/J     }2Hp0u5u%y"t
    if(res[i]=='.')
4Zyd,G"]iL?1un*G         res[i]='\0';
.P2q?.{;?W]f     return res;
;T6L.[r'L ]!k"\&yi }&rHp)g2wJ)W%b3n p
+B x k1`iv NZ.y
int main()3O6^3O%_o]C
{*q;@e#cqqR
    char ch; h;A0QKckiZ5?Q
    char res[64];-vK$p,Uu7K"] ZP!x
    float result;3e;m}u6b;f
    while(1)yzt#U;G(ll8ZY\(s
    {R2LDcU'CQh
        result=compute();-^0l4i7|'Y2D)w
        printf("\nThe result is:%s\n",killzero(res,result));Ep,}"aA
        printf("Do you want to continue(y/n)?:") ;B'TrL rz/B%|
        ch=getch();D_r-Mi6k}
        putchar(ch);
-O-[)LnEcp [L0Ok         if(ch=='n'||ch=='N')
s+]-IF:wS5o             break;~1_(u-B1dl ]})h
        else9H&T CAx1P_x~;L B L
            system("cls");(J$X;a]-U*V C6j6I
    }
1G7g#nPQw^     return 0;1W8](_6R*Lb"m4h%G j
}[/i][/i][/i][/i][/i][/i]O&A0nVN$kq4_
AZ2PLGFh(Gj { m
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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