捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. O5YbOT7mDyAT&]
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
n]k|WN@Ye hr^ /**************表达式计算器************/
X'nc9T7xS #include <stdio.h>
5qjyo jQA} #include <stdlib.h>9zkd)U(b [%|,]:Ih
#include <string.h>%hHMx+K [
#include <conio.h>e(k6A`1wX%q
#include <malloc.h>
1wCRjM
(]8I_9VG"r S;P5I #define STACK_SIZE 1005x2w,hgC%r0uX
#define APPEND_SIZE 10#N"`8g{0m o0y PM
&T7B[3X1q%C9P
struct SNode{
f B3h!IN'?L&LO6k     float data; /*存放操作数或者计算结果*/ e a~ CN7i_
    char ch; /*存放运算符*/:qC*]'^'h5D^
};
&S&PK~7Nm|
9Zu P#c6H D struct Stack{(O-b(E!w3s&{NQ
    SNode *top;? v,`'Tiu1f
    SNode *base;
l_Jw8M+M     int size;4wf Um3p8wC
};
9Tx!st.i(I7?Y M-Ov#J
hF/_v~ FH /*栈操作函数*/4S]a2Jx5g.L
int InitStack(Stack &S); /*创建栈*/,o%n8^ X,Cd(@
int DestroyStack(Stack &S); /*销毁栈*/
'Gyx-a\ int ClearStack(Stack &S); /*清空栈*/
(mdV A'|7z x-?-xF"g int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/4z^3c p3|
int Push(Stack &S,SNode e); /*将结点e压入栈*/Ww4e4?P\z
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
-^6H%d({3k~u`a4r
1]8|"C)h:~Sxj /*表达式计算器相关函数*/_"bb+M Y hG d*rM2J
char get_precede(char s,char c); /*判断运算符s和c的优先级*/q`?'UW4h|} O
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
@5utC.O!H8]9{ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
o;}X}npr\ float compute(); /*表达式结算器主函数*/
0z*[ C#W`SX char *killzero(float result); /*去掉结果后面的0*/
y%X"nw!Z%UrU [+x UGG+Za
int InitStack(Stack &S)3slC@@a
{Jj*Y.Z G WC9I
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
w SI]%s a)z"FD     if(S.base==NULL)X\ ^\-?w \
    {T}"N'L OL QM8Q9Z
        printf("动态分配内存失败!");aQ9DYi e-f{9w
        return -1;
sK+fN/CiK     }.V O|+aj;DH
    S.top=S.base;
oSl:OD`     S.size=STACK_SIZE;
ZR4PY%f \1D;bJJ     return 0;
%zZ(AGR3z3S.A }
'Y8j_{1j0h i 1dl$M5ah7G6|7Q.^
int DestroyStack(Stack &S)&^S9vdR4y^X
{.A O*Sr$`NU
    free(S.base);!eu%K+U'i5n@
    return 0;
3N6Ag2^Q-Wm*x9~ x }W],w(SeK b

w/H'|#^~%FB int ClearStack(Stack &S)
|.O/V.n/Q C {9[SZh+Q)u6v%j
    S.top=S.base;NiU*^)u!X
    return 0;!MRs8Gw
}Oy,U0juu

{"\(UjX^,^3p int GetTop(Stack S,SNode &e)
+@ WIE0zJ {@_f.k@1r
    if(S.top==S.base)?cW)B n#|'X
    {+ciD ~tv hc^
        printf("栈以为空!");+gF4T$L kZ9o
        return -1;
/_|0W K mL     }"}9Z'd @ @ ^5f sM
    e=*(S.top-1);K(p Hz WY
    return 0;
D!n}R!zG }2E/c&yo-N8q#b(U
Cg@1Mj GI
int Push(Stack &S,SNode e)
-]\hi KDxP$tF4H {
k2I;m DS2]n%}     if(S.top-S.base>=S.size)
?$lv'f1[]:SI'x     {
9E?S+uL(t'zij         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));a9w:tsHp*n{5B
        if(S.base==NULL)F Z@!v:|`2Bl
        {-n0U'I F(j)Gp
            printf("动态分配内存失败!");)jk1l9U u/n9f
            return -1;3Q]g \$B,~
        }2L:B \"f(}W+E$Y7a }s
        S.top=S.base+S.size;
F!rjJZ         S.size+=APPEND_SIZE;
g9Y!s[0D     }_XXKPj@ R
    *S.top=e;
O\0^+[o     S.top++;#MVf4f8Z`
    return 0;
tx{U8P/v)O:u;ZLn o }|C&s'Vp Mk
)yw pc)Z7hf+y$@
int Pop(Stack &S,SNode &e)
$Z n0\[:wK,?*E {#[:aR4y"F I$R
    if(S.top==S.base)&p#D@@ sZ
    { [E~"iw yExNE
        printf("栈为空!");n X:O6MT,^1z4\T:K:[
        return -1;3ZFi X@ |
    }xZh ~ U8`+Lo
    e=*(S.top-1); ]Cr){)o
    S.top--;
q:cJ LH d     return 0;
*l$v:b9UPw }
4Tm']Qw~ k )FU4gw JW
char get_precede(char s,char c)b&\efj
{;A.T x*mVp6j[!`
    switch(s)
U}5J1i;y?1Z\1t     {/UZ"[6s,s8c
        case '+':                 lk%rF%ck/f;k h
        case '-': K)w{nm#^
             if(c=='+'||c=='-')
a'X'}6Gg ?{5Hz0F                  return '>';
s Y JK"? p ?}/J(BC              else if(c=='*'||c=='/')0Y m#^o/V
                 return '<';Z2xA(kFfz2^y3t J
             else if(c=='(')8? sAmZz#k
                 return '<';!H$d+x&?TYen,s
             else if(c==')')JE mTyI.N~7W
                 return '>';_*o4`oi H(Uq
             else
a2o4N,ar g'sJ'|                  return '>';,Y4z#rE5C2a@d
        case '*':
)LM {~ q0V2G)NVs         case '/'::l s/[Q W?)KW H"X$_
             if(c=='+'||c=='-')E3|`] h5i
                 return '>';_pE"Q]
             else if(c=='*'||c=='/')
W9R!k)y6c/v0d^                  return '>';
~^k7c+lR\ZA              else if(c=='(')P!igF6G?0@
                 return '<'; UD jlU+[?%D
             else if(c==')')U!S.\`n*} m,t
                 return '>';4?&O2~"g)]3j
             else
K:d*q~,yz^sF                  return '>';
s6D"uwOI6{(F         case '(':
3k"[Y r$^ fAp              if(c=='+'||c=='-')
L0d AS I Kt0E                  return '<';Ma K ?0p4}/LZ
             else if(c=='*'||c=='/')
k4_(h DL^2G                  return '<';rC+`4zN1g
             else if(c=='(')Z*y)U.Q5V/rE%[&a`)hd}
                 return '<';w0u|E Fo
             else if(c==')')
7K_o1w po9P                  return '=';
osHNsHK              else?!Y TD Da9e@ Q,b
                 return 'E';
O+{7B3_uC Y         case ')':
G!VB{V2u:E5T0g              if(c=='+'||c=='-').d|q ^F9o2n
                 return '>';.y;lpsa:@.`W
             else if(c=='*'||c=='/')
|S!X)on+d|V B                  return '>';
&@4?+vs:Em              else if(c=='(')0Q,r[+A,Gw5m]
                 return 'E';
1oDJ*Z;C2XHY              else if(c==')')
5l/?$UmZ_ {C3fU                  return '>';
0n'YR1RK n#hc7wkA              else
)Y {$S5e'?@:u                  return '>';
*db1^+yV         case '#':,Lfm&]Ukr
             if(c=='+'||c=='-')
I}8rtt eJ                  return '<';Vgp)O'z7C
             else if(c=='*'||c=='/');R+@&ZC+oq:{
                 return '<';
%sZ,d-T'i              else if(c=='(')g!Y&k Dd(Jt
                 return '<';
(W;aa`,Y;O q              else if(c==')')
4M psfB#S2U5|                  return 'E';
eR*xI7B,Eff              elses/~b2WU-~#UE
                 return '=';
i5Q hf{rou         default:5X1QW5J t
             break; B-]&b7A5obD"w{
    }
G u']qcL     return 0;    A$g#et!z
}'k-Z*A;h)F as\\P3a

8k[&` r4S9aEd int isOpr(char c)@+sx3nv }
{jD+gFzd _7y~h
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
m`"tb Um@4qe:[         return 0;
g'on-b'[6vi     else l4}-[7iDM
        return 1;
b)Z_$@Zn9jp#xp }
(DW*U?w2J!M ,Wns-j D-k!qm0Z]
float operate(float x, char opr, float y)d#n7FDB1Dau1a
{$^%H"O]^T m:W
    float result; so Nr ]:h9WI m$^`
    switch (opr)
:iJ^A!G7p6J)[V-B#Z0oJ     { Vn:NU8Z
        case '+':
vu,[h?aDe;p              result = x + y;,}&G/F_2Lc(t6Q-eI
             break;
6X$H:qo%Y/q EzT         case '-': K4q"y;S/b{ [
             result = x - y;P'l)kUi ]C
             break;
G.x;G2l)fJ         case '*':
;S(A ^ _/JdD5k6tE B              result = x * y;
"N^2N%c%Ws }              break;'N)z)}yKl@
        case '/':
o Ky#d9y.C`              if (y == 0)c6|&m:Wwa/iu7c
             {(f1Lf4gPaGX
                printf("Divided by zero!\n");
3t9C-B+Ix%iD                 return 0;
L$^W1c/jL U0B V              }
Z{iR's)c6i              else
p+o ]I(I2dSE              {
_Pan4UQ9Yn:c(d^                  result = x / y;K6k%G Y6aO(b6WI(e ?x
                 break;
l3p-Ok-\(K\8\f              }
P#Uv"azbG*H        default:
/u+H,E,cD8XU              printf("Bad Input.\n"); Dp[/S8k w
             return 0;
o4iX y jC P     }
G(m-SkB1t$NC+k(ZB     return result;+s Fx$CO$|-O.Tn0[wv
}   
_b_\ B3h .o0@ nDZ.N1Q
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/h7?3]1j3b.B
{6y] fVh
    Stack optr,opnd;
"y*uB;~ {j-u1f*x0G     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;@(TY6D!]j9gm9Bx
    char c;(Hgz8oJ8@Tds_G
    char buf[16];#E$C pUq7{| \
    int i=0; mNA,ML,a2X
   
:uTm([s     InitStack(optr); /*用于寄存运算符*/eiPY0{h
    InitStack(opnd); /*用于寄存操作数和计算结果*/H9G:Z2F1b#]Xn
    memset(buf,0,sizeof(buf));X)j/s6cU
    z-OG5S?:mS
    printf("Enter your expression:");c-U?,C H2V'G9AMq
        
Dj&VbTw6o     opr_in.ch='#';
)x-_a*Gvs     Push(optr,opr_in); /*'#'入栈*/ o{j1HO*i"\A0}
    GetTop(optr,opr_top);
yqgN)h)K2{#m B     c=getchar(); J@'H d&euU#rPe
    while(c!='='||opr_top.ch!='#')I }Y~QYC }b
    {U2L }1H8u
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/1@N[ g\!Pz:L$X n4R:H#~
        {
_`Y%h%r+hAjA             buf[i]=c;i1S6~ lY(U @
            i++;'U1m] hq.LE
            c=getchar();E$`6uM#]
        } JoH!E{I W Q#Mk
        else /*是运算符*/
5ljhlLTx9J         {eNm AY_
            buf[i]='\0';Bi&{#C;_P
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/$z k H*Af,R w
            {8r"U&M+D7| TliB
                 opn_in.data=(float)atof(buf);i-Gj(R&y
                 Push(opnd,opn_in);q:|O].U!MCs9Xm\
                 printf("opnd入栈:[%f]\n",opn_in.data);
+h d l u.`s i4ey                  i=0;
[r)}K!m v K*r9Un                  memset(buf,0,sizeof(buf)); F0e,U^9{)k
            }`#~B PzUqWF"q
            opr_in.ch=c;9E#a?X8S+TTw$I
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*//Fd5o!IpU/_ }
            {
]U6N8WH"WS9_6s O5P                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
}~fm)M1T                      Push(optr,opr_in);8SM7^z2q5_#j5U
                     printf("optr入栈:[%c]\n",opr_in.ch);'S:Ykw8}(O1S/G
                     c=getchar();x.N8oD LFp:C
                     break;
M%| mc2_b P:vd                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
"R6t@P)u1|8N                      Pop(optr,e);Y5Y5Mh'IIzh
                     printf("optr出栈:去掉括号\n");
k,eY*]/?nQb                      c=getchar();
|/\&W1|2ro;ctK                      break;'tql)p N4p4`
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/l$e!c RFk)]M
                     Pop(optr,opr_t);
1KL4q:Ub_L                      printf("optr出栈:[%c]\n",opr_t.ch);
`e&`6h&v C z                      if(Pop(opnd,b)<0)
8A Ul7bl4}                      {.H eO)s!]OB0@ R
                         printf("Bad Input!\n");
L5@y Pv%E&{3B                          fflush(stdin);
x)eG FL?(k(lLy D                          return -1;
NsD}Y^S!o4W                      }
7JdYlS"G xXa                      printf("opnd出栈:[%f]\n",b.data);
(_8w(M c,qT                      if(Pop(opnd,a)<0)
v#S UG\!X                      {
}w)rA0~OvUb                          printf("Bad Input!\n");
e\nv)Q P5^:JhF                          fflush(stdin);%P^ {CDBg5Rs
                         return -1;
$z D(s&Lft                      }
HI8b q\%b                      printf("opnd出栈:[%f]\n",a.data);
@;}czP[ W w6s                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
ox NlVm                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
I@,z9\k}SG*D2p                      printf("结果入栈:[%f]\n",opn_tmp.data);
bp)V_o!h"kY                      break;
,b N|3ZN#v0Y [|             }$Z)[1VQ%r7vj#~
        }
6_Z[{sE         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
}4t0~;en hYmJZ!v]&k     }K2j6I@-da
    GetTop(opnd,opn_tmp);
/z;d-UX#gWjk     DestroyStack(optr);
K:~f,N0npHG+O     DestroyStack(opnd);
%bP1O/h*qE#g     return opn_tmp.data;E#i"aW-@:j]l7e:{
}vM]+f(f6@ ]5s$k.T

[ nn5`(]1r.q]L char *killzero(char *res,float result) W n8eW7I+W
{
LY1JcP{&k     int i; y\PrB E

uo-h7t)hw\^     sprintf(res,"%f",result);F b3_ Dt8rY2yj(f4n
    i=(int)strlen(res)-1;k7uo Y7[ Wa6@h
    while(i&&res[i]=='0')S` HF _#}
    {
atZ(e0}X/w ~$`%c9ry         res[i]='\0';
{7I"W.Ul Oe3ju         i--;
0Z\&h"O+p-X     }
zrk&g_/bZ     if(res[i]=='.')Ch%wQG:T
        res[i]='\0';
_%Fn ? Q     return res;)E:UM,[#sWh8\
}.n%mIYKB%RF#~Wi5b/iN

.y{DKj!_4R1S/{ int main())T/E IA&m y*L
{5Z(A&N{;G2v0Em
    char ch;*D*|Fm-u'Z
    char res[64];YQ~q;[T c
    float result;
Q9|&ZD9qxV     while(1)U+~{)i-Sv1z4v
    {
WES i5XEfL$M         result=compute();
#X.FT/I"G?0`,D         printf("\nThe result is:%s\n",killzero(res,result));d-~h*wu6@6{[?.p*^
        printf("Do you want to continue(y/n)?:") ;
U(ga)? g;Bh;o#Ex%~         ch=getch();kJm%h Ws0Umb o p0`
        putchar(ch);
'B$^lx D)v%K7p         if(ch=='n'||ch=='N')
-} I9Z+w^ @T             break;
`G0V4CWj0S         else
.Ky}/?"{             system("cls");
2m-L6^@X     }
!ao7B{yG"j^ VU     return 0;CJ!`vq'J t*p
}[/i][/i][/i][/i][/i][/i]F N"Z1? @Ca|U F,ix

1j9_ TN%DN{IOa3b [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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