捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.xJ8J,]]nw P+wJ9G
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
1S H'Jn'Jil /**************表达式计算器************/
g4H~JFv){-@ #include <stdio.h>
n2b.m[$D{/z#JnL #include <stdlib.h>
2tvYm:V|(SG1g #include <string.h>8~;p%g hT*z?&|6S J
#include <conio.h>
c e0AxyT&C)m'm #include <malloc.h>v8H+Zq5LO%O
w6C4l#k%S\3[V
#define STACK_SIZE 100
hkqJ.K#Hj|8iDG #define APPEND_SIZE 10
r"Iu9r'Or;r6EZ!]
&S(m/FX)o#ED struct SNode{
`nB5UJ9vms7g     float data; /*存放操作数或者计算结果*/H%C6V6W$E%p
    char ch; /*存放运算符*/a$n$m9A-t|#G$Ko]
};
c:{*m9G0|#xZA $In TahB
struct Stack{%~!IR{;V/u0Y ~dqL
    SNode *top;
i8On'N,E!d8JU     SNode *base;B]3u9x_*VxW
    int size;W/R4NXeI bNK9W
};
?OoQ5W `W g&u\
/*栈操作函数*/&oagHnPLx_
int InitStack(Stack &S); /*创建栈*/
6GA bD+P int DestroyStack(Stack &S); /*销毁栈*/_6N3^e,XOd!e
int ClearStack(Stack &S); /*清空栈*/
H I$n$?kt:Wg3W int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
DE@)A*pE s4q{V int Push(Stack &S,SNode e); /*将结点e压入栈*/:Zr&|&[ Z'Z
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
%P:H(h#xs3{L#i (i/p9BQkaLS
/*表达式计算器相关函数*/
zL I,PgW char get_precede(char s,char c); /*判断运算符s和c的优先级*/
v7r7i(Cg7V8u int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/cf'k!|R2n7Yz&B6E^7P
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
3p(Qi0g5gdxP.i float compute(); /*表达式结算器主函数*/ M$e}B$s!@O[ M*\
char *killzero(float result); /*去掉结果后面的0*/ T1Y}l} ],N1|

(J5KtNO$x NL int InitStack(Stack &S)_:cT |"n F6`CX_!q-U
{2i:c^e W3k+K
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));7{4VS%M}[
    if(S.base==NULL)
owa2u5K k;S     {3R'F:@*U3d6Y7\3\#e
        printf("动态分配内存失败!");)I_8W C(H6l4R+?7y
        return -1;8P@(@ a bl+]-e
    }b2H9B6Nf'frxE
    S.top=S.base;
o6d/@J-c)|+Uj     S.size=STACK_SIZE;8U0RB2r\(Q ['C wl
    return 0; N?i"cF
}fl1~zQ'NJ

^Q]G1ie:O int DestroyStack(Stack &S)0~&sbB-C*a8a8U
{
o#f1Y IC)B:[ dM     free(S.base);N3L\szSC
    return 0;
R/_ UvP }
@+x C"F {+q 0@V3X5Mr
int ClearStack(Stack &S)x,^N b%iy-?[
{9x2EJXNL
    S.top=S.base;2uD1hp:J/U
    return 0;
r*]gxz(b }"N V_*w%L-gi(X:D
.G:{M yo
int GetTop(Stack S,SNode &e)`\9_|-H SN:b n
{B7f1ZH7M5}
    if(S.top==S.base)nA%g0p1t
    {
yes&B1t&k[9P Q%~         printf("栈以为空!");m8XSD-L _ A
        return -1;;Z Ba(I9U
    }
;aZ#G{?U:H(^ a&}.U0V     e=*(S.top-1);1f"b.bCw_GL
    return 0;
S IU:cTl }
+[P\;_}J D9t.d
1{.Xm4q HwY$e$Cu int Push(Stack &S,SNode e)A5Mp dD3r3G
{:p8DX,~&tv)j7s1T#[9N
    if(S.top-S.base>=S.size) U9je U9w;x
    { f0I!K?s!n?TV$~u
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); GSP"Z.g {"v&On
        if(S.base==NULL)
[5k"W/Zo}ic6F M         {v(T%?LO
            printf("动态分配内存失败!");N1j|*O"}yXnB}
            return -1;C.v"l4q [A6mE
        }
9Z8o._V4ho         S.top=S.base+S.size;
V$N;N/Dh         S.size+=APPEND_SIZE;o3Rmp&nA(M
    }AH8u| M`P i/X&G
    *S.top=e;MhuUq l{
    S.top++;,}3g5e0r|wl
    return 0;
%F8Q.o#v1Ga:e }|Td._/j:v3iM&H
,T:eO)HS
int Pop(Stack &S,SNode &e)1Z*YcG{X.~
{sm |qh7jrv
    if(S.top==S.base)
c }&DY\ _3{8k q*t     {zM!h/R1M0\m#CvV
        printf("栈为空!"); e;Q6}j oC f
        return -1;
j:fIga     } Z:{g"O~CK8P\M2fv
    e=*(S.top-1);w%S qaV8K
    S.top--;
he)KyM}*s]-z8D     return 0;
J)|GFUP&wb)Ht }
+?? `TK:cr ~V~+I6j|
char get_precede(char s,char c)S_8K&{I'p/W8` m I
{4u.b@sH'uN#P
    switch(s)
\f$~}Rn5w/|     {
1o%c]"d5oB         case '+':                 +frv3C8\;omC a \m'W
        case '-':d(t8^"Sc y+o
             if(c=='+'||c=='-')
y$LXA9l}zW                  return '>';
v0y\#Y6~+^              else if(c=='*'||c=='/')
'd-I.HE'^Z?:ZW                  return '<';
}m8I#w}4~^1Z              else if(c=='(')
!v#|"Yh {m                  return '<';/t#W0~)fH gotP/\!|D
             else if(c==')')
't%p2T9]8\ e D$f                  return '>';
}Q C#Yx/J {Y              else
d/_ ?8Yr                  return '>';zt;Ci)bS C[6Y
        case '*':P_(w6y*Wr
        case '/':pu.k,p8kO9~
             if(c=='+'||c=='-')Nl!](V\+QY
                 return '>';)K"Yy-_ q'M-D Z
             else if(c=='*'||c=='/')
(^S0hV?8Dz                  return '>';
NPi_6bXZPi              else if(c=='(')
*y\.e)Nm(L h                  return '<';Jh@ yzz9k w$W!X%i
             else if(c==')')[!HJ mQB
                 return '>';"he*^^+C'bC$oX
             else
4uIv@6Xm"GD U@U                  return '>';`+ip.H)BsX
        case '(':
8_ l v&d9z#P`F              if(c=='+'||c=='-')
l.G H!r7X                  return '<';F^u6R L7f)}$X
             else if(c=='*'||c=='/')
o,?Sv,a`4o T8p$G                  return '<';'l]8U eYg
             else if(c=='(')
)u3~k+}{&\Dj(i                  return '<';6JPN/\$x*Y&K
             else if(c==')')2QBr&Z~D
                 return '='; fDJ3}uI-A
             elseBZJ.i!A6QO&Mx
                 return 'E';`,M3o*e[k&\w%r9I
        case ')':
`:? s;m,pp/h5Tf              if(c=='+'||c=='-')
r{ZD3T%X                  return '>';
5R mgt3li              else if(c=='*'||c=='/')
h?M1Eie$v3C0}                  return '>'; z:|&]S6hz V7j
             else if(c=='(')M0H5Y+JTQj!u P
                 return 'E';
1l5m4r}| i[              else if(c==')')p5D5J oa]8g
                 return '>';
;L(_(Gbm              else _ RrYf2Q
                 return '>';E8V?,X1A zU M Yu
        case '#':&p2{:k3I a] IO*LVqs
             if(c=='+'||c=='-')c x~)S*E"`H;onp
                 return '<';t#|{Qp#c)g5{ |
             else if(c=='*'||c=='/')mT|e%~
                 return '<';xR.H(K5v Fg$I!G
             else if(c=='(')
1QrWj#x~8x                  return '<';
b*pj1j1|*d6d              else if(c==')')
7S Z}$U,D7}                  return 'E';
V b*s,J F              else
BPri1L:tv m                  return '=';
l4n w3XKE'q         default:
E g SY Q              break;
y'UT&OX_a     }*|h2N!r^ w;hP;]"X
    return 0;    xR r X/J$}s2DDBL5v0Y
}
5E:T$f6Jb'_3E?
y,y j7BuV#xF5k int isOpr(char c)3d|+Nn6Yx
{}`v cbB ~j
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')6F1j;N [)Z
        return 0;
%dP9tpc7ph     else Ui9PP}'a8y$E;q5m
        return 1;
a!@5QO7w? UR%wv }
/K3d K'v5i
1@p`MM L*NB float operate(float x, char opr, float y)
-LRF"^P/w U"f9b M {
_5V MH K!o Jt     float result;
/uU2M _#xR;e[E*O     switch (opr)
o r!N^T;_d1M ?OG:bY     {G;^9^ qGZyV
        case '+': +ka:r8}6w]
             result = x + y;2r/D,Xk)V3@#it_
             break;
g+fUlJwv         case '-': u P"`i3}
             result = x - y;
b Fy$P vV              break;c-qBg o4J
        case '*':
bS5bxT9Df              result = x * y;
u#P,K M7m f              break;AvVLl @F
        case '/': W:Z)}~t$p
             if (y == 0)
4o0[x$Hh I1oeH              {
,uCs6}5c?_P                 printf("Divided by zero!\n");S8ii[FJu
                return 0;
oH;x|-_ I;x+j;~c;D              }
~4lP3V&@              else4~cE jh2zYMco"f
             {Lf_H6_-G
                 result = x / y;
MB:DM`5{*T                  break;9[X!NW2o[
             },d:HmPRKT
       default:
)xpjAMVN-mx#X%Q              printf("Bad Input.\n"); N:F*@kh&Iy g
             return 0;
E4ko)bL0S!iM4c5Z     }
[M oo5Q1k+~V     return result;HQ"j s+}0gim
}   
.u#pm$~w W(w;V&DI
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
pUF#Y0@c+r'q7n I {
` L"tYvEG     Stack optr,opnd;.CXDWiS{`1p3m
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;K[ TgA7D` GQ
    char c;
*Utu^c0| Tuc     char buf[16];
,m*Ycs8`lB8q     int i=0;8r&z xyG
   
8Rh6~2Q5qT2g     InitStack(optr); /*用于寄存运算符*/VPNYi
    InitStack(opnd); /*用于寄存操作数和计算结果*/ pj\KAY
    memset(buf,0,sizeof(buf));*[2U7N`N7V;v.O
    )L,x1MCK4@&Z!U"R
    printf("Enter your expression:");/M&P0PHv
        u~#e Oh;g
    opr_in.ch='#';7wMx/W4~8G
    Push(optr,opr_in); /*'#'入栈*/
.u})D9_#ref} H Nr     GetTop(optr,opr_top);A7Q&UK.x!{B
    c=getchar();
h2wTV(\F     while(c!='='||opr_top.ch!='#')
9b#QZ-O$k6[h)T     {
,O#o?7P^%Y2ZGs H         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
tz w.}p:H X,B4l         {&j:A5d1d+{1s7g#zL
            buf[i]=c;C!{bc-R!}7Q9I
            i++;V3HkVj
            c=getchar();%[-Tw[~~4i y
        }
M+U%n&I0@-h Z"q         else /*是运算符*/
zy&PmcJS         {L0m3e6k$p ^*gi'{|
            buf[i]='\0'; oD$Mz;n%t8W
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/,i ?$wFz*}!h[
            {
%Yl%TS@4BxIeix                  opn_in.data=(float)atof(buf);@Z gi%mgGY
                 Push(opnd,opn_in);V ku-?PX6h"n0C y$kDC
                 printf("opnd入栈:[%f]\n",opn_in.data);
KGUl{ }W+\%p                  i=0;[7J1|4tg$? YC l
                 memset(buf,0,sizeof(buf));
Vq;wGW             }1W1]4U,j{V3v
            opr_in.ch=c;5U8B+rT/`%\QZ
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/Ks q n`Y@
            {
[ C4t^O a                 case '<': /*优先级小于栈顶结点,则运算符入栈*/;kQq#YD5Dj9z
                     Push(optr,opr_in);
q k:Y&] ?"H                      printf("optr入栈:[%c]\n",opr_in.ch);
M8a/i!Vha\"I                      c=getchar();
NR&q~Q                      break;U y1J0RPu&du@%g'b
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/.N0{2DsCY-W?
                     Pop(optr,e);O V`+K"N#d ~S Yz
                     printf("optr出栈:去掉括号\n");8nO.LNu gjkh
                     c=getchar();
1{m Dm&j\;P                      break;
4^ w3j%@@9wt                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/hq(tI7c9T%m0{^?K3|
                     Pop(optr,opr_t); SG:qB?I'TmXV
                     printf("optr出栈:[%c]\n",opr_t.ch);
%]7v3e.hn_p w'o2E.\                      if(Pop(opnd,b)<0)b-v'n._ V[/I8VlQ
                     {6vu(R| J I&S
                         printf("Bad Input!\n");
t6Jl5jUG0a:e5[ \                          fflush(stdin);4?6t:j~"S:l`x%X
                         return -1;J,u!R;Z2a8C.uay6f3ZF
                     }
I\n(C \d!o'Z*R                      printf("opnd出栈:[%f]\n",b.data);
&B/|h5NI4^e                      if(Pop(opnd,a)<0)(Q7F Cg7g$dBS
                     {
?9SB oL                          printf("Bad Input!\n");G/XPC x4Cw
                         fflush(stdin);-OI)q+[Zj*}m"X6r
                         return -1;
*y.Si9Y)b3CuY                      }0U B_ZJheL
                     printf("opnd出栈:[%f]\n",a.data);^"M?K4p$nDHb
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/{6nB Me
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
-WfE/qc}"M                      printf("结果入栈:[%f]\n",opn_tmp.data);'cZa4K9iQ1[
                     break;\ mWQ6EX
            }
'ms1s\Qfa2~.d:S         }
vyu4B8Z         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                (tHY\5l1Ci/?
    }I*c*xa/D*P*U
    GetTop(opnd,opn_tmp);
0}9Ix#b&\     DestroyStack(optr);
_k.`:H?9v$Q(p     DestroyStack(opnd);
XA*\MUG     return opn_tmp.data;w\iC+G B(c5_{
} Nb@ tBl#F#o

,| HL7Y U H;_M char *killzero(char *res,float result)h]#{?6L9\2} j-_[
{q;B"a0kJP9f
    int i;6]Ul b{

7Z N9rDod/G     sprintf(res,"%f",result);#`2IW p!ak%b gT${
    i=(int)strlen(res)-1;
&i"Q4_c5~k!?4E"k+V     while(i&&res[i]=='0')_%b2h2p7O
    {
F(Ti4d'e/y~?B/\         res[i]='\0';1a)X{YL
        i--;0?"FP#g1v
    }L1c8yo3MCB\
    if(res[i]=='.')\zN0F`q$M5q.t
        res[i]='\0'; B)kw LP0h$s:_4i
    return res;
#HUE ]W4T,O }
X,Z2Za0[#Jv })H B[ t#`+A
int main()
{ cf2T0Y:j D/K {
2ic ziz8VI     char ch;
&SP9[ Ymd     char res[64];(gVs Hm;T1j
    float result;s8De0f!Z4L6K#Z'G
    while(1)
r:Os,Tj(I)_&@     {
Zb1G8rR         result=compute();
1gdhY,@2c Kv         printf("\nThe result is:%s\n",killzero(res,result));5SW Py9i(oT
        printf("Do you want to continue(y/n)?:") ;
xQ8L#H,r Fl         ch=getch();z-a4IdjaZ0_
        putchar(ch);$L @ ] y"L9H#td
        if(ch=='n'||ch=='N')Fh-?m;[x9\4U
            break;
Saf%{ f^v$T P(n         else
F!`i+iN6e             system("cls");
-y7Y X n VE6KXW'V5E     }YL?A/]MYo
    return 0;;G~n8\;x.V!V}-B
}[/i][/i][/i][/i][/i][/i]
f ? aflN3w!Z g~(w`x,ha*u;|
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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