捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.,q#vf"i yuwMB
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=-C^ F6m#c1SZ
/**************表达式计算器************/
"O*|-A&b Gme-I5A4Z6G #include <stdio.h>YZ]$[)QuR6i
#include <stdlib.h>
2JQ'cf)i&M(U6x #include <string.h> lr#U-} r'IJ U
#include <conio.h>,n6hCfm
#include <malloc.h>
J9E]4j8_[-K
7]WD2G-Y:`FzY #define STACK_SIZE 100"jA)g(x;CA"A
#define APPEND_SIZE 10FNR2s$]iY
z R ^'Qq Ud
struct SNode{
'_*x uS@     float data; /*存放操作数或者计算结果*/
,B;MA:K]'_ Fo Fo     char ch; /*存放运算符*/
&L1P&rx3E$Z };L0q"l0F-kb|

^7x^)|? x4Y'? b F struct Stack{
{$tl:\:b N     SNode *top;
xW`viO A/nb}     SNode *base;_#| q%WJ#F"N
    int size;x0~N!N3q/u?
};
4iH:]"V7[km
VX5f"H"O0]ak /*栈操作函数*/2bd:] YO
int InitStack(Stack &S); /*创建栈*/,C.E!]$pu(w$w
int DestroyStack(Stack &S); /*销毁栈*/,a I(b s-K+E;} f
int ClearStack(Stack &S); /*清空栈*/}l:SFh@}$D5bY
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
.K ])b_1z;B int Push(Stack &S,SNode e); /*将结点e压入栈*/Cl'L9z[].|
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/F&TX5b,q O2^Y
X%v VNzr#P
/*表达式计算器相关函数*/B'I9] ZWv(M
char get_precede(char s,char c); /*判断运算符s和c的优先级*/r6jWd3cYU^
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
U!s@PaR;G float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1^C.S*^cRF*e'tJ float compute(); /*表达式结算器主函数*/
4S|(m\ l1\3sma[ char *killzero(float result); /*去掉结果后面的0*/
Y*aIx-N[ 1k pU_+B G N
int InitStack(Stack &S)
9x? D,](Jy[u#?I {
E@cB2ky8X$dZK     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
MY I$E6tf     if(S.base==NULL)
3qN&Tb,k-D     {$u4F:gHvKsc
        printf("动态分配内存失败!");
2B xM M CJN         return -1;
{4qY hi!t,g$q-Q-]     }
l3aKRG;?,?;T     S.top=S.base;|'u~FqV/^/q ~
    S.size=STACK_SIZE;sE2wJ3w f[~
    return 0;
V:EV&[!_~ }
md \&g1pV n
{8l_3J-n{$u T int DestroyStack(Stack &S)
]-sW"Ut*^*B {
1Zwv m/n\ v @i LK     free(S.base);
NL iT1b4M!a     return 0;:Q-Fi:A7g'x/_.F?
}
GH g(EWELZ
{g jJms7DX j int ClearStack(Stack &S)_CC0c5}3\
{:E9}:\-K W x
    S.top=S.base;s/w3dAT^
    return 0;+ZwD|{3ycX
}
at|5?yx f h8z:ntb#I+k;s
int GetTop(Stack S,SNode &e)
&x5f*a-Ko#f n {U#c)h0E _#x ~
    if(S.top==S.base)B#gA%\;S-|-H I
    {5{'xY8Sa6?-h
        printf("栈以为空!");LE,z(N2G h ?&C
        return -1;5]Z/b9| U h
    }!sJ.?#KHCz*Yj
    e=*(S.top-1);d |&Kf1TZ\[#o
    return 0;6K j!O:woz#T3v{
} f*fH+DN#D

$R'M xJ6B.^1CO int Push(Stack &S,SNode e)E Jv)lf v kE
{ qjQL'ngv"r7K*i z-f
    if(S.top-S.base>=S.size)-J vk DR+X1p^ V sA
    {V^Q6^-o3b
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));2@%fm"d#~8n
        if(S.base==NULL)
LB:\d+pt3b2{? h         {B1@X6?#VE7Hn
            printf("动态分配内存失败!");0A7u2J*U*Ya%@Z
            return -1;{X9vqI:y|
        }w$r)jYK2y K
        S.top=S.base+S.size;
/_ r.{)CR3VR$r$hb         S.size+=APPEND_SIZE;ow,yh)\l#|r;pkFT#{
    }
q6xm`'DY     *S.top=e;9EcP0O#dc*z.pk
    S.top++;
v8{#i n~*Lcokl     return 0;
u_i!Vk }
x}L(XO-jAh,I
*|*G"n8{QBQy int Pop(Stack &S,SNode &e)
JBb"O \z {WBc s&OJ-r/y wy
    if(S.top==S.base)b&u@X,_0?\
    {
9z-T4H,F3w3S*k$q)u         printf("栈为空!");+^X9B"i4{ uT`#rP
        return -1;
H8kzP\     }
(r'oh,r&D*B},[F`     e=*(S.top-1);4D ?5y:J:K*p:S
    S.top--;%F1r7xHy2e%SP
    return 0;
L&b+iy+j0g N} }
\P[1@"p r+U4]ch
u5W xX*Lm%G;f l char get_precede(char s,char c)\SvXL m'GYLs
{~:v(}'P"H6U0V!s D
    switch(s)
~6icy I qDlcQ-C     {8vrL;X3V8E
        case '+':                 
mM/s&x@,WB[0T%a S \5r         case '-':
jZ3g'H ^r              if(c=='+'||c=='-')
/r WL F:Y                  return '>';!d;tY o+Q+P-q[-_s
             else if(c=='*'||c=='/')2Q7TA-o.KF%tP4v^
                 return '<';
%pF)E9P\'npQ*dG              else if(c=='(')
w^.d)rG.H-V9Yd                  return '<';
/~1Sj5x*?^/r              else if(c==')')
5?*tw7^7J,|                  return '>';
]&b3|@c;VL              else g3YD)a!w
                 return '>';
+cn;Ce f*mP9w*M         case '*':
8j#Tp;Iy0n v B         case '/':
iX?w P]Es,^g              if(c=='+'||c=='-')
:te.V9r RH1Y,D                  return '>';
sN*G#B] J              else if(c=='*'||c=='/')
5F2a0s0Y$cJQ}8u$K                  return '>';
|a kAHg              else if(c=='(')
~t7gf V$^                  return '<';E#b}ZBXGpg
             else if(c==')') M6_ @2E[0p{
                 return '>';
G;U/?`(Rx r4|              else
@C[K H                  return '>';WP,w#j;@*j^
        case '(':
M"og;t&N&O9Mkb              if(c=='+'||c=='-')
KXMA6_O,M                  return '<';
"E'dP!Ki              else if(c=='*'||c=='/')
t0G;Niy1t                  return '<';
8gt:W!dGF              else if(c=='(')
%F&KSu{ A9tP'\+I                  return '<';5q:]K$z:~$|\
             else if(c==')')6f#p DX7zfWP(f
                 return '=';
)?(KG(f5Se+c P`$Yd              elsep5r%D#R%O a~!~
                 return 'E';
&_b9sDtdk.@         case ')':
;s)U6Mx(b              if(c=='+'||c=='-')
Pw/jJ)B                  return '>';A.{|[};u2j
             else if(c=='*'||c=='/')
%@S E5Mc"n/D                  return '>';X v q'P$]@uFf
             else if(c=='(')xP3R/gUAEQq
                 return 'E';
0F:P!}| X\-l              else if(c==')')
*F^ v y+xy$Xr                  return '>';
u G7I|UdyP t)D              elseugw4b&F
                 return '>';
;R&An}a6LG G         case '#':
+}\+YO:f7H-g/Z(c              if(c=='+'||c=='-')
`t2Jo_&h'i                  return '<';
$D M'bPd_ |              else if(c=='*'||c=='/')
,zg }(t{J)~+H                  return '<';
/u!e/w:Ct,A@%e              else if(c=='(')
W\7j0W%y$C~                  return '<';
Y Bc"hc;Ew0R1fY              else if(c==')')
hwv5\Ii                  return 'E';.N9n0?$s,~0M A,PL
             else^x+L @&d"}i$H${&_8c
                 return '=';q;k{3VT?@:g%c:L
        default: D2c\3?+@*N
             break;1N+w;I#F9D;a
    }
Z@$u0b!_     return 0;   
'q9x2Qo8xl }1?6xEY%W:@wlJ1] ?
6Mu8Z\4r
int isOpr(char c);~#^*b tf1Z
{
],g;Zs:H     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')uzanV2y
        return 0;0_M ?-|_ _
    else .RWT9G6|~
        return 1;
'lN] A ^d@+aX }vlJbR X,fAfkb
2Pa\/CNAdS
float operate(float x, char opr, float y)6B9}2oLaX*M4{*[
{3yt??;Tm ?1Y
    float result;
8Qb$K%@8^/V+k     switch (opr)FE~w C0f)r
    {3wxU7M6}#]|5gT
        case '+': *l gYEv3AD
             result = x + y;"gW)f5fs
             break;
'{2gt#Zkt^u         case '-': r*X+Qvi
             result = x - y;-^S`:W8u+qYo(]1K
             break;
B\'i^f0~]         case '*': e`.O['I v
             result = x * y;
1T8?']:fa W{_              break; U:^%v)d%T odl
        case '/':
-c,t ^W@!O'Z Jf              if (y == 0)"`/Q&r.N)s2eW
             {
-V O0dC1V qy3@8F                 printf("Divided by zero!\n");
\%Hi&r$v.jZ                 return 0;
n"Zy-rMDoBJ              }8K|0on,G8a,zj
             elsen `+r }]*a
             {
3]a,u.m-w                  result = x / y;'FV#t e7ae#urXcT
                 break;
{&c7aT1X*Uc6`              }ev _7d`Dm{-@
       default: u Lg6s9B%{8[
             printf("Bad Input.\n");
0l$G4M&t9Lu/k              return 0;B&IE}.n/re
    }
@&WF's^ `     return result;+{8`%H:V'Pd m{
}    q-KtY"Wy
&F@!SM} Dqz
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
6@j4^M6o.^*]'f {0jB:lD S\-s3_
    Stack optr,opnd;Y:[)]pw
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;fX tF6d
    char c; V(zTpZW
    char buf[16];5Wm(yN'A/d`&z
    int i=0;z~3kO"N!_z6Z1o vZ9K`
   
2FBuO Pt`~"S     InitStack(optr); /*用于寄存运算符*/AA%P&PD$[
    InitStack(opnd); /*用于寄存操作数和计算结果*/$AZ \zCu:}sq5|
    memset(buf,0,sizeof(buf));9H ohrn8S
    ,yPGu5V]8{!k1u
    printf("Enter your expression:");5o_N ~6^})v!@o&V
        
1?&N y;@l.vvN     opr_in.ch='#';
;n_'`Q0\?     Push(optr,opr_in); /*'#'入栈*/
m7s st({"G0S     GetTop(optr,opr_top);;y7jkTC`C/y#x
    c=getchar(); aiLe+_+E
    while(c!='='||opr_top.ch!='#')0P1q'x;D.OWV}
    { }+V&rQD(mV_
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/c!o P,x+G"rt3~zvs0@
        {
5t] J0b0uY             buf[i]=c;
z)y@(fJ4W$^             i++;
A*` ~.B,q             c=getchar();
9]R8Y`o1h'w4z         } wC}'P3Tp }R
        else /*是运算符*/Aq1@6C.y#z w
        {$WvS-wC;Z
            buf[i]='\0';K0gJF YF,w
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/FM@5fHha
            {,^N!P4^ sF3N3|
                 opn_in.data=(float)atof(buf);NYV1vM|
                 Push(opnd,opn_in);4K%O-qWVo'G$@
                 printf("opnd入栈:[%f]\n",opn_in.data);
7S;I:AQ&D b                  i=0;
])J ]eg&e&YQz0{                  memset(buf,0,sizeof(buf));:Z,jI[4Z-q/gU
            }
Z0@3uk._             opr_in.ch=c;
)WR#fcE6W e z             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/;U1cF&| eF"_6aX5|-Y _
            {
VM9~0A\7H                 case '<': /*优先级小于栈顶结点,则运算符入栈*/cF${t2Ry @
                     Push(optr,opr_in);
D~ ~T/~A9}\U#_                      printf("optr入栈:[%c]\n",opr_in.ch);
;u2{dyg&I0hZfP`"T                      c=getchar();
(XugU$o8W                      break; I(w;r ~.C%C G&V
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/z S~f a
                     Pop(optr,e);
6v(e n7k'zuWv]s                      printf("optr出栈:去掉括号\n");
(x?E(x1_UC                      c=getchar();
Z4J&lX^n                      break;
+`&n_4?6Q vlZ                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/Nc1c rd+I
                     Pop(optr,opr_t);;u8\#i#r6w2z N
                     printf("optr出栈:[%c]\n",opr_t.ch);
nt3U!])RQ,Y                      if(Pop(opnd,b)<0)
1X*~ ^G9n0W2`                      {kgJ lKR t
                         printf("Bad Input!\n");nH"S+pw!s
                         fflush(stdin);"]/\W"Z#Lb#](y
                         return -1;%L^5`x6I5@WI
                     }
)Nf}]_zly!B                      printf("opnd出栈:[%f]\n",b.data);7cS9S'Fu-`'h
                     if(Pop(opnd,a)<0)j"l#CxN k$i!]7q
                     {
h)^-m~)Jd#Gq] ll                          printf("Bad Input!\n");
]p8@|Ah                          fflush(stdin);
UU;B X*_(iI                          return -1;FbT8C9d
                     }
/d*dT:k@Y/^                      printf("opnd出栈:[%f]\n",a.data); t{0w1k"M J:t
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/!k/Fzr^.V2S6cNf
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/;lyf%D7t7u2LZ1Q-G
                     printf("结果入栈:[%f]\n",opn_tmp.data);6w-TT2[-x!YJu5g|9t
                     break;1?Q A? ld+gj-g)e)O
            }{!C3w9A S x.j
        }
"q"D,V$I0N2@         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
;o6sl{If"}|p     }
F"h_#U1\"v     GetTop(opnd,opn_tmp);U3v Xzh-u$}6Cy t
    DestroyStack(optr);
,}/r-f? }8eJ     DestroyStack(opnd);k hc0D8q_j0z,D
    return opn_tmp.data;
\ Z3B"b,k8un ^8i-D }
(@XQ w@;so ]z 4F/] k3Va%yln6G
char *killzero(char *res,float result)
6S8U0lZ~/MOD {
(D\B$}A     int i;W6x9eL5w!Nj

p Xv$ga7BT`+qO2|(Lu     sprintf(res,"%f",result);M|.~(h3c s4[|yW
    i=(int)strlen(res)-1;
;XH;I ?U4]3s/x     while(i&&res[i]=='0')
IB'q'w&G%@c1G7Hz     {
`lx.X zD ZF         res[i]='\0';Tq'o j0TS~x2C
        i--;Q&~:G y0rx!q R quN
    }lNX1M;KM!l{
    if(res[i]=='.')
&V+H+tGZ ^z?b         res[i]='\0';B[%WU1Wk
    return res;
B5GonjH*j,f6A(Z }R'OfO Su
E9hog~&z"@
int main()
f B|/bgTt(k%] {3^6j[7jz S'XH
    char ch; nht/XN^iIS ~
    char res[64];
;l-xR-^d8q     float result;jB%B1q+nlo
    while(1)q_,Y['_pmGt
    {
-Tdh [ Xx         result=compute();'SD @u&u"L`"i
        printf("\nThe result is:%s\n",killzero(res,result));
WE2u R.NI!S VU         printf("Do you want to continue(y/n)?:") ;
:Bj]I.H;O*e`/Zt         ch=getch();
me2G1P0C2C:w         putchar(ch);
L?7j1S4\         if(ch=='n'||ch=='N')7B8j HF,J ~*U_0p
            break;
)D5K-{"o)B$_G         else
Hj4Am"N.t             system("cls");
2u%Xr[b,n)hS     }
ZV-j%D2e3E     return 0;i(}Vp]%X
}[/i][/i][/i][/i][/i][/i]
|d~.Xs
Z `[3W#o5k#V!_[ [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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