捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.n,f#Px.p6X:z|'F0F h
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=%H{~1{/c\3e
/**************表达式计算器************/}Lx8g7C+\ ^I
#include <stdio.h>
{O~/Uqn Fv #include <stdlib.h>G+S8_!Q*A3lUNB*\
#include <string.h>ro/u!w BF
#include <conio.h>{2Z-WT|U.{/y!~n
#include <malloc.h>]|iI:Mn G]"h.e/H

8Y,g1c$XR #define STACK_SIZE 100^2['X@*m W&X
#define APPEND_SIZE 10
$GR tz.r)Gh
n3j5SP5s$?!N0C+Q struct SNode{)w~9s] M:n
    float data; /*存放操作数或者计算结果*/#k!fX1^:]5lU
    char ch; /*存放运算符*/?8g2K-B+bL
};)b+X J&hO${k

^ e(|s3a.h X9~4Y)L struct Stack{0Fg"t5B"r
    SNode *top;C8sa(l-N%b9U-^;`
    SNode *base; g7A h.h b+] p
    int size;
IByP0WW[5V };
4Q@"v$C4T+d1bm
%_[R,D\&[#d _$w /*栈操作函数*/^ ?A-bsv
int InitStack(Stack &S); /*创建栈*/ZU]n eJ
int DestroyStack(Stack &S); /*销毁栈*/6j%P_I R7JV
int ClearStack(Stack &S); /*清空栈*/
R2M'}Xc r B d| int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/0? H]6v!`
int Push(Stack &S,SNode e); /*将结点e压入栈*/ A3Z.B&IY8QO
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
8FWV&^Zi,Jt,I~F *C,Y` @f1R2}\Mn
/*表达式计算器相关函数*/
g)]e{edy-U4o char get_precede(char s,char c); /*判断运算符s和c的优先级*/
:pU dd-w4r int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
Y"BxD8Wb,i float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
b u/s*E ME#O,er-a float compute(); /*表达式结算器主函数*/(aX'm vM;EM;@4Sqer r
char *killzero(float result); /*去掉结果后面的0*/ c(K%J1t3X$lE
z6?/RlxJ'D8fl@
int InitStack(Stack &S)
6\g W1u-s6@ {I#?,j|*yqm4}
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
u1Pxu'oI     if(S.base==NULL)AxP,zCC:csKE
    {
C5C0Z yU o9CHs;yq         printf("动态分配内存失败!");
&R/}|5Qq1e2K:fh F}4f"i         return -1;8h Zrl2ILa4@
    }
8pR(~ rC2I#N^     S.top=S.base;lc{5g&f1p9z,q
    S.size=STACK_SIZE;G R,_4s3X m,jc
    return 0;
'?fa#O l&n }
0]1H~)X5fc2NIC/k
6v.t T5yN DYCAk int DestroyStack(Stack &S)f~,AVGi
{GV.Gqk5{o
    free(S.base);
$h#V+q#\,S yso,y     return 0;
G] Cv0zf el;f T1p }
n:yuHa-h;a8w (Jk8[0`k&C`3^
int ClearStack(Stack &S)%f$Rr_ p0QL5F
{
hm/pL+n5I/P$H/C(Lc     S.top=S.base;W+Sp1N{'l'n7R0]9Gs
    return 0; C$P/f!l0FPj @L}
}
2{ r AueD4s Y7KU.hy A
*d]H TX3\wn&uc int GetTop(Stack S,SNode &e)
_i(I^ H {n/b;U|th^)R
    if(S.top==S.base)
v T\m xgs:l     {.{5_+S ]aH
        printf("栈以为空!");
(hOg(@5kYD2S+[6d R(B4W         return -1;
,xyydS~Y     }
2e/U6m8e9q$\tq$C     e=*(S.top-1);
KL P.JCXi     return 0;4~pGp*S4lU1ur$n
}
AJi@7?%YwR a-q 9e w(lqjQ P6}-b
int Push(Stack &S,SNode e)
)S2{VPd&C9y)z/B^ {ejC+[.[YO c&y^
    if(S.top-S.base>=S.size)dt0Y~3]rQDfI
    {
&Q)f#r(vTOa,A         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));#pfwffX"u Z
        if(S.base==NULL)
S)n M1Iw&sR*t d9g         {
'Bt7B-d_ B             printf("动态分配内存失败!");
-G V m*J:~             return -1;T Ek2}R
        }2u:f0R?)w UTL;}p
        S.top=S.base+S.size;rEvjQo%h*pA
        S.size+=APPEND_SIZE;
Ud#E%V r$J H|     } P2[Tbx8ZFk\
    *S.top=e;
F]x.Ib e j     S.top++;N4LOG(H)Qi2?
    return 0;g{'N }s B*o$Y C
}
~$A8@C,pF S-qTA{:{5RB
int Pop(Stack &S,SNode &e) B#dJaqB8EeU*s
{]Lk x| X_2t S
    if(S.top==S.base)
&f(oy t6bP     {
X0F Q%P |'\d         printf("栈为空!");
!Mq#E1H8`1gO         return -1;
u1Z/QV&n#M9OM     }
@-h"lvyC     e=*(S.top-1);
+xrd%Z}     S.top--;
1}[p6T9T*d l$c"X0J&~     return 0;
kB$ui/W9~ }
d+Z Sl4Cj V^
K9RW'j7r6C$T"\| char get_precede(char s,char c)6O6O*YV2L8C |c
{&lU:AO2Q7BJ&h|%k
    switch(s)
"t!H"IP#P jf9S     {
#g1z7z _ V6p\;\mG Bx_         case '+':                  ~9PYOK2ni5Z,G8f
        case '-':
V*V[8C$A5QN              if(c=='+'||c=='-')
2PM,yY8A0l_i Sd                  return '>';
+s1`r?7J(it9l              else if(c=='*'||c=='/')
8J7W3{${G3z#Y1I                  return '<';
nZQ!vU              else if(c=='(')
9bo+m.n2q&_c(^,K                  return '<';
W9v"x ~(c_p              else if(c==')')b ?(kZ'I'Oad
                 return '>';
Ib1}N%VQo1kw              else jij3{(B;Ci+A
                 return '>';4@ p5tB u}a
        case '*':(A1w%k%C Y4`5B
        case '/':
;`z2L2b YV1l&uea              if(c=='+'||c=='-') w4V0B G8h5et
                 return '>'; tF;\!A gs ua
             else if(c=='*'||c=='/'))G L_-F-c&Lq;L2TA
                 return '>';+d RGR'B,N
             else if(c=='(')'LG7YU!A7K
                 return '<';$znE;H}9M3P
             else if(c==')')BV#l,a[$O
                 return '>';
T4\[&{/{              else
0h;_oMuv&hK&\                  return '>';X%Ok&s}
        case '(':{#sE _todX
             if(c=='+'||c=='-')
l|7}S7aM-CWfU                  return '<';7nw.\0C`^ kM6J]
             else if(c=='*'||c=='/')
UC eV0k3qi                  return '<';P7CGL1H9T4Z
             else if(c=='(')fJb*d:D/[B AS}0i
                 return '<';
zN wS `NF              else if(c==')'){}S3vnC5K
                 return '=';
8C5l0pA*q8f,[2|              else
%z@\3[ X                  return 'E';
sLazR         case ')':
-X }9F8ll;[@V              if(c=='+'||c=='-')
4h!Xd/^3R7oF                  return '>';o A j)j!ny)]S,Sn
             else if(c=='*'||c=='/')3}+jzq3[d
                 return '>';
N4I K6IQa;U              else if(c=='(')
:R\-g4N7s*pA+k                  return 'E';
})fb0N(B \*z              else if(c==')')i!F,eOk{i
                 return '>';
8N8I$H]O8J^c0?'r              elsey'rM}b^0h'k
                 return '>';
cz3^4DEj         case '#':)Q.?f%A |t'w
             if(c=='+'||c=='-')
:y-~K.Qke,R                  return '<';
(@iK.s,ah y'BE^]Dx              else if(c=='*'||c=='/')
2r-Q&T ~\ C1O                  return '<';'N~-R2U{1FN(}
             else if(c=='(')
U+[ ~5GQ|BIZx                  return '<';
@,Y3Td~$P              else if(c==')')+u|/?vo{!UWB l/P
                 return 'E';ZL7UhsJ wr
             elseu,U:T;m`] |T4W
                 return '=';9x]-ttbGi
        default:
f2Zmny9[x@Y8c j              break;
yYI/Er     }T;EWRH'[
    return 0;   
J#J3v {8v)N7QS5i }&j x ~l$V
e1Q"`,P9P [*b
int isOpr(char c)/x9CfYA4i0sWyDn6V
{
l }/fb%Te C0C#LU,m     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
VO'[aaM2I9C-a         return 0;
2f{;m9plk     else
.]Mn\}'~         return 1;["BJV;_Bg#J Ps.}
}
[5jiH p8v
$sH8lQ4IZ"W float operate(float x, char opr, float y)
,C:c W(C,^x1p1C {
N9gr*f3Dr     float result;
-R {oW\C8`     switch (opr)
JK:^r y([T     {A J9Co j.tF
        case '+':
R)Th DW ^              result = x + y;
.S4a$Y!ksU$f              break;|9c,W;P*`(\~8J:I&H
        case '-': )W3D jVH4i
             result = x - y;]!Odix tW/Y`
             break;5Sw(J%Of h#G
        case '*':
ca4B3u#B O%~              result = x * y;
o!mc4k{{ l/_              break;
g2H)^!gC/ZJ         case '/':
8P#?$t2p:E,RK              if (y == 0)M*f"Gy+d6n3uZ7q
             {| }8@_DeA
                printf("Divided by zero!\n");)Km7j@w*[ X
                return 0;
dF:av o+GeqI              }3|VS"j1q1_
             elseo }5E-Z*JF(a,H#S
             {+R|F }|:L1L
                 result = x / y;Hb)]S'rkpP
                 break;
2R4F di-D&moH,_              }
4U^Xe.x#ru/P wi        default: yt GU(e ?HF#q
             printf("Bad Input.\n"); 9dk(pG-Wg
             return 0;
}v,lK~w6?v1e     },U"y*o6`,ept$zl
    return result;
?8oG/\ho8k4Um$mh }    C E$Jj:\m,w
T(e ih(L~
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/lNS%u/W P3S
{
%m1Cv h&h     Stack optr,opnd;&eQF.j^
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;C#M t#ae%x ^U3e6~
    char c;
m"j9CkF0MM(E0h     char buf[16];
n;L:U4[R$h2?     int i=0;6B.tzzV6GP
   
@)tjy7hF     InitStack(optr); /*用于寄存运算符*/z ikq_k
    InitStack(opnd); /*用于寄存操作数和计算结果*/
kJJ5c#x Al&c     memset(buf,0,sizeof(buf));X+Em?0H0^Yk6U9G/vZ
    'rS VR]
    printf("Enter your expression:"); k1mL.Zz
        Q!x'W'?+iRm
    opr_in.ch='#';C1S;D&M?;@-f
    Push(optr,opr_in); /*'#'入栈*/
`C^4H+VEorE     GetTop(optr,opr_top);Qc o$U,Y%i)Lv0h
    c=getchar();p Ay-S;BW!tt1oA"O
    while(c!='='||opr_top.ch!='#') K!nV!E#O(X:f
    {
1C.D-n5Za P_HZ.V8w         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ e{Wx4hh e*C
        {
S ?+I a;]_             buf[i]=c;a9q9J([9vE|
            i++;,YQ.aB z5\)[S6w
            c=getchar();
P)YFS_wNbk         }
3_2c!sn0?LH/MuL3Y X         else /*是运算符*/
_#aOH@!L9O         {
1H-w0j7Po+I             buf[i]='\0';
F6MV&b+c eN5w+u+~F             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
7V _;h2` A&f~%d             {
a"K/X[8P;I7E                  opn_in.data=(float)atof(buf);&G.b/v"z0b2{2Yu
                 Push(opnd,opn_in);H'{E e)gh'pq-f[
                 printf("opnd入栈:[%f]\n",opn_in.data);
+_bD9^bCg&L%C                  i=0;&Ds@*ev _,k!~&f
                 memset(buf,0,sizeof(buf));pbz!qu&j
            }
_Z1K%Ea"i6mK6{ nY             opr_in.ch=c;
0]tja@,R.We             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/0vifk2z2~'DK
            {
F|+Z;r.?#M|zx$y                 case '<': /*优先级小于栈顶结点,则运算符入栈*/:p:J PHH
                     Push(optr,opr_in);2Vn or V(U
                     printf("optr入栈:[%c]\n",opr_in.ch);V]cO o$Lb:a3X,V
                     c=getchar();*C n,FSjD:tzL
                     break;6r;pn9n?u oRU
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
t#J;{?@,ND.@                      Pop(optr,e);7Ty{8q9z7Z
                     printf("optr出栈:去掉括号\n");
+pS4XfM;r                      c=getchar();Xc d&d`%dL[
                     break;
N7C5h8L't$V0O                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
$^!V#\%x*v                      Pop(optr,opr_t);
/rM} dW eu"q                      printf("optr出栈:[%c]\n",opr_t.ch);
Z wH|"a"f$I                      if(Pop(opnd,b)<0)
)V#Pso4X$@"]hi                      {
b ]TOA"^x                          printf("Bad Input!\n");2Db(r4@f]1Q9s
                         fflush(stdin);
'x}D#tK*dd5PC/X                          return -1;)oqp3U"S
                     }
5R5{(f9WRw7j:w                      printf("opnd出栈:[%f]\n",b.data);
V6d6D gC                      if(Pop(opnd,a)<0)#m c l-w:RW0O\j
                     { Kj6Gd v
                         printf("Bad Input!\n");kL B/y2q`7[
                         fflush(stdin);
\QK)ljmetms                          return -1;.AyZjt.C
                     }
0F qy`2d(C BED                      printf("opnd出栈:[%f]\n",a.data);,M_&\/W1wu9B
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
r@RvF g0@,x                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
*p@~t q*Y:pg"~                      printf("结果入栈:[%f]\n",opn_tmp.data);
"FimrJ0At!S/g(y                      break;4G {\/K3RhB
            }
9\ q'\:n*MKFLq         },}(p$GG.F`
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                #w5d N/D}
    }K[RO0BT
    GetTop(opnd,opn_tmp);)?O:ko,h_
    DestroyStack(optr);
.J2uCz)JIl     DestroyStack(opnd);*RtyT9r hP,T
    return opn_tmp.data;V)Bto'L#Sog[
}+q {` {:]o_x
B$N5N2] VQwb
char *killzero(char *res,float result)
(`r|I;N {^S9x(}9Z2{)E``aX
    int i;
+{d DefHta3Z{ O
L:wyw5Y;M     sprintf(res,"%f",result);
%?.H/ORw LD     i=(int)strlen(res)-1;
|L;Db$H,|WT     while(i&&res[i]=='0')
(EO'Y1rHh6m     { A(S.g2e+m8K
        res[i]='\0';
]3fQ4Z'vsn Z         i--;
.])FC ?l^ JA     }
`"? L/G'e     if(res[i]=='.')
2[1v5G qf` d7b-FN         res[i]='\0';+befT/U `uS7?
    return res;*E zy/Q-KRy2w0S
}
n r d4W ?K q]%Msz{8i
int main()np]!l.sY
{o}*il~t$h*Y
    char ch;
H4WJ DJ?     char res[64];
0V eF,^;{E1d%O~Z     float result;klsk2`+O;G
    while(1):_ T n5p4L"hr'Eb
    {
)G|P^4vz8m         result=compute();
$X O+J*IcCP         printf("\nThe result is:%s\n",killzero(res,result));8g?{*W&h
        printf("Do you want to continue(y/n)?:") ;B siH$s9ijS
        ch=getch();Vq7G'G`Ut
        putchar(ch);
+Xn3@]\6] F:f         if(ch=='n'||ch=='N')l@U] n1poZ
            break;!c2r&RFW/d
        else
QB6| Xeu m             system("cls");W([#P}\g4P#tRLf
    }
q Om:z0R'K"~q1eu     return 0;
H'K z/|`lFE }[/i][/i][/i][/i][/i][/i]Y#F n6S*P"X4i7ONw

7Z l+^ oB,S9ay \?i6XQ_ [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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