捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
%F6g"D9N HL 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
"z7[T3KCm9R /**************表达式计算器************/%z3Rf]!c6Y;V#x
#include <stdio.h>
z%?v ?wz;O #include <stdlib.h>
4m"j? @p8rx vS #include <string.h>
9J;TB#N(@ ju #include <conio.h>3txT6C@^5ic
#include <malloc.h>\)G(SD,Pr T8Gja

8m [d{ J*L#_^ #define STACK_SIZE 100
S/]^.d7aN4x0puS [&O!h #define APPEND_SIZE 10v2`-~.jP7p
eff}QxuJ
struct SNode{
4gc*J^#B \&`6s     float data; /*存放操作数或者计算结果*/SZ3sOT;Y,w @
    char ch; /*存放运算符*//C H V|IX
};![V!PID"K;s`s
9B!@.q8`P+[
struct Stack{
RA9nY;{     SNode *top;0Q~s `N
    SNode *base; Ta1_6{2e/T;pY
    int size;ks,{Da9cV L)gB
};e.YS(N(_
1MQ*l{!T
/*栈操作函数*/ ?'_!ok2b`6o
int InitStack(Stack &S); /*创建栈*/-z5zpoM'O'y
int DestroyStack(Stack &S); /*销毁栈*/
KI/XP5Kz int ClearStack(Stack &S); /*清空栈*/[$Z_;o%L8WCy
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
9D_ R7Kj%f/U int Push(Stack &S,SNode e); /*将结点e压入栈*/8o-ka A R T"|;}&k
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
5rP V `"p;hJ
y9|HY y /*表达式计算器相关函数*/
!S ]6G"fAlT char get_precede(char s,char c); /*判断运算符s和c的优先级*/*h2@ ?,c ?9r
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
3M!X!k6p#a float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/'\ko(}/v'nv
float compute(); /*表达式结算器主函数*/
H-`]vB char *killzero(float result); /*去掉结果后面的0*/
\0?6]2E.}d5}pZ h3p Ip)}]$K
int InitStack(Stack &S)HD'iR/Q'P)i
{"fkV"f"J6x]wFd/~@
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));1mZ{;r;\v%@E(q@
    if(S.base==NULL)
vD(Z\ t)D!dJve.@     {vE eM?
        printf("动态分配内存失败!");'K7^H9d9G
        return -1;
us f@5s-[6U'PX c     }}n{6CZ0|
    S.top=S.base;8t]A*T-[i
    S.size=STACK_SIZE;!if/su(fU5J
    return 0;
,{!Pw7^kO G6z+Y }aM"n,gm$g G
9e6?Z/Vex|
int DestroyStack(Stack &S)
h`ANh*v F fh {a6doo&GT0kzF
    free(S.base); ?p9v"q5AX
    return 0;
/n G9t7O:X8K0S/c1{ }
5N-`4f8A9EJ *z pC PN v,T
int ClearStack(Stack &S)n^$i4}}s
{
&o Nq~g     S.top=S.base;*t&^1U6z9cw&M u{ A
    return 0;
(K#S^ m$BEp } Ecq2ya8H
]{ RptD
int GetTop(Stack S,SNode &e)
Qw Lw,m4P y c { ZIT2e7aB]-c
    if(S.top==S.base)8x-vT6o s C;IN
    {
}I${Y^Q\6H#C         printf("栈以为空!");
%p#b6Q'Y1nWf2[         return -1;
)j(t1Fl-R C2La     }
QN%d2JwK3T     e=*(S.top-1);
-f F._T"J.\#RQ     return 0;a.b@5oe.P
}
MH\3gU2n'L
QQH@9ic int Push(Stack &S,SNode e)7Acg(K&L] LK
{
0Xq'N%H [ n     if(S.top-S.base>=S.size)
Z N6zA6JMG     {&hC"Y6R5v*ZY:B
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));!?U.EA"G
        if(S.base==NULL)a3[4~*O0w:xLly:k
        {$`2J1G(gGrz:U
            printf("动态分配内存失败!");bs2w!XK\
            return -1;
q-z O Z {1cd         }6Ya&k&j%m
        S.top=S.base+S.size; b:mM4\9x
        S.size+=APPEND_SIZE;Q+J[7R {l;N7AD
    }0Cx)w7liM!o![
    *S.top=e;
4@+Y X:sT&D6c     S.top++;
s+CG;]{     return 0;A!X V)e#? I~K
}
w A0d @ S7] A`
9|b:pG0]HCD R/c int Pop(Stack &S,SNode &e)
0xu8X`3a@ {9_#vtcV&{6f
    if(S.top==S.base)uLm-{A
    {5K,S5z}n+H/PXO
        printf("栈为空!");
d*xgy(nvJ         return -1;
Lv[~r&~Dwqv VQ     } { dd)WS Gmo
    e=*(S.top-1);5{ zo:C Bz
    S.top--;
I}%WI_ V     return 0;
Q7d A(lTa })a(ce+z5l;h;[&h
~DD)i;M0N
char get_precede(char s,char c)$P%N4X#o5j(Y+w zo
{*B!|%}!]z"AJ
    switch(s)
d"xHQ7i5ZZ     { e4zUL@
        case '+':                 *jHtd mR
        case '-':;}-dg2L)c+D
             if(c=='+'||c=='-')[l2{`,[e ~
                 return '>';
M3d%I^7O(s              else if(c=='*'||c=='/')
K/}AvdnO `{1W3R1b)@                  return '<'; a8m.n{0@vs;o
             else if(c=='(')
Ld$rGj'?#ux"P                  return '<';
9J x$aj a*mu              else if(c==')')"d"dF2nO#s!@a1U
                 return '>';
z8r3VANB:V)JL              else 4i|0h rX%j @Z
                 return '>';
_.Hv$N'Za         case '*':
a%]8y6jOP         case '/':!ztwb'p$x*E+Gh{
             if(c=='+'||c=='-')9HH!WNrVb"fW lhX
                 return '>';/|Oi)hUk
             else if(c=='*'||c=='/')*VnPir~GW:P
                 return '>';$f"\)AMij(s%E0E R'b
             else if(c=='(')
,|LZvH+qz b                  return '<';3tV Nm\#{i*EJ
             else if(c==')')
&b {4|*kM4G                  return '>';4~mG;SG2O
             else8dGLYetk0RS
                 return '>';pf0}D{&sM
        case '(':
t%IUzE l#x              if(c=='+'||c=='-'))[ N#U#Pz3O*W[&Z
                 return '<';
9Xs6`9w c3Ff`-n              else if(c=='*'||c=='/')+y{0k*s4o|H-DJ
                 return '<';5gI~qk!P{
             else if(c=='(')
gh1z/n M ANLh;ai7}                  return '<';~f9H'NmIM&iLR
             else if(c==')')
"g(nF.Jo(hT                  return '=';
d/S7x1LP0{"R;}              else
+v N:|C0jd [] P                  return 'E';feV@PK:t*C
        case ')':
'?pfaH#\j~!Z              if(c=='+'||c=='-')%J`-A;t"jg
                 return '>';
E6Wf0|{y x6y              else if(c=='*'||c=='/')"`6Q*{(N/B Oy
                 return '>';
4Ao8WdUAY!FoM              else if(c=='(')
*F8T2M#r$x o                  return 'E';(eZ"Hj_F&x
             else if(c==')')t%k3]u5k!V
                 return '>';0G+W&rX#o"[:l-H
             else
o;@H BtkmWI                  return '>';!k F c&BUp)q8y
        case '#':
|'POM,SO0k1m(p(@              if(c=='+'||c=='-') il~+r9i{5[E
                 return '<';%vvo_/h?3h8| tf
             else if(c=='*'||c=='/')
(^btV^!Q^k                  return '<';
@2u"b(R4f+X0w              else if(c=='(')(cg5cSf M+C#?
                 return '<';3W g l3iU$T O r
             else if(c==')')
VE |_cN#G@                  return 'E';oa,hdyt&s%UJw
             elsey$fs)n'\
                 return '=';
(gp$EC"B[         default:%y Y[l va
             break;Q X-T"}(p9[
    }`@L { _bH q
    return 0;    4k!|/K-I,}#A~
}&Z8Ajh+@8c,H
C2x[@.DS)k\
int isOpr(char c)"Km9W jBwuM
{(w!e p*@/^bMTp
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')m9b(D&@ p,n9B2Wp8?
        return 0;%jY8s.l'y&`#o ^*C&n
    else
.Wz BW)mrz'n         return 1;]3[6C_9hH
}
!NRC~4ip
D0?@*G9B float operate(float x, char opr, float y)
vsphl']n4J[ {
!X$[7W l$o!bGtc     float result;
v0N K`7_6A     switch (opr)%`7j:O Zj
    {
6Hg4@5jP._*V[         case '+':
{2S6R.Vl X#Me              result = x + y;
sbq&Iox`%y              break;QH$q&kJ;Z^~eL
        case '-':
VumL%S/tR              result = x - y;8Q8]J nh0[
             break;
-{#D?~7l9]0uPB         case '*': "Bz;f-s a
             result = x * y;
3dmRN!n*M n              break; kF9A'~J1ks
        case '/': e:S1D6^ Z o
             if (y == 0)
)B)rT5y:{ ZE["t              {4y"u/Z0Bz e2u
                printf("Divided by zero!\n");F4_F Be
                return 0;
$W(k^4?:{$\y'@z              }
BegJE+D              else
dy0k+t*r9Oy-I              {
U UN4\J-T3B twY                  result = x / y;P2_N4s,U*S"Wp ~
                 break;
$\cD,p&l*^              }
:{3M/_7KSA        default: w&j\2g#rJ7{L
             printf("Bad Input.\n"); D0T.X'i} Q
             return 0;1Q)m1a+U5~~%x6lV:s
    }@F9S,}#rok_
    return result;
%\8N:fA z8B c }    tKswbzV _\$e3b
-d u7aw2g"k
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
0A,unz2zZWT {OzC-m j g#sL6`;Ss#H
    Stack optr,opnd;9S7l4}iT9K]$]TN
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
D5xjS V+|0k     char c;
im5}4G7Em2|0t     char buf[16];a6_gj+P/v
    int i=0; VV\%O,pP R$J a
    9p.D[\ Kz
    InitStack(optr); /*用于寄存运算符*/
2^nl(x0U `Jj     InitStack(opnd); /*用于寄存操作数和计算结果*/
\ @|dB Qg \     memset(buf,0,sizeof(buf));[3?\__4[U
   
W;Nea x$~ A ` K     printf("Enter your expression:");9@"k Z+LU mX l
         hDk&Y1Ho[b+W
    opr_in.ch='#';^-B!z.E\G4I!E
    Push(optr,opr_in); /*'#'入栈*/
)NJ-B$s y#B HwQ     GetTop(optr,opr_top);+`*C[,];J2S*f
    c=getchar();
3g)[9H%w$\8s'?x Cw&e     while(c!='='||opr_top.ch!='#')0v&Zvc;^Rdq)]8I
    {
,V%{E d }Z`/hF         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/!bD8tuw
        { t3S Z I(y M#g
            buf[i]=c;K Xs-z)h JF6d
            i++;.n3Z6VZ!ps(C;w
            c=getchar();0T%X"q T%S:~4c9h
        }
9|B^h*e)? g         else /*是运算符*/4A2k#V(nV|*e*a,}~
        {
`)Y f9CQj             buf[i]='\0'; ^4FBV4RZ
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/)xWlG@
            {/`)u(j Ku.{b3U"_B!}|z
                 opn_in.data=(float)atof(buf);q(p4{5D\(mkP/W$OD
                 Push(opnd,opn_in);
}i0Xo:Bm)u$['z2Z                  printf("opnd入栈:[%f]\n",opn_in.data);
x\/U@~0X:]ehw                  i=0;
| ~`9|M)N&L$HB                  memset(buf,0,sizeof(buf));S4GO1R4_V
            }8p#m9y#V ~0x
            opr_in.ch=c;
8l \2Hxu q             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/.RVn F] z@
            {Rj z?s*yH/DL
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
-Nz}Nz2i[                      Push(optr,opr_in);
7dQ8d4s6Z.L                      printf("optr入栈:[%c]\n",opr_in.ch);r&@AVZ_ qt
                     c=getchar();
2nKcDCOPK\                      break;q[e/J/`
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
9OZax,X.n#]!^T                      Pop(optr,e);
h{(R:EP9nfN U2[-W                      printf("optr出栈:去掉括号\n");
_'oD+Xs6s A:AH|0R                      c=getchar();
J$c-_6J3_-MGs'~                      break;
uN~!y6L:|`h;zP                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/C9Xm\2|\f
                     Pop(optr,opr_t);
:x#G6kn_                      printf("optr出栈:[%c]\n",opr_t.ch);g$|Y~ D;r
                     if(Pop(opnd,b)<0)
o5s4jZ!^\                      {
;f@P2S)S{                          printf("Bad Input!\n");Nz[&g#G*X Y
                         fflush(stdin);
(Als O Hn2P F                          return -1;
K-]4{i1_                      }
k&T}[xN/V                      printf("opnd出栈:[%f]\n",b.data);#zdO+b(MM%F
                     if(Pop(opnd,a)<0)K,\;i1p:Q1v2te5q
                     {
[UW%F:JuW|0c"X0R                          printf("Bad Input!\n");
mgM"p$m }                          fflush(stdin);JEQ d0|5dD'?
                         return -1;6m:Rspnz A_
                     }kr,L2_;{~
                     printf("opnd出栈:[%f]\n",a.data);
cINu(m \                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
wxddOOwuz)k                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
%O OV;@nSb;^,H                      printf("结果入栈:[%f]\n",opn_tmp.data);
k*Jo/k!cS                      break;i&}'F%R0hcx
            }
9F8r6Al;? L         }#f@W0\y2[Bm
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                HV7Q?QpUUD
    }
8[sX HAk~tv     GetTop(opnd,opn_tmp);
;?u9A-j7_l J*K     DestroyStack(optr);|Dh ]g,_o
    DestroyStack(opnd);
t6Cp2|Y)`Ue     return opn_tmp.data;
*S#qAyv HI }VP%v)c2Qc:i|`&z{

MZ'S^_ nnKP char *killzero(char *res,float result):Gg u6_Se
{
)pp)B4|$a0P)dg     int i;
O^ y@&z1hTk v} u0t}/i'Z
    sprintf(res,"%f",result);L`%Y;gq%g}7~
    i=(int)strlen(res)-1;
g x;s#CD&vF     while(i&&res[i]=='0') f:cC9~7PKe%Z
    {
)P{@/]h.W AK         res[i]='\0';)Pcc%` @ d]7QwO
        i--;a^'wF9n s
    }H/{4ZO)X%AGs
    if(res[i]=='.')
"`b;E;H(|R s6XRf0^v         res[i]='\0';
Vo^;E\4X1T     return res;+n2o*CV'G"n U$u4x`
}&G^h:?o"^V

+_ C ?%iVU!q int main() r\@lAi%Hi-[
{?8|8l@|^+?:e
    char ch;
OM~#UA!JEynQ     char res[64];n*e3]3P3v4}R
    float result;s_LxQ_
    while(1)
C}*n%? ~:Ua"_e     {#P d-}Vn7T"{u
        result=compute();
k7[&q1s[6n'{1[         printf("\nThe result is:%s\n",killzero(res,result));
9TV5dg,f&VP         printf("Do you want to continue(y/n)?:") ;
;] ymK7vd         ch=getch();T"b$YKGE m
        putchar(ch);
XoBOfJc6[z XR#M         if(ch=='n'||ch=='N')
p+sm$~Bv EL             break; lDmv!\/a^
        else
*k%wz4r-|,r2A3`             system("cls");_ yjos(J
    }V zd9eo(h8w F
    return 0;
+mMR;@ y-z }[/i][/i][/i][/i][/i][/i]%?~ g6g%F.s$`

aFb6MD*r? [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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