捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.WH:OM$}[
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/En~5q R5D /**************表达式计算器************/
#B-Vg+GS}nX$c #include <stdio.h>1E(E9}+O ?)?9N6fQr
#include <stdlib.h>1Me%I*|*i/AKz G
#include <string.h>
]$Jg3bk(x #include <conio.h>
b N*a:m[v'g&d V #include <malloc.h>
V%EtK6u|Og+m g
1n+kqh0~l #define STACK_SIZE 100
8Sw4kF$Wf #define APPEND_SIZE 10
0e`;TTUh0z
8ig^7}` bQ struct SNode{
)J,wIQc}7g5Z     float data; /*存放操作数或者计算结果*/Gm z9Q5^,h)A$p
    char ch; /*存放运算符*/z j*?6TV+o+_*I
};
*Xn w*FXd1^OU Z 6}Qap7?#W(f6E }*A
struct Stack{:cP1w5t bM oT}
    SNode *top;
(S+lyi*Z,{ ]]&x)x     SNode *base;J0hc:[ C
    int size;
H `$Q.?fCo(K2? };
m#{Y xzW]"X ;AR7dt%o,C O:q
/*栈操作函数*/'B5{~i{F
int InitStack(Stack &S); /*创建栈*/
+L%F({4]BU$s%O int DestroyStack(Stack &S); /*销毁栈*/ G1_5[*_9r?L
int ClearStack(Stack &S); /*清空栈*/yl U}gbs/\
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
`8o(zm+l)S*m-b int Push(Stack &S,SNode e); /*将结点e压入栈*/
uknnt4N J5_ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/%a&^,]^/_)EQxY
9UB&nIi.IX
/*表达式计算器相关函数*/QG1X l2uC
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
A9dAr \0\Z!s int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
5u9SaUQ,x"O$t [f5Y float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
3}/a/v }.zZ]H4} float compute(); /*表达式结算器主函数*/
{^E:Bf@#Ot%{&r:d2x char *killzero(float result); /*去掉结果后面的0*/
6H(z)u._0w*H(Y !q,Zv9T}!K
int InitStack(Stack &S);t.I2{@Fp.w.g2R.r
{Ke `w1D#bCu~@
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
rS+VSq     if(S.base==NULL)Sm6EiI([E?)|%{~
    {
/vC9c_+A$@u6SoMH         printf("动态分配内存失败!");3S`J q-QIKrnFM
        return -1;
M"i3Dj Z*m     }
,lu3gw*a;]R8mNv     S.top=S.base;
h%u?1wb(?     S.size=STACK_SIZE;
^ h|@k/k#n:q8C     return 0;$m8C$n+~-U;e"? Y^+\
}
/FwebT .O5X{1we)H)G
int DestroyStack(Stack &S)!g/Fen| J2L
{{~4EN9Vx b T
    free(S.base); j tf%Z2i7l
    return 0;X8G(o W"TM w9K2HV
}
-n pp)|9]+O U4J Y.Wc3N6Y([+G6]3ubT
int ClearStack(Stack &S)/T J` l#k/d
{
,`5Z h:cmP     S.top=S.base;g&W/X ~G`!e
    return 0;jkP-t"Afk
}
/L:M,o:LR v Os.Jeq%b-v$sZ
int GetTop(Stack S,SNode &e)8E7i(F1xl%UE3F E
{%w5EZR2h}^(n$j
    if(S.top==S.base) f!g zy;m `4B7dpd
    {
?^;{A*gB]'BI         printf("栈以为空!");
6DP'N"IN} c         return -1;
hF#|-eZ     }:G_8GF;U
    e=*(S.top-1);
ed5O'o'{ ^]/q/[     return 0;
j&Y|FRl+dU/R [:jb }
HI m!fs7c2X4U4HJ fb zI5SK
int Push(Stack &S,SNode e)
|1U K8n0X {
[(R@u.M@     if(S.top-S.base>=S.size)
I7h'hSv     {
9g@ }b'gsj         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
d E8k/T:dc         if(S.base==NULL)M hKL*|-x(H
        {V HI0ii
            printf("动态分配内存失败!");*NWogt^ j
            return -1;
0R7g+w7xg+HBL*|         }
wg]6BV         S.top=S.base+S.size;kO:h F^h%s Z KMs
        S.size+=APPEND_SIZE;6_ q0FU sa
    }i+S-{b {X
    *S.top=e;
X?d)n/~/tx3^ s     S.top++;|:a'F%w5o.Pw.H"O {
    return 0;}}"D D-J
}
^ n$mbz
,e~W4~u,h[ int Pop(Stack &S,SNode &e)C4v:Z-vcOX[]1^5R
{3|T@;[Sw x
    if(S.top==S.base)
-j]FQ,w!W$F     {
dOjw5|         printf("栈为空!");
?f,L n0SX w9f]         return -1; ha!U.JmT{;n6|L
    }J,E P6o1L)BE{
    e=*(S.top-1);E/t p9O2_ HQ
    S.top--;.?V FEf$TD&f
    return 0;
G1?|/S^$i^ }+}C7g s.qU;F

G9s1BR qF.l char get_precede(char s,char c)
6s@l ?(qCr[ {z-] `!Kb
    switch(s)V _} ~}
    {&Xm9r L\
        case '+':                 #@tnWr\?
        case '-':
qC2u9]p R;o(d(J              if(c=='+'||c=='-')
_:PCzdA [                  return '>';
%keT$w \|              else if(c=='*'||c=='/')
Ji5A(D|%l                  return '<';,j0wx?*u p \S%m]3k
             else if(c=='(')
4[%xM%sE&C"D                  return '<';
q1?0CK&h(a8~;q e6Gr              else if(c==')')
_y TU |                  return '>';
@6}'w}/q[*tU7J S              else
X?"^bJ'D~7z`7@                  return '>'; |8_7E:|Bdttv
        case '*':
iA3lq8X U;VK p8H!y         case '/':b.j|t9d6\
             if(c=='+'||c=='-')
/PYd"Iq)B                  return '>';
0z%J*H6{(i:`o T~!J              else if(c=='*'||c=='/')
$j~"t e4A                  return '>';5Wds5q!U-b]
             else if(c=='(')
5GV:zs prb:B                  return '<';
:rh8DuF,Or              else if(c==')')
2W9_0lDK(pE                  return '>';
%tuk1v3Q%V1G'iZ              else
}1rsyT:c | K r*t                  return '>';
)WI!TS^0y@:O         case '(':
m/b,nYq?z9ig              if(c=='+'||c=='-')
Q3V5C R-H[ t0H}                  return '<';@J1id P
             else if(c=='*'||c=='/')+azF(n,H?.O ^x-i
                 return '<';
a%V8h![N1xT              else if(c=='(')
8g)eg `J                  return '<';B%im.i:XV I
             else if(c==')')E{-K8RXK+@
                 return '=';
7[(JuI-`$m!P              else
cXZ&AT2QPS                  return 'E'; rve @ T"^l
        case ')':
5c,S*~B0M V i              if(c=='+'||c=='-')
,h3b+b:l%Z,D!U                  return '>';-AUV:s{ Ra$hD
             else if(c=='*'||c=='/')*~%fQI!] mOC0OR a
                 return '>';
U$r0wKG$O              else if(c=='('),B9AGc `;VT
                 return 'E';
fkK+f A              else if(c==')')
-U i:SYvm1Zu                  return '>';g F$we3lP
             else
.sF h0R p                  return '>'; EG-uF2]
        case '#':
z'J^OF;\;G;F w~              if(c=='+'||c=='-') YN1_r3GHN5p!F
                 return '<';S;t JIYJeE
             else if(c=='*'||c=='/')
&w1OBW8Q                  return '<';
LA@? gA              else if(c=='(')
xn%r-jz                  return '<';
}av5Py1K3n+|7L,y+DA'f              else if(c==')')9P Yk$F&j!e0XZ
                 return 'E';y2{6n C J1?8ai
             else ol8qX.i?J)Jf"GH
                 return '=';
*su$G5p|         default:
,n.l7f;Y4a              break;|_ N[S?
    }RQD H5b2@
    return 0;    7iD1B:]JK:qY1Z
}z];ss;F~9i7E`

r1^\ Wz&U| p int isOpr(char c)$I6XfbE%FU1]X
{
U_2l(wbYo2|?f     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')c3O7a,pxc
        return 0;
Z6A7p$dk v_2J Iy     else
? eV1X2i8B AL         return 1;
)h-F'y/Geh nq }1U Gn5~w\6L
2h+x!r^2C I4|-P
float operate(float x, char opr, float y)
vG4s(|$\R {z-gsn(Y
    float result;
cvJU"R t+` iq)fcg m     switch (opr)[Zt?a#ZO FU
    {
M n[3Qc:Y@0B         case '+':
;~t*b.`Ut9L7R              result = x + y;E m;cd e`7T,bYd
             break;
r(Rt{ u4\+mt w d         case '-':
*_Je_;\G6b'Cb              result = x - y;2W6k l`2d*I7ODK)}
             break;
4M-{ q7S A         case '*':
Yg gl:Y4b.g:O              result = x * y;9[$L4[h0Qv6Z+^Y c
             break;]q@ [afP4ir
        case '/': 0xa]D5~%T8u@p\{2C
             if (y == 0)6~@E Y8P%{tg.[D
             {
B`8@R/{:T-i-F$K                 printf("Divided by zero!\n");m!A)z~}#n
                return 0;8QI1aZ9U
             }
;oJIB&|&S              else3vNUHk$XEH
             {
.glaaF(q                  result = x / y;+q Sn g`#eG.|
                 break;0zoKl$G/q
             }
,qdDrV0EX2T'r        default:
l2O/Ld/fp3t              printf("Bad Input.\n");
&g+Q!ix{ GP              return 0;P{I'F2S$o:U5II%y
    } w9v pZ3e-Yf_A
    return result;
I"K p.CghK(C;M }    z Xa:w?p$fS

FF6V|B9zTTl float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/| SBa qq:Yc
{
u*tT^}8d/Z#g     Stack optr,opnd;
gse ]??1o3l a}L     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;%wYB2o-M
    char c;
)`*h7bc2t$r     char buf[16];}A {K.k#u7TCM0c
    int i=0;
CoxGz    
B5C3I?T     InitStack(optr); /*用于寄存运算符*/
:d_x"~'?'MP     InitStack(opnd); /*用于寄存操作数和计算结果*/$j)kx!zpY
    memset(buf,0,sizeof(buf));
w7c!ct l/T1\y    
Kpm F%E)R,[.Z     printf("Enter your expression:");
\ w f`:K@^^-N+Zi^         y` c;o `$HO$_+OH
    opr_in.ch='#';q Q#}W:V'e!j
    Push(optr,opr_in); /*'#'入栈*/K3ZM?3Q
    GetTop(optr,opr_top); u-_V V'zG4n:B;x
    c=getchar();
,xu9b xtS     while(c!='='||opr_top.ch!='#') ?.j9U8Ly8QMt
    {
RO8f1Y~$b[.u,d         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
z^~ f}y9[TP3p         {
4vWGC#ZH:r             buf[i]=c;s,|h5z4s2[*k2h bj)qZ
            i++;KI[ ~/sU
            c=getchar();N0y t%Ku:n}1f?6o3z
        }'x2~DZ8C)M
        else /*是运算符*/
[k]6r*s"PD+G(^         {ol\&F3z
            buf[i]='\0';2}oXI"a+Eb
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/FL9Z.}R![9bm Q Q`
            {
6u y7z[5K)o~lNVKS ~                  opn_in.data=(float)atof(buf);
Vk V lxk"yz&n                  Push(opnd,opn_in);iB$l Xa(JMj7RB)I[
                 printf("opnd入栈:[%f]\n",opn_in.data);.VT&cvT
                 i=0;| \l)`P{ A} C
                 memset(buf,0,sizeof(buf));
&Q2` p{o2P ^:b[             }I&V$a:f-LKZxG
            opr_in.ch=c;
1XR0AU3t             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/T1G!u f"M W1t7u
            {
tj;hh I F`P9V                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
5Y X&@-h _9{                      Push(optr,opr_in);iemyO
                     printf("optr入栈:[%c]\n",opr_in.ch);D!\N_/W1IqSRL
                     c=getchar();r7q]q,U;zj
                     break;9{.qR/Gt
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/;x5n oNZ
                     Pop(optr,e);
/]7W|wf3s                      printf("optr出栈:去掉括号\n");'mH{+YS l'D,g'J l O
                     c=getchar();8tS)B8B$Aw
                     break;On+E,C6L%Thm,V9YN
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
,gn,r+{K                      Pop(optr,opr_t);
j ~5\8MM4E+Y                      printf("optr出栈:[%c]\n",opr_t.ch); Ii2B'd4k
                     if(Pop(opnd,b)<0)
b zUO!G]){                      {
,M$B0XJs Q1U;_!g5C                          printf("Bad Input!\n");1l4P ~ yl6N C
                         fflush(stdin);_3l1m/K v
                         return -1;/O R+uHeb
                     }
.c2Pij M mm1Y5Fk                      printf("opnd出栈:[%f]\n",b.data);j9\/sb;c]X
                     if(Pop(opnd,a)<0)
.DZ2`#_B;D:\                      {
7OyE9JH }                          printf("Bad Input!\n");~0p j F;[E.f4]
                         fflush(stdin);j `\IW+A+VK ]:{s
                         return -1;
+T5OKZJj                      }sbzq'|#v)csL!l
                     printf("opnd出栈:[%f]\n",a.data);
\n([8z2uA4V GU                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
[R2~F8@ n(G                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/Eb.U8uK9SxH
                     printf("结果入栈:[%f]\n",opn_tmp.data);
;V7@gV C2l:_)Xl                      break;R&x@)?"I(WLd
            } lo@\ky2s(~
        }
ww@%X*_5q0SK         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                PNwJ"Y0y&e
    }
i xt%~_(h     GetTop(opnd,opn_tmp);W L]8D#?l#L
    DestroyStack(optr);
C Wt#to5V,u     DestroyStack(opnd);GH_D"] l
    return opn_tmp.data;
i-lFZ1O$Q&X(x4i }
9{+d6n6w5R j9S\)N0F6A
char *killzero(char *res,float result)
qN,J a2NTqO7H {
x*em:k|(r     int i;
,h oCS;r*a^ 5Hb(p"ou y,A5S&j!P
    sprintf(res,"%f",result);
'\0uCgsu7v6W6|     i=(int)strlen(res)-1;$RvE(Up*U
    while(i&&res[i]=='0')
r&M?:I7}F8zh     {
,V;Vx}.X+H o/zs${         res[i]='\0';JJ K,f%L6S6u
        i--;
-sg J1r"z$C6L+Wzx     }\U"G X:Y6HGt
    if(res[i]=='.')
Z$T)I3D,V&k         res[i]='\0'; _*H+vc|^
    return res; A2H#y.i\ b
}D/oZ@ p{
v;VAH U:]s
int main(){Xd'r%_/t+e
{
4eEZY@i     char ch;Z#Y]l"qf'f7^
    char res[64];
f9g3b*^K4l'ua     float result;
]"r#C!k:LK9N;t     while(1)8F%cW6O%{
    {
x(u k9S4N/^e@ _"W$nJ         result=compute();
N(b$e1O@wA]         printf("\nThe result is:%s\n",killzero(res,result));
"LvitKT         printf("Do you want to continue(y/n)?:") ;
E VIz1U3T r_         ch=getch();
(bsq#~/{dZ         putchar(ch);
OOqX9q5A)p~         if(ch=='n'||ch=='N')
*t mB+lPw hv+y(O             break;
;jkqm;lJ         else3T n(FJ&x vuG2J
            system("cls");3y Z}Gl7GI f
    }'Q1Bb g}C
    return 0; _ qWDY9~ \
}[/i][/i][/i][/i][/i][/i]
h#_;y;_+s t8\U :e9N de3T,J
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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