捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的..Cu!vP"O#S6Vd%d
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
:C`:mg8T#}p(?#V /**************表达式计算器************/] N^6}[
#include <stdio.h>
.i X"m^'Y9D1aR$? #include <stdlib.h>7NR#{P[*s8S$_/] cM
#include <string.h>2T3o/h*o)_?7x
#include <conio.h>
)D[pGM #include <malloc.h>n_}q-|c/|1Pu N

%T4cd(Q-bU'\ a #define STACK_SIZE 1007\;Z Y8wU
#define APPEND_SIZE 10
`6I2ZaD C"Q
-K7w@E0d5y9jI struct SNode{;eY[9I:j5\
    float data; /*存放操作数或者计算结果*/
rL"@jY^,u"]t     char ch; /*存放运算符*/
w4j n4H5y }; @ @3yi.v

eNln@F struct Stack{^{.?}q(y
    SNode *top;AE-oj2]T l
    SNode *base;
;uJ'c KG~/B5x     int size;
J#y aOUN(L6~ };
s/C)f;?$G4| ZO (m!v[6oHw p{
/*栈操作函数*/
;|-_5}/Wfk.j int InitStack(Stack &S); /*创建栈*/
$F6E)K4eae int DestroyStack(Stack &S); /*销毁栈*/:pgR.s@ \)E"b
int ClearStack(Stack &S); /*清空栈*/ Nz,a-RGG
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
ui^l B.U int Push(Stack &S,SNode e); /*将结点e压入栈*/5jZPQ TUP
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/7Q8bh$Cc
5d2~+rH%IM A f#EdW@-}
/*表达式计算器相关函数*/
z@E`%` t%X@C char get_precede(char s,char c); /*判断运算符s和c的优先级*/
S2T6jB!L}1K&} int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
'x'Ei*l:h*X"^x float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$vn8\Xs"z
float compute(); /*表达式结算器主函数*/
,i%Vuss char *killzero(float result); /*去掉结果后面的0*/
V{e A e.Om
.aqq$wVa] int InitStack(Stack &S)
3x2b4_8zQ r v { qt+O%Yg
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
!Y!{;C9|,B"g\D2H^     if(S.base==NULL);t e#r&V*_Rd
    {+U7@*`9|d
        printf("动态分配内存失败!");U_`R(V L&j_d{
        return -1;
h{)t;D Y0eg     }
NL_.N b2Ft6Dw \4W     S.top=S.base;+k0Z0Jh"C;h3s
    S.size=STACK_SIZE;
U U&Mqp     return 0;f8QUEa.n[
}
i{&eT.p9^\2A9SX
|9g5_\[~6h5O8F int DestroyStack(Stack &S)
O8O L!yP?3zrw!q {
SD7iVP%j%d     free(S.base);@!s#Z(v ~Jf7PU
    return 0;
i:r#i2}x'a'q[n&y4q }
0l7]Pq@ *^ [1rz6b%Ez5{*G
int ClearStack(Stack &S)
pU5x4QV3m-j+`C {B0?$`#a.^,g
    S.top=S.base;
_W8b1@^     return 0;]&v2p)M&]9H4V
}4~OQ'Q*Fu9X(hX
nm!] Bdb @3R8d
int GetTop(Stack S,SNode &e)nYiNKMT
{'Vm\IrcVSS
    if(S.top==S.base)
4lgBr5h8hj Uk:O     { D1jEBd9g-kI
        printf("栈以为空!");
~Ux7d%N8F]s         return -1;%nhX+K9c+@ ZD+d
    }Xw+ICQ.?5M
    e=*(S.top-1);
S)}Si\6M/Y`|b     return 0; ?)m5w&UX$r
}:gCypeAh$_%em
S+X } `-T uB/T@
int Push(Stack &S,SNode e)
@ j7Txq?z6Y {
%d'a6G#o\P"q0E     if(S.top-S.base>=S.size)
+U$HX|"s aO$lW     {-G7M+u~5_^v
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
i9N0R-G+g\L~5r         if(S.base==NULL)
f{x0L9V'k1o3A         {/k'ADG4c
            printf("动态分配内存失败!");
G| |)t7DR,o             return -1;
!M"h/n M4xz^h^4o         }o8[ n C caO(~5LM,\
        S.top=S.base+S.size;YD\7a{
        S.size+=APPEND_SIZE;
0Eu&^-C7qrj     }
:HPcwTM"R"{     *S.top=e;%XF.hhGh
    S.top++;
*f`4P"GQM[Gh     return 0;
,[oyts mF1u;k+Y }
w j;z5q:LAR 1GW]a,u
int Pop(Stack &S,SNode &e)!r h1fA F vU
{
)r zt m8`,i*e     if(S.top==S.base)
&B%dZ$nKT4}#H8z     {
\"c%@nx_R"y$[         printf("栈为空!");oi0q K c^.J4q
        return -1;vm}-H,G|u
    }
*Zd S_$K     e=*(S.top-1);
6v} B8^7u@     S.top--;
a%l R}N     return 0;0vk^[K
}
h;C$C(r-D V 6@:q;]"e1^$D F,D b-@
char get_precede(char s,char c)
0Ba(T-?d/_Lt9G9P {
T,N!Z {1O     switch(s)%e`b~q[3Rs
    {
6z `'H.rG&xW;VGd B         case '+':                 2s*@'bF!Nt,z6|t/M-l
        case '-':
i&e1d ~!?*y e Y!];@C"k              if(c=='+'||c=='-')
&GM^A TK*^ ^ W                  return '>';
yuw/i8q              else if(c=='*'||c=='/')
K*@&evSg/ArA                  return '<';
|X%c4H B0Sq              else if(c=='(')ymavh*J k8\+GV
                 return '<';2fZh'D![
             else if(c==')')'ko}a$e~6|j
                 return '>';1lsFeJ$CpO&}
             else +b'A r7J1`A
                 return '>';
W#V$jt R@-wn+mT8V         case '*':
"^O l/mH&I.z*@)Sx         case '/':B iG;M:~'H2XP!Y,N
             if(c=='+'||c=='-')
;d1q Q'O_ qK$h                  return '>';
;U2A-D1X$b&y/d9b              else if(c=='*'||c=='/')QIH,S9Lw(c
                 return '>';
a3wsQ+aG*I7RV              else if(c=='(')lHuS.MkH0AY
                 return '<';G UJ5QP(j
             else if(c==')')
3`-|g{ f:g                  return '>';
;~3G:U8\W"cd              else
#Qeb%_)`:`7p8N                  return '>';-Zu*g5t|
        case '(': R0X9e8YR
             if(c=='+'||c=='-')
g H*Z7h/S5{4|)V                  return '<';
YRR6|'FU              else if(c=='*'||c=='/')/mw;[ Wx)YK
                 return '<';2[x8^X9@p[%i&g
             else if(c=='(')4\;dHq[)FA4[w
                 return '<';
|4n'CQ |)P6mKd+\              else if(c==')')V ln$p%K_"D9?@
                 return '=';
O.~w!znUHG j+Y              else3G5Hs/{G
                 return 'E';3Bmz.y0y5X5Hm
        case ')':Y${~G:uE4ku
             if(c=='+'||c=='-')
*Ahuy*pR^ Z3U                  return '>';
:IZs;|;s0R R&?)a7Y[              else if(c=='*'||c=='/') ?G{9C6O \:z
                 return '>';.Xt `.CP hB8k
             else if(c=='(')
S'_]Sy4v;x                  return 'E';
'I(W;@c:L Tw0P              else if(c==')') c8Xh9~T}
                 return '>';
~"^5v o2X;{%s              elseea'mO:SSa8Kw*J
                 return '>';
NQ$bzf         case '#':ycf'_:T)C
             if(c=='+'||c=='-')
IguH^ Y                  return '<';
:ut;j9q?HC              else if(c=='*'||c=='/')
B;~+dr2E(d'jM                  return '<';
)e3T9b*B.e(A$Vd[)q              else if(c=='(')
lK$T {2j*Pg                  return '<';bWP+B_hU [
             else if(c==')')/xep9I@nn)w
                 return 'E';
;J5] Z9X'E}-Ef              else
N({3b5}aU*s/pn wy%M                  return '=';
/D y!F {`/d W         default:
3T&} Kl8h1?w Ll              break;h we'^F
    } wT&~1ct r!y
    return 0;   
#sV0Lq_}8\ b? }
5d;hP9P!m.l
#E E0ao5iC int isOpr(char c)'Q0bp,K`#c WjB
{
t,J/EK4t8S"X mY }     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')5Z"}[F X^ teas
        return 0;N.gd K|#EkzP!g
    else -d0TsJ2yc dim_
        return 1;8A,b(O2{8pfW
}
|o0YgiL;Oy8d iz y1_ I+y;t
float operate(float x, char opr, float y)*_"vn"r1zo5FXK*[
{
"{_j v3O#]     float result;
V]E5N!K     switch (opr)o7v-m2I*Rt
    {
P"uJ@[;G&M&D]5t         case '+':
YY#IY"D [Ls              result = x + y;[m6OV&ULE
             break;
msSB:A5oc,E7N8k         case '-': %TGV$|P^[
             result = x - y;
s{Mby              break; wUi-dt9d
        case '*':
H?2o"y,IP              result = x * y;*w@CvI%`&SS$?
             break;BH op D1{L
        case '/': j|zrQ@+GE
             if (y == 0)
$fHf{b              {B"hb3B4B^%DT
                printf("Divided by zero!\n");Y7X'Q @4M4r9?R)^Mh*[ Or
                return 0;BtEz@&H Z*EwpC
             }
%W0h9qeSU              elses6G8H/TM"E ^g'C%T
             {B|KW)o
                 result = x / y;
f0_]R!]g#I?                  break;q9hJ'U8s q)d&vg
             }y IYo C|.w
       default: _/lz [mWhXP
             printf("Bad Input.\n");
V4vQH4o/Y              return 0;
Ms)]:haU&AD4Y{     }
a3s g6p6f_$SoD     return result;5N:m [3`!D3L W8r
}   
^JKJ.r
7^A_yy.r K0Y float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
y9us,| mA3{ {7svy$U i:BC
    Stack optr,opnd;z ? { [j!EK%Yb
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;1g hv?;@Nm
    char c;
,^N'i,?@dg     char buf[16];
'_.` t7yt{;R1g     int i=0;
k+[%X5NF     3kr+R5`JT
    InitStack(optr); /*用于寄存运算符*/
DAh'@"?     InitStack(opnd); /*用于寄存操作数和计算结果*/okU3_ki_b
    memset(buf,0,sizeof(buf));
Hih Tl:D0_     "M? \A%Cf2lKs
    printf("Enter your expression:");#m,^4zb2]*B!`-c:u.r
        
j/E5|ZF     opr_in.ch='#';.[2u&[ \h;Zc(z
    Push(optr,opr_in); /*'#'入栈*/
]1u#{._mM9[w.s     GetTop(optr,opr_top);
1kdr;D~n     c=getchar();!b\'d_\B^t8P
    while(c!='='||opr_top.ch!='#')
R&]|0~j RlT     {F*RhdY
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/jiWG:LcI
        {
"|w#s#U+X             buf[i]=c;@-x k9K!BSP
            i++;} k3q,e6C-B^;c`J-t1qW
            c=getchar();
?'H/D9K'Av QEYD         }
uW(wZ&l)vP;b|D,pb         else /*是运算符*/
d5Y,O!WFt         {
I3ru8B#NK             buf[i]='\0';
C j C$w+O\*avbm'x             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/q/I%sB r~
            {
(l8Y_D+nsg                  opn_in.data=(float)atof(buf);
-q4K}6D_p                  Push(opnd,opn_in);
{9u"Jc1jR.V                  printf("opnd入栈:[%f]\n",opn_in.data);a3W{"q5_F"KJaGY
                 i=0;w/n1|t[
                 memset(buf,0,sizeof(buf));-b@1oFdh$t{
            }
6{ vD:z,ND             opr_in.ch=c; VI8a:xH
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
[a"T%SRI             {MwU%sKs5?{
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
@5pz aT o                      Push(optr,opr_in);
;e9@RH}8Gr0K3lY                      printf("optr入栈:[%c]\n",opr_in.ch);c Z,f2p(uG9j
                     c=getchar();
#?{%M/Md D}                      break;bcUty f
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/Q#v1m E4W)zE5_p
                     Pop(optr,e);9VSM"Xl"Mi3oN ?%G
                     printf("optr出栈:去掉括号\n");
5P[NI&y                      c=getchar(); fc#@@8Srjke'O
                     break;
u1^Uy&?\,I6j                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/y*I+z&nx W
                     Pop(optr,opr_t);PDz Q$Q5E#U
                     printf("optr出栈:[%c]\n",opr_t.ch);3F,_ Og'If
                     if(Pop(opnd,b)<0)
+Si:OBX$Y,|nm)kG                      {
O:Zr7a&Rv+` |nG$w                          printf("Bad Input!\n");
%? SE7l+V:sl                          fflush(stdin);
"S i}5Ih                          return -1;
3F4CH1eq [Y*@%A5w                      }5Z)E/v$I%^!H
                     printf("opnd出栈:[%f]\n",b.data);
t3k-f^-A5B!Tl                      if(Pop(opnd,a)<0)#s5C4aN2y
                     {
?;|AE Y Y                          printf("Bad Input!\n"); l)k*uw M-j
                         fflush(stdin);)XB^J2Ha9uO;F'Ig
                         return -1;|$m TTC0o
                     }
i;N d8`8TOS*p0e2]                      printf("opnd出栈:[%f]\n",a.data);c5U+lb3\8EYd
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
` ^\r9i5Gh"Im~                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/k!l6{EAy
                     printf("结果入栈:[%f]\n",opn_tmp.data);x4]VDnb-H)R
                     break;
Ek^]hsV0O2y             }i7`#l {$p"u/V5e1Qn9S/P
        }S C}L|H4d
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                to K:Y]\z
    }
(xh r"Vr%Xl.}&]     GetTop(opnd,opn_tmp);%e"GT1J"~ cI
    DestroyStack(optr);Z%SD5Ztr?Ty5G |
    DestroyStack(opnd);
(h1_d^ e#K` OE"fO-G     return opn_tmp.data;
lL*Q]E(l%j+I;[ }/`4zB)^)Wm$y3hJ

N5e{~4RVd o char *killzero(char *res,float result)\mj(b y7v
{
{l!MZL _S x2]{^     int i;
l tk if;I)b #P6q;xai#A
    sprintf(res,"%f",result);
F:o]K,a {(UF:J     i=(int)strlen(res)-1;
0l2lZ(pNX$eq     while(i&&res[i]=='0')
z,} J{8}!RE I*K     {
j#?XRAv1Z'\sS         res[i]='\0';
sS7DTwIQ#R         i--;
1Ke x5j~lL!G,dqd_7E     }
CE0V.fOzx^     if(res[i]=='.')b/RW g,A7O1bV
        res[i]='\0';Z PptD9X
    return res;_9LZy&m2jK6x5X
}
Y4|}(}1\ k F)|!DF7a!HlW&V
int main() UyY6tJ#s-C
{M^4qy3p H
    char ch;
W b9O0`gQe2f     char res[64];
+c2ml'o&@KM     float result;!ni6^9l nf({6J i/L
    while(1)
V[~%[y     {
eE\+lv         result=compute();
uVF%Y,tvBA {[,`         printf("\nThe result is:%s\n",killzero(res,result));?n0n/G5r v"z o6l
        printf("Do you want to continue(y/n)?:") ;
{-Q0Q#m$}\y(K @         ch=getch(); g l8mJ F+a KXt
        putchar(ch); K r4lp6G7h%U
        if(ch=='n'||ch=='N')
~*P9`H;A|'s             break;
,c `e3u];u#xW         else
)f.F/F OYxg             system("cls");
5M%[IUhk.s     }IXox3rtB NZ
    return 0;
C$jXi wu }[/i][/i][/i][/i][/i][/i]4fAmEwN
0Y,Ok N}Zs*Q
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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