捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.(nt.n/^ J9}
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
$IrO.L.p /**************表达式计算器************/
!`DQ$F T,D #include <stdio.h>.T2d!Gy6sm@
#include <stdlib.h>wX.mu5w9g?r6v(Z
#include <string.h>
\r8L0~0R8Sw #include <conio.h>(Rh.T8Mz7A3O
#include <malloc.h>
L xUo'A d'ctch
#define STACK_SIZE 100
@E}G5bn #define APPEND_SIZE 10
4AdKdnpV
6k(Di9~#b%^G struct SNode{
X*EZc4I     float data; /*存放操作数或者计算结果*/
6G.I4q4_/~1f     char ch; /*存放运算符*/o8d~+m(E A9Uc,{3B
};yebEuT M
?@s6qd
struct Stack{
C"Yyt)U `#b&U     SNode *top;+to G\)No
    SNode *base;
L,wu1Q$pxs     int size;
p9hd:\Xf };8uO6j:k#B [J n

_H2fbq4@9H /*栈操作函数*/
d9`!K[|E)[ int InitStack(Stack &S); /*创建栈*/9T x.J"d^N
int DestroyStack(Stack &S); /*销毁栈*//\ W}:]3H Y
int ClearStack(Stack &S); /*清空栈*/
|BUpL7]&o int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/4C}Q|jU Y4y
int Push(Stack &S,SNode e); /*将结点e压入栈*/;m#sQQVCL3}
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
7I8{E*t'g8N!f3jl '~!BH&p ^5?;v
/*表达式计算器相关函数*/Lv_3Do
char get_precede(char s,char c); /*判断运算符s和c的优先级*/o:p)}0?.C(y%q
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
R:i-@ {1p float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
$z;MAAPo5RO_ j float compute(); /*表达式结算器主函数*/"r QTwz9A8sr
char *killzero(float result); /*去掉结果后面的0*/ sU T'k1OwCJ!Dny
8Rz x2Ga9o}Gm
int InitStack(Stack &S)
c0J{%lr,zk {5_k#{ |'@K
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));I`L,U$G/E
    if(S.base==NULL)[QAK(w[@!I Xac
    {VU+g7o9B$z l:b
        printf("动态分配内存失败!");
[5Da!i\ x4d F         return -1;
t OaT:zoJ     }
(I3ME)m7z*P/t4yf+V     S.top=S.base;
-d[I(aQ%N L     S.size=STACK_SIZE;o-G#m+o.r_U
    return 0;B e:o;kP[$R'l
}
7n(@a*phDb/C
\m&X&Z;W^R int DestroyStack(Stack &S)
'CmEiyYc6^ {M*vc#f p Pk/q"tAi
    free(S.base);
&Tz-p ^3l }(e-m$w     return 0;9K(hJ-qaz Z
} ON ~|!s

+Y~1EgwaU8_'e int ClearStack(Stack &S)
QzV;uBFm_ {
)OC1n cKPOB     S.top=S.base;GTM&{kGi
    return 0;
L*`5d|B^h }
M*p6D8BS/{K[ +W Vx@ V(]t
int GetTop(Stack S,SNode &e)
"o L,uRL.w1X t{'C4X {
!B5V1cWL-CKu(]"ui     if(S.top==S.base)
y$gu t)t Q     {/?|@n`XGe}
        printf("栈以为空!");t}y.z8JpO
        return -1;%?B2v e9l$U
    }bs"j[~ v'[f9?[
    e=*(S.top-1);1Wdun8w
    return 0;;qG;O$WZq5G
}!K%o2E-h'D y ]+[6K
bI7RfIW9swC
int Push(Stack &S,SNode e)
SFrd2l7J2JL.^ d {
bNh?e2T9u6F     if(S.top-S.base>=S.size)
ax`h+k8~J,uA     {WZ6j\e/v
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));w Y a}O;\^'q^
        if(S.base==NULL)
ML'zk2q F9mF         {Um ?TF?
            printf("动态分配内存失败!");
)X-LN:]X8WA             return -1;
6@@X"eN[^e)N         }
+N*j!I kVh;qn}.[         S.top=S.base+S.size;
8_3~o4X9v(l         S.size+=APPEND_SIZE;i^M$Oh f#i@R*}
    }"y EDE,h` Rf-g D+W
    *S.top=e;
Ng#UcTH4B     S.top++;
YW-r&]4Y1v&vwy9b:On     return 0;O1v a%@7H;JH2yo"O Ql
} @1YGj&df0Q

+NJ}3k!i'n*@)DY int Pop(Stack &S,SNode &e)Pey+c.c_
{
/ze u"Rii'b]     if(S.top==S.base)O ^G)jdD`
    {C!yt`6H1?[
        printf("栈为空!");
!?:yA {Eu4\;o2@9b         return -1;
vD jgo     }
hL1[&s(j2?     e=*(S.top-1);
@.YB9k#s{     S.top--;
N2N-K E8UYwR Bc     return 0;
*tS M5y&vY.Dz-O }
q-i%Ueky7@ |uJ` '{4F9]m)S_g)q%T N
char get_precede(char s,char c)
'?8I`!E"o^B {:E8G;V]-PZ*o7@
    switch(s)
Yo X ANI     {
E7} wZF1Bi!Rk W         case '+':                 ;ZHX.K8q
        case '-':
%Q^(Bzq,]%?F              if(c=='+'||c=='-')5}.s"r:F?Q+r d
                 return '>'; IzO D8i6d&u]
             else if(c=='*'||c=='/')
u5I:W\ m4x                  return '<';!{rz#sBk:yw/m
             else if(c=='(')
`#G f;F&c G%R                  return '<';
+xw:I6mGz,?[6A              else if(c==')')
&M[ld,l`DrS^w                  return '>';!xB ~abNU(v
             else
8n LV ]D(_\                  return '>';|$u'i#{;N+F@:F{
        case '*':
@(]R,VDp/m         case '/':
:Y!V9I2v G&|              if(c=='+'||c=='-')F'o$QD+nj^YP
                 return '>';
s M}1ZL+p I              else if(c=='*'||c=='/')
w"z)Jm2_k Q5h                  return '>';g hT#Y m4\G
             else if(c=='(')
,_$K m)J!Q-E@"}(j                  return '<';
7y@yR L6mo w1y              else if(c==')')
6bh'Y,]DSN)k                  return '>';
~5G#_*j/I:X@&@+e              else Vu&S;N;tXY$a!r
                 return '>';3g\9l'~#v ^
        case '(':^5H.A.t.k
             if(c=='+'||c=='-')G;`CH/^N
                 return '<';(wyu1||
             else if(c=='*'||c=='/')
Oco+yg(s]                  return '<';
#H5q4F7a](r              else if(c=='(')*Jj4Q!_$eg!d
                 return '<';
C!mmr*Du+p*@5h8J              else if(c==')')G J"?(J\D k
                 return '=';
;t3PiG8f.J2w,z|              elseUZ w q"m(Qv
                 return 'E';x{*Hh!c3F!d7B0C
        case ')':
*px s!aj9G)w;o0w              if(c=='+'||c=='-')
{s9L-t^-J7N+kQ|)t                  return '>';dR!Z){+a
             else if(c=='*'||c=='/')*rdpfb:\'c
                 return '>';
.ju_P!f#n6O              else if(c=='(')
:Lp7iZ!d&uEU#m4]                  return 'E'; X'`?g3`t3cO
             else if(c==')') ~ A.p2N%n
                 return '>';
0W6Pt.{R              else
'a:a'C[6i                  return '>';r"?~ \;r7`Z
        case '#':
W,iY.DzQ\+?              if(c=='+'||c=='-')(FV8t"nA
                 return '<';e6o;a8N+ehPrx3c go
             else if(c=='*'||c=='/')
PP;T#hN                  return '<';
4A ht @mL1VktT%[              else if(c=='(')
8~7g~]7H uevV}                  return '<';3]j jq S
             else if(c==')')
4t i4l(lOtlM6Z\                  return 'E';
J9F.NrlW*sb{              elsef9CeqC{#us4a
                 return '=';
)R)?.n| z         default:
2\5Nz{B-y{9V              break;J+PtT;X
    }4j8J&Jo!oO
    return 0;    p0fjN_;j)LU
}
Zc a ^:|GmDY
!Bn,@.j\ int isOpr(char c)*K EfE,Zw
{%lw b"R{Dm)t,R
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
6sUX o ma         return 0;.c?9K7Ww
    else `&n uE4~ D Zg
        return 1;Z[9BeYg `0c
}
]4e B8W1Z-{7N/a__9s
[(A_jQpL float operate(float x, char opr, float y)cmt:t;k?X
{ j l,f"bVap
    float result;;]3J!w S!h _*[4z5?
    switch (opr))TO-R]`
    {
2O]^ Z5r:Xa         case '+':
f},SR+XQ)Tq:lT6Y              result = x + y;
JjBVg.upj!C              break;
G#A p&Q qK.e ~4m#d6P         case '-': 9_5\6} h#|3{+k h JO
             result = x - y;A"t&Y9VOJUx
             break;
r(k2h~ U'KB6}9Fc'S         case '*':
RV GW"O7Upq&s              result = x * y;
:t7]z(kc%h6b d              break;%?_D%N]|ajeB
        case '/':
NsJTc&TL              if (y == 0)
&z YX0og z7p              {aV2Y ?j
                printf("Divided by zero!\n");
#s$A}&enCb                 return 0;
v1G`X_6l              }zfGlbY~^U
             else'v:d*`&[Ru*A
             {6FN'\?slM-{,a
                 result = x / y;'d+G:@'Hm
                 break;4zd#x'f_V9Y&g[
             }4e/[x hj}Tbx
       default:
q#H(OU,w,I[(?8P              printf("Bad Input.\n"); ngx3`8w#f
             return 0;
2KE6EwDgQ]v     }#G/w!S;fa0\
    return result;
5iK]7V4a){XY,] }   
xg7dT_-~.Wm S e E o$d`D[
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
~1bXH+Ppd(L/\z ? { z q\_kZ
    Stack optr,opnd;
Z ^1m ib-@oUm     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;~"L,q s.?4i }{
    char c;%HVO'W3Z!oWM:EU
    char buf[16]; ]5U,Q;t'D.M
    int i=0;&|4h#v/zi5B;G9x2V7G Im
    9s.k*Xpb#Z6M5{c
    InitStack(optr); /*用于寄存运算符*/&zDc0Mm+|t
    InitStack(opnd); /*用于寄存操作数和计算结果*/
8x7S,GH}2h!C     memset(buf,0,sizeof(buf));XWW)`VBc,vG ?y
   
L4a j5wT Rz#`     printf("Enter your expression:");5Dwg'Z^
        J irgY3^J9xI
    opr_in.ch='#';G6qt Uw"t,u$g^
    Push(optr,opr_in); /*'#'入栈*/
l#[F/c sL5}     GetTop(optr,opr_top);
.] EKq(B     c=getchar();
mo` CR F&_     while(c!='='||opr_top.ch!='#')n2au-eP8t(U$Ib
    {
z:if syu]@-kk         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
G`"H S+|         {
H1T B/` AK"R aC:E             buf[i]=c;
[tk"PN z             i++;t%P)w;` W `!bVR,v
            c=getchar();3^,Q%o7wT*B8d.r
        } |.cF*u+}ytP
        else /*是运算符*/
)^5O-vb-~9D-}^         { j'[Zl}Ndh^
            buf[i]='\0';
L,V!b k9@j%p~e             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+T&y2wm+p N"Gl*M
            {
(w2` D P |ew                  opn_in.data=(float)atof(buf);z |6b'C ]]`r
                 Push(opnd,opn_in);
&[ G1] z6@7W{                  printf("opnd入栈:[%f]\n",opn_in.data);
e WT/TdC*r)c                  i=0;
{T#x9}*t3w]9h                  memset(buf,0,sizeof(buf));y F*z\\
            }.q!G.N+L:n*~-i
            opr_in.ch=c;
/NwD+h WTAqu             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
uZ8Is,f             {+{u3_1x8E0z m
                case '<': /*优先级小于栈顶结点,则运算符入栈*/%pyXQI a
                     Push(optr,opr_in); v:lK LH#V{8M
                     printf("optr入栈:[%c]\n",opr_in.ch);-OgW,Zj9k8I
                     c=getchar();
e/av*i(T F9`DyO                      break;3D)t%T&a0`!_&O
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/h$[;f Ho8D$n
                     Pop(optr,e);lc;@s^*M%~g
                     printf("optr出栈:去掉括号\n");)I6t%Fz~9U
                     c=getchar();1WK[#e_9~
                     break;
MRCMae                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
-\-S3R9YV ~%k ~nwx                      Pop(optr,opr_t);(si}C"a(k"t
                     printf("optr出栈:[%c]\n",opr_t.ch);
5j^E w X'Mu&_$]                      if(Pop(opnd,b)<0)
^x Yi a mi                      {
o*RM R'w},q                          printf("Bad Input!\n");
.AB*|[;]                          fflush(stdin);
|+w;T KaF$XE                          return -1;7f6i/I/zrk}c
                     }1QTkq0D'? j
                     printf("opnd出栈:[%f]\n",b.data);
[]K7c.G5G8g*x[ M$W                      if(Pop(opnd,a)<0)
+A(KVg"r(Eielh-a                      {
g3Np/R9B0hQE"o                          printf("Bad Input!\n");P ITu \7qWtI
                         fflush(stdin);PR0w*oQ]
                         return -1;
F'^%}:C1A(Td$ux                      }
&n`h gS9[/z5C                      printf("opnd出栈:[%f]\n",a.data);
^ o6h3Rno_                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
uW1kT G6V                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
F^:R'Y*vLW~3O7\                      printf("结果入栈:[%f]\n",opn_tmp.data);
g7\)X2FI+s6J}                      break;b\,z$~S
            }
B.Gc$eM ?         }
j(]e~/xUh:Z.|4i9K         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                j$|R.h,j;jq
    }
@6BkRa{     GetTop(opnd,opn_tmp);
1~$S*~)[Zs h _d     DestroyStack(optr);
W-Un^E     DestroyStack(opnd);
"eg3h] e2Usy N     return opn_tmp.data;
S~e{$If }
KfT-ek%]
RgiM(gE;Ci char *killzero(char *res,float result)dd4|3wG(j:wf
{t4lj+DpO a'C?
    int i;9t_&?8s jE\

OD)|"p+}8E&m4i     sprintf(res,"%f",result);rk/TI!e1Hl5L&L/h2T
    i=(int)strlen(res)-1;
x J t4X7F9Q(H3[     while(i&&res[i]=='0')
|"@"N9o6~]7F/s     {{#]v RnB(W
        res[i]='\0';
-I@u*N`,SCx         i--;"O0SOr&H
    }/P_2O"m.R
    if(res[i]=='.')@5]4g)T^*Fv sJ^.k
        res[i]='\0';~meP'va
    return res;6KLm a]-G[
}+c;r^"]i;V6] Cs

v[O;p{A2M)Fe int main()
1B7` d"gx2LbIj {3J"MTP$w
    char ch;
,I*XL@%m;_ w     char res[64];:t ]/u5JN:Vx
    float result;` WnE n~4{
    while(1)
(wB4d!J!Ow:\     {jp/o Q*k*\D
        result=compute();
WbWA u         printf("\nThe result is:%s\n",killzero(res,result));Z[Q`\ zP
        printf("Do you want to continue(y/n)?:") ;
1PE1r0[rY         ch=getch();
$l;K%K%t(?/HK         putchar(ch);7S\|I0ZW:Y!ItQ1VB
        if(ch=='n'||ch=='N')v-a't8^~^u.b!K
            break;cne(eMa4bs J
        else
,c4t+mG_zD X7t ^k             system("cls");
Z5g;y I YU5eQV!k     }
A+K*G et ~yJu     return 0;
O(K2~*l$g }[/i][/i][/i][/i][/i][/i]
U5nCD-J+Q 3F(G7H$KfzJ
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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