捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. Ji~)O8UI
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
6[@ p[!j}J+DH^JZ /**************表达式计算器************/X+|.xHwS:E
#include <stdio.h>
:}v8T8y!_I%ffC Z+L #include <stdlib.h>
o4sI%o1q)_ #include <string.h>(ep-L uU*yo*mL;C T
#include <conio.h>
Ul \Uh #include <malloc.h>
ov k9b#In:h5c $x)gq w&B;a}@;D
#define STACK_SIZE 100*h+QSRq
#define APPEND_SIZE 10B9aT%zr-[Qz(S
.S'vMAa R
struct SNode{~Zf!N G
    float data; /*存放操作数或者计算结果*/
(~\+J] ly     char ch; /*存放运算符*/EN \+N%F&FK
};V&^HDJ9U2[
`/WXG8Y;q
struct Stack{)omjg3tPr
    SNode *top;
&^H`d&lO3[     SNode *base;
O%[5D0i1s l3U]     int size;6{h9r4m|6Q
}; Fq A$R+t\6gy

\(zrh+{ c([b /*栈操作函数*/ |:K%]n!YY1B]&\
int InitStack(Stack &S); /*创建栈*/Z0E ul(d Q n
int DestroyStack(Stack &S); /*销毁栈*/
&Y#[3?'U)LY L4e:B)i,{9FW int ClearStack(Stack &S); /*清空栈*/
b@4X |zo!h~ w int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
-w'N)r!g Y.I$n@-_ int Push(Stack &S,SNode e); /*将结点e压入栈*/
9o)ogH"?A int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/%};N$ruvXDI#D

%eQ&nG,l;CpQ u1k /*表达式计算器相关函数*/u-C ^i-_2DvYDP
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
F;EP%IftG6@0m int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/@:mzN\+z2G@ u+I
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/R}iJZ$A
float compute(); /*表达式结算器主函数*/
{,}$df\)L"_ EGxG char *killzero(float result); /*去掉结果后面的0*/
&f7?B,s K K{ I5w&CE Q3rD"}
int InitStack(Stack &S)
1B]IB9Qvy2B {}`5qX}fNh!cQ
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
$fGw `K v     if(S.base==NULL)(K+e'[,^ npn*n
    {Ef_#f]p
        printf("动态分配内存失败!");
^2C4xO7P _         return -1;
"h9yWM&[1v     })to2g{*phEuu
    S.top=S.base; N TF ]\w qG
    S.size=STACK_SIZE;
tI |0DW.C     return 0;
R y"os9F-X.\{ pl }(yE&D+n/]@

;?$?0A-R:[Q'j{{-u2q int DestroyStack(Stack &S)
,? ~ld5T {
|B^S _,^CK     free(S.base); ?Sy&t/E(w
    return 0;
e5D*t.S~i }? ]1U @0B2{+u

1R1k.RzVy:? x.@ int ClearStack(Stack &S)1Y.n?-Cd2w
{'?.Yv-ib.E;q c&l;l
    S.top=S.base;
e"~xaCn pzXn     return 0;#\d Z+W!_+Z7vs
}
p7Q3a-N%z
2N2|"q i0c*I int GetTop(Stack S,SNode &e)
w0{ M:Js:t B {c ZdrB9}*cF
    if(S.top==S.base)
F1q!s,[:Vk$K F#z     {
}3l _7t0y         printf("栈以为空!");/q*B+B"~1V%xN z
        return -1;
Z$m U7~ fh }(QU     }G1~3x'`4Y
    e=*(S.top-1);.r dn;\%s7o7{%N
    return 0;
Xh(NF.J)]}#u4Q9}+S!c^ C }
,QTQH/k
7sp(o(zW!rbI:E"GM int Push(Stack &S,SNode e)
j;m%s8N1de {0{$qQ*rs!f
    if(S.top-S.base>=S.size)
,[B+[ ]'hiXU     {h$C,o3aE$~
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
!GfB?u.o$o         if(S.base==NULL)W,oo^'w"J
        {4g)\ w JiOCfGqC4x
            printf("动态分配内存失败!");b V8Ee,{2K0z
            return -1;
4`j)L9poiq         }
/C^'R].` T7\'w         S.top=S.base+S.size;
s,P;n6U+DJ0|a/X         S.size+=APPEND_SIZE;
0sv(v/s.F/U)^U$~,k     }4sxx8EG`
    *S.top=e;
?1k2m&i a;m?     S.top++;F7u8r do,F bqt.B1w
    return 0;
/}andslL0}e }
y&G1I_R'^D ko t-Di{Z6i
int Pop(Stack &S,SNode &e).{,DS&@c8W)`0D
{$\ r~QI`
    if(S.top==S.base)
-g%b/J.~1O@4T     {
4D6f-A~ S^;G         printf("栈为空!");[6^*Rl*\p}.b r ~T
        return -1;
p N4rTo'q     }t|Jn3H*~&LwO/X[
    e=*(S.top-1);0DB.?"qJK V9K
    S.top--;[4I Z&u,r0]
    return 0;
8DAT{ LgSXW }&`(O9u+j(v

'f1p]:c;Ly~/l;nP char get_precede(char s,char c)
^$v |0On!Q7s {
VQ ?;_6^ t%_     switch(s)+cWz#_'`X
    {
-M9e7nv6we.j         case '+':                 
]lrmYA&L-z0FE         case '-':
`"~i:}l3Ggo3D'`              if(c=='+'||c=='-')
b'~.T(b*D'n*N                  return '>';w4Z IP c+SRz
             else if(c=='*'||c=='/')
vD&F8VB                  return '<';
zl*o M^              else if(c=='(')
'|$a5ze5h(J2d                  return '<'; hJj T PAj}
             else if(c==')')QV&a*hB+d}^8I
                 return '>';D,Nn R X2j
             else (q1b$A{z4E$\;vV"\
                 return '>';
8x4kC u1``y+S         case '*':2U+z*lr(Z4wP4U
        case '/':Ia$H x?8t|
             if(c=='+'||c=='-')
0ISsQ/SW                  return '>';
yvXpI              else if(c=='*'||c=='/')I2HZ,`O9J
                 return '>'; [ c%^ XaD N6g5w
             else if(c=='(')
fz+m6r"cfZ%c ]l                  return '<';
`$YK@3S'i!]y              else if(c==')')
4a9H5O?W W                  return '>';
;`uZ!j2X9RMiqT k              else%kX%Sj#qN
                 return '>';
m7`1~4Mnb1L!jap         case '(':n+a-SCq#fY.T
             if(c=='+'||c=='-')
3{2A.S O;Qg9[ _                  return '<';7p;|}(yL \:y L HM
             else if(c=='*'||c=='/')
t"FolI&RDR                  return '<';
P3E%WfB~              else if(c=='(')
)jO4t*Yg)~k P                  return '<';
R yO3Oh2J              else if(c==')')YPW{ e0Pk9N^1Wp
                 return '=';2F.w-]b@;x!A m
             else
,X s%~%}5n%b                  return 'E';Fi? pvS]:uU'~
        case ')': I s1iO:@9k
             if(c=='+'||c=='-'){g_J;d
                 return '>';
jhETm#wZK              else if(c=='*'||c=='/')
8R5E-v\R                  return '>';
8t D)V }3|3H)Q(Wk              else if(c=='(')
{9f)? S ]t#iS0aCQY S                  return 'E';
p2b!B oY3[0t"cL              else if(c==')')
n.]7mG8[                  return '>';
/qQ^Tff_*c              else
D+eQ&x T? a Y                  return '>';7^+{ s&I?&SH~
        case '#':5V/Q'jo-t
             if(c=='+'||c=='-')#ltU(G&WI#J
                 return '<';
*fG&?0D8z JBB6lS              else if(c=='*'||c=='/')7`e5a*}pp4`ot
                 return '<';)z1o/t H9q }B8xu
             else if(c=='(')JiT]Kl
                 return '<';\\E/e7AYVI
             else if(c==')')
DE3Z A|b                  return 'E';
2t.} M6M5x8x:lj"R,~              else Y%f _U'AUE
                 return '=';
'O MF9\NQ         default:
vYtqg{$nf!D              break;4F2c({ f5a(O[2I
    }
YZd%Sc:yyV%TI     return 0;   
HP:F:Y+F$R2P/k }
o xX Y4i(g
!?6?Y|~SlZ0[!p? int isOpr(char c)
Fc R k-H [/g {
7e+Muxrf     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
W9QB*tWO(s*cD         return 0;
4YM8N0OB     else 7U2|pe:gal8A d
        return 1;
K$Y P.nAm0~wRI }q0u4{*H.xC2d"Q
2eaqfd t@6|
float operate(float x, char opr, float y):tNMwf|QL
{
.FB_;^Q/m(K     float result; [9t"v-B^0[-TS0df
    switch (opr)
#^${$|TI8R }P     {
1O+xH;m^ }0S         case '+': SL i@C/~W!hF4a
             result = x + y;/t%d|:rdAG5G
             break;
t(V%vYf8C%s2r         case '-':
;yn%^;E/jW              result = x - y;I!^h`@5r/owAa
             break;$O.W2U#k)I7X)B
        case '*':
,m*wA}St'o%d({ Z              result = x * y;
0\ @"S"ci3[%i7@A0I              break;@\@w(D
        case '/': hg4OMS1n
             if (y == 0)
tMD7MVy S              {E%av o q `C
                printf("Divided by zero!\n"); onq6[o[1p"]I
                return 0;
sS*}g L3v              }5Q1H8Hh;k)df
             else
bRZ2Mk              {A6p?t m
                 result = x / y;
8w_7ljLY C0g                  break; Et/O&PP Jue(d&iV a
             }
4j,g"mgr o:s5]7czE        default: ,Ft\za#o`c
             printf("Bad Input.\n"); #J#N[L/H2q,X
             return 0;Uo{-@e }D6~#N
    }
(_:IF&F+fi     return result;
QSNRbp.L K }    mJc {y b

!zR,^5Q9LQjY\ float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
o?{cjgp {
1OlGFK\)~(E!^+a     Stack optr,opnd;T|6x}#W!jlYC|k
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;;rR} l"lM
    char c;1n!}dl ^jA
    char buf[16]; O-M5ky%hi G_K
    int i=0;
;S Er\:}3SG    
6[[Deo&? vH1r     InitStack(optr); /*用于寄存运算符*/
l5O6LpFO5B&F     InitStack(opnd); /*用于寄存操作数和计算结果*/:KG*R9M~
    memset(buf,0,sizeof(buf));7H0e7N(c0SWGw6@UE3y
   
n"Y'kV|w(^kl#^     printf("Enter your expression:");
E2dd,mKK:i8I)g*`?          T:d?xGQ
    opr_in.ch='#';
S7Y^$b/g#@p!K     Push(optr,opr_in); /*'#'入栈*/
V ^c5^0T,]     GetTop(optr,opr_top);
h|-AP1AJS     c=getchar();3C;}&s:r"Q
    while(c!='='||opr_top.ch!='#')V7t-iZ$c
    {
6^;ICm ~6TE         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/mWqa#IE#@5VCj
        {
K1X$g:m`8cK'^             buf[i]=c;x Be.d-LN1V ^f
            i++; SZ_4a'\ ^ jk!K2j a5_
            c=getchar();T:q#o$pIr
        }/N%um1F j
        else /*是运算符*/l%k6B&g8^6v
        {
,d+pCYe1gP8U7_             buf[i]='\0';E:j2a3]!R-kvrZ
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
%] X'_ {l]%{Q             {
E3QUg'W:Z+ft                  opn_in.data=(float)atof(buf);
[.R%G1f,l]"{                  Push(opnd,opn_in);
0h,V\1p xbUs!i                  printf("opnd入栈:[%f]\n",opn_in.data);
d5d\:m \6} wG a[!tb                  i=0; ?up1Zc2]c
                 memset(buf,0,sizeof(buf));
8hQ0]"ijt3A@-M             }t8~{x~
            opr_in.ch=c;i V {i P4m,l3Du S
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
!en0xG2P$wv/rl             {
1Q&|2@UH._                 case '<': /*优先级小于栈顶结点,则运算符入栈*/F0q Q/b vL6C$iw
                     Push(optr,opr_in);
.Ma;?h0aBb                      printf("optr入栈:[%c]\n",opr_in.ch);
&Y'DQ/ZWV                      c=getchar();?\0B k/WMG)n;Y"|0Y
                     break;wv[Au-I
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/9@-?1s1y!m-z
                     Pop(optr,e);
Nz^.[ Q/ef                      printf("optr出栈:去掉括号\n");uv2y0heQW%QoU
                     c=getchar();
,r-d;D4GZwvKR                      break;
8n(E1]\L h7zB                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/^$J$tkf4}GwnK ?
                     Pop(optr,opr_t);
-W/rC,J5i,K6K)O                      printf("optr出栈:[%c]\n",opr_t.ch);
p"iS \7[*q$c                      if(Pop(opnd,b)<0)
|(O'R$v \k9_                      {
#F/aE$_#f}*sD~2]                          printf("Bad Input!\n");
OpO'fYK                          fflush(stdin);
NcZ4h3b&_0x*rX                          return -1;
F&A Z#?.Y                      },_1IE!s6mt
                     printf("opnd出栈:[%f]\n",b.data);
AH_$? G(]                      if(Pop(opnd,a)<0)
@_k4SuM K8Hu7z}U                      {um4o9EZ `jg
                         printf("Bad Input!\n");+[P:[1} Z*g
                         fflush(stdin);
s$ZaY#I"ty                          return -1;
.S+\:kgl\"T|{ S                      }
\lxwo&K MfhF;y                      printf("opnd出栈:[%f]\n",a.data);(y Xr1At(Ft P
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/gvQ_X)_}9ZZ
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6Z$r }c#y6VK"O
                     printf("结果入栈:[%f]\n",opn_tmp.data);
f8x:q%gtsr J"o                      break;]+F5]R:W t6\'~
            }
-ReD1iaD         }n%@j"j8n9B6k
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                [ip.VL
    }
(s{)\^*E%g?"?     GetTop(opnd,opn_tmp);:p.g l*d6K*y[1Hy\;GS
    DestroyStack(optr);
wd$zET4P     DestroyStack(opnd);
D2[7h9oPJnMA0@     return opn_tmp.data;
]+CCED2[ }
L7l ok:]a:F
m0^L1y1M char *killzero(char *res,float result)
-S*\0i0ILsyf'C {M$[EgZ5~*F~ |"}
    int i;
J h!lX1b6QEq*Y V-O&z?G
    sprintf(res,"%f",result);bJ2l$d(S3Z]+n
    i=(int)strlen(res)-1;
/B J5V3T6Lu'r*[U     while(i&&res[i]=='0')
b bR@ys tR     {H|7aZ9d r WO B5F
        res[i]='\0';"Jw;Y$R(@o
        i--;:K B|~?n|8R
    }B$|E^"e+ig ]:S
    if(res[i]=='.') j;h\3At-{ v
        res[i]='\0';
/B;m;_n+P$?U     return res;
2k q aVG2NKG }
-]&r$o+i(P[]
EL h\x*\6f R\ int main()d6t-_N}
{.bFs.X1{3IqI}
    char ch;
8C(R;](i6~yl     char res[64];
9X+R!Qp;i4[(OH     float result;rH$T|Zp Ju
    while(1)
(MJ"F/l|0H     {
!\6bWW.k(Sx'U0T V         result=compute();
yM,~%R.bn/M)G-t I         printf("\nThe result is:%s\n",killzero(res,result));s-i_c/V6\J"ls'Od _
        printf("Do you want to continue(y/n)?:") ;S)a I1s-n/F5?
        ch=getch();t(N)Xz\b8Y[
        putchar(ch);,M&Zd``0b;Q5E
        if(ch=='n'||ch=='N')
rV)Uq;^UXT)~             break;
7n&KwI@%pc         elseu4z0b jO8b[*e+q
            system("cls");Q s@H{7xF [@
    }
^}5}yV4f     return 0;/fn4juB`1~_ m
}[/i][/i][/i][/i][/i][/i]
YwhUy
YJ,k5T$|@2Cl-[ [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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