捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
V(bC}9Ya 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=` yP+Z"|b*h2F
/**************表达式计算器************/$Y$Q+xnj:WN/j2^
#include <stdio.h>1f/qUq }f&I2Hm
#include <stdlib.h>O5aZ"^ _GM
#include <string.h>'@K d-nC {
#include <conio.h>
5L{BN[k2g #include <malloc.h>6I8X M)_S6q8h
9~8~0t6^ i
#define STACK_SIZE 100pGQ*Ft5D.H\#b
#define APPEND_SIZE 10
ynj:xT *FHj(eto)Q2S ^c
struct SNode{8?vN*p8x]2LDjB/_j
    float data; /*存放操作数或者计算结果*/Sq/K9[GF^z
    char ch; /*存放运算符*/;wII-n(h+^
};
;r@&C7m9]6\ ` x+v
JjCG`~ struct Stack{
#fm h2U$K,Y-^L1h4SMp     SNode *top;
*I9f^6x0~z,]m{x     SNode *base;
+X ?0oHu\4Q     int size;
\J A0f%r!j };
y"["OOl6M5y$e v2z8I LT4mS&O5`'v'w
/*栈操作函数*/?x;~2[ i ru
int InitStack(Stack &S); /*创建栈*/ Z0nC'ba
int DestroyStack(Stack &S); /*销毁栈*/
4Jd$PJ9j3[ \ int ClearStack(Stack &S); /*清空栈*/
J4~R,?*v Yw9N int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/M$RT!NS
int Push(Stack &S,SNode e); /*将结点e压入栈*/
#Kx F ^/a{.`:g!B F2f int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/G2M7D5ds&mhv,A:C#Z N

lAgh O$Z1x B /*表达式计算器相关函数*/9G i1ev\6~*m2@ s9MS
char get_precede(char s,char c); /*判断运算符s和c的优先级*/#f]t M$D
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/%`(mC8vue
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/\_5x,L[A o.K
float compute(); /*表达式结算器主函数*/0[8E]#qAXZzQ
char *killzero(float result); /*去掉结果后面的0*/ #?r2r1V'd#M/G
yXZ)DAV)E
int InitStack(Stack &S)
%hw\4F?$t*q#h {
!q?u3jyGDx5r     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));qa9X,d.Q~
    if(S.base==NULL)%jh3Z5R u;}
    {
W1NG2p.U2r5Z+jk         printf("动态分配内存失败!");vyI%U"dA4@r Q;S
        return -1;
4h7olYm+u%M     }%Bt;mj[b'u qT C.X
    S.top=S.base;
B(W D7WrZ0~     S.size=STACK_SIZE;xW'Y+Z7A
    return 0;q#c'QXy)G
}`K[}&{a p
.E/Bj;H,_
int DestroyStack(Stack &S):T!C9L-kU3j:`,d
{0Uke,i`-D4fTp6I h
    free(S.base);)^6yr{bf\a
    return 0;'en B.J_O|)}
}
D7DS [ zR cSu Z y'i5RgN-k-_
int ClearStack(Stack &S)
NIDUE%mc {R+s`,|yO%GY
    S.top=S.base;
u~D1Y$OV:lL     return 0;
-}!p%~mi8i/h/| }\s4G7R$ad
@Mpfe5NT/A-L
int GetTop(Stack S,SNode &e)
3J9OO.}9Y:m8V U%} {O)x9\6^2n3FkW\
    if(S.top==S.base)
9`'tQ*e.c     {
+Uic(y g ~5T%t$[_{         printf("栈以为空!");ZV+?oE(z1x$_k$?9fW5A,?
        return -1;
^9g?W.An     } U xt.B:zq;f
    e=*(S.top-1); C)bI"w(k;}1a'@
    return 0; fH2Mo\DO
}S}PbxFf'`

e4y!pVc%nq int Push(Stack &S,SNode e)
7q*V)YSl JK V/xU5b {3zd bnsau
    if(S.top-S.base>=S.size)
pFU Puv p     {
%s0ri]2x XhE         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));`C"W@#WG
        if(S.base==NULL)D2qOd~Hr8w
        {,^,p5?h3j_({7]4D
            printf("动态分配内存失败!");,M vk2[:rJ
            return -1;tiGIL?_&?
        }S%b4Z)w"~ e!|EY7R
        S.top=S.base+S.size;*]lu,Y7gN`1v l5J
        S.size+=APPEND_SIZE;e;^UF(T
    }
Z;t _\#m6e-QmZ1JH{     *S.top=e;J#N)C8A2~8Uv;d
    S.top++;
/X*O9Y#z8Z+J5|0TYD     return 0;
_ q0{:eH1\9I4@8Z }
`P+uF6? +L[-L|o
int Pop(Stack &S,SNode &e)8H#T S)jVGpk
{
1|2H.U Y@5u"w0h     if(S.top==S.base)
6B:K%v^]u2^     {
9I k{ \-}         printf("栈为空!");
2GO&u `+iV6]         return -1; ?-V1i] {5]|(DP
    }
1z9[_z9J2@*r!~     e=*(S.top-1);
Q$z6\2W!z(k[ v     S.top--;R'pv[4S9tv3x X
    return 0;
v/Eea Z+o }
mKb~9A~"^q
'DQVf/I H char get_precede(char s,char c)8]d%Ey)LI{ M7M c.t
{
d8Q5l!l;A|"kx     switch(s)
*R\5\l km+w hw-vZ     {
8p:P1T;u g0]0Q*x         case '+':                 
Fd2p6Y2xn? | N         case '-':ro V;tL9a\-L {
             if(c=='+'||c=='-')J(^-M-{(Y!S3cN8c
                 return '>';7b(g/Ehc"W nO
             else if(c=='*'||c=='/'))|7~{W+i$e'v
                 return '<';
6\ Gt,au6dI`-{1Ep              else if(c=='(')~a:~8tKQ\
                 return '<';1V4c'TRN nI(L@ EJ
             else if(c==')')
!_8Dy!T BHC                  return '>';.Ee6^i1j&vn @
             else
c:AkUZ                  return '>';
0_A5gf3|LA0X\         case '*':
/Tqb@z6H-bq[         case '/':
/Alv `w;Z9Y `?              if(c=='+'||c=='-')2Q'sD2O7N(w*r
                 return '>';Fp8gQ_7R
             else if(c=='*'||c=='/')
G rO/xN1g                  return '>';
9cE&aE t9w2U7o              else if(c=='(')
Iy6BO\ M s-l-O                  return '<';
@.U BjI*a2j/h              else if(c==')')
G9s~]JdC L&?'~                  return '>';
qnO,|6ws2i              else
TLFi:`7Z                  return '>';S?4F!}W!quG
        case '(':
op;?6Zv"m              if(c=='+'||c=='-')
C2XX%ja2Gp                  return '<';*LM/Z^4EH;g
             else if(c=='*'||c=='/') lcA6zk/OC
                 return '<';
p+_sjIa-v$m({              else if(c=='(')
-h^ H'vnnW-YD j m                  return '<';M4B:`'w*hq
             else if(c==')').h u$KBt-C
                 return '=';
j:E6T(Dl              else
9F)V lz-t5qkb                  return 'E';
8J"uj Y+yHp         case ')':
~W1~,Z"H\:D[              if(c=='+'||c=='-')
^7Ik2Yl:B1bI                  return '>';
o7PSrIq kvI              else if(c=='*'||c=='/')
^5J*e f4i:f0Y)x                  return '>';#Q;I6P+tx \:d
             else if(c=='(')1w(I_g%YC$N
                 return 'E';EH}oaaR O1N;n9D[8l
             else if(c==')')~/Y6?'u3k"}N v
                 return '>';"x L!jtA\6LY
             elseo_:o.a'R&~]
                 return '>';vc aI'~#daX7t h&k
        case '#':
8r-D;HZJX0D              if(c=='+'||c=='-')&K[4vy2A,B)e6YN
                 return '<';y} y9ak5kj
             else if(c=='*'||c=='/')zK JX0EAa~w[ d
                 return '<';
XS~nD @4d              else if(c=='(')
DQ p0P)L,J'N@                  return '<';
[*i&F&|P@9DI Q:S              else if(c==')')
6N+G}J6ev9U-zj                  return 'E';l!KB'tv;G JyYW
             elseEQfqFC/k
                 return '=';&Y$_mA | KI_N
        default:i!KNQ;B:I}
             break;
m1u(H['|e     } q;iO!{$D_"@ ]e3I w
    return 0;    9f!nI1q%kH `Y
}O%gVu8v | \

dfiF+b/hj P int isOpr(char c)
Q3T#X4nh D {!]Ov&q~A{
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7D7Hsh9I4k0~O
        return 0;
^ aN9e$wYr;X0q     else 0l-s@,_Z
        return 1;
4]%yEY C }rL vU M4r oU

W/i%h ] ~vE1h*GB5y float operate(float x, char opr, float y)
-x4Y yOtC-@!Z3rx {L6^6rxF{qn^
    float result;|\ah h3`y
    switch (opr)]kRVdq S
    {
;N@ h `5tYx`#\         case '+':
T"m/B0[&~+C              result = x + y;Hu H+A/^m{i|P.D
             break;"l2a gY!g:ej5a
        case '-':
2RV|`^8Iu0jl              result = x - y;v0Y%\tj,} zG%R5R
             break;$l-oDZo8j,Q G5`_
        case '*':
XC&`'t Z4B              result = x * y;
)b0ieI(T w p8V              break;lV*_[li
        case '/': CUk E4z5T!}g
             if (y == 0)
k8^1G+pc zlw$i              {
1q7g e]c0J$^                 printf("Divided by zero!\n");K7YKBp+v @7V
                return 0;
gf.s E6k u%O              }
5}K|s)N)S$zJ#z              else(S+h$J/v!O%j]
             {oWe8[/H
                 result = x / y;zm2jokb \i&S4d
                 break;
)H[ Xauj*@              }
{S/P jrC%C/p        default: %RcBPg'j
             printf("Bad Input.\n"); -a M5k:SOB{9z
             return 0;Rj1I m K+zq#X
    }Q Z8a(L5`4W(egx(ui
    return result;
)J$@ [(\| bcrv }   
/r7yYle"O#l2i9i^
_iQ4@}bL9uu8g float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
#j(^aB(n {Q U r{Er
    Stack optr,opnd;
\Q,fNw)sC2of     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
"l,G2{"` B/sRz%Y C|     char c;
7m)D B0ZH7{9R"v2^     char buf[16];
cTfc CDqZL"q     int i=0;9XG`/z^u _f
   
Fs(@Z7y|(P6n     InitStack(optr); /*用于寄存运算符*/!u I9B'D1M[(q r~ w
    InitStack(opnd); /*用于寄存操作数和计算结果*/G ~L"^8y
    memset(buf,0,sizeof(buf));
$tu9?OT     +o/~W\u}%Z;G8nd
    printf("Enter your expression:");
.mmZi/yU4r         
E-G5@&^E"@o     opr_in.ch='#';#Bqrr:V7}N#T
    Push(optr,opr_in); /*'#'入栈*/
*nf;px2q$`0mV V ^     GetTop(optr,opr_top);
7r/vl2P,YiZ.F     c=getchar();
6];j,J$?sF)`%oA)H     while(c!='='||opr_top.ch!='#')T+zq[qf7M
    {
/aB2ID c         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/rQL2`XQlEc:O
        {
goK7Az-i             buf[i]=c;f/x/P0k2^S
            i++;
7n1U-LXp;@Eft             c=getchar();,ls|)V0j&`&Sr.a
        }
L!c-txf+QC N0B7H         else /*是运算符*/
%\M7@T0|'V         {
)Y f3]/t-i&R,C{             buf[i]='\0';
:i/[y6N;AQ             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
-kc3h6o*C-j z,L             {
A.V{}-E                  opn_in.data=(float)atof(buf);h]Z&Tg
                 Push(opnd,opn_in);N.EDL;u/z
                 printf("opnd入栈:[%f]\n",opn_in.data);
Y6axbo?D T#L                  i=0; ad+k9l$R$o
                 memset(buf,0,sizeof(buf));Lja-Iw`9O
            }
1U2Eh F Qe[Rq{             opr_in.ch=c;
&Q0`8P-dtA,s1e2n&H[             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ ]S~!d,l7c
            {
r1Mr4Jd.BG                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
}#W BI"}                      Push(optr,opr_in);-eex jg
                     printf("optr入栈:[%c]\n",opr_in.ch);|nBNN_'H
                     c=getchar();
;RBVi5l                      break;
`9t{4IV9I3o#p;c                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/~!]8pE!Un1R
                     Pop(optr,e);
o%{7V.[1ywD                      printf("optr出栈:去掉括号\n");1m@M7v3M%R)c
                     c=getchar();WEv!eL\2h.us
                     break;o+[j8O Y9`%] y4D
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/Dl fXSi:`2p
                     Pop(optr,opr_t);;` iA9n} `gbl
                     printf("optr出栈:[%c]\n",opr_t.ch); @'NV:{JH Ps
                     if(Pop(opnd,b)<0)
B3i I*h8Q+d8q                      {
)fD(b,Q]*OC'_5zR                          printf("Bad Input!\n");9ZB;h1cqk
                         fflush(stdin);"c c P)[S,@^
                         return -1;
]2AL!Rs$h].tjv                      }t1G4y},D)b;V
                     printf("opnd出栈:[%f]\n",b.data);
a ml2r`2^t&J$?W5P                      if(Pop(opnd,a)<0)
yQEc,k,iN`                      {
9OgWAI                          printf("Bad Input!\n");;K_Y H"C+n*[
                         fflush(stdin);)?Xm0wM#^W
                         return -1;`9TT ^Y R#Ki
                     }5~b2@![id ~|
                     printf("opnd出栈:[%f]\n",a.data);
vs9q}#t{w                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/'`5t-X F#@tLo
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/{ gV2H5J}
                     printf("结果入栈:[%f]\n",opn_tmp.data);
*~|&EUg6nzu g                      break;:qqdA8g d5kU
            })jl]/dU0F(u'K
        }6c;wE n7J/oK7\`4p
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
I9_s*_"\O.Hwf     }
/L+W0Ey j.TQNE     GetTop(opnd,opn_tmp);
y0M`a\(kRG     DestroyStack(optr);
jh.?do"c     DestroyStack(opnd);V]` mW7WJ!u'm
    return opn_tmp.data;
6N+oECR-Bh8^{p"Z] }7s,^#P x,s8zH

9vWIrP a1I,N8Np&} char *killzero(char *res,float result)
4_ xh;s(B[ A$} {
2mha;Q9QTI}"]     int i;-SH)a [+Z C*zL
'Wx4la7I7C~.zb6C|R
    sprintf(res,"%f",result);
[Xtia f&e4k     i=(int)strlen(res)-1;
9? C%w;F1Au     while(i&&res[i]=='0')
0\)c.RQw2?     {$v;H[(O)NTI
        res[i]='\0';
!R8t`h#G G8z         i--;.ld;r.P#ct
    }
\,D7K ~G4_%y"[     if(res[i]=='.')AL1uYe:JS |
        res[i]='\0'; P.n~ g&P
    return res;
'`(j^(_*kR Er(}2i }
.h d|q2h$[.vH Y,h,NC'ct
int main()
&Z9D6GNm.l*mI { a(Ze-e!BB&D%k \
    char ch;
^1gP9Za,Tf7M     char res[64];
.Rm;u#`+xI     float result;!S+B KE)U } M#ekk
    while(1)
Pq!E-]e     {2j5Qm~%J&q\P
        result=compute();
VN9Nq GK         printf("\nThe result is:%s\n",killzero(res,result));1^jGi"e+rxF0A
        printf("Do you want to continue(y/n)?:") ;.ur.OsRI$d
        ch=getch();*|1EHL9J7kIw
        putchar(ch); qH$IAC
        if(ch=='n'||ch=='N')
E\Xp8@             break;
O(V%~u0M         else
b3J@W v\-]             system("cls");,CVx9V P s)D0o_7Q
    }!Lsu)iT]kP
    return 0;
d*^"Tl^h;n M }[/i][/i][/i][/i][/i][/i]
5~7X,y] BWb'LHQ
&M)xe oY4q [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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