捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.,`oj5FT8b
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
c6rn%xmM ~J2s /**************表达式计算器************/s e T9?9b/L
#include <stdio.h>
#D+P0S(T'C,D;W #include <stdlib.h>;TC{v*G4Q Yn
#include <string.h>
#}|BWlh #include <conio.h>
,Mo } F H D:b #include <malloc.h>
-j$Ur,\[6HI$Y
1b3QR~`W$b)r5j #define STACK_SIZE 100.|5jo[(Eb
#define APPEND_SIZE 10#C&w ~%KCQ
B.e0B"@_K
struct SNode{
JS}|qR#`7Gq     float data; /*存放操作数或者计算结果*/k$]r_3q?t
    char ch; /*存放运算符*/K3y'F'H%m;Vy\B.Ogj
};
^a5a9H |g-kzL A,t&k!x'jKOL)]|A
struct Stack{$?!hk:u(DQn
    SNode *top;'nH?~{3U;v'Y
    SNode *base;
Ky(NF1ey.Hrz;w     int size;'W+T9] Apt
};qu ZM.n"g k0@.Y R;P)Q

:G&bm:?w;u^ A8N /*栈操作函数*/
g-SH@|_1d int InitStack(Stack &S); /*创建栈*/ TZ9eiG*pv
int DestroyStack(Stack &S); /*销毁栈*/2x9qjo:d\
int ClearStack(Stack &S); /*清空栈*/
:x.}4_0BS fh int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/i,VUb V_?^
int Push(Stack &S,SNode e); /*将结点e压入栈*/4sls epd j#\Y
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
W`(Ek [c#I
j-x0H5t4fNfb /*表达式计算器相关函数*/
K4}:Z7v&E(v/e$t P char get_precede(char s,char c); /*判断运算符s和c的优先级*/
'F$d;c0rr int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/J3|&\xB8C
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/aJqYJ7It2}
float compute(); /*表达式结算器主函数*/
(xQ.s/S } {y char *killzero(float result); /*去掉结果后面的0*/
?M? L,y7}5@
'Ri1k9sVg2~(D[{5o int InitStack(Stack &S)
0? @)V!lm:?s^$z;q K {~ PJ PF$M*`O
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+A@pD6eCk
    if(S.base==NULL)zY4J8gcq*y
    {r#Z7lF;f t,B#_
        printf("动态分配内存失败!");
1qUf~ZC6P zl         return -1;7CC7al'U~J$P'L
    }
D h,Yc`     S.top=S.base;'QL|-e9N @ M!f
    S.size=STACK_SIZE;
m F$]2L,Y n$E9a*?     return 0;
fLj(Z9u!k9t }~w*Q1]2S-`abt1hf

N@(_4R&`;G2{g H int DestroyStack(Stack &S)8q0_~ S|j%n {
{
Z'f-r2FM!oJNA     free(S.base);2~t(Ou9[+|\
    return 0;
ZZjy5fD\ }:[e$W1aAb.e!U

R'fjo:qe int ClearStack(Stack &S)C(t1pMT*i"h
{Vj"`8~n%h
    S.top=S.base;
Z7C _ZV     return 0;T+Msgv)Q
}
;K:T5T#@4e{f^
:{"LP3B9i int GetTop(Stack S,SNode &e)
%?(qzh8j"{ef J {
Pj/g PuS     if(S.top==S.base)Gn&ER3z
    {
(MDYf~Q         printf("栈以为空!");Lbw/M/o i
        return -1;5Qc+P&N;v+u
    }0U l IS7[ TH
    e=*(S.top-1);
e)j&l!B,mTL$Z     return 0;
r L[/M8op z{ }s[*F*h-tA(c
6hZo:V6^
int Push(Stack &S,SNode e)w!I V \uY:v
{
^z9jz*WT     if(S.top-S.base>=S.size)N#v+~)ht} w)\
    {!dM^Aj/q7~U(x
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
S.]fb5S.@ rs         if(S.base==NULL)2X2u0h,oOt TD1F
        {
It{%B7W VVS%z3~z             printf("动态分配内存失败!");
^)] }2~2z             return -1;
+vq~#?7[Z         }
Kfj5iC1xty!Uu         S.top=S.base+S.size;@2Yw@5fJ
        S.size+=APPEND_SIZE;7Ue8K_Mr K
    }5L!PK e6Vl
    *S.top=e;
^9F%{W"J cP;s,}     S.top++;
i.v$f+r7C.{ u AK+}Y     return 0;
A4? vmz z:k| }+H3UJ N @#Osa(`

h$Mq$etE%l+nN int Pop(Stack &S,SNode &e)
0G Z8Ez-DIE {
w f7XS+T&^z     if(S.top==S.base)2]NQP$q QR"H
    {
~R7V`&h{ jf z         printf("栈为空!");$H] qI.^v(rL
        return -1;
"Cr&UW{0ej     }@Y$rWCu o;l3BkL
    e=*(S.top-1);
P*wwTs ok |     S.top--;{l%jiU~
    return 0;
zr9UxH&c!Q l }
b;A5\~Ew'j | N z&{Oe_9C
char get_precede(char s,char c)
cAV%bG/R#DZ {_~}5F2F6c.n"`2E)i0j
    switch(s)
UVt7H3u     {
{j*a2kbPJx:zYL         case '+':                 
5^:}E7vin O         case '-':
{O&Wwo              if(c=='+'||c=='-')
8[ f&d.U,h y                  return '>';
t5J3A:lx*mW(b4Sg              else if(c=='*'||c=='/')
M3~o,@9yJxs*u                  return '<';i+l"f[K d!lof/w+Gc
             else if(c=='(')
~](J/sgk)}U9]6c.t                  return '<';
a(H;O_S-^2pX              else if(c==')')
"g*UkB8]                  return '>';
;Z i2Y%x-b6p)s `              else ?G$_ G%gGXyO$m7R+TV
                 return '>';
F7u"Nsrxe         case '*':
+M?s9c}0uY X~;dG         case '/':S5H7ZO4~)J@g
             if(c=='+'||c=='-')
3yFz ~F8f1k aDDd#C                  return '>';
+p ]k"Z7N0aFb/g8Su#e              else if(c=='*'||c=='/')
a8G;~Pa3U#oZeq                  return '>';
@(p,[.[Z)kv%p6p              else if(c=='(')
L1g5y!r*m CW,j'`e                  return '<';
jyD_ S:c5A p4U              else if(c==')')Yc5\&Tk]-H G0E
                 return '>';
[N;K+ZdT              else$gm4cpknn5QL
                 return '>';!Q}PE2N-a?%u'g9o
        case '(':D5y@w?(BCV$t
             if(c=='+'||c=='-')
Ns._"m(s$yW                  return '<';
S]-IC7x              else if(c=='*'||c=='/')
)Rhc9Wr(^                  return '<';
[FD!^X/MXRY              else if(c=='(')!Y,or:PS0TZ
                 return '<';JufA1r#Y
             else if(c==')')
3~1~!X%b0O}:u                  return '=';3u(b'Jaj+s R
             else'[s!D#V5N%HuC
                 return 'E';7V;^#[]/q1]Z6SsV4Q9~
        case ')':*i2c{`,L{
             if(c=='+'||c=='-')XK`x9s`cg.m0r
                 return '>';
:G&L U ~$Ro*[,Z`              else if(c=='*'||c=='/')
%OlQ6LB(B                  return '>';
)K)Kyj \:qK|7u              else if(c=='(')n8`#t{)vV1VJ W"f,r
                 return 'E';hD(|u.S5e%{Hz
             else if(c==')')
e7r V;Q4XeA&G                  return '>';[xkM~v*w{
             elsezHp2QH.v'q'}
                 return '>';HXv[{*Yf+J%B
        case '#':4z*N;s)}&w/Qu%M
             if(c=='+'||c=='-')m+x1YCD
                 return '<'; a#KY9\X;Pg
             else if(c=='*'||c=='/')
UlszNU2z4`q                  return '<';
HF2k0F+Lm              else if(c=='(')5R;`}b#uR/l
                 return '<';
h&f%Y;bc |}5Z$zx"O              else if(c==')')
+[LB8q5o`w m%z8N                  return 'E';
FG i j@ _ ?3RX              else
a[!xw:z2Q5|                  return '=';:a ^ n6T0]Z[|.e
        default:
6lA9x-_,?P0w              break;M?CFu
    }g'z3bqX
    return 0;   
bjDa:v!];X }
[ BK"a$T;i ]^)c(|8Ht
int isOpr(char c)
S;Ug["K {
WPCj5S/k{.H`)|     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')b ws h0E*U6K5?
        return 0;
I8[a0JT     else /xSFp&K:y z o
        return 1;
*AnS#TjB;S.duu }
[ h lM{P/|
'dj0V({9`!t5I float operate(float x, char opr, float y)^'bgG^-h,|9Y
{}toM#n_LH:Z ]
    float result;f~3Y'b/W!b
    switch (opr)
|A^3jN w1e     {P{L$aL
        case '+':
&J@J0G |              result = x + y;
0l!`,\c9ft~              break;Om-`6V f1Z mCG$nd
        case '-':
P/B dG ~+S(S:t              result = x - y;
9HL Nx0i V/^}2G              break;
#v$X,Foq!m@8YW e(M{t O         case '*': o Il'Y3E;em9Q)O}2?
             result = x * y; y8g#B#D^#E i
             break;
b c8^:P!T,[6Fa         case '/':
e%WCY sc              if (y == 0) x2Fw6q*nM:H3U
             {
/xH6?/Wu.k                 printf("Divided by zero!\n");
gTaVM;\AhN2^                 return 0;
\3c{L JE.vw              }
#U|t:iSq              else
x4oiT/d e              {v a#~/^|@W
                 result = x / y;E^bi$A4Q&n'D
                 break;"L!z"rd5E#Lzf
             }nO*vf0o _
       default:
?}v@^7uw+n y              printf("Bad Input.\n"); p+b O}I I^:V
             return 0;fk+q&fQ;vIG-`(A
    }
#X:}sQ)KxO:]     return result;*OI#gq(j8G
}    _/J#l:c9ohg#?

3K`/pf6YW"x6v b float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/R5X Xl ?
{
U iSf6c_ V.pl p_kk     Stack optr,opnd;
1D d`9G\:^!EN     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
'[+\y#S%G Z9Z U'Uh     char c;,Z"N]-J3u SP-o%VX
    char buf[16];E#\z l3d EU1D
    int i=0;Rh r lD
    D1DCTz%t*O!S
    InitStack(optr); /*用于寄存运算符*/
:Q.lhd z!]6pOO     InitStack(opnd); /*用于寄存操作数和计算结果*/
0d:p L&uj)_u!CRj     memset(buf,0,sizeof(buf));
!_8v@2Xpd:`     !]W#Y w0P4JZC\E,e
    printf("Enter your expression:");
4JJKSL&X         #w$^)fX/N1yz-|K;v
    opr_in.ch='#';
.]!Ljt8G     Push(optr,opr_in); /*'#'入栈*/
!Z7ba0l+O CB7Q     GetTop(optr,opr_top);Y f~"P*|/B$U"h-D+J
    c=getchar();UoI Rz{F$F
    while(c!='='||opr_top.ch!='#')1Ik,Y^LB
    {
"hitdg2GD         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
i)[El'k:R         {
!r_L(zo#R             buf[i]=c;)xK2t3l m9Z3z:c]*h"f4_
            i++;u,\)[0| R
            c=getchar();9q1_*]lwO6Z JC
        }
,E(m_0Q#E8A         else /*是运算符*/ p tc/M!l_O
        {
3rS3s6pB7^h             buf[i]='\0';+V.|0b/aTH }H
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
j.x}`1PFN9}o             { x,O:Kf5F3^
                 opn_in.data=(float)atof(buf);K4z J.{pg1G
                 Push(opnd,opn_in);M){?7^)`%vch#]K1s
                 printf("opnd入栈:[%f]\n",opn_in.data);]+E-z2oP5d~
                 i=0;
$o'Up6{ex5@#@ r#@                  memset(buf,0,sizeof(buf));
s k,aVI             }
Z8z+Xqtsi             opr_in.ch=c;xOg*KWZSO
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
V,_ _~(^2|grWp             {&HdN"L4_-~2I3]
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
y*Y;f8{d]R] ?                      Push(optr,opr_in);
J?_"oi9~                      printf("optr入栈:[%c]\n",opr_in.ch);
.B;sF R3s8s,p                      c=getchar(); T} x#|8Hz*Q1[9p.b!ZK
                     break;
T.@SsE                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
*p3kuX'?5O8KL H.tg                      Pop(optr,e);
.[8gp p-N}kl                      printf("optr出栈:去掉括号\n");+kNPZ9f+W+J0wk
                     c=getchar();g ^ucE
                     break;
\ ?!S;WW;at"LK                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
%oO-Q{ n1c(T                      Pop(optr,opr_t);
$g-Y |9j'g:?                      printf("optr出栈:[%c]\n",opr_t.ch);"^| Cfu Beoh
                     if(Pop(opnd,b)<0)/`"D1r9lZ%t\
                     {
k)nRP(M&SbxK                          printf("Bad Input!\n");
N6_Yr ]%ku7`                          fflush(stdin);g}%A q Q6w
                         return -1;
~pg![%@V+Ebb)j                      }
kbW,{ME                      printf("opnd出栈:[%f]\n",b.data);
y;Vv@k$q0d4W                      if(Pop(opnd,a)<0)+n6R ZfdF,c]@
                     {.l1dMN|
                         printf("Bad Input!\n");
W j*@"mV%n                          fflush(stdin);]~z2@{(I5w(H*n!s
                         return -1;dNfM'h}
                     }4g PM)}[["[,{
                     printf("opnd出栈:[%f]\n",a.data);p zf5a$D;}'v\
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
M9w0Ri y                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ FI{Q7BH
                     printf("结果入栈:[%f]\n",opn_tmp.data);
'f,V8xP2wS^                      break;
7u3TG}%E,|P             }
/M"k4@4k/z u         }
)l:F3{+U-h?)TD+A$Fg'W         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
n`$m:pM\9?     }
0Ep|4{:w.gn     GetTop(opnd,opn_tmp);
1SEHa o$Pr$D     DestroyStack(optr);
7Jo f v7v6|\     DestroyStack(opnd);
9VVr4l'p{ U%E     return opn_tmp.data;
6V PN/k'UG&H } VK{x,T&B tL8p*~&j
{#mL K1m8l7b&R W
char *killzero(char *res,float result)~'B-g3K!f Ul
{
W9OZ-_h.{     int i;.E&^3bnOU?

B'~;J2p'@h.U     sprintf(res,"%f",result);
vKm7v$S9o&JS$Qc     i=(int)strlen(res)-1;3Lr.~0NJrCMP'?Y
    while(i&&res[i]=='0')
K.MB9\Gt+bXMl     {0b r D6?;]\
        res[i]='\0';
!Q"u$H,a;u,O         i--;
7d-JZK S)y-P j     }
9X g.XwL ^ ZV     if(res[i]=='.')
_`$c~4xOZy         res[i]='\0';:@V*Tg s3n w0y
    return res;-Gj%L,K w'Rd[9k
}
x+g `+yk vc &MbI&Q%U5l
int main()
?&j)Ta$C {
d$S;r|Z;h3|L8B     char ch;1UG+x%D%`%SX#L
    char res[64];s1x6o$\&`o-i f
    float result;)[6Hkw.A
    while(1)}d ?qRwj
    {
h-[$A;S C(V8j.y         result=compute();
U3YF*XnR         printf("\nThe result is:%s\n",killzero(res,result));
x1j{3p6z)V@_;gn         printf("Do you want to continue(y/n)?:") ;
i@"U#uw6KD         ch=getch();ib`:D;c"X_&T
        putchar(ch);HUGs'Q#yo
        if(ch=='n'||ch=='N')/LtohO~B,S
            break;t#K,x!Puso2d
        elseU.XHw;G1m%~'abJ
            system("cls");
!cuE;mC b^/N     }
m|\e ^bv(m E     return 0;
%T2X%[~.v%f }[/i][/i][/i][/i][/i][/i]
iv ybo;xS J ;I![uEPq
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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