捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.Z:Z`E/j$w"C.U
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=nY^} E
/**************表达式计算器************/
7R@?-Qf9\ u"BI-Q #include <stdio.h>
G/S Y.h#E~A #include <stdlib.h> t"Or.hPW
#include <string.h>
.M%p3m8z7x #include <conio.h>
$xcXR z#rj #include <malloc.h>
S.Nn$F ]U x:IJL:eiND
#define STACK_SIZE 100
m2TX%N%dC7G9ZE #define APPEND_SIZE 10
.W%L1g,SD5HL}s0H mi9EN5E
struct SNode{
N&szQK`[5\ [ U     float data; /*存放操作数或者计算结果*/
epkTM"rf^^     char ch; /*存放运算符*/
%?^2Np0U U$X&YJ1[ };&BNr A g

9R t"V.v(t [lf%tq struct Stack{*o'Y.y_;UK n5O(d+PTq
    SNode *top;
U#Pz2FPM     SNode *base;
AKy$~'`"E)ZO(C0Lr     int size;
1v0OQ;lx5Zj };1@?J5ZR]l.G qp%[r

h[o$ikEd:P!~a /*栈操作函数*/
!}&a0Z9Q-p8NvHp int InitStack(Stack &S); /*创建栈*/
I G1e#wA int DestroyStack(Stack &S); /*销毁栈*/1S V+i3T%a
int ClearStack(Stack &S); /*清空栈*/
QD7T"O#f#`h/E int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/'jc4s&{%uS `9_
int Push(Stack &S,SNode e); /*将结点e压入栈*/
+mHRp9l,W int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/+p)H Hx,? tG

,H nl!n+v*Ev5^N /*表达式计算器相关函数*/#`vT)_:L N4?9Z o
char get_precede(char s,char c); /*判断运算符s和c的优先级*/xd+kYMUx,@$J)_Z
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/zDvSm.y
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8?7Nf!E-bB float compute(); /*表达式结算器主函数*/n:p&S0b-_7b3t\
char *killzero(float result); /*去掉结果后面的0*/ !y-A%Dn F^j0D R

vn8CjZ~:Pi+k int InitStack(Stack &S)a9oG qa2v
{Ta{Vb
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); r2\5TV:Y$_o,u*d0c
    if(S.base==NULL)
DF8F:G_kC4|9]O     {
RkZd+dR&{)}         printf("动态分配内存失败!");
!R0R1v$kW*H         return -1;
C9O{'V\o     })n+tLpl+{Ry
    S.top=S.base;
}Qd [5\Su     S.size=STACK_SIZE;w wIm2eJU
    return 0;
@;@C}m$a }6AKSyh
*wN/aTI!U ^
int DestroyStack(Stack &S)
!{|;RC e2Q*p {
5\+p:IK+C-z)B gA     free(S.base);K7[ m2HeM#`r-`+rD
    return 0;
e9S,]3C U;C }+s.D&e5Lt

_%u)WbJ(rfkJ int ClearStack(Stack &S)
'IZ1UkF7}8B? {+Z*H.tB-U-` Ay:v
    S.top=S.base;$hniqaJq _
    return 0;a-FxBOk T
}fkT.@[
[4R7^"HIb0Px*D
int GetTop(Stack S,SNode &e)
4k9FA-P q1Be(]t {7B*SZtL
    if(S.top==S.base)
M6\aOL2E     {
UL2x2e&i$e,N         printf("栈以为空!");
u/z.{ k [JS         return -1;
*d)R#s&Cx3o"tm     }Stq%E$@e{
    e=*(S.top-1);
qB l]s;p c     return 0;(~#d6Qt)i
}
V&M0a)O0u(hD%Z^ R-@q(P
z%?j+w3d7e8nk int Push(Stack &S,SNode e)
1s6~lO)]9]$| {
\7Vk9F$Z$O     if(S.top-S.base>=S.size)K*d.\0w W WX`]
    {@.a/XJ-` @/p0I
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));TkH5K,ZR A,ME
        if(S.base==NULL)
$k{+c:Se,q1J8A"zOw4m3G yi         {f%B-Sv L:p7z
            printf("动态分配内存失败!");E&n\1r)Y? _T
            return -1;
#Bvc#?'yvOv         }
j'~.B^ O"\*JU0~         S.top=S.base+S.size;+P+yl5q3sF
        S.size+=APPEND_SIZE;7m5l[pq9H
    }Y$R]6Fx,pqA*u@
    *S.top=e;xZr Uue6r
    S.top++;
.~#Rb_6S k     return 0;
8hS8h+m ~7@] } j4[;Jy}Z6ec%|F
L+S3Lqf8K8L m
int Pop(Stack &S,SNode &e)L3`%H&m [(ZX0x
{
yx Og n(F [     if(S.top==S.base)7}p!dwweV6l
    {&{N#[B"l
        printf("栈为空!");2FS7A({1|y-x
        return -1;^ K\[Y\9Z
    }9V2t:u$u E.\K J
    e=*(S.top-1);
rbLuney     S.top--;
(U3`&E+jqz:J5P     return 0;,la_ VR5IuO]
}
1b;j+~^DA(U
9nh YD&XWi+E9v*K char get_precede(char s,char c)K|C$MDS+o
{
j8gHF$|o4[!U|H     switch(s)s,g5jVm_I
    {4xv,A(pL,L
        case '+':                 
/z+_l0Uh         case '-':;hN7rd \n
             if(c=='+'||c=='-')mD X au `%Z5u
                 return '>';/c~TyY[yh h
             else if(c=='*'||c=='/')
8?U&^ k Z"O R                  return '<';
_*j"SG$]              else if(c=='('))l F vcR"x s%s
                 return '<'; ?hd_$hjs
             else if(c==')')U/Q-_+eNI
                 return '>';-I4HF%F}!x9\ J
             else P6?G/z(e&Fc+rH
                 return '>';7I$H_w4JHM#a
        case '*':o0d+^s.E!ah%me
        case '/':(k7A2dYf
             if(c=='+'||c=='-')Q9e%_Q7}] X#|
                 return '>'; m6vW+g4Dn*aR:R.^
             else if(c=='*'||c=='/')
]{aD8n                  return '>'; v]/so.y7? s
             else if(c=='(').T/q.PA8qW,[ N:ezj
                 return '<';
A$L+uIV;q ^8G~              else if(c==')')
?~y"l MG                  return '>';
YtB.{)r"{-m/{.FKa              elseVnUu$S(o1c;J
                 return '>';
I.q sZX#P         case '(':o p+Av8O"}yyv_s
             if(c=='+'||c=='-')
:zwo@u0fn y                  return '<';G-J#}$t ? N
             else if(c=='*'||c=='/')
?1\@5d2u                  return '<';~d4B)S`/Rj ])i3q
             else if(c=='(')
3d/W II]`[X8U                  return '<';QO&]!\Y0O
             else if(c==')')
h&n*|E |6ws^D                  return '=';
gRG&h3p              elsec|2u_&e9Y-n;r T
                 return 'E';.mr,bw3z^PbD
        case ')':
[4Fb4m+n Md(cyN              if(c=='+'||c=='-')f;a,y}?6@4rIRM
                 return '>';{r0?!N+V9Ij'K,T
             else if(c=='*'||c=='/')Kkr6OPY`_CZ
                 return '>';-aS/|2D4as
             else if(c=='(')
2H9wx~-S                  return 'E';
\u]~HQ gf7l              else if(c==')')"RHn4|K r
                 return '>';
$?0TH&D5n[3h"K F              else HC\6G q0V
                 return '>';
w5o3E:vRR)[7i         case '#':
gU7Wq^CW              if(c=='+'||c=='-')
A.xG,HG0q                  return '<';o&M;s5fAC)Z
             else if(c=='*'||c=='/')M lT"k{8JzW1O#Q
                 return '<';)H8W@:`zq
             else if(c=='(')xH-vVO4TpmO
                 return '<';
%W0E So]D              else if(c==')')7^,ew*w5fR ]3GHiC
                 return 'E';fUA2@8q,cZ5p
             else
3m"P]eSY                  return '=';
p/W8e e(@!O@B         default:G2e%TS*fBY8S
             break;
9A"~&\.ft|!p     }
5B#X-A'Q@'J     return 0;    5]+Bj ih*oX
}
({5A3A1R#m Q;C
%K g-f2} W S*x int isOpr(char c)Q;Y&JE~oF!a&dH.c(`
{Zk`_,Qv2o(k
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')R%a we'K$S\
        return 0;$g"G0MB1W#w$[Z'p
    else
~B|rYD         return 1;
0}%\j)Z%Zj@*L o }#V,O g:A iQ
5nkk]$I/U
float operate(float x, char opr, float y)
3}9O6}b#n*RI {
)p qs-K^1E(A     float result;#XCfL2?Hdl5|
    switch (opr)%HB+e+y dGomK[X9Y
    {
F}%G%t\         case '+': e;J(\+~L
             result = x + y;UY/[~&A;P
             break;*f?k#Z6`2P
        case '-':
OE QXC:@/v              result = x - y;b+iD)sT7J$Uo4P
             break;
8h DXc6Wynq\         case '*': V4IU:Ad`3fyK[!o
             result = x * y;
]k2Wv7f9^ ]6T              break;~pXN:xb#a6P1^
        case '/':
#aNb)k#C5M]t              if (y == 0)P nd ? K}E
             {,mg%rfW`]{
                printf("Divided by zero!\n");Q2c+Ny `(E/_M I0i
                return 0;
&~)F$Y!C!GU9PF              }
$zN;]&iA&h-R]              elsecy E }x ~DsZ/h
             {
oxh0A`'B*u                  result = x / y;
_,K9GNcy2nH#SR                  break;wDR Jf\ Vh
             }M:GsE9O8o#NL'Ba%G~
       default:
r rP`4u`uh              printf("Bad Input.\n");
&nGf5O5L#{              return 0;
}9Q m\,r2txko6S     }
]Q%SKD.I2W#S,[6| qA     return result;R\$Q0G2aH;]
}   
I%Te$q4Gn:@w*_P Q/[Gh-X)o4~
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
X ]2iKKzRTO z {
~&y2?*l Lx;B     Stack optr,opnd;js*~;F9x/G/u
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
6H%V6G'|w4I1S3p     char c;W%mt$A*j9Ps8?0U
    char buf[16];s eB!mWo)t GH
    int i=0;;]-r*dy2v*g
   
y*Z*z Yjh     InitStack(optr); /*用于寄存运算符*//Ws&`;v5@}.hm
    InitStack(opnd); /*用于寄存操作数和计算结果*/*Y.s7z@wx3{ \/l.E3KG
    memset(buf,0,sizeof(buf));
(A$H6w^NYX]     s3`(w-O;b }QT
    printf("Enter your expression:");#r(h`.])wd$nV#p
        Y+H S%Uo[gS!J
    opr_in.ch='#';?(n6|.Eq'j8H
    Push(optr,opr_in); /*'#'入栈*/ j9V2r,O {$v
    GetTop(optr,opr_top);L-Y4r{n5?~7Jr[
    c=getchar();
-p.hF2c"S)?Z     while(c!='='||opr_top.ch!='#')
!f%OY/p5hq-e l     {1```aZS$k
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
TjSQ#Y)_1S         {Cq tC*a zx2H
            buf[i]=c;
~M0@u7oJP W2p             i++;
"a![!Th$Tq$N#\_S             c=getchar(); l%nY5bn&a!S
        }@8}Z| s;SJ-d
        else /*是运算符*/|;s)U\Y f3x:N
        {
k$S2v+a.W,OJ             buf[i]='\0';
tJpZ6OQ}3e             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/y(FD [2B4w;X!D(v[2w#V
            {"iha8p H;B:}1eE
                 opn_in.data=(float)atof(buf);
JO2gn(UE Ko v                  Push(opnd,opn_in); I:g-P@^o4`4d_
                 printf("opnd入栈:[%f]\n",opn_in.data);IZ S6@,o:[`+bv
                 i=0;~ w }L3e:j
                 memset(buf,0,sizeof(buf));
mVI?3s'C:@             }M'o"L0M}A{
            opr_in.ch=c;
+^f{#]umYg] Eg             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/:i1v.Lpb
            {
Y,jR1m$`x^                 case '<': /*优先级小于栈顶结点,则运算符入栈*/RD^&T\)E},R7kZ
                     Push(optr,opr_in);
1Y x @AR!^1F                      printf("optr入栈:[%c]\n",opr_in.ch);$K/IC-G.z#f7^KE
                     c=getchar();
/T|G5R)D%I j                      break;/H }(pWS X
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/g!@e V/Z LCs
                     Pop(optr,e);
j1x!M J;u mr#n                      printf("optr出栈:去掉括号\n");.yB ?h:f ZC oG
                     c=getchar();4g&Gd9Y?!b
                     break;R7[Wh+[
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/}*u:^!jcN#xw%q
                     Pop(optr,opr_t);
yVw8F?{                      printf("optr出栈:[%c]\n",opr_t.ch);(y K!Z p4oS8@w
                     if(Pop(opnd,b)<0)
T#r&w1z1g SBt                      {
I` ]B!A?3][+qL                          printf("Bad Input!\n");
who sCZa                          fflush(stdin);%S`2`:[7O[Wrb
                         return -1;xz#oBvD/Z
                     }T-M,ythe
                     printf("opnd出栈:[%f]\n",b.data);F1`m:b b
                     if(Pop(opnd,a)<0)
;u.@$rHd c FZ                      {-XLvxkPJR7T
                         printf("Bad Input!\n");
1C6SGgE/p2xD P!e0u                          fflush(stdin);
iS9O[:~6jpcp                          return -1;e%dAlq1UU
                     }
Fq,[e FD                      printf("opnd出栈:[%f]\n",a.data);
m3B!seYRr7w7F                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/ \#_.n K&`W;P1Xj
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
.n A+z0|7M7t                      printf("结果入栈:[%f]\n",opn_tmp.data);\]v}Dj
                     break;
+O7J0?8aF:g             }F,OV*hug Wi$o]
        }
6R,~"vy4Py].e7E6I,_         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
DEp;x(q~x p:HVW     }
n?8c8V ^P;Fy     GetTop(opnd,opn_tmp);
|-D2M@M Z.F'X'z/x     DestroyStack(optr);9fsyT\
    DestroyStack(opnd); iN%kG{t
    return opn_tmp.data;C%L`Qdsb"_$a
}
nm`e+Pd"s1Y
y)^)\Ir1Dy char *killzero(char *res,float result)@Eyn;yx5Z
{
q.v{|rq/[^     int i; twX q K M3K

G1?*@o]m     sprintf(res,"%f",result);
jx"u)t}     i=(int)strlen(res)-1; MNK7mZGJf
    while(i&&res[i]=='0')+gDM _ IZo,J
    { |(_(wF \[BG
        res[i]='\0';;[~)w/b/F/G+w
        i--;Rc$]ZyP
    }
| gA$}H     if(res[i]=='.')
~z5iC/@R Ml         res[i]='\0';
R[\V\(o*m&n!N     return res;v c!pM B[E
}rN8Q Z:K ke]

SB]/F:RW:vy int main()TQt7Aq4n;}v&t
{M8o&_,c"gB
    char ch;
SYBhj3y     char res[64];
0Z,u/O2Hv     float result;
N:p%_~X2e$`?k"q     while(1)
M%y0@v!spa(v @ v3m     {[c8qz9k\p
        result=compute();K+`v8X2c9W Bk
        printf("\nThe result is:%s\n",killzero(res,result));
6s6y L)u:W*s[so]\         printf("Do you want to continue(y/n)?:") ;/]r%oAT%`
        ch=getch();
E*h~~ v         putchar(ch);wD7K3Fxr q#N/D:p
        if(ch=='n'||ch=='N')2D5m+m)^MaK;X
            break; B{,x!s R2o6Z
        else
mWFW-T+U0c             system("cls");p}$P7Y*y9~i
    }
Q b9{u$f,at;d     return 0;
Y3NP _2P%Gb }[/i][/i][/i][/i][/i][/i]
-nd|8]!J'Q vu1r t0B,Dw
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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