捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.`/K$C'Z Q0C%R
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=}C&uDe J
/**************表达式计算器************/
T@3c O6cW #include <stdio.h>y jf_+{ t
#include <stdlib.h> s\J_F V2Y HopF
#include <string.h>
F"wGx#^KV #include <conio.h>
^,Fz5~!|t%x { #include <malloc.h>
v&Ph,V7T6@ (xbpu.T'PR
#define STACK_SIZE 100
)@+XMUp #define APPEND_SIZE 10
Q&Q9}C N!{f4w7w#b9@ L;{?o3D&p`
struct SNode{
&L-j e a4oN3V(A?6x;Y     float data; /*存放操作数或者计算结果*/)et:D s"lZ5s
    char ch; /*存放运算符*/
z4g)rxAF-C };s.P#^1@-^*{F

'yG7f9HRu#na struct Stack{g-p0hpE.SC
    SNode *top;
F^|y2nB     SNode *base;
-RTWX g6b&f)R*k     int size;
/px"SO1|P };FC f'Hf

w)lM3G9~6]2J oO0q /*栈操作函数*/
:kg.^(hf[$N4w int InitStack(Stack &S); /*创建栈*/,c$\9^(V Pp
int DestroyStack(Stack &S); /*销毁栈*/aEJWf
int ClearStack(Stack &S); /*清空栈*/*T8~n;a(B?oV H6|
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
^9brJt'n'f int Push(Stack &S,SNode e); /*将结点e压入栈*/
v l8D6]aP(b@ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
?dk)khT Z X-[8@6t,Mz
/*表达式计算器相关函数*/
q?#M)g0A char get_precede(char s,char c); /*判断运算符s和c的优先级*/ i6_ `\a3m4|(m
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
B~g2SP float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
.XI*?n!]K k float compute(); /*表达式结算器主函数*/
2}o[ f+n~sg%VO char *killzero(float result); /*去掉结果后面的0*/ |{`!cmE4H? z8}y

A)Yl;iFv@X$jy int InitStack(Stack &S)F3Xn3f dX
{
1i#BKHt'~ w7d,o\:Q     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));{:MK:i"I4[J!tc
    if(S.base==NULL)#S&Djpbz9N
    {)Hd t;R"pcY{
        printf("动态分配内存失败!"); R/_1G:RDf7U"zxi
        return -1;
3KNOUKL     }3]4dz L*|~
    S.top=S.base; z0wCsAz%G[
    S.size=STACK_SIZE;,L] cb-P%Z(oq B
    return 0;
1y+M8U)] S B,Dc pK| }f)Q*oLK0f!KJ)} n
z2v;YWw%Ge
int DestroyStack(Stack &S)
;jih1h |w`gY {
)fKB/d)~-wl{Ae     free(S.base);
|pW6l_ K m*P     return 0;
8E5p`f|l.mx"N'e }
5v.zx'}c!{ Mqz$j7N F
int ClearStack(Stack &S)Uz1[~ OgQ"T
{$pEc \XCVAdpO
    S.top=S.base;
$e x&W+C8\PyV     return 0;
L)Pq$N(l TnV }
%B }{sWE3E }%_8`t7C:w1Rf
int GetTop(Stack S,SNode &e)
,G1K.r"XF8| et'M {
+V@m R&q0G,c'y:[&[#h"GWR     if(S.top==S.base)
5Fh[~;P:N     {
]-] IL@,C         printf("栈以为空!");@-d1y7W/i@S\-f nN:Y
        return -1;
YC5u2F;drMfVu w     }-a1Tx"e(l4z
    e=*(S.top-1);4[#]oQB ^ ~V
    return 0; iAEQ4xH*x\
}
-K0@ H| eB\
4k%aH+n-a:WQ;u_3C int Push(Stack &S,SNode e){%D8X2^0r g5B
{
|O%H`@)xHx     if(S.top-S.base>=S.size)I E5Mq ^'G+}
    {
'd |+YhWba         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
?7_"?b~TA#o         if(S.base==NULL)
!Il-W:[3e*Jb:^-o |         {'e [#w%^P%Z
            printf("动态分配内存失败!");uOP5P-@
            return -1;#O*yGi*OS3F
        };K|@(V4\ i z~
        S.top=S.base+S.size;
\n\Rc]]#Vv+n         S.size+=APPEND_SIZE;_u%]1zTih0Ul+u
    }
\p x T/m     *S.top=e;
CQ3LoU }     S.top++;
6@-kg(Plc7_4e     return 0;7ce8GMX |u
}
y@(DVvx
8EXb C,P int Pop(Stack &S,SNode &e)qQ_@0r*zq*R Fx,L
{y|5S%EAfj#Vg
    if(S.top==S.base)
K$F} } b(lg:P R(q     {
Bf yU1q [         printf("栈为空!");f4F4XqJ[%Lb/m
        return -1;
Wtr!D/~'G1p%xs     } WnN2hi,?F
    e=*(S.top-1);
p-K D!_&d3R     S.top--;8R1p D#PR
    return 0;
5R/o\0N_I }
5M*n`R,c R
E-D0Z){3qXz char get_precede(char s,char c)
Q8U:p)o|1oZ {
&ZE$p qz     switch(s)
A9TOwh     {;Zu8tz9x^Xx!_
        case '+':                 SOVc,U,j.@5e
        case '-':
W&l'~\d|              if(c=='+'||c=='-')2J hC0bRE9\)s
                 return '>';]HYP4LAqj v
             else if(c=='*'||c=='/')
V2m0n}"}&@A8c                  return '<';8@ C,T+u&@sTv
             else if(c=='(')
q$@3vco`o                  return '<';
y!K;]a(Gs              else if(c==')')
s1i d9O Ds/gA                  return '>'; QCSaO"i+}Q_
             else
'R3Xi6B6nm                  return '>';
#qJ{!^$q-N_         case '*':
5N.f!\'C6P%M         case '/':4kI0@N||:G.FR
             if(c=='+'||c=='-')b+d5`*OSi
                 return '>';I:{ m(eFe$@iH H
             else if(c=='*'||c=='/') ejw6a!ug}/n2_
                 return '>';$dt ^,?KXz8`&h"X
             else if(c=='(').q_7~tupio4??
                 return '<'; CF L,Mi
             else if(c==')')yZCa#\ f^w
                 return '>';
3EQ9h:rE              else7} p zAz },y*G
                 return '>';@"`7xM m"jh/a
        case '(':CjNTZk
             if(c=='+'||c=='-')
*So9VC&r%i)R.q}                  return '<';/qK4f'DEd$c
             else if(c=='*'||c=='/')
}/S5E E'H%?                  return '<';
7} C6r)LUF4^*c              else if(c=='(')
l6O t#}U                  return '<'; l6h8U2nmk"S@/C?
             else if(c==')')$h-tB+gy3h2m4i2S
                 return '=';
I1v0m3~nX[              else
$DX a:D%} H!}5?0bs                  return 'E';
-HH2M:X4{M         case ')':'PI?9RX1d sE6X6E;jLt
             if(c=='+'||c=='-')i"c#I|&nQ"|;y
                 return '>';
&D"Z@k)n8i`X              else if(c=='*'||c=='/')i)KX9Nzh*NF
                 return '>';
~8?f5g;JnV6L:R+?              else if(c=='(')4C c&W)jR)B-R1w*IU
                 return 'E';*Dt%A$sNC cn
             else if(c==')')
?eDauSkfBh                  return '>';#o!p O7CEMc
             else
FEW&K&U4T3R M                  return '>';
i[:u*i0D4O:]8}         case '#':
N{ @U7o1}L4n-M              if(c=='+'||c=='-')%W)k9v-? n_
                 return '<';
St&a:f)W              else if(c=='*'||c=='/')BXkP!^6tq
                 return '<';[uZm4Rw#|Qv
             else if(c=='('):?$q d m{7^Jd
                 return '<';
7{_rS:a              else if(c==')')ej jk0dM
                 return 'E';
W)Ar6~#Y x9{l&c              else
"G7f Sb I+~                  return '=';
6gt-B$G,S2Mu}         default:d4[&Wdk+h*Zh
             break;7C m_i E@HD0R:m x
    }
(wG)~9t(A1u.Q{zg     return 0;    1X"{7n${(}`;k)G-r$N
}She3@ H

/R$TW9GN8iX0x int isOpr(char c)
,} mn7@5D` {SE)u0w.P"E1d9qUA
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
*nrR}'kg5~R         return 0;
2ySh/G"_H-] S%N     else Ik]:i^Gc
        return 1;viH H2D$J
} dZ h HiY

KN$r$uQ Z float operate(float x, char opr, float y)_9aF'uS,O[k
{O;pg#u8yjZf
    float result;:PzCk[V:d
    switch (opr)4O5x+P3IkC
    {o {9~4E.q x+b&xI
        case '+': *xhrg#Ls8`*^Yh
             result = x + y;
0i:t"P5Sd)Uo&eN              break;
qA?xgk         case '-':
C2d E7w5S3X s5q              result = x - y;*OZ c ?h(S }(\
             break;R-uM:U]?;k
        case '*': (h4sPP5y|(C
             result = x * y;;pPun+xP
             break;
e"Ch)jv         case '/':
!MRR%S.]q              if (y == 0)'| Tl{ a
             {H.Zjp6h{-q8\
                printf("Divided by zero!\n");8f+[e:g~%n
                return 0;
n0rj6{ hk              }
Rr+~r/B*aW {              else3}5a2eu.r \
             {
%G5^%HJ3_)[{                  result = x / y;
6\?2_^_                  break;
Q(Ih1\ ?RE] u p M              }
;WEx ca0V+z3lQO]        default:
aj4V5I(EaQp              printf("Bad Input.\n"); X8v(G)Nb*\? E({
             return 0;GM+|V ^c&n
    }
n&bL5^_+R)G*O     return result;"z;Jw2g^O
}   
8Acs,^eg.GP
]Y!L%M.^8j#B(X float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/.\ \5r+s"Kh/re(v
{
+@'f)q S-e     Stack optr,opnd;
t Gy+C.FTpz     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
-M Zk#]W{zy     char c; f7Pk9u3mW0Y
    char buf[16];!otY'hQ%oNt
    int i=0;*] k r'vr? {!x
   
(_)CWp^[:hS3~)b     InitStack(optr); /*用于寄存运算符*/ j~:vy;|r
    InitStack(opnd); /*用于寄存操作数和计算结果*/'`/L8B6a2u
    memset(buf,0,sizeof(buf));"b6h0a+n3{/w{^
    g:`_%J9d T~3s
    printf("Enter your expression:");4g _s ]G`"a1s
        X e.z P$xY ejI2H
    opr_in.ch='#';6@m1r ^EY
    Push(optr,opr_in); /*'#'入栈*/9xd.iCW*])QN`"ob
    GetTop(optr,opr_top);
0NL9M _#T{z     c=getchar();
8I$x;TEU h#i     while(c!='='||opr_top.ch!='#')
ky(P la     { b b&u `HS
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
*c)W4i6h2ez         {!^%N'aY r
            buf[i]=c;
JFf yabP[6?             i++;
H b9ZB"w kso             c=getchar();
G)k^ec         }
&W\[k&Q         else /*是运算符*/
[p`$W:[.`h         {
;M$PsR\             buf[i]='\0';
5Kf!\.sJ4s V7_             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
5R%x)u+T`$g(b!R@             {
G.tV5pQ*a                  opn_in.data=(float)atof(buf);~.\`,\5o
                 Push(opnd,opn_in);Q|!u zNf
                 printf("opnd入栈:[%f]\n",opn_in.data);1@J@e_/I#|
                 i=0;}#[9{8|-{*L_
                 memset(buf,0,sizeof(buf));
5e2R(cF~J} l             }b5m@gi}I
            opr_in.ch=c;/Y&Z}[$z'g
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/o7?!V*a:z.J{j`
            {xZV7X*u |~R
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
!w r(Ig d*l;W9lA                      Push(optr,opr_in);{uz `DxiM
                     printf("optr入栈:[%c]\n",opr_in.ch);n"q_9A*~'Q0Rk
                     c=getchar();
}x%B&O!d6GF!}\"J                      break; H-r*]`/l0[0L IGi
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/4}Uqf\8s$q#g?
                     Pop(optr,e);
/Bc6Ep%U0q!h                      printf("optr出栈:去掉括号\n");1b_MM4w&i E
                     c=getchar();
Ygr O mt                      break;
.q-K;Q \ef                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
HS F I5t8BDL9{5V$?                      Pop(optr,opr_t);
P wa8rF!|5K-B6g                      printf("optr出栈:[%c]\n",opr_t.ch);m.hN.D/N"tH2P
                     if(Pop(opnd,b)<0)
9X}u7`v)W|.U                      {
m(k x6|&@e.z}\                          printf("Bad Input!\n");
E3? K/|4L m                          fflush(stdin); B8b9~BaX6N.cyv
                         return -1;0o/r!{0kDO%OG,G
                     }
k:TP8[]Hp                      printf("opnd出栈:[%f]\n",b.data);^F1Lh9Dz
                     if(Pop(opnd,a)<0)
1K!JP7D4i;X                      {
C9K;HF+[-g                          printf("Bad Input!\n");5RG-u+Z7]!X0{9K\ t0B9o
                         fflush(stdin);
Wg sX2f8FR\u%FQ                          return -1;-Zg%Ubk&Pm
                     }
-meaY#z;B6gC:O                      printf("opnd出栈:[%f]\n",a.data);*dp2n6vsC4Q H
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/*YN,}(C/p a.U:y
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
*l'Pe,oy!H9oW#r                      printf("结果入栈:[%f]\n",opn_tmp.data);0eb8dKO5?}
                     break;
v Nm N9Z#@T"g(g,gT             }5f-v Zv xa fK jw
        } ?~$H7GJ j
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                o!V ]#V X*P Q+KK
    }
s~-ng$N R l     GetTop(opnd,opn_tmp);
1O o#{kb1tAKDx     DestroyStack(optr);,~^J*P;AO
    DestroyStack(opnd);
znn5m#o%B zau     return opn_tmp.data;
m2l[ {8L,g6u } n-~3J2D)K1C
&iR m^%q? K1q
char *killzero(char *res,float result)
zmg\#Dm7x5[ {t&T6l0d%OM
    int i;
Q1Q!TI9c8nR7rf
D4sW%V!Mr0h     sprintf(res,"%f",result);
CT7\I"WZx _p+H     i=(int)strlen(res)-1;
Z:b v y6Psx h [     while(i&&res[i]=='0')
2i3h*C@'J$QtVQ!U5I     {
r:}[T\)h&S b         res[i]='\0';
'`7a7xY;TR         i--;
3N"V.^I&KUu     }
yx:Q%P v}czW     if(res[i]=='.')"{&b+n(`I6oC
        res[i]='\0';
}+G,f1?V     return res;
;] r,RI+p%a }Z)~@#xP*VL/n6h

g3Q n%w(Sz0` int main() z5H#M-srVF+T
{
oiJ3G"Jf     char ch;
J)bF8HtN2T     char res[64];
w^ D/^*t$cG5@~pt;dW     float result;
d7Bbt P$Nr-C     while(1)
,Qc3I/Ga(d     {
wd;`;ZK |]S:C6\         result=compute();
0n m_[^` k         printf("\nThe result is:%s\n",killzero(res,result));
(n$Gp'l1tp.~+wv         printf("Do you want to continue(y/n)?:") ;
/X a gu jB J         ch=getch();
?ve;W@l*Wy         putchar(ch);
7k!M1I [:H)~%K`         if(ch=='n'||ch=='N')
9CE@Z-^c             break;({+M Tq7`
        else0K,FTA3[M_[
            system("cls");
+t|4ADNJ%wq     }j b2X aV h0f
    return 0;\ C*P7Gj
}[/i][/i][/i][/i][/i][/i]
*Nf8L!cI;j{&MD
;[ ~!cD'F/G`vw [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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