捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
#p.b FtAn,` 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
A7~"rY V oj o /**************表达式计算器************/)K@!m `/_t6P
#include <stdio.h>
.i6X*^'Sv j7D%o #include <stdlib.h>
q1a:TchL7M*`b #include <string.h>WfN ?5ZNFes_
#include <conio.h>
5` ]Uh9d$`2W4b"c #include <malloc.h>m I0]I!Y7Q
ne AoO^u
#define STACK_SIZE 100@ Ec:H1\-`2T
#define APPEND_SIZE 10.jXIu2gSt]R

e-}0msA"?AP struct SNode{M|{#}h)s{C&C
    float data; /*存放操作数或者计算结果*/
7SQq3A r-J     char ch; /*存放运算符*/
Pc(u0}/gNpe"B };
6CeL3Q-tP.U;mI #M5H;O5s Swb'J
struct Stack{)s3C7t{ V3K |
    SNode *top;
B3U:X-B4z6k0]8I{     SNode *base;
ZL.dyl`9`d#d     int size;
B ~S8K\,E!|9t9eJ };*Fz|6J LGO MQ |{

#G"vbo^4cv%N /*栈操作函数*/_W&[+h3^#yVF+^ L
int InitStack(Stack &S); /*创建栈*/!QI)Zl`:pGpZ
int DestroyStack(Stack &S); /*销毁栈*/JA }!zCa
int ClearStack(Stack &S); /*清空栈*/
#c-^%r,HaL:r*C#dO] int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/(C$Sc$T!M&W
int Push(Stack &S,SNode e); /*将结点e压入栈*/
^2T%n"|R;A3zc;b int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/HO/Q,}?ke
\/} PdMH @
/*表达式计算器相关函数*/
B2Hn]HI \UL char get_precede(char s,char c); /*判断运算符s和c的优先级*/J9j y-C&H3D2H,_*f!K
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
b{2\3k/S)^"] float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/1vp}/W"pft
float compute(); /*表达式结算器主函数*/w5]MBA,S
char *killzero(float result); /*去掉结果后面的0*/
A%t6?%_E o 1T3E4ul7]`
int InitStack(Stack &S)
&SA!B"v @nh#~ l#u _ {W0Vi5e6\*KIX
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));S M7pMP{
    if(S.base==NULL);o;X Fm6kR r:h
    {
5w T%[@,s"l$D$D9Y         printf("动态分配内存失败!");3t+n:P\ E7c
        return -1;0\[gKQ-c6gk
    } zWN3l O
    S.top=S.base;
XDU'u o&z&Q | D2z     S.size=STACK_SIZE;
/L*t*I-_gYL     return 0;V v)I:y+}]zdA
}
%u2SN,w%Ro
n6|P"J4Hnp"DT V xFA int DestroyStack(Stack &S)|rb1{#zn
{r\t$o} jqaUg
    free(S.base);{g;j[0K Mv9s2F
    return 0;
e _%~R2dJ;B }
yS&w^:U+y$c
aYaM\["n}!o*r int ClearStack(Stack &S)
URqst2SG {*L6{/k3f[N['lM}
    S.top=S.base;
0?~I6O.L"Wh     return 0;j V.^:n.Z:bC'N
}G$L'Waxr;D
[1^f2T0G1nV]
int GetTop(Stack S,SNode &e)
WjsJZ3l2]$Y0P {
^*v}S IFd_y     if(S.top==S.base)~k0t C4[%?;~u4B+ls
    {*d%i;dj EHJp
        printf("栈以为空!");CnF'u+GvS$E&iX
        return -1;0Sv(V`~"` G
    }1cCFS&A;X7Z} p&Ms
    e=*(S.top-1);r |+p@8dY#v `E
    return 0;x"{[*`$}-J(Y
}
3CFz!Y]{*f 5F'D1Yh D
int Push(Stack &S,SNode e).Jt$y-y,LNt
{
*b,k6Q)Vab*z!P     if(S.top-S.base>=S.size)
Qc@X:w a7XE     {
r zW/`;l?6Yj         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));1U%O/Vy*L~4a
        if(S.base==NULL)3k H/x0Z,E4`8? d
        {
"v Tv G(vY b             printf("动态分配内存失败!");w"VVtfNE/?
            return -1; bB4\L V$||6AZ
        }qr|"Y[L}
        S.top=S.base+S.size;!|4?yx]2x9?q.M&M
        S.size+=APPEND_SIZE;Aq0p8Y%l [:x
    }6B ~Fx s(}MS
    *S.top=e;
yhe@JR6r     S.top++;#}S7FREv
    return 0;
|_9S d+kQjCGY }!O}3^ Jr&w`(j+Y Y
]n:FrE"g
int Pop(Stack &S,SNode &e)UAZh\yZ
{
Zl1pO&E+j}     if(S.top==S.base)
IQc2Gtp     {
9O7F7@ z$_,j8^         printf("栈为空!");
D m+O@$?$f \{ @4L`         return -1;#w4e9b3z2q-K4J]
    }
:fXgI,hU @?.h     e=*(S.top-1);
tX7S}tE8|%`;YZ     S.top--;s5b L,n X2~
    return 0;
g7d$_.BD8y} }
%|e?9MS I9Xd1?Jg
char get_precede(char s,char c)
6[ o7f.dp/_mC0cR {
f6M'@V#zv(tuE g     switch(s)
5];} l8RJe{h     {
*h/N5BN2_Xq-Y         case '+':                 dm]R$q uC:C @
        case '-':+T S)Y qh)v)G%?1o
             if(c=='+'||c=='-');dI"J~)S1pQu1x
                 return '>';zR7jR7H:NT7lY
             else if(c=='*'||c=='/')
.`;ufy9d;o~~                  return '<';
vy)N]6f+aY$XCV              else if(c=='('):g"Gv!w dw_*T\`"BE
                 return '<';:E#f}+Z!{9D&_aO
             else if(c==')')
;nKhK9n*H                  return '>';
N g/CF4X#S.Y              else 5i[-P7HgWx1t
                 return '>';
2fl6q-j'X         case '*':7Fz%O0U A(@9r
        case '/':
}"q#U4rw6B&O              if(c=='+'||c=='-')
2u.i/p$X+n_*^.t                  return '>';.u,~%R5Hii"h+e
             else if(c=='*'||c=='/')?s I-J:gW-Kc
                 return '>';Q)U$I;U`TUx
             else if(c=='(')
t1f]3dF|$Z                  return '<';
:|"C6nmH e|1C L              else if(c==')')
~~+b4tA H                  return '>';oL[Yb
             else B7{#l z;i/n.l3kMB
                 return '>';
/J d|xDX[!Q         case '(':
'j(q3B4E7u"`ze5l              if(c=='+'||c=='-')_5Ec7z Of8k3T.fV
                 return '<';
hxFP*l:|jp              else if(c=='*'||c=='/')
#V.e5G{$?\_*cvR                  return '<';w"VtA&B~B%A
             else if(c=='(')
H:M jxF$Pw^*I                  return '<';
}n"F(}?/zA              else if(c==')')
m-c|'{ml4d                  return '=';
,U J Q)o _/k              elseQOs0x1p8h3f
                 return 'E';W ? gk?[
        case ')': NFt*\UX"l
             if(c=='+'||c=='-')
6a)j9y&S k*s ] N]                  return '>';rN1T8g%D]![y
             else if(c=='*'||c=='/')
b}9vy n"B+N1O-vQm                  return '>';
_8h:uvQV4n              else if(c=='(')
oW%iHd                  return 'E';
$Eu%hAj jJz `              else if(c==')')
Yj#dP6}:j/E8v                  return '>';3t6Lv4pT[N
             else&ncH#Z1j8H
                 return '>';|:ffLM:b7R2|
        case '#':
Ei(nR(_\)k\g              if(c=='+'||c=='-')-tg4v [o-E:\
                 return '<';d"}_3Ro:E
             else if(c=='*'||c=='/')
{~ z$L Ms$W                  return '<';
n0o O*VSA              else if(c=='(')
(QyP-C)\q9Q/Ea                  return '<';
Jnk4@3d,A%ul              else if(c==')')\ r;| Z1x|9tX[E;gk
                 return 'E'; J:L&GKn
             else|N | X{&O
                 return '=';j BR0M\}
        default:
SI-t5` t6|              break;
-L5E6A @@H;t7r     }7@xiY:iHW
    return 0;    /PQN9S,c(L yL
}
p[e.tq+k,H?U N &pD'R Vn
int isOpr(char c)
)bif"D;]'W't~ {
}} N Yx     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
'r#\)m,Pq0j+G6C         return 0;6lHj(N-b(s I5A
    else
(q P`\"G;jm#Y A         return 1;
lwRw%s@ }
1h$?Y/z6Uvf2s;p 1T8e|v*Xt
float operate(float x, char opr, float y)
$nY K#O bB,ej!g2k"{ {
$O(`TS%a!Wfd     float result;UZ^V[K;Ht}#f
    switch (opr)
@6\dBLCR@%h L O     {H"g@/}!@+]v hDX^
        case '+': ,fn@;R$O8OVGc
             result = x + y; Mi9d P0`$w_!s
             break;
OMMhpM3{5[ jfY%et         case '-':
Lu/O0U*oX5]              result = x - y;,tjws \!J|
             break;+e,aD0~}4mq Np
        case '*': fH ~%gF%eLK W
             result = x * y; U;v!j&xpq
             break;
w OY-N|7p         case '/':
3Z$E4e i9|0[ lb:K              if (y == 0)
"I0ucGFD_WO              {
@(?%} z&a"^                 printf("Divided by zero!\n");
]Lu`C                 return 0;
;n ?{4I} d PSc*q              }5o!ME })p
             else
%T!_HQ^6]3M~              {-t d!S%T2St
                 result = x / y;%l)Q d6bL Zg/X&A(Cu
                 break;
8di&mDJ)]              }]-qpoWb8z
       default:
2LP,Y3a o(sw              printf("Bad Input.\n");
/L0B6D c]U['b              return 0;
0J(P"}*zp B R#ri     }?(f rE:u8D#Gg5}
    return result;?tIc2CaXP
}    1he!kV zYD{
%zF/Fq*e"G
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/9qSz8Mxz
{V.aa0~[H#d(EC
    Stack optr,opnd;MO Rn]Q3\K
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
o HPvJf     char c;A9yz-h#u*if;l}2A
    char buf[16];a%yS:V#}(VLZ
    int i=0;B;V?0vyG
   
r'n&l&FzbC     InitStack(optr); /*用于寄存运算符*/
Ky` \O ?'^f     InitStack(opnd); /*用于寄存操作数和计算结果*/)d$z Zm h}k]Q k
    memset(buf,0,sizeof(buf));
X7o1E^'DsC    
l0Y T5fYx8b W     printf("Enter your expression:");?*KoDqa
        +K;E~h?Jj4w5_N6b
    opr_in.ch='#';
lZ4QD*S#S/jk5rc-M     Push(optr,opr_in); /*'#'入栈*/&\c.Zm6g1z$d"ij
    GetTop(optr,opr_top);
na,x#aa XT1eRQ     c=getchar();-}:T"kgk7x6b
    while(c!='='||opr_top.ch!='#') p |,G? heJ(E}j
    { {9F7b+{6U
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
_u;h0u(]         {L~b(I:E:H-{
            buf[i]=c;
5_yw.h8_,oAte5kP             i++;
'E"E(We@X V)O             c=getchar();0~{i5ORO._
        }
M7m,H0yYn6YP         else /*是运算符*/
#D G ~r W b K-c         {m ^2e"x:@$a*cQ$BJQ
            buf[i]='\0';
P(w W$peU6wJ             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
fI)BdE'jH             {!sKM"c1k)q"u$a s
                 opn_in.data=(float)atof(buf);
[;M!M7j4b!\"V,D(yF                  Push(opnd,opn_in);%\(M \ER@
                 printf("opnd入栈:[%f]\n",opn_in.data);y4] f3LZ In;P
                 i=0;c3q\hz
                 memset(buf,0,sizeof(buf));6Oe?KE\Q*qy
            }
*gqGOzJ9Z$M             opr_in.ch=c;
*caz4j;ma             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/+A*`5@$X;c
            {
p*ap7v`.[}!R                 case '<': /*优先级小于栈顶结点,则运算符入栈*/k1c,?p_(L$dS,byF
                     Push(optr,opr_in);,\kH'p_g0^`7y[+`
                     printf("optr入栈:[%c]\n",opr_in.ch);.Y(Oi$[v~9e
                     c=getchar();Zn3iN(r1a J
                     break;3S)em2M$^+Um?.U
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/.fwR,uESKr
                     Pop(optr,e);2AjuE QV
                     printf("optr出栈:去掉括号\n");+NhZu)[
                     c=getchar();2X&u g.\M:l {?
                     break;#BN(o1C)j!Ga:m(F
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
&S9O7["`o^                      Pop(optr,opr_t);
sKN&[%Dg)a                      printf("optr出栈:[%c]\n",opr_t.ch); z@y2K {?"x'M*JB
                     if(Pop(opnd,b)<0),IR4u x6V8M
                     {4fd2F Y%Y0Y9]O J8h
                         printf("Bad Input!\n");
zNme5t{$S e                          fflush(stdin);
B1p@+cl e,D [/m                          return -1;
uH7R'{Xj Rf@f                      }$L5P,MN0u
                     printf("opnd出栈:[%f]\n",b.data);
']h8A8~8Jjl!k                      if(Pop(opnd,a)<0)
:jU s)i)bGv9I                      {Tg:Y/Y8j$i
                         printf("Bad Input!\n");
;J3{\p3K-a5cx                          fflush(stdin);
Jg$^d6~3`O w/K                          return -1; W-|;L-?bf+]
                     }'v/N,R-A)Aaq"Y
                     printf("opnd出栈:[%f]\n",a.data);
]$M q/m6mu\                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
U(u:nKH*P |-Tp                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/i4J:q8Z \\:kSS
                     printf("结果入栈:[%f]\n",opn_tmp.data); ZaJMx0N+\9H+O*h
                     break;
c*C#z]t$W9?8]"UY             }
4rU[2i:H)Jw4\A         },_ J mUtV
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
@;?H4N!Lt     }2Z$N/L5y(I\k
    GetTop(opnd,opn_tmp);
~(t)T1j%s/[\7N V     DestroyStack(optr);9R sg1H9J~g%R\
    DestroyStack(opnd);3po\"U uJ7Q5Ep
    return opn_tmp.data;aV1\&B8F
}
JT[%bxik0u!MJ Z(|{S:F?~
char *killzero(char *res,float result) Z'l4y/vG RS!vIK(o
{5R BR*b:\
    int i;:tE?4Ep1Vu2K8] _ P

M T!@9t+o~tk     sprintf(res,"%f",result);
)Qfy*jJ0Nz     i=(int)strlen(res)-1;
%NjiL,e"F7B4q     while(i&&res[i]=='0')XR5o4iJh
    {1J^C5v;x[c
        res[i]='\0';
%_7c*}K~~5EJ         i--;
3yLx"Y&t.E#~:_/i!W"Lr     }
)u r0N d7G}4d     if(res[i]=='.')5G2o9@BW H
        res[i]='\0'; h$b~7^&N}i fB
    return res;
V E_)Q|5fB/X n }
#w n5_&{}"~6[ 'pV+d1y|O$}
int main())aY~vC X
{
i'HTO'J [-z$IO0J     char ch;
;~*Y*qI/yFXX     char res[64];fE*V~gq
    float result;
Ac"dBN^0R     while(1)
)U&V DHt7n'\vU5h     {h#Bt| aZS,l
        result=compute();%xj;N,e5`z2t
        printf("\nThe result is:%s\n",killzero(res,result));
5f8e mIK+u         printf("Do you want to continue(y/n)?:") ;{9k%J x:},H#E6[f |]
        ch=getch();%F6p+gF)b;E Dm }
        putchar(ch);
9]*ik E8lJ         if(ch=='n'||ch=='N')
$G_6?sa1h6R{             break;
7n(a+Lo_ jH         else)GVA/Qd_
            system("cls");
2ny$q;\/H     }
z^'RN_ I+s"nw     return 0;
1m0x` p~P }[/i][/i][/i][/i][/i][/i]
{#g`$]4m!ET8j
W?'o,tal0|)d,m [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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