捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
hUSWRk5Mh5N[ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=;A?$}8j c Tb
/**************表达式计算器************/
g,cD'^.hoDgs #include <stdio.h>
,J8oqc%g.r #include <stdlib.h>;Q!d4j^*wBGI
#include <string.h>hy@;`.}Xz
#include <conio.h>;@q|~Qrk8\]
#include <malloc.h>
]Y7Dn,Qx5g o&t
h A:Q)g|&q8[d\_ #define STACK_SIZE 100
c9X$u-Uk5| #define APPEND_SIZE 10GgvL'x-ljm k&w

5I2qR-m,gh"Y d struct SNode{/xy1i MGRgg?|
    float data; /*存放操作数或者计算结果*/TtbAX
    char ch; /*存放运算符*/
poT+i0z N };
D+M5O9]MD%uA1yhy rEr H(`~ CU
struct Stack{8HW8\ }h-HT3P
    SNode *top;
KvZ6vo2t     SNode *base;
0xqa4ZEx?U     int size;
j? J.w6Ta/A };(ZEDNeAj&fb
)T FA%P BS8gAYl7f
/*栈操作函数*/zSMAU
int InitStack(Stack &S); /*创建栈*/(]!P*oJ]? A8wU\J6O
int DestroyStack(Stack &S); /*销毁栈*/-H`0g5[)w y![ m Jt
int ClearStack(Stack &S); /*清空栈*/*K8P}*D-?v"t?1y
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/+J-g^P0E!C
int Push(Stack &S,SNode e); /*将结点e压入栈*/} T4Vk @g8LX
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
`(}4zdJ5_t*@3u (j+RgN@:G%M5r
/*表达式计算器相关函数*/ ]B,\3C0F(T
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
vnAF6R Ya,Xx z y int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
8G,n'~eU5Jny/Is float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
s i-~;aqU:X0u float compute(); /*表达式结算器主函数*/#U0XH})n-s(j E
char *killzero(float result); /*去掉结果后面的0*/
J7{1f F)z i~ T @ n4wqLL
int InitStack(Stack &S)9B Do b0{8@Nq^8q
{&J'Yy/O8bB
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));$VU7]*^$qB?+q?:XS
    if(S.base==NULL)
e.bv4R@b$gT[     {
i;]}N CG         printf("动态分配内存失败!");
$B'B'I B^4iq         return -1;9|(P+Pu,m Sw8A8qt
    }
'x'`#SpqT_     S.top=S.base;
O?~j,B     S.size=STACK_SIZE;
^2S8y%u`     return 0;)IX,e#s(z
}
[diwf dCAX8ox
int DestroyStack(Stack &S) kh4YPd/s cC
{
8x5@1G]0gx ok     free(S.base);
U4Eg"e.lo     return 0;#J@{t.Hy
}BfS+I!pI![w*G2b
8S/[{:Le
int ClearStack(Stack &S)
qU;r ^R1P3S9O {QmS.c/?'\:~ ZR%^ E
    S.top=S.base;
%J;a*x;d@/cZ1n     return 0;6o*`dPt
}0U&S.TC"`d
t7l [a*V*Y3n.@X
int GetTop(Stack S,SNode &e)
"FYP p Z"hE!@j {`+zw-c8b'noKa
    if(S.top==S.base)
-^we.hM$rY} CM     {jlE"`zL,}
        printf("栈以为空!");ZI^/VZ;~4\
        return -1;3F5_'|DO.h]8N
    }
)N/Nx!PA I:[9tr*pS     e=*(S.top-1);.C4Fg-eM
    return 0;+tR8gj~a%^,v
}
0fw4tZ"eg0[YC)kO
'bp:M:~ m int Push(Stack &S,SNode e)
u&T3GJh!]A2x.q {
Xm,[3Y8J*_&[     if(S.top-S.base>=S.size)
2SQaqC f"v t0S'`     {
%FH1}9q-SFk }         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
Z4B7PGN1c*fQ         if(S.base==NULL)
'S)gY viv         {
o$yFhc             printf("动态分配内存失败!");
$Acn7lz0?2s             return -1;
!HZV r IC2I         }
.L@C y!V2z;s2L+@lwfM         S.top=S.base+S.size; j^GT#w6G
        S.size+=APPEND_SIZE;
`A6IF;B     }
Jp*e~9h*xG u%X     *S.top=e;i KECS
    S.top++;
\8f7W gTHmO     return 0;
Og n5as \j }"@{8o5nof(o~_-@S
9}G*c}#`#a
int Pop(Stack &S,SNode &e)R})K4tg@0Y
{
hMf/@&_     if(S.top==S.base)P?4A+R:x }wagZ
    {3^4Anx3?YTW
        printf("栈为空!");V#KVDdD#C{A.M u/B8H
        return -1;!@l0C;Em&a2|
    } n @,M%p N!`%|W
    e=*(S.top-1);
7wP&t2g#~eND7bG     S.top--;"u r5mL:a#xf^
    return 0;
n2`_g N } |9V J*hD g0J
]UW6cll[5y
char get_precede(char s,char c)
%A UD Ial4G*r I {
CI+H/g(yV)^     switch(s)Y1DI X0W;TIAS
    {
.n)i9?^wL;w         case '+':                 
7Yp2`8BO         case '-':
zwWq W2loRV$r              if(c=='+'||c=='-')+ZQ2Tbb+V,P(k
                 return '>';
l7fT9v u'I*B              else if(c=='*'||c=='/')tX*K9d%u7kR
                 return '<';u*?t2p1?5j1p
             else if(c=='(')
8xO o7p/f,D*r1jQ.m                  return '<';4UA K:^F/]
             else if(c==')')
0X Z?d xF }                  return '>';
FVxa0s              else {XC,_p.Z8Rs
                 return '>';
B8G,gz/o         case '*':
;\9b rB6|-x4Z+x ~4Y K         case '/':
F|$b Q:kPt              if(c=='+'||c=='-') ge7D9fF
                 return '>';
A;yC8P? o(S^ U`              else if(c=='*'||c=='/')
.GCf/d+u6P qsL[                  return '>'; kH ump6yn[ O
             else if(c=='(')
z`E;GfY }                  return '<';@'b?d;l+r;cK
             else if(c==')')
gr d,c}{-r                  return '>';z0@]S8o(E
             else C w#Q#DR-`#l5z
                 return '>';.^eZ6}T h%l
        case '(':
nv/D7E~wE7Dm              if(c=='+'||c=='-')
GZOc r5tz                  return '<';"{*_ E A0i[
             else if(c=='*'||c=='/')p OA)e)O]*va Xz;K
                 return '<';
q?7W!lS` G)Y              else if(c=='(')
;k s}O|"~ O                  return '<'; ^J#W @ ?\\0K`e k
             else if(c==')')|!?7hx h X
                 return '=';"ll)\$|{:If
             else
+{%z&O~-l%L(s                  return 'E';
7[})@D `A&[N5kj         case ')':
p`j sj-l              if(c=='+'||c=='-')?7g.u0H'I;T
                 return '>';
;~:c@%fj5H@?,y              else if(c=='*'||c=='/')tbiG9C'G:|
                 return '>';+X*PII,T3v0u&a L
             else if(c=='(')
y*~Za t4^:fs;k                  return 'E';
E?m9U{'w7@X|              else if(c==')')"] ]i5R9_
                 return '>';,m(P%xL/@g3S
             else3H,J&p#LD$L-qx.Z
                 return '>';
7_ D%tjk         case '#':
(g_'e5v)nX ~              if(c=='+'||c=='-')
e3Y6Q C/iU                  return '<';
[Ae,s M5f              else if(c=='*'||c=='/')
hvI aS_"s?                  return '<';
BH([#}Q I+f              else if(c=='(')
w$yKnJ                  return '<';
(X6Uzu+PG_              else if(c==')')M+?7i1_`
                 return 'E';h'IYH"\in
             else3{\ _s N
                 return '=';Rp*I` O~ n
        default:
#Eh f/U};L&F ]&T              break;tDXa`)O2k
    }
DK?1Ugr-Q)}     return 0;    F*qzOyW0@
}
?JS2e0sK;[ ] [g8t%u(Wt
int isOpr(char c)
i5o.mq!h+]S`N {G!{&]aFI
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
6u0x;U*Mwr|,B.c"z         return 0;']}KH![l
    else }:fr9C\4F W*@7{
        return 1;
}K8k$[![:O-M_*j` J }
@(m`0w!yU3g ~ +a%V(fk$Q7fB
float operate(float x, char opr, float y)#^!q iK!| a
{
&f$hK8}~ SI1a     float result;6U?d p f JS
    switch (opr)"|2R/nW1y(Y
    {
Bi w3Q W6f el         case '+':
M'n)J%i6c'eR+}Z*[y4C              result = x + y;
(W m7a+@4j,XEv6A M s              break;IEEx.Yu X
        case '-':
qf L5h0V Fpu`              result = x - y;8F/k$}0Q ]!P!h
             break;[ K'A0d;Seu'D
        case '*':
Pv&MX@Kr$`P&i              result = x * y;
A Tgm-Fb@x              break;'j],{B#k`v
        case '/': !E{ HZ'a
             if (y == 0)-Z Gs a#{;Yz$D}%S
             {S"pP4Tu*k
                printf("Divided by zero!\n");jh"s5`*Oc'x$m
                return 0;6[,j_}K4GJo3h
             }
:bnH$wf{*A)c              else
CiZ;E*iIEwV              {aBK-|[
                 result = x / y; f"Ha+a G8wN
                 break;9V*vCy'^K
             }
^I4j,k5L3PU/P{/p/n        default: H6YBNa
             printf("Bad Input.\n");
)c r+Nm*J N\,\%ht              return 0;
3c)qxq`)y3La     },zEje.ie [3D@eyF
    return result;
)V0R"~(r7}+as;i~ }   
*S.f|6? a@
}(S$T E2h6x;Q float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
5I%T E*`E-CD#X {H&G|8Jz7eP-A
    Stack optr,opnd;j'm1a9Av'j ^
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
Q"zT;A^&[?     char c;
7rN!U/sX     char buf[16];
'g^6`6@ d     int i=0;
lg%x {7XSl9oCP    
|y7`[} V xuL!_     InitStack(optr); /*用于寄存运算符*/
K6TJV&Xn:L     InitStack(opnd); /*用于寄存操作数和计算结果*/
!p^_ |Q \alIK Q     memset(buf,0,sizeof(buf));Sk5h"mJG$v
    Wz f!P4q']ua
    printf("Enter your expression:");
'n m _#_9l*H5V5P         v@T#J'^4m$H+T&E
    opr_in.ch='#';/b/|#r5j-C%V
    Push(optr,opr_in); /*'#'入栈*/'d^$Pq8f*K Q(onMF.@ bV
    GetTop(optr,opr_top);
hU!g7Ogq     c=getchar();
+sCq/@D9SLd7U1o[     while(c!='='||opr_top.ch!='#')
SI)X Bw w~     {UOo K.fG%q
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
kDYf,a4W2SW6M7L E         {/K-N;vn8y.@Xq
            buf[i]=c;)L#c Z`.r$i0h3o
            i++;
x)Q;{"[sBQ$G I'l             c=getchar();
!WW~ ~,Z         }
!U|2p7qA{         else /*是运算符*/ xK0}1B-nc:@Z
        {POu%v9`%TA
            buf[i]='\0';
])v'j!h2?1m%x6q             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
]Z7qUp#{@W             {
(c*Z2H1h m-z)_[t+R                  opn_in.data=(float)atof(buf); GF~#o\}YQ_
                 Push(opnd,opn_in);
o(y9|:B)\                  printf("opnd入栈:[%f]\n",opn_in.data);
J/D ue8?r Z&R                  i=0;
!_^&A1_'rK;^                  memset(buf,0,sizeof(buf));
$N M\7UVY`Hu             }
!m3r(\\ s             opr_in.ch=c;Ak!vY,Y3y1I3hW GB
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/"YA|N&@Ur
            {
R n g)@5\y~A]*N                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
Mazi.vn                      Push(optr,opr_in);
y S7D%Q#g X(_g8|                      printf("optr入栈:[%c]\n",opr_in.ch);
E6[1zN'~5x Ei I u3u                      c=getchar();^\#C3| KK3Ed{2C
                     break;B Lk-z)g }
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
6^4s%W&Y8o)U1h+I4p                      Pop(optr,e); Z!D u6hRi!g
                     printf("optr出栈:去掉括号\n");.Z7w$lU.~7P
                     c=getchar();+UI }yn)L _
                     break;
1X:]wi(XU9tT"{].M                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/c`2mg*h*@D)`J.A3{
                     Pop(optr,opr_t);
O$UGV3d;R*I                      printf("optr出栈:[%c]\n",opr_t.ch);?'tOP6Qu-G
                     if(Pop(opnd,b)<0)
Pcqx)@h                      {
W$cs8j6A)Y\9F[                          printf("Bad Input!\n");
&NI [BgN"w$Ko                          fflush(stdin);
2Blsu{ _XL/] H^                          return -1;Dz$f h1f,\
                     }PJLU_,v)G
                     printf("opnd出栈:[%f]\n",b.data);/rV0j(V{{w!O5D
                     if(Pop(opnd,a)<0)9y%i/~vf }QN FP$H
                     {4DAVar } ^
                         printf("Bad Input!\n");(F P1cB-~ [
                         fflush(stdin);
4G^}+o5h5L8LT&s                          return -1;
f|,~ dq9a:u)B+G                      } r5W3?-Rh s
                     printf("opnd出栈:[%f]\n",a.data);
I7H gM)w0VNF                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/}5yl+T sD;lk
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
I;gb"@8Sz1v                      printf("结果入栈:[%f]\n",opn_tmp.data);
R`b.^`)y^3N:VCF                      break;x~8Ms v([ t
            }%P1HOn)W$_~c [l
        }/T7f l6nv!ul,rEO
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
Bx"zk5r     }k9g0},VJ+^
    GetTop(opnd,opn_tmp);4O9l0D GV.ba3N
    DestroyStack(optr);
Gy!C,X| R+m~[     DestroyStack(opnd);
1ERpA H2g HI     return opn_tmp.data; yK:CawU"p!n
}UGw6j*@Q#U'f
ls$ax0i,]3?
char *killzero(char *res,float result)q)IA.P"eQ.Q
{$n g;s7z~*Le
    int i;*h'RFLP9lQ
'[$h`]_:hw#ful
    sprintf(res,"%f",result);rAd$A"I0{#_HA4]
    i=(int)strlen(res)-1;#GWu#g/O&s
    while(i&&res[i]=='0')
eZ)ij'x;~dd     {T]-B QPH'R^p
        res[i]='\0';(h/{y{*y,e^
        i--;
z0m2ECjVD     }`r@5fBnc3W4p
    if(res[i]=='.')9e)L%n Z]6p(Z pW9d
        res[i]='\0';
n/n]5c8a#V:P     return res;
6{H6?&T#H,y-\} }&I7w7apf&u;D

Qs__"T0u9u o int main()
z/Tqj$I/i {
5HlXa9d m5A aaX     char ch;,eyM P PJ'C1}d
    char res[64];
U WvgC8d(r     float result;
t6Zsaa^%l:n     while(1)(F1Rs~0f
    {k&i u] e E&G&[
        result=compute();0lY7kkJU*cH
        printf("\nThe result is:%s\n",killzero(res,result));
*U Z$Ids*J*DA!t         printf("Do you want to continue(y/n)?:") ;
$d/|;~w/e*Lx!lv         ch=getch();
MPdO2w         putchar(ch);7d$G`-Y:K1[*|Gww,~
        if(ch=='n'||ch=='N'))pIm&\9o'C4N
            break;
0h)x2c2h!N r!i!F         else p-oi ^QE&i4A
            system("cls");*n w#i,z*u/w Re q
    }
e W |k/J/_     return 0;
XY:Y"r'~,q0aer }[/i][/i][/i][/i][/i][/i]
;X HH$LC PY9SNE g
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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