捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
3Y@^/N0_4kj 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
^kr%ESP8s.{ /**************表达式计算器************/
!~)mH a0A.["? #include <stdio.h>1|0l-~9ct SdB5m+|G
#include <stdlib.h>
?i6TE8r #include <string.h>8Hhc1jP!Y
#include <conio.h>+Y/{)i7Ox[
#include <malloc.h>
m;L`D#rig W&H!db ]qW C,O
#define STACK_SIZE 100SYb ^C
#define APPEND_SIZE 10 Pi3Y1{K*n

:~@ D0}^*~P"u'j struct SNode{w'~*_l3MKn6?
    float data; /*存放操作数或者计算结果*/
,{(UD5j*G^     char ch; /*存放运算符*/
CBo \8~Pn };X^;Fv#I3F(E
&cw z g'q9JZ&V$dYD
struct Stack{
9f}e3~lLVe e     SNode *top; o'U ]U9n#M+k
    SNode *base; eS"P1I(Z+g
    int size;
,nTx%^,IU };1s9Y4Bf {.aZ]cz/o
vB:d/n!fX)m D
/*栈操作函数*/+B.H,w"?%fT:@ WuK
int InitStack(Stack &S); /*创建栈*/(r[7VRg+^x8Q
int DestroyStack(Stack &S); /*销毁栈*/
2t*TT'pf;Yo int ClearStack(Stack &S); /*清空栈*/u0M%b$mg?
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
c+l7ic J6N int Push(Stack &S,SNode e); /*将结点e压入栈*/:T)nyw)b0@
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/'OT s+CD/kr ql3N&A`

,o|\%c,g#tdTC /*表达式计算器相关函数*/7[5Q/X` B
char get_precede(char s,char c); /*判断运算符s和c的优先级*/fUK r{
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/9jo3fNLwurk/B
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/y4Y!f+dW)zl
float compute(); /*表达式结算器主函数*/
YuN ij1C/`+F)t char *killzero(float result); /*去掉结果后面的0*/ ].D/Y)Au(l#]/}5y

*Nc/OQ9I4F int InitStack(Stack &S)N&x#bJ g `,`-z
{
8q?j;wn'Z     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));&O3F7v ?*a
    if(S.base==NULL)K9~!h `d Iyn
    {^5e,Wrs].Tr
        printf("动态分配内存失败!");4]/Na${9i6{
        return -1;Ts'yJ[ t*I,E:r
    }6\8L-[)v{O^*K
    S.top=S.base;
t XKy_2i M^ Ks7W Z     S.size=STACK_SIZE;
im Zz5}     return 0;^5c+A yt t.^g+y%Fc
}
yNW%Q$h
OMd0y5\,[Q int DestroyStack(Stack &S)eo(L;pY(S*?)z aR
{&y8]-a;H!Y-b5R/Y
    free(S.base);
z ynk/RG;_     return 0;
K3VyK*EpA&d {ue }
\q;l1gR{~n 'Zi_}3\2J
int ClearStack(Stack &S)
eoWtE!` v {-y,vF2K:]
    S.top=S.base;
z,H&g_$A7_     return 0;
wQfr^uA }4K'DY+K'^6d.u

&j.ms \Ucn6O2V int GetTop(Stack S,SNode &e)?y'~Iy r+T8V
{
;acD.]2qa8]     if(S.top==S.base)
eV,lo)V8G{3qS7my     {
TCbHGXF!b         printf("栈以为空!");
am7B1NL&}MZW         return -1;a tx&W@vh
    }gf3L$W7c&N{'T1{)gB
    e=*(S.top-1); Np.SM{q
    return 0;
&R3Blp7B&Z E7g }
p3w|8h5d g(V*W y"A d(x zaD%j!`
int Push(Stack &S,SNode e)qS \@0KZ
{ Y.a2G"a [ J2@)I
    if(S.top-S.base>=S.size)
w"ScE%yO     {
.E&Fs~'md1Ky q         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
)M!^\ _~#R'Q}         if(S.base==NULL)1H&]9gD@R$_4E
        {v g1Z&al'sv
            printf("动态分配内存失败!");
L7E"TuEc5^             return -1;nSFT+y*yqo
        }
3k M!FsT9~[c6HZ         S.top=S.base+S.size;-Y ~\ED2WU*}$`m,b
        S.size+=APPEND_SIZE;
*UY I{~&@)[     }n}-|h/DUj5v
    *S.top=e;
4{6G"b;d5w q HJ@ g}     S.top++;
YT9?\3E$MB V     return 0;5R7|1bn#\&ls\{
}
+m(n J7Y1BU h4_v 9xa(a$y-\[T(N
int Pop(Stack &S,SNode &e)v/OmM+_8o_Lg
{
p/^0x}WS:m"Km     if(S.top==S.base) \/gx a b
    {*MrTp5y6p I I
        printf("栈为空!");t w3c7{5Y_ b5in;g!B
        return -1;
3p0E1}/?g:it;m2y     }J,kZ-T_R^
    e=*(S.top-1);
/G.Gb @WB9My dLjd     S.top--;
;l S"VOC9b^9o8t"wB"S4p     return 0;
L5TO^/Ui.V`l }jG&o'v E,D
-|%IQr@)@7H
char get_precede(char s,char c)
\/E4B(g1a-`3C6X {jqz6X4DYU
    switch(s)y3i fG/[K3|
    {
2BF*KL2Pl(N+{         case '+':                 
7ND,?3iI!K;c|7_m         case '-':
g){ZGr              if(c=='+'||c=='-')V Q;y~EP
                 return '>';cn9Q#t$Z*a
             else if(c=='*'||c=='/')pT3diP[2q#cx
                 return '<';
r5Y K&e$db              else if(c=='(')
B0FZ%@ JO                  return '<';
r2M$p&i/@3il P{ j'y              else if(c==')')
R3s.A qo"GO                  return '>'; B:W\MW R
             else +K1U+c%vg)ka N
                 return '>';+PA$TA-UL Iu7d
        case '*':
2d:i y;dV3dc;CCS H         case '/':
P9O5k r I9H6j`'nm;rt              if(c=='+'||c=='-')
9T OE;BAPi1@Z,V$k                  return '>';0fY.sA'K0{H)Iko.u&@
             else if(c=='*'||c=='/')!dH+}(IN3E'il7iE
                 return '>'; T`'Hm;[
             else if(c=='('))mcf%U1^ TJ
                 return '<';8uX1{.v"e#L
             else if(c==')')
^]2``5v mOt-ON                  return '>';7T EF(s!Kq!B4p!`
             else&H6ti%V$we-E(~3_
                 return '>';
mR;a*F-i9bz         case '(':1hmIw3iTx^
             if(c=='+'||c=='-')M |$ub1C
                 return '<';
n np,t|.I9L,e              else if(c=='*'||c=='/')N%?HvCG_
                 return '<';4M G0bn]4T`n!s
             else if(c=='(')
'F c[`{6v QM0}                  return '<';
d,[pM,A*`?              else if(c==')')R[/gh!z~
                 return '=';
'W/@$y$A*R2I2X              else ]WJ3j]FJ [ O
                 return 'E';
"W&kG-?"D LBv         case ')':
K(VwF y              if(c=='+'||c=='-')
%JQr[ p                  return '>';D1V^d'h7x^
             else if(c=='*'||c=='/')q's"T$s{ [y3VQ
                 return '>';
e4D*u\spO p              else if(c=='(')
sY~.EJ                  return 'E'; Q;JnD@^:tx
             else if(c==')')2i-hb0`1{fAf
                 return '>';,Ln9M|p1?l,W"Lz1a
             elsei.Ep(EW3V i
                 return '>';Zzq:Ol*q N.~
        case '#':
;Ai'k}3JIQ N              if(c=='+'||c=='-')X-uJKc
                 return '<';F-c;cGEN9Usc!a
             else if(c=='*'||c=='/')'p Z s)o5gM6z l u
                 return '<';
txk1WD y              else if(c=='(')
p GI6a X {^S$Jy                  return '<';-Ee;p7PI9~.G
             else if(c==')')B#M`sI3z
                 return 'E';
#u$uy }Fcid              else
6he4WVS8F&x                  return '=';0}.wCY*igLfa0D
        default:
P1i!bY dPua AO]5L              break;5dF9vMLU7[rC(q
    }
%OL;V a)E     return 0;   
-a7s$tN#TkVk|:K;W }[;n5?'jQD| [9g;T
j ]*ub R
int isOpr(char c)+J^vNQwxx
{
bRo(p!l9De#U1X0X     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
p @[B'zU yjB7z?         return 0;.rHc5w)P+B S
    else e7^o `+r p VF
        return 1;YN%g}YVr
}
-a.I0ww^#{ k:p
FZ8l#^ cl float operate(float x, char opr, float y)
0o/jD-Fz k%w {wo#X @4m*v!k
    float result;
2T]Vz/\P-m     switch (opr)
Q#[ z'@8Z%Ls/@t7E     { i8b3aH dLF
        case '+':
m5r)e.C!eAM'C?5d              result = x + y;3}]6S'pR*B*cUN/[8g
             break;$GV {v)G-t!y9`
        case '-': +h7r#J+R/Vb.\z
             result = x - y;
D6XD4f/d1[              break;8OcS~Q"V"i(?I
        case '*': g t2g]J
             result = x * y; h a z`;?t
             break;
;Q} PL HdA9K9oN;r2P         case '/': $az8T]:K5Oq7r4a
             if (y == 0)
%Z_x7S*S-@i              {
P&d8{.v3QH \(y]                 printf("Divided by zero!\n");
7hxPz1|2w!_5d1PO(w                 return 0;
#? X4PM6NY              }
(}7D1o8z{9^#SL              else!V'| L&komB
             {'@4eYfsuY2a1n9?
                 result = x / y;
r F5e ?Dc I                  break;
\(d"o&KP{              }7Kcxw*_!U1{"^
       default: (]M K8?+?2V
             printf("Bad Input.\n"); g"Q'H;S c~z;D+z.C9a
             return 0;B#l&d3RhQ0O?
    }p6g-V}A7?e L/G
    return result;U0uq4S(q \b
}    ,\/N%sV+b Z
;W AW/z ?6Ko]
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
6LJ5AtB#{e5n7Lp {GRfn)f!],Xs[
    Stack optr,opnd;
@pF6|2cH4Z     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;[E&~ E(F.eC3dq
    char c;q"^-Y-s3Kj_
    char buf[16]; yl5DE5F6E
    int i=0;
xfF Ug W-b;J};p#v    
&h H5}R Xa}z     InitStack(optr); /*用于寄存运算符*/
H\6i]q7dG     InitStack(opnd); /*用于寄存操作数和计算结果*/'g D;fWJ*z(Ui
    memset(buf,0,sizeof(buf));
o;{m.Eq5Ga"}A1Ve    
]2li BG6Kd     printf("Enter your expression:");
CC$M6RBz1K2b         5t$b.O]hm:r eq8N4XY
    opr_in.ch='#';
Il5h*]6T(?N     Push(optr,opr_in); /*'#'入栈*/a'oHyaS!z
    GetTop(optr,opr_top); LkM%kk:f)L/F'W ?
    c=getchar();
!v4FV0Y UC qE]E     while(c!='='||opr_top.ch!='#')%{C6qD6cU%L(it
    {
&J s d3{Ief         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/6w7y7^?.K5d:NAC
        {
k*Hq"Ao']             buf[i]=c;
q8xtw:KNWf             i++;@q2O*EO"e
            c=getchar();e@8ki"[Gz
        }
'U.X#Y[r-?,z         else /*是运算符*/2GUw mz v \
        {j7azS~(@!HF*N
            buf[i]='\0';
4tk;b@+P L/H             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
*vV p4X*^G5Jy#u             {
%w^'BUf                  opn_in.data=(float)atof(buf);T(I b+LE"~F1b*O
                 Push(opnd,opn_in);
m`D^BLd                  printf("opnd入栈:[%f]\n",opn_in.data);4u1Q S8c6H3T5BxG
                 i=0;
{W}oU be                  memset(buf,0,sizeof(buf));
w#Q O MR t b2o D0h             }
)}2C4pzh~d*?M             opr_in.ch=c;
0JJi#L/?v7K.q             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
0h4Y1Ap#AX5yP*]             {
0JG`-E,zT                 case '<': /*优先级小于栈顶结点,则运算符入栈*/kY$mj,d;q4]]N
                     Push(optr,opr_in);tv!gC{.`0Eb
                     printf("optr入栈:[%c]\n",opr_in.ch); ] n0JDd.f v
                     c=getchar();*hxP'g%a*~!RB
                     break;
+Z4M h$I6\$k8{ Pk                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/j0_}#f7xL~ i)v
                     Pop(optr,e);
W+Y#_$V*C                      printf("optr出栈:去掉括号\n");
RJ7o?5tQ                      c=getchar();n0_&s~^#@] aI
                     break;
|Y#e |R                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
J#Mh2z'E`Kbf                      Pop(optr,opr_t);w*`QWgD.Dx(S+b
                     printf("optr出栈:[%c]\n",opr_t.ch);
Z9py} X&{P                      if(Pop(opnd,b)<0)#]] T3N8m:e'\uV
                     {
~ n c%S.q                          printf("Bad Input!\n");
dvd;~ x"~%_&x)W                          fflush(stdin);M0X3OJ)l%xx6M2G L/X
                         return -1;
+M_*\ i{3F)r                      }
&v*W;j\@L;N?e                      printf("opnd出栈:[%f]\n",b.data);
+No)kv3Fi                      if(Pop(opnd,a)<0)o`|f f
                     {
VGdI:W,_+Za                          printf("Bad Input!\n"); R;N6V'J3l Wr1U-^+h*Sz
                         fflush(stdin);
FF w-L ]4jW                          return -1;
,s4W-@pl8U#Dg3{                      }
n/u5h-Hr-\                      printf("opnd出栈:[%f]\n",a.data);
i x:t9}$SB5lby                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
'B0if|F%\                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/0te*}-id0t1g%K r
                     printf("结果入栈:[%f]\n",opn_tmp.data);$k ~E2BBe,B{
                     break;*i \|Q2@+pr,oc&n
            }K%XA yG[5n
        }bzgefW:?m
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                uFX _;d7P;U'Il:aJx&R
    }Y {)Z v@6R#@
    GetTop(opnd,opn_tmp);i{!C{ ^;|z
    DestroyStack(optr);-lzK5a4Ms b9v7H
    DestroyStack(opnd);
N@ x\H%m     return opn_tmp.data;/S2b&e7FL#A@?
}.rNW,Y"s#J

@6x@8JH?oU[` char *killzero(char *res,float result)r$qDbk:o
{0T`&SF D
    int i; St)^8v2V#FB
3uC s5tH~y
    sprintf(res,"%f",result);
e_0EY hD/s     i=(int)strlen(res)-1;/I ~yq|]0C^i3k
    while(i&&res[i]=='0')5{zkn} I}
    {Ik7c W"n/|R5V$z
        res[i]='\0';
-}0@8Y0k+Hy         i--;_.coe4D`:s3k
    }zR o%ok%`\gx
    if(res[i]=='.')
/SmL'fxKr1]         res[i]='\0';
$q'}&y1k$cM/s     return res;
+s;@2IT8K_ }
(T0_[6? Qs5x RC*f NW c5r
int main()Vv kb T)E&A9L5xO
{l9D/R$eSv
    char ch;z.C5o4@@UY
    char res[64];"H J*gVV;eW
    float result;
e%GB4[l;] j!o w A [     while(1)q)M;~JO[
    {
:rD E#g*_r0^         result=compute();
#Ps+b_/z6o         printf("\nThe result is:%s\n",killzero(res,result));
Z,]n1F.]N         printf("Do you want to continue(y/n)?:") ;l/uu#BMh.vv\1d6n}6i
        ch=getch();
s } m4ZG\a         putchar(ch);&ZdQu;n Ml
        if(ch=='n'||ch=='N')5CK vs+NM!h/~} M
            break;
x|Hr,V I+kz(m,Z         else
Y b_s5\(x-V             system("cls");
(SV'c y&E }s}     }I8xd3a/C&`;~N'I^,Q],K
    return 0;
_&F^%tF_$El }[/i][/i][/i][/i][/i][/i]v)`{3Q/U#xL
f:N'i,Ub}8xss b`
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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