捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
@_Gw7}$^5o9fJ)^ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
9aV @jv_ /**************表达式计算器************/
w&V7L4DHEV.{ #include <stdio.h>9~*LIdUO'koxP
#include <stdlib.h>.Np&L {3T VP
#include <string.h>
,hf HwU#FlJk #include <conio.h>
3Npd g T^DT #include <malloc.h>
Y"g!oR$]
6iI-KO?BI ?7K #define STACK_SIZE 100
(OgU A `1X #define APPEND_SIZE 10W#{@:x c"Q

!T7V;ZI*?^9RN struct SNode{#lYx:OSYc:X
    float data; /*存放操作数或者计算结果*/3vr&\N-W.l/_
    char ch; /*存放运算符*/#tdFH/amQ
};
o7} WA @3m2`L $wW T5smr8}v
struct Stack{
&pzTX I0T Z S     SNode *top; Je$}0PZa _
    SNode *base;}9e{ m'}
    int size;
| K1\5|-j;xq;\ };
6t;F G&C\$a*@w
,H4l.T9d+Fwv /*栈操作函数*/H F)O? F%K)?`L
int InitStack(Stack &S); /*创建栈*//n`r%_avJ
int DestroyStack(Stack &S); /*销毁栈*/
0L1D'J(?+R(y int ClearStack(Stack &S); /*清空栈*/Hp%o7Z)?k
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/ uFS _+p6w9F v
int Push(Stack &S,SNode e); /*将结点e压入栈*/,N.?vIp*w$JX m*Z
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
q aVKI8rt)LU G F:l-s"U;W{D+F,|^:p?
/*表达式计算器相关函数*/h Tz9|.}'?cC7Bh0J&q
char get_precede(char s,char c); /*判断运算符s和c的优先级*/&iR\ y6sC
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/~'WD.ePJK"w
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8t-V'^K!M&T:k6O float compute(); /*表达式结算器主函数*/$km5w+v2z*o _t
char *killzero(float result); /*去掉结果后面的0*/ I.|;f2k(l9S

|Te!ix&_#YC int InitStack(Stack &S)I*G(O!qg:o2jg9H\
{
'@r(pf-VuR     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
1j#J&\ ww0[(j     if(S.base==NULL)
]r+h _L@)B!kEY     {
)k+Y5lt6MILFX E'OX         printf("动态分配内存失败!");
9s9UmuP         return -1;!m;Bk7ETP/W!~
    }!k`u'\;}G!C
    S.top=S.base;+ZuYpk7j_'O/s
    S.size=STACK_SIZE;6MgfY;f$eW6^(`|
    return 0; o1}t-BUV O*V
}2i_y{Q \,M |6B$}:o G

Q)d6} W {6ov int DestroyStack(Stack &S)*px|sa-@W
{B3U V3{c$iR
    free(S.base);
#G pU3XT(dp/m9d:b     return 0;
9o~(L:Pb!p f }
oT0dW2R g D7rfK T'A#@
int ClearStack(Stack &S)
9o![)v!r rG {2~!w[(w|r(D0I
    S.top=S.base;
A:O,_}e }cIn     return 0;
jD9t%SB*H }m%ZLjCmX
A+u`Wh
int GetTop(Stack S,SNode &e)F,P3{Y*xt
{ U u5D8De\Tr&w px
    if(S.top==S.base)/KS+]#Y^9|0X9R
    {'U%V*^"H6o.pC q0V
        printf("栈以为空!");
J5j+shS3n         return -1;
I f2M$?d4e0j_     }rLn+C;s:\:N
    e=*(S.top-1);
1U*|f1N#I)h%U!N     return 0;5H {6be F+XQwxP
}
n-[oTc0^ [Q!q
AP#@N KH int Push(Stack &S,SNode e)
z-Jf&{[.a;w!TV {&[C@X_
    if(S.top-S.base>=S.size)5G~3K yA s2B3r
    {
~ ea2F#r_ x9?N         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
c${,^? kY}"V W         if(S.base==NULL)
PB'~K.x:xPzNy         {%KQ| y]M/I
            printf("动态分配内存失败!");
/dDwiYq             return -1;Pi.SK"X?(c
        }
tp!i6i K g P sXU         S.top=S.base+S.size;jt'{ d%Z
        S.size+=APPEND_SIZE;2ZC%X%?#Q ?.Jzd
    }
:J0?LU/QO     *S.top=e;0I)p|5[rA'U)Y[ F
    S.top++;
_7ea!YN%`     return 0;
b C5L/I:vm }
?P-sD5Lw:l(W P 1v p~a/Y-d6w/j
int Pop(Stack &S,SNode &e):^g+ODm%Y6ei6i
{$MoP+o u'[&xik r }
    if(S.top==S.base)
o5@ c"MT4hObk     {
*n"f V\ }|CI%ha         printf("栈为空!");0fx;F!^/M
        return -1;5P;n/G#ImAFU,_ L-M1a
    }
K F)RGSP^D     e=*(S.top-1);
H8u |H m!D     S.top--;
kF|Hsp]M-E     return 0;Yq(}"dT9]9^/m
}
F]t A@ke #Y^&QeU)V|L
char get_precede(char s,char c)
4Fh'~:W|X7c'O'| { [HQA w*_*y
    switch(s)
.~n0W"G;SNWd     {
t1o-f3Pc:f:l         case '+':                  H-S:E;q1Zn1M(g4a\
        case '-':$Vfl7?)]4awA0s
             if(c=='+'||c=='-');F RQ(WG'K VbXL
                 return '>';
@HR4h*k              else if(c=='*'||c=='/')
\:N#f s"M9^:RkFz~8t                  return '<';
G4`OI_buh\              else if(c=='(')
]_eeGC I                  return '<';
a^w|-wUy              else if(c==')')
e[&t|lyb                  return '>';
[|[DS              else K+e t6E3~3J7g
                 return '>';
5T1X\e[K L1Q(S|ve         case '*':
[6w h ^#L3T'ns%^cC         case '/':
B'] b ?0gF3]              if(c=='+'||c=='-')
G"i*waa[b!z                  return '>';
z7l0[ EP              else if(c=='*'||c=='/'):B'ul@`EO-bS
                 return '>';#R!` cmX%c(a:I
             else if(c=='(')
QF9m F6u[dj                  return '<';rY(V(zL5x)F
             else if(c==')')
;aW0x^Q)~1|8I7t9w                  return '>';
'g\ Y"WK e \6m5m              else}M7T9dkFK"h1`
                 return '>';
Y&Yz2K&A3t^         case '(':
_\6[uG8au"M              if(c=='+'||c=='-')
+vH5M9K2uZ)[1p[B4o7t                  return '<';,gd I y t0?%V _f
             else if(c=='*'||c=='/')oC I? xY}w9i(fL
                 return '<';
Wq.O"h.jK"hPc              else if(c=='(')
+i2@R\)Bp7yH                  return '<';
O)M0pqF&aF*T g              else if(c==')')8JV,PJ:A9|{Hp*E A
                 return '=';
5l,` R-n r8C9\R4G              else
9ce Cr0{*`1ZZ                  return 'E';
M J1u$c E It(C,B@z'C         case ')':
!S5M2@0x }{i              if(c=='+'||c=='-')
0E3J,xm(w-T j uy                  return '>';ZRG,w w0B$^0L
             else if(c=='*'||c=='/')8d|}!`0{w-g?S;bWJ2t
                 return '>';G+y+|"\_OAj r
             else if(c=='(')
5e t'|;J nSxXI                  return 'E';
3ccrZ{;M+M              else if(c==')')
Shr#A}s`2CL                  return '>';1U,v&N7k Aq
             else ~b\4l} MO h].]
                 return '>';!l$uGt'Z0{q|$X!I [t
        case '#':#@-h8tnj4p1r}
             if(c=='+'||c=='-')
7vVj,vdI(d                  return '<';
\(O.b zyNdA              else if(c=='*'||c=='/')di g+e.yp"E v+T
                 return '<';
w%k|;t D1xS'z#_              else if(c=='(')z7r-A0y] Rpy
                 return '<';
B1n3{XYg1C              else if(c==')')
QWumj1{!PI2m                  return 'E'; o)nl(sSR
             else
+`Pq&e{Y                  return '=';@2R `Q$ydgC3xDaT
        default:
@#E!K&Y r7O+wB              break;3Wf`E h3X
    }} ["qTSX
    return 0;   
7l@g Yb }+E Qhf8_i3zLP
1?&EorIa9K.]
int isOpr(char c)
#oF.]6]%p}8F-q-gl {
o4G,j0y6c+\     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
H P zIJ7{         return 0;G]:BY$eY'|;_Q
    else a DOU(ZA5\ Uc
        return 1;:A4B$gV;@ \
}
Irz:Xl &pk^D8KB_
float operate(float x, char opr, float y)|^A#O|Yc(b/F8F+W-{{
{
+~&S.G$X'p1k8WO     float result;^.F7pps&|
    switch (opr)
})x)?7Z_ i-o     {
+CiXx Vz         case '+': .Q]1uP7XN|Y
             result = x + y;!Ix(t ^"duT
             break;,P%\&LS#^X \h
        case '-': P1NX-V^
             result = x - y;
a`-P#g f!f8{3U6`              break;R4n)HLi'EW^ R+HC*G
        case '*': 4@n"E2B;rR1`G
             result = x * y; ^ x$a@9\"~j A
             break;
|0q(g FL/h4R^3I         case '/':
mws1yT\N.Z              if (y == 0)
;s$q0[;t"q$l7x }6r              {
~!k[v LW |5Dp U                 printf("Divided by zero!\n");
OE*N)D$ez                 return 0;6P RI&h W
             }
|V/c6B?Q I6g              else/c~u/cQtH8hn
             {
mph.h5e u-B r{J                  result = x / y;-qr+|jEO!~8x
                 break;6s@9NZ_
             }
*t4ADsC9L0@a&i g        default: r+wCe])g_i
             printf("Bad Input.\n"); I\NX/J5`+jO8C
             return 0;
AZt0Id|8u-V^9[     }e4mk2}v6w t
    return result; ~9o6k(WX]Qi
}   
JY*]L0Zz"D 7t(^ yN0o z\ A U)W#r(s
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
p$rJQx/a+\ QS K {_q$y J,|Cpk
    Stack optr,opnd;
9QWzk0{*R     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
2@-Hp1t4f G"rk7d     char c;pqc'}-U
    char buf[16];
Kr"{ R/N4B)k+F     int i=0;)[eV|.j0}@
   
eX.g6I"["K4i!g     InitStack(optr); /*用于寄存运算符*/
2e y4J5Q*mz     InitStack(opnd); /*用于寄存操作数和计算结果*/'S&G;[L9do
    memset(buf,0,sizeof(buf));
]&z%Sa],Gu'W H0e    
H![#L z%TW0}F2[     printf("Enter your expression:");
8l7B"o(Z)l         
+d3AQ ta#W     opr_in.ch='#';H KS-{ y"u4u
    Push(optr,opr_in); /*'#'入栈*/
%d RJG/|Ncq     GetTop(optr,opr_top);
m$LS J*}5\Xs     c=getchar();5LgF$N)i:b
    while(c!='='||opr_top.ch!='#')n5cW^%mzi
    {
d h%b:QiIo3l&ax         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/6L.K W { z)J
        {
;Es$r)^,G^n             buf[i]=c;
m$m.w G.~"V'D&p%wF#E             i++;
,p*h:s ^.U}6QgH             c=getchar();
9ke h-DZoN         }1Z p)^ @y9dH
        else /*是运算符*/M:\#VSW4lLR.Sj F
        {6x`*G!Zyc!u:y
            buf[i]='\0';)bwG@W#T
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0Nm4lp FWq"y)\.^0R$s
            {4yS Y{+O|E
                 opn_in.data=(float)atof(buf);
Cms"S.VzMW/C                  Push(opnd,opn_in);
.^ `-R-R'u&ZYq                  printf("opnd入栈:[%f]\n",opn_in.data);5s,EeN:FT PZ&r
                 i=0;
R%I+yW|y                  memset(buf,0,sizeof(buf));LHE,[_Ww)U
            }
6XB5K,[h#G;majC[f             opr_in.ch=c;
OWeoe4o             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/0x:^:rQ3}I"T
            {5{P,NqlL
                case '<': /*优先级小于栈顶结点,则运算符入栈*/1z T'p^[!C"z
                     Push(optr,opr_in);%I4_'M'Qq_'f
                     printf("optr入栈:[%c]\n",opr_in.ch);
S @'x'{ P/h2A8R                      c=getchar();
n#r.r3A0v                      break;
4TlN?[                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8WRlLq `!{0j
                     Pop(optr,e);y1kC@L @~ ^
                     printf("optr出栈:去掉括号\n");0T4eV0[8S6\)t?
                     c=getchar();
O{ oA7L jF$v                      break;pWUV?h!M d8Q!u
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
0@b)aBp?                      Pop(optr,opr_t);
6~N)E c J                      printf("optr出栈:[%c]\n",opr_t.ch); utfj3Z(o.HL%AX
                     if(Pop(opnd,b)<0)
2x2s/[6RTc.}%l K$tt a                      {
T z[!s%v$w9L5^                          printf("Bad Input!\n");
&rl|!V4b/~*i6B4|                          fflush(stdin); y/l7}'q7qfSAu"^
                         return -1;&? A;G\,l5~
                     } g ]%Y&aph
                     printf("opnd出栈:[%f]\n",b.data);s$u w%^Dn
                     if(Pop(opnd,a)<0)
2^G-Jr(]]W#t.{3[                      {QOJ'Lb!kkW
                         printf("Bad Input!\n");
J e.Bc#h7i:LL&V                          fflush(stdin);
f eHI[B5Y                          return -1;
%TH l7l$}+^CI                      }#N)SG%K,q
                     printf("opnd出栈:[%f]\n",a.data);
(? t&zjm                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
f1n:c:c#cC                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
QNt+|#Q?,v                      printf("结果入栈:[%f]\n",opn_tmp.data);
;l+AT|Nh|U                      break;
3j pm z*H0WhO9P             }!G:X9Nr`b+fY
        }
:hW8Z[3X,o4^         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
PJqT?g$^ ~{     } ljP%re
    GetTop(opnd,opn_tmp);
-L:|(?-B&@ A5CgZ*C8g     DestroyStack(optr);
7@ VBV B     DestroyStack(opnd);
!W!G.Itp"`u&J     return opn_tmp.data;1gu-Om$c1ob S
}
@$h qBFB8W }F[1w1j-TA
char *killzero(char *res,float result)Y9szf MO1F&z
{*D(y%C`.I;s
    int i;
6Kc2j ?E2v m4B e,d;D%j#biw
    sprintf(res,"%f",result);
/}1kD ~ ` @ BT0s eZD&V     i=(int)strlen(res)-1;
AqE:A6d{g6L     while(i&&res[i]=='0')wZ mpd+m_Y o
    {
W,e^9j,X$API         res[i]='\0';D%\W)unI
        i--;
JM/c/Dm     }Dlt*~5W
    if(res[i]=='.')aQ6EjC
        res[i]='\0';
Ti~,{ qn W)A+g?     return res;6[\"iD4gR5x'B6n K6~3D
}U!N;[R SzK1i[.XZ&~
;Q*auT,hTE
int main()sW-{*?:JXL
{
A/N ov5g7s I]q*V     char ch;,v@jru_
    char res[64];d ` V+Op5x9U
    float result;[:VD|.z3l
    while(1)O/g({;FZ'E@
    {
q7||5oV         result=compute();7Q^9|5k+o({&]
        printf("\nThe result is:%s\n",killzero(res,result));
_Yj+d*Rw         printf("Do you want to continue(y/n)?:") ;/G#{9@2yJbg+?1v
        ch=getch();
HE9X!F6FkSjP         putchar(ch);;aoYVv/M`
        if(ch=='n'||ch=='N')
7W o4d5?"}7n NixS@             break;
Ku/Y*Yu$L e         elses+oV)WB
            system("cls");#e5w7mb-B H)dY
    }D9R[$b n$tW*J
    return 0;D5YR3F3w{ ]
}[/i][/i][/i][/i][/i][/i]c? b ]l:GZ
,K{9q#q;D
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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