捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
xUL3Ff!X 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
&F(a"e-G'x5H;j /**************表达式计算器************/&K\ny%o'@
#include <stdio.h>]JuEk6T,c
#include <stdlib.h>
ly8e8E)k`0M #include <string.h> aX Upw$n*i
#include <conio.h>
%E7U.f4L o$oD D6C #include <malloc.h>
*`/_;E-ma;k\
6nUF&eS:Z\ #define STACK_SIZE 100
8|h"kE(F$VT3l:L #define APPEND_SIZE 10jH}!e-QG0Y{\F
%p%U%j9r}i}L
struct SNode{
&Zl%q]V9U o,[j     float data; /*存放操作数或者计算结果*/Q^]M s,e
    char ch; /*存放运算符*/
)I4S,SNR-[` };6_!V$H,a-e?

{*hj @mfF struct Stack{uK$R#F!Hg
    SNode *top; H Ya ZF'u
    SNode *base; ~c4e"dqUT+n E
    int size;]:^9F(Q] a
};0rFlQoI/Wc/v
%{+E0G2dE}3T*^C
/*栈操作函数*/
Ii)A%K d| int InitStack(Stack &S); /*创建栈*/
Z*z,E6{c)^7a int DestroyStack(Stack &S); /*销毁栈*/ ]1Z+Q[sF3}t
int ClearStack(Stack &S); /*清空栈*/
SKc?.qJ0O int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
7n-`8gA'Qu` int Push(Stack &S,SNode e); /*将结点e压入栈*/
#_V | S$] QE int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
n xQ\C/K 2r5p |IIrP?
/*表达式计算器相关函数*/;k(U-R;bN(R6Tw
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
P"uw eI(R*hK2I O int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
bJJ'd!|8T LuH float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
&p jw(L.r/B float compute(); /*表达式结算器主函数*//fH~@,Hwj
char *killzero(float result); /*去掉结果后面的0*/ $BT4}x"RZ.s5h:~ @f
8Ih e6dc4{6US
int InitStack(Stack &S)8H"klpH3E p#a9n
{'F1N{KT$dn
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
o Mu+T&I6xAe(t     if(S.base==NULL)
W"W4Z j'@;c1g     {
4i!^aWq\2UT         printf("动态分配内存失败!");'g9vh%u"d!l}
        return -1; s4G[ Mx2@.w]
    }
e1V/_5M$Zn*gI     S.top=S.base;
q8l'j ms0rP;{&^"|W N5D     S.size=STACK_SIZE;
\6ht"mxr     return 0;K1c MsL7M
}
.?7Qe&S c Rwj
~1CG,~2^0C'c;S!C int DestroyStack(Stack &S):l5[veP'E\*t;G
{
?,};g,q5Z4`\.E~$_     free(S.base);$v%\ e6{w {"[?y:f
    return 0;$\DLg f4s-J
}
jC2?l-^T2mu 2g&s^&J\Me#D
int ClearStack(Stack &S)
OU0bv5Yk {a3zz:k3h6^
    S.top=S.base;
k4\ F i7YU     return 0;
:[G"n0U:\&V`P nk _5M }
a3Nga1Kp9`
6g+g3t-{z9W8kB@i int GetTop(Stack S,SNode &e)
&pE"\ }9g^M(w(|,u { @/w^o,Dk7`_8U$X
    if(S.top==S.base)]8L:jPX$p%n]
    {kY Dq?4^_,P
        printf("栈以为空!");
!w&YY.o%m?6L         return -1;
*}TTr{T;K O1C     }-_-}OQZ;g
    e=*(S.top-1);
C1N*{5z+]:n-Lb ^     return 0;
hQ;]7` WQ0AA G }}Jyyy1QP

H!k kad-v"om int Push(Stack &S,SNode e)
SXK?:j*C1w:n$Q:~0M4aur {(V'q?~bcc
    if(S.top-S.base>=S.size) `:A2Ao h O Q\{ aH
    {%_8H^M:q:`
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));.hV sn\:c-O*Kc%N;S
        if(S.base==NULL)
9n5il0a6aT         {b%|n$^%mI#rrN
            printf("动态分配内存失败!");
Q G;g0C[!aE             return -1;
2B6bu'T:l v,NT         } B$h{$FO!uT
        S.top=S.base+S.size;;@\qL$Y G
        S.size+=APPEND_SIZE;
^o+}:^ZL)g     }
{8K7V2k#Rf     *S.top=e;
_ bkzU H2^     S.top++;
.d1\8v R {*Yrb     return 0;
*Xjz#lhfsY }
e9AwR(tGi
L a^UM-L8t int Pop(Stack &S,SNode &e)[{&Mz9f/@h.cHK
{
F aH!va8L     if(S.top==S.base),G e~b(y)B&R(z
    {
eI Qr Y%n         printf("栈为空!");t[C:I7^lM#n
        return -1;X5~D c,ldX
    }
s u P&u$At)m E]O     e=*(S.top-1);
"y`;E3Cvp[-d     S.top--;!\'xpHP
    return 0;
_G!p-R ?!sPq }
d*S O[4k'c'V,H:hG .e|o\4@?
char get_precede(char s,char c):SG.sG+m `#gk
{1G!I"P$[ o9y
    switch(s)#[Fi)Fh&jbIo
    {
W.Wo:gu$J         case '+':                 
S6wF,gPUyY8?+o         case '-':6TgJ;Y:cJ)Y
             if(c=='+'||c=='-')_H2bYL~C3Iz
                 return '>';
l5k0](Vk$Z              else if(c=='*'||c=='/')
I8z*b U'udv"uo                  return '<';|5lW ?+U*p
             else if(c=='(')
M9}Q(mf ]Iy*T                  return '<';
T6f'j6Xx4IRI)| U              else if(c==')')fFd/qE4IV9F
                 return '>';
w x F8dIb8hw              else 7V~9t,smJ.y
                 return '>';I.j2r U!jf]QL
        case '*':G e/^ KR&V7@6e[c
        case '/':
4hpl;NZ              if(c=='+'||c=='-')w0U2k.c8h!\P3c
                 return '>';
0k%rva#kY@              else if(c=='*'||c=='/')
rP/d%T e^rW6`                  return '>';
C"I:E\R s-q+Bp B              else if(c=='(')
!eY;`$?W^ q                  return '<';
-[^)S4B-H O              else if(c==')'):@_3hNB+F'M
                 return '>';,j$sjIBO9x
             elseXQ9x8a%rg\} J
                 return '>';
Y,A-RGm"YH d+v         case '(':6a.lcc | M
             if(c=='+'||c=='-')7^)DV\*DX!]
                 return '<';(Dm}-W hE"K'xs
             else if(c=='*'||c=='/')
] H }5~7V9\,J                  return '<';2BNh\4cW:[ l-^d6`
             else if(c=='(')&V:q\ Hb:\-E
                 return '<';
{ s i&b:a`Fp!}[}              else if(c==')')
7^_9Yq}L| ~qM                  return '=';
9_9? e-`O3p              elselcl7l&g
                 return 'E'; @:Y5`b R9w(r&] a
        case ')':PQ}uFYKI+W~
             if(c=='+'||c=='-')
k6K"Ke}Y%y                  return '>';cb'g?3g;E
             else if(c=='*'||c=='/')#?:KX#l,gn
                 return '>';
)?@.J?*T+X#lKk(x              else if(c=='(')S*H f?+n c
                 return 'E';
H } d,~'E ya/D ` |!h              else if(c==')')'S{'~3](VL,~ G6y
                 return '>';
q"["d2\FK1[              else
[8JMdp.q V"z                  return '>';
@.tMt&e#Z         case '#':E7iQ4~z#a
             if(c=='+'||c=='-')/b Zm&al n2M*F
                 return '<';
G-F](C*wKr0m3[              else if(c=='*'||c=='/')
"v,K q;H+s] Zy U                  return '<';
iVv-@pF(LT              else if(c=='(')
sqR[*lA                  return '<';
kTEh0Y{              else if(c==')')
@7Cs0x&y j:s                  return 'E';
r8rh+^1\,?V+Fq]              else-TV!p'q+QV
                 return '=';
sbHFtV         default:
1k#d g _Q-ZK)~ mR              break;_3cRYN.I"`k
    }
:i(`I&bR;?hcw     return 0;   
&IT(v!p,R"` }iQ!D(^0[/[ZY-O

%@"{ Xk S int isOpr(char c)
US&HU6T jU+I9Cf-V {S U N,S5X
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') @ C*W#\!FL
        return 0;
o;F5f+gk&tr0O s S     else H jsmXb-A6I AY~z!~7l
        return 1;
8o&HJw DYi ^h }
^pYU PdJ a%};n Q uZ D8dM^
float operate(float x, char opr, float y)
*y`&yA)E h$r3~ {&\$|(_t.G l n
    float result; x0j;G+z.XQ7AF)L't
    switch (opr)@~'Bk.{ o0g:_
    {
`1J/iv.q2K         case '+': y4_ v,T#t
             result = x + y;/wbI7TRh y
             break;
j.h9Fa"|"v         case '-':
&T6a8T |)m3b              result = x - y;a4]4iM+kG#f@D
             break;
[7z:MPW%DGo         case '*': b-W$A[ dY(ox
             result = x * y;
/`A;_ L&^:YR9\              break;
}/J-}sr sE/nN         case '/': G@jZBM
             if (y == 0)
HTqi1n`w              {
9AS9~kn5Yz&I                 printf("Divided by zero!\n");b#a2DX \ C
                return 0;
wd)mE8`              }
4v&N(L eHR| ~:j9R              else
f\A5t}K,i h              {
cFUY9X                  result = x / y;
0c Ai!s?n                  break;
Np.yF VI%P"{h _              }f3HEWj:_
       default:
4b;F8txq.d,YR.z[4p&re              printf("Bad Input.\n");
#~4O7dl0X d`%G(}V-}              return 0;
/n e"sxE4{;_E     }
s4q,lgXX:pW#K9S     return result;
X\4Pn[ {N }   
J%|;^_:g8m4?L2Z _)f.v^ B/bm ?
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
-CVGGj+\~3f;` {
(^+D+rIQM%w     Stack optr,opnd; x(_/_7{T^k
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;E$yb ])w?p&i
    char c;0l;N3s0ShA C)P'R
    char buf[16];
2L}i {\o yx     int i=0;
6Txx(P3mT:u     Na0A7lzP,CU_
    InitStack(optr); /*用于寄存运算符*/!U:Y9I.N F4fR@
    InitStack(opnd); /*用于寄存操作数和计算结果*/
f;foQ _     memset(buf,0,sizeof(buf));
Q"jQy2C#t{     6J?{7K7TmC#W
    printf("Enter your expression:"); h vC)nS&|M^
        
| J.|d%Y'P(\"J     opr_in.ch='#';%x n#xQ?9Wm
    Push(optr,opr_in); /*'#'入栈*/
Z|?a7Y+W#g     GetTop(optr,opr_top);
%|O'[2B$H6\h0H     c=getchar();G+X$b@"I
    while(c!='='||opr_top.ch!='#')(R)i\ac'SMpf
    {
K p$V5_yP n         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
:yl]yW         {
;bAq @ ype             buf[i]=c;_8w"N{,~2Q
            i++;
9W3M0l!wDk%N"ui             c=getchar();]c#I+Z:U-w W
        }
s L2S2} JD~         else /*是运算符*/
\D\.D;u qvN r z         {[,M2r'M,~.ww| P \
            buf[i]='\0';
n O ])e[*?E             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
$bkQ%Cd%W1} }             {pK;Q+mE4j&[
                 opn_in.data=(float)atof(buf);
)OMz n$E#q                  Push(opnd,opn_in);^,QR%jif$g
                 printf("opnd入栈:[%f]\n",opn_in.data);
+k @ y'd!S%Zi%i                  i=0;.ss[a?-}
                 memset(buf,0,sizeof(buf));
p"}z%{1ih             }-e+i,rQ$E7S Ci,f1W
            opr_in.ch=c;XL3H)Ej!W j[
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
Y@ hS(g!i1SY#T             {"e!s0KsT2Xq E ]
                case '<': /*优先级小于栈顶结点,则运算符入栈*/#s/E&mF.U!O
                     Push(optr,opr_in);be7F8K7M erz
                     printf("optr入栈:[%c]\n",opr_in.ch);pp,^N6Bm(n/N
                     c=getchar();
q0b^g7b'q5S7w Xd                      break;"sV*G!mR,?6`
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/0x9FV/a&IA
                     Pop(optr,e);"\ ttZ8I*@Bu9g
                     printf("optr出栈:去掉括号\n");4_qCZP q/R
                     c=getchar();~5U:w3g1\y|
                     break;q)PV5pt,n2@ z
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/]hZ HJ X
                     Pop(optr,opr_t);gFn.rt-R0N7e
                     printf("optr出栈:[%c]\n",opr_t.ch);
,CpbXh!M Z5g-X a                      if(Pop(opnd,b)<0)
0m(G9wU!n)Z                      {Ho {Z|,C?j{
                         printf("Bad Input!\n");K't r ? ](PjD
                         fflush(stdin);uYI GkM9Y4_
                         return -1;
O$} B1o*x9L                      }
s;CrF)Q`                      printf("opnd出栈:[%f]\n",b.data);^i/{%H1S
                     if(Pop(opnd,a)<0)+{ \&}'o"`9Ka%~!U
                     {"d`;N;OC#o5T
                         printf("Bad Input!\n");Z)w ^7fpA E
                         fflush(stdin);
4rX#N*S9DUA C                          return -1;-A6y2c w;y.Xg|`}
                     }
@yt2@}R                      printf("opnd出栈:[%f]\n",a.data);9n6r5]"dphm
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/!J Zq;T}PuE
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/)eeN _z$a:h@)O@
                     printf("结果入栈:[%f]\n",opn_tmp.data);KQu7a;u_o
                     break;
NQ[*b4e([3Q'?\             }#[uTB0K
        }
-Y3vw#ggK6~bj z         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                wS-] c6m-{Z"DK*a
    }E#[&_ kd?8`
    GetTop(opnd,opn_tmp);
C ki[gJs     DestroyStack(optr);&F(T/T`?)p^ MJ]
    DestroyStack(opnd);
E*Se-b2B9qZd     return opn_tmp.data;
h$wL7QOe-}vw"[Jl }
M Z |tH)p0C(rw G,tF:K$N[ a7[
char *killzero(char *res,float result),j GqfIS yx
{[+r'J6a)t4l2X's
    int i;-N)g:Z#M+N

"[ lqK AsKhy KnT     sprintf(res,"%f",result);0i G8J-k&?8V
    i=(int)strlen(res)-1; A%CRi7wHH7g_
    while(i&&res[i]=='0')
gev m,IZ`UH7VE     {.k!b-xx| U
        res[i]='\0';ql"^C)O1x?)b
        i--;/J/I-r |1a"[ [
    }X5`5TFGf
    if(res[i]=='.')
#E i.Z.G Z|Ma*U&MP r_         res[i]='\0';
,fc+Yq SAp     return res;
x&[ P0p3|9Qc }e` ]T/w%{s8{
xV Y2Y3qYl#\b&m
int main()^&R"`;T9w \
{KVk w E-kq_+t
    char ch;
r-V x2wN~:W3R1u ~*^,`     char res[64];
k0e1e YW QY     float result; ui~D,P E G+bi
    while(1)*j(C!u;}"`%[z
    {e6sn:m5jC
        result=compute();
"H5S%O2mh         printf("\nThe result is:%s\n",killzero(res,result));
']M2u0ae_         printf("Do you want to continue(y/n)?:") ;8jN2gc e \f.OUr
        ch=getch();
MrhsK1m8Q(NF2f         putchar(ch);1kZr/q(]E
        if(ch=='n'||ch=='N')
yzE$S:YP             break;
D$D hphu         else
c m!E beU.o,v             system("cls");
,t9v9H)ls Mf     }2gjJ+q/~S5Z
    return 0;
!y!~)P)?zh }[/i][/i][/i][/i][/i][/i]
"kL]`3NNr0}
;tb9BOVNi [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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