捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5ArfH*Y|L:Z_ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=In7^D4t |Zj)X
/**************表达式计算器************/
-v2{ eEXd S \WdfH #include <stdio.h>
D*} a0LV:fS-u$N"u #include <stdlib.h>6~S AC&l#m2x
#include <string.h>I#[-zs3`'Vy
#include <conio.h>8X(`%G0LB~
#include <malloc.h>}MR4Z){*yke~

7x3y7W a%Hj G #define STACK_SIZE 100
Sv yKbK'~k #define APPEND_SIZE 10%r(Q s\:a}%n0Y:[y9EQI

:fRJTBYdd struct SNode{
yZ})j2IqZ]     float data; /*存放操作数或者计算结果*/Lmw N&zH'J(F
    char ch; /*存放运算符*/
}:TuEzg };
&f ihl c E#R
#o(l!wiX7@*r vhf.F struct Stack{2T7|?rk6l#_;w
    SNode *top;z].v7{4?3p(`
    SNode *base;4U U?*U:i
    int size;
*a*eUp|;|1_ };
F| mDempT &M"@,g(k'[
/*栈操作函数*/
}4wy"^:QR int InitStack(Stack &S); /*创建栈*/.U5u4m.JKf5K
int DestroyStack(Stack &S); /*销毁栈*/
^A X2c vm3uP2A8~ int ClearStack(Stack &S); /*清空栈*/
n#oupO8u4_ int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/+T r:n7Cb)F
int Push(Stack &S,SNode e); /*将结点e压入栈*/]_Y w#b }
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/'uXz3d)@5q

4I3^GLC /*表达式计算器相关函数*/
u:UF"d%JE)s y char get_precede(char s,char c); /*判断运算符s和c的优先级*/
9bp2vk#fh int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ UO!iL(l&C ]B
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
_%TzS X9w[:{Efhb float compute(); /*表达式结算器主函数*/%u Q ^Er9@vC
char *killzero(float result); /*去掉结果后面的0*/
cRZ/o?%Yl0\ _Z
8Xgx&yA Ol_B z int InitStack(Stack &S))f8S4JbY$Pag+}{(V
{
8HR;f5y mM.~2t/E     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));j5dpU,z/A3A:X
    if(S.base==NULL)
v5mJ8L%])b4[*R'SM:c     {
I'f8VN@^(Fp)RI         printf("动态分配内存失败!");n9j|(t;CM SN
        return -1;
^ ^0WU]\WL     }
JmqZ6MMv+vD     S.top=S.base;$k^"Az6cq
    S.size=STACK_SIZE;
,eR t [8|     return 0;dTr+Xs3pm
}
(F%^A2D;lcL u
e'G'M"v6?6_'z int DestroyStack(Stack &S)
*X[2L'_7a/L4K5|q {
MKD.z6N T$A6i!N ~     free(S.base);
$f.jIq#fk8Fy3m     return 0;2P Q/tVvh
}
;Gu8m6I,W G3Cl:I*~%Q Ibm8H^*@+AU
int ClearStack(Stack &S)
"| ~` cHa,F9t%u {
BH!U#Q*is*n T     S.top=S.base;3mB"HM0J9FM
    return 0;7I1T];IWfKQ A4e,R
}
M0y Y/n}(Jgf#LZ'v
&r"T6la7d/m8J int GetTop(Stack S,SNode &e)
t Cxl%[.UFZ {
3X'F&q]-ZT0Xk`'f     if(S.top==S.base)
1vA |*^a9K     {
-[D0j8k1I y         printf("栈以为空!");
5~'hg KxUK j         return -1;6D0}1q2rU5v&V:z{xV
    }
#K)AY(pCms     e=*(S.top-1);*^5q%a$C.~e8}#[Y
    return 0;M,M7@Q@_!L6YgG
} ~G9l|9~V m#x
'Tu9G ML7N#O
int Push(Stack &S,SNode e)$sRvQ#r-Ved
{
4z}{$u%h:g N     if(S.top-S.base>=S.size)
WZ1w1_8U     {x\0RB"Vi*L/Q
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
m Wtqp2b         if(S.base==NULL).m$l U%NB)v B$U
        {`m]g z4T
            printf("动态分配内存失败!");
\.~/G{ g!riMO             return -1;r Me5}_
        }1y*K5D+w}0f
        S.top=S.base+S.size;
Cu v\9d|/c         S.size+=APPEND_SIZE; {(P _*cnR!D4Fu
    }
7\5Q3tr%w \     *S.top=e;
$k$^'o!p-H,i#U*T     S.top++;
^(L;UZ&CL     return 0;
oN }8qA~;p }(ip1O:d,s _!Y
xlw$sJ9Y)q+G
int Pop(Stack &S,SNode &e)9E4]!l'g,@
{
oRC0K[,S;lRzC     if(S.top==S.base)
0h8R aLg     {G wGZB"H3_ JS&}
        printf("栈为空!");
osC7d$M         return -1;
-In7s'~,L)Z     }
;X k&F8H,l r4a S     e=*(S.top-1);e,St9Cq a
    S.top--; VaiQ U`p4z7U/d^/Q
    return 0;v_DC+EN
}*L6Wx@ UOg}3rU3}
-x K\!F4_U
char get_precede(char s,char c)
?$jSx)EB~ {
xAZ%`U3n:~     switch(s)
7_0m nZl     {F`t x+D;?
        case '+':                 j` Fh-X.r,T
        case '-':*?r&nl`xM
             if(c=='+'||c=='-')'mGO)K3l$`+^
                 return '>';4sWIPM
             else if(c=='*'||c=='/')"V7L2vo)]}/T+t3AISu
                 return '<'; h,G6D vt6C.PS jv sp
             else if(c=='(')}#e9y(rh*P2`l+b
                 return '<';i1E2[JvYH5~
             else if(c==')')
%c N7b.@QB[EU'{%R                  return '>';
1yBp0v;BZn L              else
%q4dR5jys0D                  return '>';
AoVtE         case '*':pDY:]yM
        case '/':
~KCH9\)M#n u5t3_              if(c=='+'||c=='-')
w5A xNR                  return '>';1g2gaxOK)W
             else if(c=='*'||c=='/')
T"E QrM j`2Rg$@                  return '>';
2cD$I8~_T }              else if(c=='(')^,m(x[K*H6p)fS
                 return '<';
Xc~Kt h)S7p              else if(c==')')1]6ug|nJ
                 return '>';cIp lH#tfh8s8\ e
             else
!?hBgb^^5i                  return '>';
^7PH&W1Q?(ge5i         case '(': @+H;l)]*U
             if(c=='+'||c=='-')
,T d#k0|-yk(l                  return '<';7C~R'l!z|ml,r%V
             else if(c=='*'||c=='/')2_h j+H'u#h%m
                 return '<'; yD V s bC0ip
             else if(c=='(')h RE%AT
                 return '<';;XRAJC
             else if(c==')')#s8h I/S6b$y@5_0L I
                 return '=';
SFj a \:\              elsek-`E5[7L+wS
                 return 'E';
2L1BS/aRW         case ')':6ew p\C
             if(c=='+'||c=='-')SwGwQXN-DB
                 return '>';
#pKt3C;Q&DB              else if(c=='*'||c=='/')
J mIN/H$[R-J"Fm4eM                  return '>';:p%KJh&b2D8z
             else if(c=='(')
6|(E+JX+CpR                  return 'E';$z,QAn~ OK
             else if(c==')')8yR'|D`
                 return '>';9j x W ob qN
             elseGN7Q1Kd-l|
                 return '>';
} }%tNQ-z2Ol         case '#':
)E9g2a*i"A              if(c=='+'||c=='-')
$tpm-Q@v                  return '<';Avm5h0RF$^
             else if(c=='*'||c=='/')j_1h&Z&^zC*f!w'O \\Vh
                 return '<';
w8s8K#e_J{3PA              else if(c=='(')
%[0O-{,Q;rB5j1P*q.E                  return '<';Rvh+D} zJ+mD0\
             else if(c==')')
o1A3P w8p                  return 'E';8TZ8J1Lb?!d S
             else
7|Y|'N I                  return '=';pU/\CX}t
        default:T5xXJ _9X
             break;*Wxk&n5?`t.E,U
    }
R_r qD/g     return 0;   
*k6? PS []-dt:{0W*f }y%GR.dY$@#d&i

5P ta"m/}$H/x/`0F-N int isOpr(char c)&c^9T7A)i B*p
{
|q#D$hG0PQ     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
"h6q~f_4O [b4x         return 0;g(P~kl]O&V;wM1G
    else
'HWl6JK0iro         return 1;
b6U&hF_ p+q0W }
R%c$k#U`%n ~
!o&_%eKm6zC x#c float operate(float x, char opr, float y)
viS-j|ceS {L C5tu(zu
    float result;
3rM&LJ mYJy3He     switch (opr)
4S+M"Ok[,v c     {
'M:H4xa7n3`-e         case '+': )x+ER/Pw9U
             result = x + y;
!t_qs(Q(O~              break;
L |N8o2QO@3x6\7ph         case '-': X$]}s2k7N;v
             result = x - y;
"Sto&c/~~ jw/j/q&_              break;-I2D1H"l}*Q
        case '*':
1}krP@K              result = x * y;
k p^Z\              break;#deY:RO
        case '/':
ocpv PQIT1Z              if (y == 0)f+Iv,HC.D}y
             {:D:EciW@ ~3|
                printf("Divided by zero!\n");0v K!jB5LK,B.g@
                return 0;-V#Ha'HK8OI
             }
4s3Z`2e2N#GN6](fh              elsePs6t6I IdF
             {
xMp-A,_r                  result = x / y;1|?@6h{vd.g
                 break;Qmuj1C5X
             }
:se*iB%le        default: 7G4Q*zJD3k)S4D
             printf("Bad Input.\n");
8RP!K5aM              return 0;
g&U-K#T?!j     }
ag.h;t2~ x7F?     return result;K$bJ0_]-K4M
}    f4U4O[$cZ1oK3dh
_ n)B,Bp(bb1V
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/c Y$kz$J
{
Dk/A w3t UU     Stack optr,opnd;
W.n/Ug L%p     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
0NVA*BX!Q     char c;}!~0^y'X!]rd
    char buf[16];
V4yG!\N c&f     int i=0;cP9\cC{:X
    #E)y ik b
    InitStack(optr); /*用于寄存运算符*/8yb0v][*yn/H
    InitStack(opnd); /*用于寄存操作数和计算结果*/
4|7VUZB,S\8X     memset(buf,0,sizeof(buf));
)c1]:]?kM Z:P%t7i+pc    
O;]*WF@     printf("Enter your expression:");,f#P;pVe6X
        
+u_0x2b-F_ pd(D [     opr_in.ch='#';
EO;BN-?&N1r A;d(cN     Push(optr,opr_in); /*'#'入栈*/
5V4Q/q"|O.S     GetTop(optr,opr_top);
2xJb _5ymB/_Z     c=getchar();
%K3~Y%j'L-{Hy     while(c!='='||opr_top.ch!='#')%Msv5u(?;SS
    {*jfeo1Y8i6|l
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
n w W"Y c k         {0K:{fO vl
            buf[i]=c;
6wE dsWar             i++;+U5F.k U*K_8T
            c=getchar();"M9^#]9wFG~
        }$XtQtf8N
        else /*是运算符*/+xFf9C:r g;L v:[#\%V5u
        {
'J&Z;~uL[2[H             buf[i]='\0';
Q.ou(G1P3Q$T             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/U Q0Ge!e;a-?j
            {
4@%C/n&}6s                  opn_in.data=(float)atof(buf);-F{T3~%v5cZ`
                 Push(opnd,opn_in);oz%PT!A
                 printf("opnd入栈:[%f]\n",opn_in.data);
j(w7s6]mL!b7P                  i=0;
7dw K+Uk&I/q{wno                  memset(buf,0,sizeof(buf)); xor:unUp~$n
            }
!V;^k v,wo%PmGO             opr_in.ch=c;
S%Lr |V             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
6^4YU2x~.u3Z6R6P             {
I$D^'P|/V]                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
4h8x``V.V                      Push(optr,opr_in);9z],h;m0NF
                     printf("optr入栈:[%c]\n",opr_in.ch);P _#Od3wc)a`2t
                     c=getchar();
xQ4V8YgT                      break;-rn0LV+M:gU
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
+KVIm Mo6?U                      Pop(optr,e);4M6TOS1|[`)s!a
                     printf("optr出栈:去掉括号\n");
%]o0{!cHR                      c=getchar();5{}.lS\y5ML
                     break;0v7Q _2XP$~
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
'r#jkO4]"}w.G                      Pop(optr,opr_t);s(p0L&Hd_uA$i
                     printf("optr出栈:[%c]\n",opr_t.ch); ^TcI/p*`
                     if(Pop(opnd,b)<0)
Fc*lY%^$i                      {$C^!fo0V~3_
                         printf("Bad Input!\n");
ZR}3prg                          fflush(stdin);!f1X-A'i!N!d_w.{
                         return -1;
7{1`U%?N/Oz:p                      }
``{7h@p                      printf("opnd出栈:[%f]\n",b.data);J-jq8S]+J
                     if(Pop(opnd,a)<0)Q7Q-~9?D
                     { s5u+D'_G j
                         printf("Bad Input!\n");
%p)q]Wn                          fflush(stdin);R7Z1P{^)d
                         return -1;7r H$X z`&r-V
                     }
&dCx2I$C                      printf("opnd出栈:[%f]\n",a.data);gNC-sT sh
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/ELb:w:sE*z3B7YN
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/2FF!nbD"SN
                     printf("结果入栈:[%f]\n",opn_tmp.data);&k.r?j#z*u4eN8a0R s
                     break;;Y ]4Y$I A
            })F*McTo A5u-~^n*G
        }
?5l@}0KBW1EY x         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                b2i A)\"|%e W
    }
H|8OtaR1l     GetTop(opnd,opn_tmp);`,g]"~PRs:S E
    DestroyStack(optr);
3C/Kn/m3HQJ9}     DestroyStack(opnd);
$M @]uQ     return opn_tmp.data;z.Nm:T&I ayrI
}j1GW hn8Yn
j5p t_ w${^
char *killzero(char *res,float result)
B2h*c(S+x {9Q} [qfIDRh#_0V}k
    int i;o*i}/i A*e6w
7Mb AT+B/A
    sprintf(res,"%f",result);
A~5?6d7B-f     i=(int)strlen(res)-1; c*n$a8P RK L
    while(i&&res[i]=='0')[+I d6t5P8j
    {
0q'O&qw!y d!f         res[i]='\0';M:wQf3]!a*IC
        i--;
:`webE bj%]     }
FH|bZ1V     if(res[i]=='.')
BzfD/F-Y         res[i]='\0';hf-PCYXMi!^
    return res;
)Zc8rsk3f }%~]yLZ5_i8b

Y/N%^hA3V int main()F1EUE.q.z
{d:w9l.[c
    char ch;
*bM"`2J'I9FI"Y&^     char res[64];
.Et$_O)x1E _c'\     float result;%se#b7b1ua
    while(1)`#?)UAz8pQ
    {
"{'LM VG^w$q         result=compute();
fFYRX C!][%E         printf("\nThe result is:%s\n",killzero(res,result));
.Mo;dj3Mh}         printf("Do you want to continue(y/n)?:") ;
VL-MP-?H3Hd.W;@         ch=getch();LMk5dB3R7}
        putchar(ch);A Y6GfWc
        if(ch=='n'||ch=='N')
ea?P&n ~ h,fVo             break;(b'o1k5YT-h,?R8z
        else&["yO YXN E&wo L
            system("cls");
/M+O;D5]/t     }v,umiCUEiB9I
    return 0;
9C hQ2^.R*~\d }[/i][/i][/i][/i][/i][/i]Ff,oL7wf
b5`!? OK/m_Z
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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